2017-11-12 5 views
2

Ich schrieb ein Programm in C++, das die Anzahl der Noten in einer .mid-Datei zählt, die Nummer jeder Note (A bis G #) ausgibt und diese dann in eine Datei ausgibt. Es findet nicht genug Notizen, aber ich kann nicht herausfinden warum. Ich habe es basierend auf der MIDI-Datei-Dokumentation von midi.org gebaut.MIDI-Noten-Zählprogramm erzeugt falsche Ergebnisse

Beim Lesen der Datei wird nur nach dem Statusbyte für Note auf gesucht, 1001nnnn, und dann wird das nächste Byte als Notiz gelesen. Ich habe Anvil Studio verwendet, um eine MIDI-Datei mit nur einer Note zu erstellen, und habe das Programm verwendet, um es zu analysieren und es hat nur eine Note gefunden, die korrekt ist, aber wenn ich es für viel größere Dateien (2000+ Noten) verwende wird nicht alle finden, und manchmal wird es finden, dass 90% der Noten ein oder zwei Tonhöhen sind.

Dies ist das Segment des Programms, das nach Notizen sucht. Die Datei ist offen in Byte-Modus mit ios :: binary

//Loop through every byte of the file 
     for (int i = 0; i <= size; i++) { 

      //Read next byte of file to tempblock 
      myfile.read(tempblock, 1); 

      //Put int value of byte in b 
      int b = tempblock[0]; 


      //x = first 4 binary digits of b, appended with 0000 
      unsigned int x = b & 0xF0; 

      //If note is next, set the next empty space of notearray to the notes value, and then set notenext to 0 
      if (notenext) { 

       myfile.read(tempblock, 1); 
       int c = tempblock[0]; 
       i++; 

       //Add the note to notearray if the velocity data byte is not set to 0 
       if (c != 0) { 
        notearray[notecount] = b; 
        notenext = 0; 
        notecount++; 
       } 


      } 

      //If note is not next, and x is 144 (int of 10010000, status byte for MIDI "Note on" message), set note next to true 
      else if (x == 144) { 

       notenext = 1; 

      } 

     } 

Weiß jemand, was los ist? Fehle ich gerade eine Komponente des Dateityps oder könnte es ein Problem mit den Dateien sein, die ich verwende? Ich schaue hauptsächlich auf klassische Klavierstücke, heruntergeladen von Midi-Repositories

Antwort

0

Das Problem ist sehr wahrscheinlich, wie Ihr MIDI-Editor die Dateien erstellt. Viele MIDI-Editoren schalten die Noten nicht wirklich aus - sie setzen nur ihre Velocity auf 0. Das kann ihnen einen rohen Schmerz beim Parsen bereiten.

Sehen Sie sich die rohen MIDI-Nachrichten in der Datei an und Sie sollten eine Menge an Velocity-Meldungen sehen.

+0

Ich überprüfe bereits 0-velocity notes mit: if (c! = 0) { notearray [notecount] = b; notenext = 0; notecount ++; } da das Byte nach der Tonhöhe die Geschwindigkeit ist –

2

Nachrichtenstatusbytes können weggelassen werden, wenn sie mit dem letzten identisch sind; Dies nennt man Laufstatus.

Außerdem können 1001nnnn Bytes innerhalb von Delta-Zeitwerten auftreten.

Sie müssen alle Nachrichten korrekt analysieren, um Notizen erkennen zu können.

+0

Alles klar, ich werde auf Delta-Zeit nachlesen, um zu versuchen, das zu umgehen. Ich ging mit meiner Implementierung, weil ein Großteil der Midi-Events nicht mit dem Notenwert zusammenhängt. Nach dem, was Sie gesagt haben, kann ich es vielleicht in einen Schalter() für das ausgewählte Byte ändern und eine Groß-/Kleinschreibung für jedes relevante Statusbyte haben. Vielen Dank –