nfroidure / midifile

A MIDI file parser/writer using ArrayBuffers
http://karaoke.insertafter.com
MIT License
199 stars 30 forks source link

What playTime mean? #1

Closed proyb2 closed 10 years ago

proyb2 commented 10 years ago

While calculate to get the correct duration using this formula: ticks / (bpm * resolution / 60) = duration in seconds

The values in "playTime" which appear in console log don't seem to be correct, what this show? Is there an option to detect the tempo and the total duration? Tried reading Jazz Plugin Javascript example wasn't fruitful either.

nfroidure commented 10 years ago

playtime is the time in milliseconds between the track start and the time the event takes place. The formula you cite has already been calculated here: https://github.com/nfroidure/MIDIFile/blob/master/src/MIDIFile.js#L49

The tick resolution is first calculated here: https://github.com/nfroidure/MIDIFile/blob/master/src/MIDIFile.js#L42 Then adjusted here each time the tempo changes : https://github.com/nfroidure/MIDIFile/blob/master/src/MIDIFile.js#L53

Beware on the fact the formula changes depending on the tick resolution type declared in the file header: https://github.com/nfroidure/MIDIFile/blob/master/src/MIDIFileHeader.js#L54

Note that you can get original events by parsing the file like it's basically done there: https://github.com/nfroidure/MIDIFile/blob/master/src/MIDIFile.js#L46

Hope it helps ;)

proyb2 commented 10 years ago

I see, the timing you've calculated seem inaccurate to all of the midi files e.g. one song duration is 43 seconds which was calculated using Java MIDI API and MIDIFile shown 52526 milliseconds = 53 seconds.

Another song was correctly as 240 seconds compare to MIDIFile displayed as 255 seconds. Both are using only piano acoustic and no tempo was change during playing.

nfroidure commented 10 years ago

It may be a problem with the float precision or the formula. Could you tell me what difference you get with the MIDI files i use for tests: https://github.com/nfroidure/MIDIFile/tree/master/sounds

If there is a way to retrieve the results you get with the Java API, try to copy paste it there, it'll help me to resolve the issue. I'll take a look at it this week-end.

proyb2 commented 10 years ago

I would love to see how MidiFile can find the right duration when the Midi files has more than one tempo, I often need to use concerto and unsure how to get the right duration like Java MIDI could.

Sure, you can compile this Java Dump Sequence code to get the raw midi data, it will shown the duration http://www.jsresources.org/examples/DumpSequence.html and has similar result to this: http://jazz-soft.net/demo/ReadMidiFile.html

Results on my finding:
---------------------------------------------------------------------------
File: C:\Users\jazz\Downloads\Friends_1_9.mid
---------------------------------------------------------------------------
Length: 230723 ticks
Duration: 240336458 microseconds
---------------------------------------------------------------------------
DivisionType: PPQ
Resolution: 480 ticks per beat
---------------------------------------------------------------------------
Track 0:
-----------------------
tick 0: Time Signature: 4/4, MIDI clocks per metronome tick: 24, 1/32 per 24 MIDI clocks: 8
tick 0: Set Tempo: 120.0 bpm
tick 0: End of Track
...
nfroidure commented 10 years ago

Just compared results of https://github.com/nfroidure/MIDIFile/blob/master/sounds/MIDIOkFormat1-lyrics.mid between KMidimon:

0,0.0000,0:0,,SMF Text,Text:1,,Hello karaoke
0,0.0000,0:0,2,Program change,0,,
0,0.0000,0:0,,SMF Text,Lyric:5,,He
0,0.0000,0:0,2,Note on,86,121,
64,0.3331,0:0,2,Note on,86,0,
128,0.6669,0:0,,SMF Text,Lyric:5,,llo
128,0.6669,0:0,2,Note on,96,121,
223,1.1612,0:0,2,Note on,96,0,
223,1.1612,0:0,,SMF Text,Lyric:5,,\Ka
223,1.1612,0:0,2,Note on,93,121,
287,1.4950,0:0,2,Note on,93,0,
287,1.4950,0:0,,SMF Text,Lyric:5,,ra
287,1.4950,0:0,2,Note on,84,121,
351,1.8281,0:0,2,Note on,84,0,
351,1.8281,0:0,,SMF Text,Lyric:5,,o
351,1.8281,0:0,2,Note on,88,121,
415,2.1612,0:0,2,Note on,88,0,
415,2.1612,0:0,,SMF Text,Lyric:5,,ke
415,2.1612,0:0,2,Note on,95,121,
479,2.4950,0:0,2,Note on,95,0,

And MIDIFile:

[
{"index":"0x27","type":8,"subtype":12,"delta":0,"channel":1,"param1":0,"playTime":0},
{"index":"0x30","type":8,"subtype":9,"delta":0,"channel":1,"param1":86,"param2":121,"playTime":0},
{"index":"0x34","type":8,"subtype":8,"delta":64,"channel":1,"param1":86,"playTime":333.3333333333333},
{"index":"0x3f","type":8,"subtype":9,"delta":0,"channel":1,"param1":96,"param2":121,"playTime":666.6666666666666},
{"index":"0x43","type":8,"subtype":8,"delta":95,"channel":1,"param1":96,"playTime":1161.4583333333333},
{"index":"0x4e","type":8,"subtype":9,"delta":0,"channel":1,"param1":93,"param2":121,"playTime":1161.4583333333333},
{"index":"0x52","type":8,"subtype":8,"delta":64,"channel":1,"param1":93,"playTime":1494.7916666666665},
{"index":"0x5c","type":8,"subtype":9,"delta":0,"channel":1,"param1":84,"param2":121,"playTime":1494.7916666666665},
{"index":"0x60","type":8,"subtype":8,"delta":64,"channel":1,"param1":84,"playTime":1828.1249999999998},
{"index":"0x69","type":8,"subtype":9,"delta":0,"channel":1,"param1":88,"param2":121,"playTime":1828.1249999999998},
{"index":"0x6d","type":8,"subtype":8,"delta":64,"channel":1,"param1":88,"playTime":2161.458333333333},
{"index":"0x77","type":8,"subtype":9,"delta":0,"channel":1,"param1":95,"param2":121,"playTime":2161.458333333333},
{"index":"0x7b","type":8,"subtype":8,"delta":64,"channel":1,"param1":95,"playTime":2494.7916666666665}
]

The times seems very similar but it differs a bit. It could be the source of the problem. Can you check it with your Java parser also ?

nfroidure commented 10 years ago

Oh, and this : midiwebkaraoke.com is based on MIDIFile, so you can try to see if the difference is audible with your player.

nfroidure commented 10 years ago

Hum. Passed https://github.com/nfroidure/MIDIFile/blob/master/sounds/SampleMountainman.mid on KMidiMon and MIDIFile and the last note playtime was 191.9956 for the first and 191995.3437187494 for the second.

If there is a problem, it seems that it concern only a subset of the existing MIDI files, can you send me one of yours ? nfroidure at elitwork.com

proyb2 commented 10 years ago

Sent Midi files to your email. A real-world testing, hope it work. :)

nfroidure commented 10 years ago

I think i found the problem. It seems it happen when there are multiple tempo changes on multi tracks MIDIFiles. Here is the commit: https://github.com/nfroidure/MIDIFile/commit/957773f0b740ff9a7306c0f9a6ff2b18693c5fe7

Have no time to write tests but will do so later.

Let me know if there still are problems.

nfroidure commented 10 years ago

Oh, and thank you for your valuable feedback ;).

proyb2 commented 10 years ago

Tried your update, I've loaded the same song in the test folder, it's showing different timing and the time is still incorrect? playTime: 45342 playTime: 44925 playTime: 46589 playTime: 45658

Other songs: Events sent. playTime: 6668.000000005122, Tracks:11 Events sent. playTime: 6875, Tracks:11

nfroidure commented 10 years ago

Please can you give me more detailed informations:

Thanks.

proyb2 commented 10 years ago

i use my one of my MIDI songs which I have emailed you and tested on https://github.com/nfroidure/MIDIFile/tree/master/tests on my local Windows 7 machine.

Tested with all the midi files I sent.

I'm not sure if this Perl code could shred some light? http://www.perlmonks.org/?node_id=414099

On Fri, Sep 13, 2013 at 8:32 PM, Nicolas Froidure notifications@github.comwrote:

Please can you give me more detailed informations:

  • wich song (in the test folder or in the set of file you sent).
  • wich time for wich lib.

Thanks.

— Reply to this email directly or view it on GitHubhttps://github.com/nfroidure/MIDIFile/issues/1#issuecomment-24391174 .

nfroidure commented 10 years ago

I just tested some of your files and found:

That's pretty similar. It simplified a bit the formulas, but it appears the results does not change ( https://github.com/nfroidure/MIDIFile/commit/a7a8daf17a217cc30d073209e92206ac0e970e3f ). Please give me the files for wich you've got differences and the differences you have plus the code you use to see midi files length with MIDIFile if you doesn't obtain the same results than above.

proyb2 commented 10 years ago

Don't mind to sent you the zip of the screenshots, the latest downloaded code from Github and the MIDI files. I'm afraid if you tested with Jazz Midi plugin v1.3?

On Fri, Sep 13, 2013 at 10:34 PM, Nicolas Froidure <notifications@github.com

wrote:

I just tested some of your files and found:

-

minute_waltz.mid: KMidiMon: 92.1450 s MIDIFile: 92.1585 s

reason.mid: KMidiMon: 272.250 MIDIFile: 272.250

santa.mid: KMidiMon: 119.580 MIDIFile: 119.580

scn16_7.mid: KMidiMon: 124.4394 MIDIFile: 124.4396

That's pretty similar. It simplified a bit the formulas, but it appears the results does not change ( a7a8dafhttps://github.com/nfroidure/MIDIFile/commit/a7a8daf17a217cc30d073209e92206ac0e970e3f). Please give me the files for wich you've got differences and the differences you have plus the code you use to see midi files length with MIDIFile if you doesn't obtain the same results than above.

— Reply to this email directly or view it on GitHubhttps://github.com/nfroidure/MIDIFile/issues/1#issuecomment-24398665 .

nfroidure commented 10 years ago

I understand now. You're using the HTML test file wich i told i hadn't update ;). I did it : https://github.com/nfroidure/MIDIFile/commit/53aceda7635d0392829fe8efeea7e2fc48174b6b

The results should now be right with it. You cant test it live here: http://rest4.org/github/nfroidure/MidiFile/master/tests/index.html

nfroidure commented 10 years ago

Yet another commit, should read more MIDI files : https://github.com/nfroidure/MIDIFile/commit/a0613cabeb5dab90336d8e98e8f14d6c54d6c22e

Let me know if you find other files broken with MIDIFile.