Multimedia 2.572 Themen, 14.455 Beiträge

MIDI .KAR Dateien: Timing Format der Lyric

Sigi Saudi / 5 Antworten / Baumansicht Nickles

Hallo Gem.einde,

Wi weitlaeufig bekannt, lebe ich in Thailand. Hier ist Karaoke, wie fast ueberall in Asien, ein grosses Thema. Deshalb befasse ich mich jetzt mit MIDI und .KAR Dateien, da hier eine sehr grosse Anzahl von Karaokesongs als .MID und als .KAR Dateien im Umlauf sind und hier die gaengigen Karaokeplayer dieses Format verarbeiten.

Ich habe mir die App Serenade v5.2 auf meinen Laptop heruntergeladen und fuege mit dieser App die Texte nun selbst in .MID Dateien ein. Um Korrekturen am Timing der Lyric  im Nachhinein vornehmen zu koennen, habe ich das Format der eingefuegten Lyric manuell zu dekodieren und zu verstehen versucht. Ich habe einen Hex Editor, der mich die Dateien im Hex/ASCII Format betrachten und editieren laesst. Hier ein Beispiel des Songs Goldfinger:


Track Identifier
4D 54 72 6B 00 00 05 E5 00       -->MTrk
Time Signature
FF 58 04 04 02 18 08 00             --> 4/4
Tempo
FF 51 03 09 27 C0 00
Sequence / Track Name
FF 03 24 50 31 30 30 31 38 2D 47 6F 6C 64 66 69 6E 67 65 72 2E ... -->Name of the file
                                                                                                      ... P10018-Goldfinger- ...
Tempo
FF 51 03 0B F9 CB 9E 1D
Lyric
FF 05 04 47 6F 6C 64 81 44         -->Gold
FF 05 03 66 69 6E 25                   -->fin
FF 05 05 67 65 72 2C 20 86 56    -->ger,_
FF 05 05 68 65 27 73 20 2B         -->he's_
FF 05 04 74 68 65 20 28              -->the_
FF 05 03 6D 61 6E 81 54             -->man
FF 05 05 2F 74 68 65 20 23         -->/the_
FF 05 04 6D 61 6E 20 58              -->man_
FF 05 05 77 69 74 68 20 32          -->with_
FF 05 04 74 68 65 29 57               -->the_
FF 05 02 6D 69 67                        -->mi
FF 05 04 64 61 73 20 3E              -->das_
FF 05 05 74 6F 75 63 68 85 4D    -->touch
FF 05 03 2F 41 20 5A                   -->/A_
FF 05 03 73 70 69 7A                   -->spi
FF 05 06 64 65 72 27 73 20 73    -->der's_
FF 05 05 74 6F 75 63 68 85 76    -->touch
FF 05 06 2F 53 75 63 6B 20 74    -->/such

... und so weiter ( _ steht hier fuer Space, Code 20)

Jede Lyriczeile beginnt mit der Markierung FF 05
FF markiert den Beginn eines Meta Events und 05 markiert eine Lyriczeile. Das naechste Byte enthaelt die Anzahl der Buchstaben und Zeichen der Lyric, die in diesem Metaevent abgelegt sind, in der ersten Zeile also 04 fuer den Text Gold, der 4 Buchstaben lang ist.

In der ersten Zeile und vor jedem Zeilenwechsel (Zeichen /) folgt nach dem Textfragment ein Timestamp (hier nach Gold 81 44, der in hexadezimaler Form den Einsatz des folgenden Zeilenbeginns markiert.

Die Kodierung dieser Bytes ist mir unklar. Ich weiss nur, wenn ich dort z. B. 83 44 eintrage, setzt die 2. Zeile spaeter ein.

Am Ende jeden Worts innerhalb einer Zeile steht ein Byte, das angibt, nach welcher Zeit das naechste Wort beginnt, aber die Kodierung dieses Bytes ist mir auch unklar. Ich weiss nur, dass ich mit diesem Byte den Zeitabstand zum naechsten Wort in der Zeile beeinflussen kann, aber groessere Werte ergeben nicht unbedingt groessere Abstaende und umgekehrt. 

Die 3. Zeile (ger,_) endet mit den Bytes 86 56. Normalerweise ist innerhalb einer Zeile nur ein Timing Byte am Ende eines Lyrics Fragments angehaengt. Was bedeutet das vorletzte Byte 86 in der Zeile?

Auch weiss ich nicht, wo das Timing fuer den generellen Beginn der Lyric gespeichert ist. Das Timing innerhalb der Lyric beginnt erst vor der zweiten Zeile, aber irgendwo muss ja auch der Beginn der ersten Zeile festgelegt sein.

Ich hoffe sehr, dass ihr mir weiterhelfen koennt!

Herzliche Gruesse aus Thailand, wo zum Glueck schon sporadisch die Regenzeit eingesetzt hat.

Sigi Saudi

Gruesse aus Wang Nam Kiaw / Thailand
bei Antwort benachrichtigen
Andreas42 Sigi Saudi

„MIDI .KAR Dateien: Timing Format der Lyric“

Optionen

Hi!

Es müsste ein ziemlich großer Zufall sein, dass du hier jemanden findest, der sich mit der Kodierung von KAR-Dateien auf der Binärebene befasst hast. Ich z.B. nicht. Zwinkernd

Ich hab mich allerdings vor Jahren mit der Kodierung und dem Aufbau von Archioven befass - rein hobbymässig. Darauf kann man aufbauen...

https://www.cs.cmu.edu/~music/cmsip/readings/Standard-MIDI-file-format-updated.pdf

Das habe ich gefunden. Es beschreibt den Aufbau der MIDI-Dateien. Dort wird auch der Chunk FF 05 erwähnt, als Lyrikdaten.

Das passt auch zum Aufbau deines Beispieles, nur passt die Längeninformation bei den Zeilen, die vermutlich Timinginfo enthalten nicht. Wenn wir davon ausgehen, dass die Längeninfo stimmen muss, können die Bytes am Ende nicht zur Zeile gehören.

FF 05 05 67 65 72 2C 20 86 56    -->ger,_

Länge soll 5 Bytes sein, dass wäre dann die $20. die $86 $56 muss ein anderer Chunk bzw. Datenteil sein.

Du hast ja schon herausgefunden, dass es sich um Timinginformation handelt. Aber auch die Noten müssen im "Fluss" der Daten enthalten sein. Offenbar arbeitet Midi mit Delta-Zeitangaben, kodiert also ob eine Zeit länger oder kürzer ist, als die gesetzte Basis. Die Noten müssen dann auch irgendwo stehen. (Es gibt eine Notentabelle im verlinkten Dokument).

http://www.larsrichter-online.de/lmids/midformat.htm

Ich würde daher sagen, dein Lyrik-Block ist nicht reinrassiger Text bzw. Lyrik sondern eine Trackinformation, die Noten, Zeitdeltas und die Lyrik enthält.

Tempo
FF 51 03 0B F9 CB
9E 1D
FF 05 04 47 6F 6C 64         -->Gold
81 44
FF 05 03 66 69 6E               -->fin
25
FF 05 05 67 65 72 2C 20     -->ger,_
86 56
FF 05 05 68 65 27 73 20      -->he's_
2B
FF 05 04 74 68 65 20           -->the_
28
FF 05 03 6D 61 6E               -->man
81 54

In den Definitionen sieht man das die Bytes Nibble-Weise kodiert sind. 9 scheint für "Note an" zu stehen und 8 für "Note aus". Dann gibt es wohl auch noch Besonderheiten bei der Kodierung, die Zahlenwerte durchaus unterschiedlich lang kodiert um Platz in der Datei zu sparen.

An der Stelle passe ich jetzt, da musst du selbst weiter suchen.

Bis dann
Andreas

PS: Da MIDI und KAR verwand sein sollen, hab ich mich an Doku zum MIDI-Format gehalten. Mir scheint da das meiste zu passen.

Ich sehe die Stimmungslage meiner Mitmenschen. Daher bleibt nur eine letzte Forderung: Weltuntergang jetzt sofort!
bei Antwort benachrichtigen
Sigi Saudi Andreas42

„Hi! Es müsste ein ziemlich großer Zufall sein, dass du hier jemanden findest, der sich mit der Kodierung von KAR-Dateien ...“

Optionen

Hallo Andreas,

Danke fuer deine Antwort. Mir ist klar, dass meine Fragestellung sehr speziell ist, aber man soll die Hoffnung nie aufgeben. Das beschriebene Format ist in einem MTrk Chunk enthalten, den das Programm zur Enfuegung von Lyric in MIDI Dateien (hier: Serenade v5.2) komplett neu in die Basis MIDI Datei einbringt. Vorher war diese MTrk nicht vorhanden in der MIDI. Der Winamp v 5.66 mit MIDI Plug-in kennt dieses Format, denn wenn ich z, B. meine von mir mit Lyric versehenen .mid oder .kar Datei (beide Extensions funktionieren gleichermassen) mit dem Winamp abspiele, wird ein extra Fenster vom Winamp geoeffnet, das die komplette Lyric enthaelt und das gerade gesungene Wort(fragment) wird blau unterlegt, wie beim Kopieren von Text, z. B. in MS Office. Auch der vanBasco's Karaoke Player spielt diese Dateien ohne Probleme, allerdings komfortabler als der Winamp. Nur mein Player im eXtreme Karaoke System, das hier gaengig ist und in einem dBase dbf table ca, 4000 meist asiatische MIDIs enthaelt, kennt das Format nicht und spielt nur die Melodie ohne Text. Aeltere KAR MIDIs, die um 1998 generiert wurden (Dateiheader), die kann er spielen und seine eigenen Songs haben ein spezielles Format, in dem Song, Lyrics und Timing in 3 verschiedenen Dateien pro Song untergebracht sind. Die Timing Datei, das Herzstueck des ganzen, ist sehr schwer zu dekodieren. Daran habe ich mir schon die Zaehne ausgebissen.

Die Links, die Du in Deiner Antwort angesprochen hast, kannte ich schon und daraus habe ich einen Teil meiner Kenntnisse entnommen. Gut gegliederte Infos findet man auch unter:

http://www.somascape.org/midi/tech/mfile.html

Da muss ich wohl weiter wuehlen und probieren, bis ich den genauen Sinn der Zusatzbytes in MIDI Event FF 03 erkannt habe.

Gruesse aus Thailand

Sigi Saudi 

Gruesse aus Wang Nam Kiaw / Thailand
bei Antwort benachrichtigen
Andreas42 Sigi Saudi

„Hallo Andreas, Danke fuer deine Antwort. Mir ist klar, dass meine Fragestellung sehr speziell ist, aber man soll die ...“

Optionen

Hi!

Der Link ist gut, ich denke, da ist beschreiben, wie das zusammen hängt:

The actual data within an MTrk chunk takes the following form :

delta-time a variable length quantity, (1 to 4 bytes) denoting the time since the previous event.
event 2 or more bytes describing the event, of which there are three main types : MIDI, SysEx and Meta.

Wir haben das bisher vertauscht: die Zusatzbytes gehören nicht ans Ende der Meta-Zeile, sondern jeweils vor die nächste. Das ist eine Zeitinfo. Ich würde sagen die legt fest, wie lange die nächste Silbe blau markiert wird.

Das ist eine diese Delta-Timesangaben. leider ist das kein "im Klartext" lesbarer Wert, weil die zur Speicherplatzvermeidung speziell kodiert sind.

Here are some examples of numbers represented as variable-length quantities :

Value (hex) Representation (hex)
00000000 00
00000040 40
0000007F 7F
00000080 81 00
00002000 C0 00
00003FFF FF 7F
00004000 81 80 00
00100000 C0 80 00
001FFFFF FF FF 7F
00200000 81 80 80 00
08000000 C0 80 80 00
0FFFFFFF FF FF FF 7F

Most of the time, musical events are sufficiently close together that the delta-time can be expressed in a single byte (i.e. for delta-times of 0 - 127). When a larger delta-time needs to be specified then additional bytes are used. This provides an efficient way of storing delta-time values.

OK, mal schauen:

9E 1D
FF 05 04 47 6F 6C 64         -->Gold
81 44 
FF 05 03 66 69 6E               -->fin
25
FF 05 05 67 65 72 2C 20     -->ger,_
86 56
FF 05 05 68 65 27 73 20      -->he's_
2B
FF 05 04 74 68 65 20           -->the_
28 
FF 05 03 6D 61 6E               -->man

Das Problem ist jetzt, dass das nicht nur längenkodierte Werte sind, sondern auch noch Deltawerte bezogen auf den Grundtakt (oder wie man das auch immer nennt).

Only the bottom 7 bits of each of these bytes contributes towards the delta-time, the top bit being used to indicate (when it is set) that another byte follows, i.e. bit 7 of each byte is used to indicate continuation or end of the delta-time data. Consequently the last byte of any delta-time value will have its top bit clear.

Die Umrechnung kann ich auch nur auf Papier, dass geht im Kopf nicht mehr, weil man Binär shiften muss. Ok, mal schauen, nehmen wir den ersten "Wert": 9E 1D

Zuerst binär:

1001 1110 - 0001 1101

Das linke Bit im Byte gibt an, ob noch ein Byte folgt. Hier folgt also 1 Byte. In dem ist das Bit 0, also folgt kein weiteres. Zum Umrechnen muss man nun die 7 Bits der Bytes zusammenschieben:

0000 1111 - 0001 1101

Ergebnis:

0F - 1D = 3869 (dezimal)

Das ist nicht ganz einfach.

Bis dann
Andreas

Ich sehe die Stimmungslage meiner Mitmenschen. Daher bleibt nur eine letzte Forderung: Weltuntergang jetzt sofort!
bei Antwort benachrichtigen
Sigi Saudi Andreas42

„Hi! Der Link ist gut, ich denke, da ist beschreiben, wie das zusammen hängt: The actual data within an MTrk chunk takes ...“

Optionen

Hallo Andreas,

(mein Name ist uebrigens Siegfried, ich habe 14 Jahre bei Saudi Telecom Company in Riad/Saudi Arabien gearbeitet, deshalb Sigi Saudi),

Mit Deinem letzten Beitrag ist das Problem wohl geloest. Ich habe mit meinem Hex Editor mal die beiden Bytes modifiziert, die vor Gold stehen (9D 1E) und die ich dem Timer zugeschlagen hatte. Wenn ich das rechte Byte (1E) aenderte, passierte nichts merkbares, weil die Aenderung wohl zu gering ist. Dabei bestaetigte sich, das das Most Significant Bit (80) eine Sonderfunktion hat. wenn ich den Wert des Bytes ueber 7F gebracht hatte, wurde im Player ueberhaupt kein Text mehr angezeigt, da ich damit markiert hatte, dass noch ein Timing Byte folgt, was ja nicht zutrifft. Das war fuer den Player dann unplausibel und er hat den MTrk mit der Lyrik ignoriert.

Danach machte ich die Aenderung rueckgaengig und ich aenderte das fuehrende Byte (9D) auf (FD). Damit wurde die Lyrik erwartungsgemaess viel zu spaet angezeigt und die ganze Synchronisation der Lyrik war kaputt. alle folgenden Woerter wurden zu spaet angezeigt.

Umgekehrt aenderte ich das linke Byte zuerst auf 7D. Damit hatte ich das Most Significant Bit geloescht. Erwatungsgemaess zeigte der Player keinen Text mehr an, weil das 2. Byte des Timers nun nicht markiert war. Dann aenderte ich das Byte 9D auf 8D und, wie schon erwartet, kam die Lyrik nun viel zu frueh und die Synchronisation der ganzen Lyrik war wieder kaputt.

Das schiften  der Binaerwerte ist kein Problem. Ich habe auf meinem Laptop einen Rechner, auf dem ich die Zahlen hex eingeben kann und dann kann ich im Binaermodus die Bits nach links oder rechts schieben.

Danke fuer Deine Hilfe. Solche Themen, wie dieses, lohnen sich doch bei Nickles gepostet zu werden.

Gruss aus dem naechtlichen Thailand (22:15 h)

Siegfried

Gruesse aus Wang Nam Kiaw / Thailand
bei Antwort benachrichtigen
Sigi Saudi Andreas42

„Hi! Der Link ist gut, ich denke, da ist beschreiben, wie das zusammen hängt: The actual data within an MTrk chunk takes ...“

Optionen

Hallo Andreas,

noch ein kurzer Nachtrag. Ich habe alle Timerwerte nach Dezimal umgerechnet entsprechend des Schemas, das Du aufgetan hast. Ich kann meinen Songtakt wiederfinden, wenn ich die Zahlen mit dem Lyrikfluss im Lied vergleiche. Dank Dir nochmal.

Hier die Umrechnung mit den Takten meiner neuesten Einfuegung der Lyrik:

Tempo
FF 51 03 0B F9 CB
Lyric
9E 1D  3869                            Takte vom Beginn
FF 05 04 47 6F 6C 64              -->Gold
81 31  177                                Takte vom vorherigen Wort
FF 05 03 66 69 6E                   -->fin
   29  41
FF 05 05 67 65 72 2C 20         -->ger,_
86 62  866
FF 05 05 68 65 27 73 20          -->he's_
   31  49
FF 05 04 74 68 65 20              -->the_
   25  37
FF 05 03 6D 61 6E                  -->man
81 54  212
FF 05 05 2F 74 68 65 20         -->/the_
   27  39
FF 05 04 6D 61 6E 20              -->man_
   6E  110
FF 05 05 77 69 74 68 20          -->with_
   46  70
FF 05 04 74 68 65 29               -->the_
   28  40
FF 05 02 6D 69 67                   -->mi
   7C  124
FF 05 04 64 61 73 20               -->das_
   59  89
FF 05 05 74 6F 75 63 68          -->touch
85 19  665
FF 05 03 2F 41 20                     -->/A_
   5B  91
FF 05 03 73 70 69                     -->spi
   65 101
FF 05 06 64 65 72 27 73 20      -->der's_
81 01  129
FF 05 05 74 6F 75 63 68           -->touch
86 06  774
FF 05 06 2F 53 75 63 6B 20 74  -->/such

Gruesse aus Thailand

Siegfried

Gruesse aus Wang Nam Kiaw / Thailand
bei Antwort benachrichtigen