Autor Beitrag
Noodel
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27



BeitragVerfasst: Mo 02.03.09 19:50 
Ich habe mir ein kleines Programm geschrieben, das eine MIDI-Datei laden können soll. Nach dem Laden werden die Daten der MIDI-Datei analysiert und ausgegeben. Dabei gibt es aber ein Problem: Die Daten, die ich auslesen lasse, sind nicht korrekt. Das heißt, irgendwo muss noch ein Fehler drinstecken. Könnt ihr mir helfen und sagen, wo der Fehler ist? Das wäre super. Danke im Voraus!

MIDI-Erklärung:
www.larsrichter-onli.../lmids/midformat.htm (deutsch, nicht komplett richtig)
253.ccarh.org/handout/smf/ (englisch, korrekt)

Mein Programm (mit Projektdateien und Beispiel-MIDI-Datei) habe ich angehängt.

Bitte guckt euch mal die Prozedur OpenMidi an. Da muss der Fehler drinstecken. Die Variable DeltaValue hat da immer den Wert 0, was nicht sein dürfte.
Im Moment wird der Wert so ausgelesen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
        // Delta-Time
        MidiFile.ReadBuffer(TempByteValue, SizeOf(TempByteValue));
        Dec(ChunkSize);
        DeltaValue := TempByteValue;
        if TempByteValue and $80 = $80 then
        begin
          DeltaValue := DeltaValue and $7F;
          repeat
            MidiFile.ReadBuffer(TempByteValue, SizeOf(TempByteValue));
            Dec(ChunkSize);
            DeltaValue := DeltaValue shl 7 + (TempByteValue and $7F);
          until (ChunkSize = 0or (TempByteValue and $80 = 0);
        end;

Ich glaube aber, dass das falsch ist. Eigentlich sollte bei jedem MIDI-Kommando ein eigener DeltaValue stehen. Aber ich weiß nicht, wo das genau hin müsste.
Einloggen, um Attachments anzusehen!
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 06.03.09 01:47 
Moin!

Ich habe deinen Code mal etwas modifiziert:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
      // DELTA-TIME
      MidiFile.ReadBuffer(TempByteValue, SizeOf(TempByteValue));
      Dec(ChunkSize);
      DeltaValue := TempByteValue;
      Kanaele_Befehle.Append('TempByteValue '+IntToStr(TempByteValue));
      if (TempByteValue and $80) = $80 then begin
        DeltaValue := DeltaValue and $7F;
        repeat
          MidiFile.ReadBuffer(TempByteValue, SizeOf(TempByteValue));
          Dec(ChunkSize);
          DeltaValue := DeltaValue shl 7 + (TempByteValue and $7F);
        until (ChunkSize = 0or (TempByteValue and $80 = 0);
        Kanaele_Befehle.Append('DeltaValue '+IntToStr(DeltaValue));
      end;
Kurz gesagt: es wird nie ein DeltaValue ausgegeben, weil alle TempByteValue-Werte 0 sind. :idea: Hier die Ausgabe:
ausblenden volle Höhe Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
TempByteValue 0
Meta-Event, Länge 5
Meta-Event, Länge 4
Meta-Event, Länge 2
Meta-Event, Länge 3
Meta-Event, Länge 3
Meta-Event, Länge 3
Note an, Channel 7 - Data1: 192, Data2: 1
Meta-Event, Länge 0
TempByteValue 0
Meta-Event, Länge 14
Meta-Event, Länge 6
Instrumentwechsel, 0 - Data: 33
Kontrolländerung, 0 - Data1: 7, Data2: 101
Kontrolländerung, 0 - Data1: 10, Data2: 88
Kontrolländerung, 0 - Data1: 7, Data2: 110
Instrumentwechsel, 0 - Data: 33
Kontrolländerung, 0 - Data1: 101, Data2: 0
Kontrolländerung, 0 - Data1: 100, Data2: 0
Kontrolländerung, 0 - Data1: 6, Data2: 12
Kontrolländerung, 0 - Data1: 38, Data2: 0
Note aus, Channel 0 - Data1: 40, Data2: 57
Note an, Channel 4 - Data1: 16, Data2: 128
Note aus, Channel 0 - Data1: 43, Data2: 52
Note an, Channel 3 - Data1: 116, Data2: 128
Note aus, Channel 0 - Data1: 47, Data2: 53
Note an, Channel 3 - Data1: 113, Data2: 128
Note aus, Channel 0 - Data1: 43, Data2: 52
Note an, Channel 3 - Data1: 118, Data2: 128
Note aus, Channel 0 - Data1: 40, Data2: 55
Note an, Channel 3 - Data1: 118, Data2: 128
Note aus, Channel 0 - Data1: 43, Data2: 52
Note an, Channel 3 - Data1: 113, Data2: 128
Note aus, Channel 0 - Data1: 47, Data2: 53
Note an, Channel 3 - Data1: 113, Data2: 128
Note aus, Channel 0 - Data1: 43, Data2: 52
Note an, Channel 3 - Data1: 122, Data2: 128
Note aus, Channel 0 - Data1: 43, Data2: 57
Note an, Channel 4 - Data1: 22, Data2: 128
Note aus, Channel 0 - Data1: 47, Data2: 52
Note an, Channel 3 - Data1: 116, Data2: 128
Note aus, Channel 0 - Data1: 50, Data2: 53
Note an, Channel 3 - Data1: 113, Data2: 128
Note aus, Channel 0 - Data1: 47, Data2: 52
Note an, Channel 3 - Data1: 118, Data2: 128
Note aus, Channel 0 - Data1: 43, Data2: 55
Note an, Channel 3 - Data1: 118, Data2: 128
Note aus, Channel 0 - Data1: 47, Data2: 52
Note an, Channel 3 - Data1: 113, Data2: 128
Note aus, Channel 0 - Data1: 50, Data2: 53
Note an, Channel 3 - Data1: 113, Data2: 128
Note aus, Channel 0 - Data1: 47, Data2: 52
Note an, Channel 3 - Data1: 115, Data2: 128
Note an, Channel 7 - Data1: 128, Data2: 9
Meta-Event, Länge 0
TempByteValue 0
Meta-Event, Länge 14
Meta-Event, Länge 7
Instrumentwechsel, 1 - Data: 0
Kontrolländerung, 1 - Data1: 7, Data2: 101
Kontrolländerung, 1 - Data1: 10, Data2: 40
Kontrolländerung, 1 - Data1: 7, Data2: 110
Kontrolländerung, 1 - Data1: 7, Data2: 102
Kontrolländerung, 1 - Data1: 101, Data2: 0
Kontrolländerung, 1 - Data1: 100, Data2: 0
Kontrolländerung, 1 - Data1: 101, Data2: 0
Kontrolländerung, 1 - Data1: 100, Data2: 0
Kontrolländerung, 1 - Data1: 6, Data2: 12
Kontrolländerung, 1 - Data1: 6, Data2: 12
Kontrolländerung, 1 - Data1: 38, Data2: 0
Kontrolländerung, 1 - Data1: 38, Data2: 0
Kontrolländerung, 1 - Data1: 7, Data2: 110
Note aus, Channel 1 - Data1: 60, Data2: 69
Note an, Channel 8 - Data1: 19, Data2: 129
Note aus, Channel 1 - Data1: 60, Data2: 65
Note an, Channel 7 - Data1: 118, Data2: 129
Note aus, Channel 1 - Data1: 69, Data2: 67
Note an, Channel 7 - Data1: 118, Data2: 129
Note aus, Channel 1 - Data1: 69, Data2: 65
Note an, Channel 7 - Data1: 115, Data2: 129
Note aus, Channel 1 - Data1: 64, Data2: 69
Note an, Channel 8 - Data1: 25, Data2: 129
Note aus, Channel 1 - Data1: 64, Data2: 65
Note an, Channel 7 - Data1: 118, Data2: 129
Note aus, Channel 1 - Data1: 76, Data2: 67
Note an, Channel 7 - Data1: 118, Data2: 129
Note aus, Channel 1 - Data1: 76, Data2: 65
Note an, Channel 7 - Data1: 115, Data2: 129
Note an, Channel 7 - Data1: 128, Data2: 2
Meta-Event, Länge 0
Insofern ist es kein Wunder, dass alle DeltaValues, die du liest 0 sind - es wird schlicht nie einer gelesen. Warum? :nixweiss: Da wirst du wohl noch mal etwas die FileFormat-Doku wälzen müssen (vielleicht liegt´s ja auch an deiner Testdatei?). :?

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19276
Erhaltene Danke: 1741

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 06.03.09 02:19 
Ich hatte das als ich den Code geschrieben hatte ja auch getestet. Das Auslesen klappt, wie man an diesem Test sehen kann:
www.delphi-forum.de/....php?p=546704#546704

Deshalb kann es eigentlich gar nicht sein, dass der Wert falsch ausgelesen wird, wenn der wirklich an der Stelle steht wie in der Doku steht, denn sonst würde der Rest ja auch nicht klappen. :nixweiss:

Wie das genau mit dem Deltawert funktioniert ist mir aber nicht ganz klar. Irgendwie der Abstand zu vorangegangenen Note oder so soll das sein.
Noodel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27



BeitragVerfasst: Sa 07.03.09 20:36 
@Narses: Danke, da wär ich nie drauf gekommen, dass TempByteValue immer 0 ist. Dann ist es ja klar. Jetzt muss ich nur noch rausfinden, warum TempByteValue immer 0 ist. Da habe ich aber leider überhaupt keine Idee, es wird ja - dank jaenicke - genau so gemacht, wie es in der Doku steht.
@jaenicke: Ja, TempByteValue ist der Abstand zur vorherigen Note, also praktisch die Länge der vorherigen Note. Ich bin mir aber nicht sicher, ob das wirklich richtig ausgelesen wird. Denn auch der Rest scheint nicht ganz zu stimmen. Bei meiner Testdatei sehe ich z.B., dass eine Note auf off gesetzt wird, bevor sie überhaupt auf on gesetzt wurde. Also wird praktisch die Taste losgelassen, bevor sie runtergedrückt wurde. Geht ja schlecht.

Also irgendwo muss der Fehler sein, wegen dem TempByteValue nicht richtig ausgelesen wird. Es wäre super, wenn ihr mir bei diesem kleinen Fehler noch helfen könntet. Der Code ist ja schon fast fertig. Wäre sonst schade ...