Programming lesson
C++ MIDI-Skalen-Player: NFE2140 Projekt-Tutorial (Mai 2026)
Lerne, wie du einen voll funktionsfähigen MIDI-Skalen-Player in C++ programmierst – inklusive Menüführung, Datei-I/O und Fehlerbehandlung. Perfekt für das NFE2140 Assignment.
Einleitung: Warum ein MIDI-Skalen-Player?
Stell dir vor, du entwickelst eine App, die automatisch Melodien generiert – wie die KI-Musiktools, die 2026 auf TikTok viral gehen. Dein NFE2140-Projekt ist der erste Schritt: Ein C++-Programm, das Skalen abspielt, Daten speichert und lädt. In diesem Tutorial zeige ich dir, wie du das effizient umsetzt.
Projektanforderungen im Überblick
Dein Programm muss ein Konsolenmenü bieten mit drei Optionen:
- Neue Daten eingeben und Skala abspielen
- Daten aus Datei laden und abspielen
- Beenden
Für die Skala wählst du: Typ (chromatisch, Dur, Moll), Startnote, Richtung (auf-/absteigend), Notenlänge (100–2000 ms), Instrument (Klavier, Trompete, Gitarre, Violine) und Wiederholungen (1–5). Nach dem Abspielen kannst du die Eingaben in eine Datei speichern.
Struktur mit Klassen und Funktionen
Nutze eine Klasse ScalePlayer, die alle Einstellungen kapselt. Das macht den Code wartbar und erweiterbar – ähnlich wie bei einer Spiele-Engine, die verschiedene Charaktere verwaltet.
class ScalePlayer {
private:
std::string scaleType;
int startNote;
bool ascending;
int noteLength; // in ms
std::string instrument;
int repetitions;
public:
void play();
void saveToFile(const std::string& filename);
void loadFromFile(const std::string& filename);
};Das Hauptmenü mit Schleife
Verwende eine while-Schleife für das Menü. Mit switch wertest du die Auswahl aus. Beispiel:
int choice;
do {
std::cout << "1. Neue Daten & abspielen\n";
std::cout << "2. Datei laden & abspielen\n";
std::cout << "3. Beenden\n";
std::cin >> choice;
switch (choice) {
case 1: /* ... */ break;
case 2: /* ... */ break;
case 3: std::cout << "Tschüss!\n"; break;
default: std::cout << "Ungültig!\n";
}
} while (choice != 3);Eingabevalidierung – Fehler vermeiden
Prüfe jede Benutzereingabe auf Gültigkeit. Für die Notenlänge: 100–2000 ms. Für die Wiederholungen: 1–5. Nutze Schleifen, bis der Wert korrekt ist. Beispiel:
int noteLength;
do {
std::cout << "Notenlänge (100-2000 ms): ";
std::cin >> noteLength;
} while (noteLength < 100 || noteLength > 2000);MIDI-Nachrichten senden
Unter Windows kannst du midiOutShortMsg verwenden. Öffne ein MIDI-Gerät und sende für jede Note eine Note-On- und Note-Off-Nachricht. Beispiel:
HMIDIOUT hMidi;
midiOutOpen(&hMidi, 0, 0, 0, CALLBACK_NULL);
// Note On: 0x90 | Kanal, Note, Velocity
midiOutShortMsg(hMidi, 0x007F3C90); // Note 60 (C4), Velocity 127
// Nach 500 ms Note Off
Sleep(500);
midiOutShortMsg(hMidi, 0x007F3C80);
midiOutClose(hMidi);Skalen berechnen – mit Arrays und Schleifen
Definiere die Intervalle für jede Skala in einem Array. Für Dur: [0,2,4,5,7,9,11,12]. Für Moll: [0,2,3,5,7,8,10,12]. Chromatisch: jeder Halbton. Mit einer Schleife erzeugst du die Noten ausgehend vom Startton.
int majorIntervals[] = {0,2,4,5,7,9,11,12};
int startNote = 60; // C4
for (int i = 0; i < 8; i++) {
int note = startNote + majorIntervals[i];
// MIDI-Nachricht senden
}Datei speichern und laden
Speichere die Einstellungen als Textdatei, z.B. im CSV-Format. Verwende std::ifstream und std::ofstream. Achte darauf, dass der Benutzer den Dateinamen ohne Pfad eingibt.
void saveToFile(const std::string& filename) {
std::ofstream file(filename);
file << scaleType << "\n";
file << startNote << "\n";
// ...
file.close();
}Tipps für höhere Bewertung
- Effizienter Code: Vermeide unnötige Kopien, nutze Referenzen.
- Funktionen: Zerlege das Programm in kleine, testbare Einheiten.
- Arrays/Vektoren: Verwende Vektoren für dynamische Skalenlängen.
- Fehlerbehandlung: Prüfe alle Eingaben, auch Datei-Öffnen.
- House Style: Halte dich an die Namenskonventionen deiner Uni.
Fazit
Mit diesem Tutorial baust du einen soliden MIDI-Skalen-Player, der die Anforderungen des NFE2140-Projekts erfüllt. Denke daran: Der Code soll nicht nur funktionieren, sondern auch sauber und lesbar sein. Viel Erfolg!