NeoGriever: MIDI-Dateien - Verständnis der Struktur

Ganz einfach eigentlich. Ich versuche krampfhaft mit vb.net eine Midi-Datei auszulesen und sogesehen zu "parsen".

Ich hab mir jetzt mehrere (großteils deutsche) Definitionen und Anleitungen durchgelesen wie bescheuert, um zumindest die Header-Bytes einer Midi-Datei zu verstehen ...

Ich wünschte, mir könnte mal jemand verständlich erklären, wie das abläuft.

Das hier ist ein Ausschnitt (Wichtig. AUSSCHNITT) eines tracks von mir. Ich glaube, ich hab dort auch die ersten paar Noten drin. Sicher bin ich mir jedoch nicht.

Wenn mir jemand DARAN farblich die Header-Bereche abtrennen könnte und mir dann quasi die ERSTE note nochmals farblich abheben könnte, wär ich bereits schlau genug.

(1 Zeile = 16 Bytes)

4D 54 68 64 00 00 00 06 00 01 00 02 00 60 4D 54
72 6B 00 00 00 0B 00 FF 51 03 06 8A 1B 00 FF 2F
00 4D 54 72 6B 00 00 16 39 00 FF 03 16 47 72 61
6E 64 20 70 69 61 6E 6F 20 64 72 79 20 28 4D 49
44 49 29 00 B0 0A 40 00 B0 07 64 00 E0 00 40 00
B0 65 00 00 B0 64 00 00 B0 06 0C 00 B0 0A 40 00
B0 07 64 00 E0 00 40 00 C0 00 00 B0 65 00 00 B0
64 00 00 B0 06 0C 00 B0 0A 40 00 B0 07 64 00 E0
00 40 00 C0 00 00 B0 65 00 00 B0 64 00 00 B0 06
0C 00 B0 0A 40 00 B0 07 64 00 E0 00 40 00 C0 00
18 90 30 08 2B 80 30 40 81 75 90 30 09 2B 80 30
40 05 90 30 1E 2B 80 30 40 81 45 90 3E 1B 5F 80
3E 40 01 90 30 34 5F 80 30 40 61 90 3C 29 43 80
3C 40 01 90 30 10 44 80 30 40 45 90 3E 24 43 80

Falls hier keine Farben funzen, einfach mit Senkrechtstrichen (|) abtrennen bis zur ersten Note. Zwischen den Noten (falls mehrere enthalten sind) diese mit Raute abtrennen. (#)

Ich will das endlich raffen.

Grund: ich habe vor, ein tool zu basteln, welches es nicht als töne, sondern als Animation abspielt.

  1. @@NeoGriever:

    nuqneH

    Wenn mir jemand DARAN farblich die Header-Bereche abtrennen könnte und mir dann quasi die ERSTE note nochmals farblich abheben könnte, wär ich bereits schlau genug.

    http://de.wikipedia.org/wiki/Musical_Instrument_Digital_Interface#Nachrichtentypen hast du gelesen? 9n startet eine Note, 8n beendet sie (mit n = 0 … F).

    Qapla'

    --
    „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
    1. @@NeoGriever:

      nuqneH

      Wenn mir jemand DARAN farblich die Header-Bereche abtrennen könnte und mir dann quasi die ERSTE note nochmals farblich abheben könnte, wär ich bereits schlau genug.

      http://de.wikipedia.org/wiki/Musical_Instrument_Digital_Interface#Nachrichtentypen hast du gelesen? 9n startet eine Note, 8n beendet sie (mit n = 0 … F).

      Qapla'

      Habe ich mir durchgelesen.

      Aber ich verstehe die Header-Struktur nicht ganz. Daher farbliche abgrenzungen. Weil ich mit den Informationen auf der Seite da stets probleme hab, exakt den Anfang der Notationen zu finden.

      Die Noten könnte ich bereits problemlos auslesen. Aber wie gesagt: Erstmal den Anfang davon finden. :/

      1. Hallo

        Die Noten könnte ich bereits problemlos auslesen. Aber wie gesagt: Erstmal den Anfang davon finden. :/

        Laut dem Wikipedia-Artikel hat jede Note ein führendes Steuerbyte. Wenn jetzt nicht noch irgendwelcher Voodoo zwischen Header und Noten passiert, musst du, das Steuerbyte berücksichtigend, deine erste Note finden und hast alles, was vorher kommt als Header.

        Tschö, Auge

        --
        Verschiedene Glocken läuteten in der Stadt, und jede von ihnen vertrat eine ganz persönliche Meinung darüber, wann es Mitternacht war.
        Terry Pratchett, "Wachen! Wachen!"
        ie:{ fl:| br:> va:) ls:[ fo:) rl:( ss:| de:> js:| zu:}
        Veranstaltungsdatenbank Vdb 0.3
        1. Hallo

          Die Noten könnte ich bereits problemlos auslesen. Aber wie gesagt: Erstmal den Anfang davon finden. :/

          Laut dem Wikipedia-Artikel hat jede Note ein führendes Steuerbyte. Wenn jetzt nicht noch irgendwelcher Voodoo zwischen Header und Noten passiert, musst du, das Steuerbyte berücksichtigend, deine erste Note finden und hast alles, was vorher kommt als Header.

          Tschö, Auge

          *mit kopf gegen wand hau*

          Dass ich einfach nach dem ersten steuerbyte suchen kann, hab ich auch schon lange gerafft. Ich will aber den HEADER VERSTEHEN!!!

          Was da wieso mit welcher länge wofür drin steht -.-

          Der Beitrag heißt ja nicht umsonst "VERSTÄNDNIS DER STRUKTUR" ...

  2. Hi there,

    Ganz einfach eigentlich.

    ja, wenn man weiss wie...

    Ich versuche krampfhaft mit vb.net eine Midi-Datei auszulesen und sogesehen zu "parsen".

    krampfhaft deutet nicht auf "ganz einfach"

    Ich will das endlich raffen.

    Midi-Dateien auslesen ist idR eben nicht ganz so einfach, zumal es ja mehrere Versionen davon gibt. Die ersten 20 Byte sind immer gleich, und dann kommen globale Informationen über Geschwindigkeit etc. Das müsste in Deinen Dokumentationen ja nachzulesen sein.
    Grundsätzlich am meisten erfährt man, wenn man selbst probieren kann. Da gibt es mit MidiOx einen Midimonitor, der Dir alles verrät - der einzige Nachteil, Du brauchst irgendein Midieingabegerät, aber dann siehst Du sofort (in Hexadezimalzahlen), was ein Tastendruck bewirkt (nichts anderes ist ein Ton in einer Midi-Datei). Nach dieser Bytefolge suchst Du dann in der Datei. Hier ist eine Table mit allen möglichen Midimessages.

    Grund: ich habe vor, ein tool zu basteln, welches es nicht als töne, sondern als Animation abspielt.

    Ja, das gibt es auch schon, vielleicht findest Du ja
    bei diesem Programm was Brauchbares:

    1. Ja, das gibt es auch schon, vielleicht findest Du ja
      bei diesem Programm was Brauchbares:

      Okay. Die ersten 20 Byte kann ich schonmal ignorieren.

      Aber wie schauts aus mit
      1. Das dazwischen? Zwischen den 20 Byte un dem eigentlichen Tönen? Ich versteh bis jetzt nicht, wie das abläuft. Ich beziehe mich explizit auf die Daten, die ich im Eröffnungsbeitrag vorgelegt habe.
      2. Das Programm läuft bei mir nicht. Benötigt scheinbar neueres D3D oder so. Kommt jedenfalls direkt ne Fehlermeldung, die mir eigentlich sagt, dass er kein D3D initialisieren konnte.

      Ich versuch das ganze in vb.net zu basteln. Mit Bytes, Bit's sowie sonstigem Kram, was Dateien angeht, kann ich rumjonglieren, wie ich lustig bin. Habe bereits eine klasse geschrieben, welches die Notenanschläge in verständliche Formate umsetzt.

      3. Wie sieht das aus mit mehreren Spuren und Synchronem mehrton-melodien?

      1. Hi there,

        Okay. Die ersten 20 Byte kann ich schonmal ignorieren.

        sry, hab mich missverständlich ausgedrückt, ich meinte, solange Du am File selbst nichts änderst.

        wie das abläuft. Ich beziehe mich explizit auf die Daten, die ich im Eröffnungsbeitrag vorgelegt habe.

        naja, daraus seh' ich folgendes:

        4D 54 68 64 00 00 00 06 00 01 00 02 00 60

        Du hast einen Midifile Type 1 mit 2 Spuren, 96 Ticks/Beat

        4D 54 72 6B

        Mtrk - hier beginnt die Beschreibung von Spur 1, die mir mit

        00 0B zeigt, daß diese Spur aus genau 11 Midievents besteht, die auch direkt darauf folgen:

        00 FF 51 03 06 8A 1B 00 FF 2F 00

        Danach beginnt Spur 2 wieder mit Mtrk:

        4D 54 72 6B

        und die besteht aus 5689 Midievents. (16 39)

        Das heisst als, alles was danach ist (beginnt mit 00 FF) sind von Dir zu parsende Midievents.  Die musst Du aber selbst auswerten, sonst schreib' ich mir hier einen Wolf. Genaue Beschreibung gibts hier.

        1. Das Programm läuft bei mir nicht. Benötigt scheinbar neueres D3D oder so. Kommt jedenfalls direkt ne Fehlermeldung, die mir eigentlich sagt, dass er kein D3D initialisieren konnte.

        Keine Ahnung, ich hab das nie probiert, nur eine wesentlich ältere Version, ich wollts nur erwähnen, weil das genau das macht, es macht aus Mididateien Animationen

        Ich versuch das ganze in vb.net zu basteln.

        Kenn' ich nicht (ausser vom Namen, ich hab mit der Mirkosaft so nix am Hut), am besten, und daher kommt das ja auch, können Programmiersprachen mit so etwas umgehen, die Pointer kennen, also vor allem C und Konsorten.

        Mit Bytes, Bit's sowie sonstigem Kram, was Dateien angeht, kann ich rumjonglieren, wie ich lustig bin. Habe bereits eine klasse geschrieben, welches die Notenanschläge in verständliche Formate umsetzt.

        Vielleicht hättest Du ja mit dem Fundament des Hauses beginnen sollen anstatt mir irgendwelchen Tapetenklassen herumzufrickeln?

        1. Wie sieht das aus mit mehreren Spuren und Synchronem mehrton-melodien?

        Das ergibt sich eigentlich schon aus dem von mir Geschriebenem, oder?

        1. Hallo!

          naja, daraus seh' ich folgendes:
          4D 54 68 64 00 00 00 06 00 01 00 02 00 60
          Du hast einen Midifile Type 1 mit 2 Spuren, 96 Ticks/Beat

          Ich bin zwar nicht der OP aber mich würde sehr interessieren wie du daraus diese Angaben ermittelst. Ich habe mir die von dir verlinkte Seite dazu angeschaut aber mir erschließt sich absolut nicht wie du bei der Ermittlung der Daten vorgegangen bist.
          Könntest du das bitte erklären?

          4D 54 72 6B
          Mtrk - hier beginnt die Beschreibung von Spur 1, die mir mit
          00 0B zeigt, daß diese Spur aus genau 11 Midievents besteht, die auch direkt darauf folgen:
          00 FF 51 03 06 8A 1B 00 FF 2F 00
          Danach beginnt Spur 2 wieder mit Mtrk:
          4D 54 72 6B
          und die besteht aus 5689 Midievents. (16 39)

          Was bedeuted Mtrk? Wie, wo und warum trennst du hier ab bestimmten Zeichen? Ich verstehe hier nur "Bahnhof" :/

          1. ... Wie, wo und warum trennst du hier ab bestimmten Zeichen? Ich verstehe hier nur "Bahnhof" :/

            Danke. Endlich mal jemand, der versteht, was ich eigentlich wissen will :P

            1. ... Wie, wo und warum trennst du hier ab bestimmten Zeichen? Ich verstehe hier nur "Bahnhof" :/

              Danke. Endlich mal jemand, der versteht, was ich eigentlich wissen will :P

              Was genau hast Du an meiner Erklärung nicht verstanden?

              1. ... Wie, wo und warum trennst du hier ab bestimmten Zeichen? Ich verstehe hier nur "Bahnhof" :/

                Danke. Endlich mal jemand, der versteht, was ich eigentlich wissen will :P

                Was genau hast Du an meiner Erklärung nicht verstanden?

                Hab mich jetzt mal drangesetzt und alles, was ich "verstanden" habe, farblich hervorgehoben und alles, was ich NICHT raffe, grau hinterlegt.


                (1 Zeile = 30 Byte)

                Sehr schön zu sehen, nach dem Auslesen des ersten MTrk und der dazugehörigen Länge (Erste Zeile die letzten 2 farbigen Bereiche) hörts mit meinem Wissen auf. Ich hab 0 Plan, wie ich die Kommandos da jetzt zuordnen soll. Besonders, weils mit dem Binärwert 00000000 anfängt, was ich aber in KEINER dokumentation über Midi iwie nachvollziehen kann.

                Ja. Ich schaue da schon binär genau hin. Ich hab schon verstanden, dass die Daten da binär erfasst werden. Wenn ich jetzt rauskriege, wie diese MTrk-Parts und bereiche aufgebaut sind, krieg ich dieses Tool auch fertig und kann die Töne so auslesen, wie ich sie bräuchte.

                PS: Das Tool arbeitet mit Zeigern.

                Nebenbei. Ich habe mir auch eine PHP-Klasse gezogen, welche aber vom Umfang so fett ist, dass es sich nicht lohnt, diese zu "zerreißen" um die funktionsweise zu erkennen. Daher hier ein Ausschnitt aus der Parsing-Ausgabe. (Exakt der Ausschnitt, welcher auch im Bild zu sehen ist.)

                0x00000000	(Bytes gekürzt) MIDI file format: 1, # of tracks: 2, Time division: 96  
                  
                Track 1  
                0x0000000E	(Bytes gekürzt)	Track size: 11 bytes  
                0x00000016	(Bytes gekürzt)	[0 ticks] Set Tempo: 140 BPM  
                0x0000001D	(Bytes gekürzt)	[0 ticks] End of Track:  
                  
                Track 2  
                0x00000021	(Bytes gekürzt)	Track size: 3918 bytes  
                0x00000029	(Bytes gekürzt)	[0 ticks] Track Name: Grand piano wet (MIDI)  
                0x00000043	00 B0 0A 40	[0 ticks] Controller (channel 0): Pan value [64]  
                0x00000047	00 B0 07 64	[0 ticks] Controller (channel 0): Main Volume value [100]  
                0x0000004B	00 E0 00 40	[0 ticks] Pitch Bend (channel 0): -97 cents  
                0x0000004F	00 B0 65 00	[0 ticks] Controller (channel 0): Registered Parameter Number  
                0x00000053	00 B0 64 00	[0 ticks] Controller (channel 0): Registered Parameter Number  
                0x00000057	00 B0 06 0C	[0 ticks] Controller (channel 0): Data Entry  
                0x0000005B	00 B0 0A 40	[0 ticks] Controller (channel 0): Pan value [64]  
                0x0000005F	00 B0 07 64	[0 ticks] Controller (channel 0): Main Volume value [100]  
                0x00000063	00 E0 00 40	[0 ticks] Pitch Bend (channel 0): -97 cents  
                0x00000067	00 C0 00 00	[0 ticks] Program Change (channel 0): Concert Grand  
                0x0000006A	00 B0 65 00	[0 ticks] Controller (channel 0): Registered Parameter Number  
                0x0000006E	00 B0 64 00	[0 ticks] Controller (channel 0): Registered Parameter Number  
                0x00000072	00 B0 06 0C	[0 ticks] Controller (channel 0): Data Entry (most significant  
                0x00000076	00 B0 0A 40	[0 ticks] Controller (channel 0): Pan value [64]  
                0x0000007A	00 B0 07 64	[0 ticks] Controller (channel 0): Main Volume value [100]  
                0x0000007E	00 E0 00 40	[0 ticks] Pitch Bend (channel 0): -97 cents  
                0x00000082	00 C0 00 00	[0 ticks] Program Change (channel 0): Concert Grand  
                0x00000085	00 B0 65 00	[0 ticks] Controller (channel 0): Registered Parameter Number  
                0x00000089	00 B0 64 00	[0 ticks] Controller (channel 0): Registered Parameter Number  
                0x0000008D	00 B0 06 0C	[0 ticks] Controller (channel 0): Data Entry  
                0x00000091	00 B0 0A 40	[0 ticks] Controller (channel 0): Pan value [64]  
                0x00000095	00 B0 07 64	[0 ticks] Controller (channel 0): Main Volume value [100]  
                0x00000099	00 E0 00 40	[0 ticks] Pitch Bend (channel 0): -97 cents  
                0x0000009D	00 C0 00 00	[0 ticks] Program Change (channel 0): Concert Grand  
                0x000000A0	30 90 48 04	[48 ticks] Note On (channel 0): C5 with velocity 4  
                0x000000A4	2F 80 48 40	[47 ticks] Note Off (channel 0): C5 with velocity 64  
                0x000000A8	01 90 54 2B	[1 ticks] Note On (channel 0): C6 with velocity 43  
                0x000000AC	2F 80 54 40	[47 ticks] Note Off (channel 0): C6 with velocity 64  
                0x000000B0	01 90 4B 06	[1 ticks] Note On (channel 0): D#5 with velocity 6  
                0x000000B4	2F 80 4B 40	[47 ticks] Note Off (channel 0): D#5 with velocity 64  
                0x000000B8	01 90 57 2D	[1 ticks] Note On (channel 0): D#6 with velocity 45  
                0x000000BC	2F 80 57 40	[47 ticks] Note Off (channel 0): D#6 with velocity 64  
                0x000000C0	01 90 4B 0A	[1 ticks] Note On (channel 0): D#5 with velocity 10  
                0x000000C4	2F 80 4B 40	[47 ticks] Note Off (channel 0): D#5 with velocity 64  
                0x000000C8	01 90 5E 3A	[1 ticks] Note On (channel 0): A#6 with velocity 58  
                0x000000CC	2F 80 5E 40	[47 ticks] Note Off (channel 0): A#6 with velocity 64  
                0x000000D0	01 90 4B 11	[1 ticks] Note On (channel 0): D#5 with velocity 17
                

                Ich weiß zwar, dass das Tool das wahrscheinlich umrechnet. Aber wie kommt der auf 140 bpm z. b.?

                Ich weiß. Ich bin etwas langsam von KP. Aber wenn ichs jetzt einmal gerafft habe, ohne ellenlange Seiten zu durchforsten, die mir doch keine plausible Antwort liefern, dann bin ich durch.

                PS: Die Kommando-Befehle mit MSB und so sind mir schon gut bekannt. Jedoch raff ich nicht, was 00000000 als Kommando für nen Wert hätte, wie oben schon erfragt.

                Also würdest du mir bitte helfen, wenigstens den Anfang der beiden MTrk zu verstehen?

                Entschuldigt bitte, dass ich eure Geduld so auf die Probe stelle :/

                1. Hi there,

                  Sehr schön zu sehen, nach dem Auslesen des ersten MTrk und der dazugehörigen Länge (Erste Zeile die letzten 2 farbigen Bereiche) hörts mit meinem Wissen auf. Ich hab 0 Plan, wie ich die Kommandos da jetzt zuordnen soll. Besonders, weils mit dem Binärwert 00000000 anfängt, was ich

                  aber in KEINER dokumentation über Midi iwie nachvollziehen kann.

                  Dann bist Du meinem Link nicht gefolgt.

                  Der Anfang eines Midi-Events (im File, bei einem Midieingabegerät fällt das natürlich weg) ist immer der zeitliche Abstand, gemessen in Ticks, zum vorhergehenden Ereignis. In dem Fall also 0. Das hättes Du auch sehen können, daß in dem PHP-Output die Null vorne zu 30 wird, sozusagen 48 Ticks später (bei File-Offset A0)

                  0x0000000E        (Bytes gekürzt)        Track size: 11 bytes

                  Das hab ich ja schon erklärt (Bytes gekürzt steht da für 00 00 00 0B => 11 dez.)

                  0x00000016        (Bytes gekürzt)        [0 ticks] Set Tempo: 140 BPM

                  Bytes gekürzt steht da für:

                  00 FF 51 03 06 8A 1B

                  00 = Tick 0
                  FF = Midi Meta-Event
                  51 03 = Set Tempo-Event (auf den 3 x 1 Byte folgt, nämlich '06 8A 1B', was Dezimal 428571 entspricht. Lt. Midispezifikation musst Du 60 Millionen Microsekunden durch diese Zahl dividieren, um die BPM zu erhalten und, voila, 60000000/428571 sind 140,00014 BPM)

                  0x0000001D        (Bytes gekürzt)        [0 ticks] End of Track:

                  00 = wieder Tick 0
                  FF = wieder Midi Meta-Event
                  2F = End Of Track - Event (was ja logisch ist, weil der Track eben aus ist;)
                  00 ? die Null da versteh ich auch nicht, kann Dir aber egal sein, weil Du beim Parsen ohnehin nur auf das Ende des Tracks und auf den Beginn des nächsten Tracks schauen musst.

                  Den Rest musst Du selbst (selfhtml!) herausfinden, Du findest das alles in dem von mir jetzt schon zum vierten Mal geposteten Link...

                  1. Über diese Seite versuch ich schon die ganze zeit, das System zu verstehen. *schwitz* Aber so wie du das jetzt erklärt hast, hilft es mir schonmal sehr weiter.

                    Was die 00 da noch bedeutet, kriegen wir bestimmt auch noch raus. Nen Fehler kanns net sein. Nehm ich die 00 raus via hex-editor, is die midi-datei "beschädigt"

                  2. 00 = wieder Tick 0
                    FF = wieder Midi Meta-Event
                    2F = End Of Track - Event (was ja logisch ist, weil der Track eben aus ist;)
                    00 ? die Null da versteh ich auch nicht, kann Dir aber egal sein, weil Du beim Parsen ohnehin nur auf das Ende des Tracks und auf den Beginn des nächsten Tracks schauen musst.

                    Die Null gehört zum "End Of Track" und gibt die Anzahl der folgenden Bytes für den Parameter-Wert an. In diesem Fall keine. Bei "Set Tempo" waren es drei.

                    1. 00 = wieder Tick 0
                      FF = wieder Midi Meta-Event
                      2F = End Of Track - Event (was ja logisch ist, weil der Track eben aus ist;)
                      00 ? die Null da versteh ich auch nicht, kann Dir aber egal sein, weil Du beim Parsen ohnehin nur auf das Ende des Tracks und auf den Beginn des nächsten Tracks schauen musst.

                      Die Null gehört zum "End Of Track" und gibt die Anzahl der folgenden Bytes für den Parameter-Wert an. In diesem Fall keine. Bei "Set Tempo" waren es drei.

                      Danke für die Vervollständigung :)

                    2. Habe jetzt ein neues Problem.

                      0x00000F0C 00 90 3C 0C [0 ticks] Note On (channel 0): C4 with velocity 12
                      0x00000F10 85 7F 80 48 40 [767 ticks] Note Off (channel 0): C5 with velocity 64
                      0x00000F15 00 80 57 40 [0 ticks] Note Off (channel 0): D#6 with velocity 64
                      0x00000F19 00 80 30 40 [0 ticks] Note Off (channel 0): C3 with velocity 64
                      0x00000F1D 00 80 3C 40 [0 ticks] Note Off (channel 0): C4 with velocity 64
                      0x00000F21 83 01 B0 65 00 [385 ticks] Controller (channel 0): Registered Parameter ...
                      0x00000F26 00 B0 64 00 [0 ticks] Controller (channel 0): Registered Parameter ...

                      Da sind 2 "Einträge", bzw. Events, welche größere Werte als Tick-Offsets besitzen. WIE krieg ich DAS raus, ohne dann explizit raus? Wird das iwo vordefiniert?

                      Das ist 0 Ersichtlich, dass das plötzlich 5 Bytes sein müssen.

                      HILFE ._.

                      PS: Sind die einzigsten 2 Elemente im 2ten Track, welche länger als 4 Bytes sind. Dadurch wird der rest hinten dran versetzt eingelesen (da ich auf regulär 4 byte länge gebaut habe) und er findet den End of Track nicht mehr ... :/

                      ARGH.

                      1. Hi there,

                        0x00000F10 85 7F 80 48 40 [767 ticks] Note Off (channel 0): C5 with velocity 64

                        0x00000F21 83 01 B0 65 00 [385 ticks] Controller (channel 0): Registered Parameter ...

                        Da sind 2 "Einträge", bzw. Events, welche größere Werte als Tick-Offsets besitzen. WIE krieg ich DAS raus, ohne dann explizit raus? Wird das iwo vordefiniert?

                        Da ist irgendwo ein Wurm drin. 83 01 wäre, wenn man es umdreht, 01 83 und das sind 387 und nicht 385 dezimal, während 7f85 unter Garantie nicht 767 dezimal ist.

                        Ich denke eher, es könnten nur 133 Ticks später sein und dann eine Mode-Message beginnen (7F)...

                        ARGH.

                        Per aspera ad astra...

                        1. Alex hat die Frage bereits sehr ausführlich "aufgedrüselt" beantwortet :)

                      2. 0x00000F0C 00 90 3C 0C [0 ticks] Note On (channel 0): C4 with velocity 12
                        0x00000F10 85 7F 80 48 40 [767 ticks] Note Off (channel 0): C5 with velocity 64
                        0x00000F15 00 80 57 40 [0 ticks] Note Off (channel 0): D#6 with velocity 64
                        0x00000F19 00 80 30 40 [0 ticks] Note Off (channel 0): C3 with velocity 64
                        0x00000F1D 00 80 3C 40 [0 ticks] Note Off (channel 0): C4 with velocity 64
                        0x00000F21 83 01 B0 65 00 [385 ticks] Controller (channel 0): Registered Parameter ...
                        0x00000F26 00 B0 64 00 [0 ticks] Controller (channel 0): Registered Parameter ...

                        Da sind 2 "Einträge", bzw. Events, welche größere Werte als Tick-Offsets besitzen. WIE krieg ich DAS raus, ohne dann explizit raus? Wird das iwo vordefiniert?

                        Das ist 0 Ersichtlich, dass das plötzlich 5 Bytes sein müssen.

                        Ich verstehe zwar kaum, was Du da geschrieben hast, aber der Output des Programms paßt zu den Daten. In MIDI gibt es für die Delta Time ein Variable Length Coding, um große Werte darzustellen -- einen Link dazu kannst Du Dir sicher selber suchen. Du kannst Dir das so vorstellen, daß pro Byte immer nur die unteren 7 Bits tatsächlich für den Zahlenwert verwendet werden. Das oberste Bit (MSB - most significant bit) gibt an, ob noch ein weiteres Byte folgt (Bit gesetzt) oder ob dies das letzte Byte dieser Kette variabler Länge ist (Bit nicht gesetzt). An Deinem konreten Beispiel:

                        85 7F 80 48 40

                        Im ersten Byte ist das oberste Bit (0x80) gesetzt. Es muß also auch noch das folgende Byte angeschaut werden, weil es mit zu dieser Kette gehört. In diesem zweiten Byte ist das oberste Bit nicht gesetzt, und somit wissen wir, daß diese Delta-Time-Angabe insgesamt zwei Byte lang ist. Danach folgen dann Event Type (0x80 - Note Off, Channel 0), Note Number (0x48 - C5), Velocity (0x40 - 64).

                        Um diese Delta Time auseinanderzunehmen, schaust Du sie Dir am besten in Binärnotation an:

                        0x85 0x7F -> 10000101 01111111

                        Das oberste Bit dient wie gesagt jeweils nur dem Signalisieren im Variable Length Coding. Können wir also jeweils wegschmeißen

                        0000101 1111111

                        und die Bits anschließend wieder in Achtergruppen zusammenfassen (von rechts beginnend):

                        000010 11111111

                        Im ersten Byte gibt es nur 6 Bits, also sind die obersten 2 Bits Null -- ob man diese führenden Nullen nun aufschreibt oder nicht, spielt ja für den Zahlenwert keine Rolle. Und wenn Du das nun als (Hexa-)Dezimalzahl angibst, kommt Du auf

                        0x02FF = 767

                        Analog decodierst Du die Delta Time an Offset 0x00000F21 in Deinem Beispiel und findest den Wert 385.

                        War das Deine Frage?

                        1. Perfekt erklärt. Hab ich auf Anhieb verstanden. War auch exakt meine Frage :)

                          *Nach dem platz für den bienchen-stempel such*

                          :)

          2. Hi there,

            Ich bin zwar nicht der OP aber mich würde sehr interessieren wie du daraus diese Angaben ermittelst. Ich habe mir die von dir verlinkte Seite dazu angeschaut aber mir erschließt sich absolut nicht wie du bei der Ermittlung der Daten vorgegangen bist.

            Du hättest Dir diese von mir verlinkte Seite betrachten sollen, da wird der Header erklärt. Hier werden vor allem die einzelnen Midi-Events beschrieben.

            Könntest du das bitte erklären?

            Nicht nocheinmal - Prinzipiell aber: der Midifile ist in Chunks, in Datenblöcke aufgeteilt. Zuerst die allgemeinene Einstellungen, dann die einzelnen Tracks. Der Header-Chunk beginnt immer mit 'MThd' und einer 4 Bytefolge, die den Wert 6 enthält. Die 6 steht für die 3 Words 'format type', 'number of tracks' und 'time-division'. Wenn das zweite Word den Wert '00 02' hat, dann enthält der Midifile 2 Tracks, von denen jeder mit der Bytefolge 'Mtrk' oder eben '4D 54 72 6B' beginnt. Das ist auch der Beginn der Track-Chunks, dessen wichtigste Information im "Trackheader" seine eigene Größe ist (Chunk-Size, 4 Bytes). Wenn die Chunk-Size also '00 00 00 0B' lautet bedeutet das, das noch genau 11 Midievents folgen und danach, sofern vorhanden, der nächste Track-Chunk folgt, der wieder mit '4D 54 72 6B' und der Chunk-Size beginnt...

            Was bedeuted Mtrk?

            Könnte das Midi-Track bedeuten? (Stell DIr jetzt einmal ein unschuldig dreinblickedes Gesicht vor)

            Wie, wo und warum trennst du hier ab bestimmten Zeichen? Ich verstehe hier nur "Bahnhof" :/

            Das funktioniert eben nicht mit bestimmten trennenden Zeichen sondern über Datenblöcke. Das ist bei vielen Dateiformaten der Fall, zB bei Truetypfonts, also bei .TTF-Dateien etc. Wie schon geschrieben eignet sich ein solches Format besonders gut für die Bearbeitung mit Programmiersprachen, die Zeiger kennen.

  3. @@NeoGriever:

    nuqneH

    eine Midi-Datei auszulesen und sogesehen zu "parsen".

    Schon nach "MIDI Disassembler" gesucht?

    Qapla'

    --
    „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)