fbpx
  Tuesday, 08 June 2021
  17 Replies
  6.7K Visits
16
Votes
Undo
  Subscribe
Does anyone have any SMPTE based MIDI files I can test my software with?

I have one particular file that won't load, and I am trying to narrow down the cause. It may have to do with the SMPTE designation/marker not being properly processed, so it throws the rest of the file scan off. Just a theory currently.

I've loaded said file in a few different MIDI softwares, including players and editors, and nothing appears amiss.

Sekaiju shows that it has an SMPTE offset. I haven't noticed this in any of my other test files, so it may be what is causing my issue.

I'm attaching the file in case anyone else can find something out of the ordinary with it.

It is an old MIDI file of In The Hall Of The Mountain King.

Does delta time still process the same way mathematically if the file uses SMPTE?

I read the bytes in the same way either way. The actual SMPTE offset loading wouldn't cause the issue, but I'm thinking maybe the delta time processing might?
Jason changed the title from Looking for some sample SMPTE MIDI files to Looking for some sample SMPTE MIDI files / Delta time question — 1 year ago
1 year ago
·
#9243
0
Votes
Undo
I'll still take any SMPTE samples and further info about the influence of SMPTE on delta times, but I figured out my particular issue.

I had added track names in to my channel display some time ago, and included too much code under the "if" statement for it. It only caused a load error if: the file was a Type 0 MIDI file, AND the file also had no program changes. This is the only file I have that ticks off both of those boxes, so this is the only reason I found it. I did have to painstakingly step through the debugger for quite a while until I noticed it jumping right over my "create an instrument if there's no program change but there is a note on" section.

Whew!
1 year ago
·
#9244
0
Votes
Undo
Hello,

Not sure what the SMTE item is supposed to be doing. As I understand it, it does nothing. The data present, i.e. 96.00.00.00.00 signifies that it's a Type 3 timecode, but the offset is zero. The first 3 bits of the first number indicate the Type, the other 5 bits are for Hours.

There does not seem to be anything else in the file that would take any notice of this data. Certainly, this should have no bearing on the processing of the delta timing.

The division value of 480 ticks per quarter note if fairly high, and the resultant size of the tick numbers in the file, may cause some systems a problem. What data type is your software using for delta time, might you have some overflow?

Geoff
1 year ago
·
#9246
0
Votes
Undo
The division value of 480 ticks per quarter note if fairly high, and the resultant size of the tick numbers in the file, may cause some systems a problem. What data type is your software using for delta time, might you have some overflow?

Geoff

It's in.... ummm... whatever the default is in Game Maker Studio, which I believe is something ridiculously large, equivalent to a real either 16 or 32 bit float. I read it one byte at a time and do some math (based on some code I found a while ago) to bring all the quantities together if it's larger than a single byte.

However, my problem was not related to delta time, it was an oversight on my part when I added a feature as noted in my replay to my original post above.

So delta time is delta time no matter what? Just the software needs to figure out what each delta time "unit" represents?

https://en.wikipedia.org/wiki/MIDI_timecode

This seems to explain SMPTE as it relates to MIDI, and with the way it's described, it actually sounds quite cumbersome. Apparently I have not run across any MIDI files that actually utilize it in it's full capacity. You learn something new every day!

MIDI time code (MTC) embeds the same timing information as standard SMPTE timecode as a series of small 'quarter-frame' MIDI messages. There is no provision for the user bits in the standard MIDI time code messages, and SysEx messages are used to carry this information instead. The quarter-frame messages are transmitted in a sequence of eight messages, thus a complete timecode value is specified every two frames. If the MIDI data stream is running close to capacity, the MTC data may arrive a little behind schedule which has the effect of introducing a small amount of jitter. In order to avoid this it is ideal to use a completely separate MIDI port for MTC data. Larger full-frame messages, which encapsulate a frame worth of timecode in a single message, are used to locate to a time while timecode is not running.


Oof.
1 year ago
·
#9256
0
Votes
Undo
Does delta time still process the same way mathematically if the file uses SMPTE?

Delta times are the number of so-called "ticks" since the previous message in the track. The MIDI file header indicates the format of the ticks (ticks per quarter note or ticks per frame).

The initial handling is the same:
• You still process the delta time bytes as a variable-length quantity no matter what format the ticks represent.
• At the beginning of each track you would reset a tick counter to zero. Each time you encounter a delta time, you increment the tick counter by that delta time's value to get the event's absolute tick position.

The handling begins to be different once you need to get the positions of events in quarter notes or in seconds. The conversion calculations you use depends on the delta time format the MIDI file uses:
• In the ticks per quarter note format, the ticks represent some amount of quarter notes. If you need the absolute time in seconds, you have to convert the quarter note amount into a seconds amount.
• In the SMPTE delta time (ticks per frame) format, the ticks represent some amount of seconds. If you need the position in quarter notes, you have to convert the seconds amount into a quarter notes amount.


SMPTE-RELATED THINGS

Be aware that even though the SMPTE delta time format, the SMPTE Offset meta event, and MIDI Time Code are all related to SMPTE time codes (hours:minutes:seconds:frames), my understanding is there's no requirement that a MIDI sequencer must use all of them together for a particular MIDI file. (For example, the MIDI file you attached contains the SMPTE Offset meta event, but uses the ticks per quarter note format of delta time.)


Delta times

As you know, the position of every event in the MIDI file is specified in delta times, the number of so-called "ticks" since the previous message in the track.

There are two kinds of delta time formats possible: Delta times can be based on quarter notes (ticks per quarter note) or based on seconds (SMPTE format). The MThd header chunk of the MIDI file specifies the format of the delta times.

If the delta times are based on quarter notes, the header specifies a value of ticks per quarter note.

If the delta times are based on seconds, then the header specifies values for frames per second and ticks per frame.

For information about the delta time format bytes in the header, see the Standard MIDI Files Specification PDF page 6 (printed page 4). (Be aware there is a special frames per second value possible called "30 drop frame" that the MIDI File Specification doesn't explain. I can explain my understanding of it if you want, but it gets complicated.)


SMPTE Offset meta event

My understanding is the SMPTE Offset meta event can be stored at the beginning of a MIDI file's tempo track for use by a MIDI player that is able to sync with a tape system that uses SMPTE timecodes. For example, you could start playing a tape that has SMPTE timecode information recorded on it, and once the timecode on the tape matches the SMPTE Offset value, the MIDI player will start playing the MIDI file. If you are creating MIDI software that doesn't need this kind of sync capability, then you can just skip over the SMPTE Offset meta event if it is present, you don't need to do anything with it.

For the description of the SMPTE Offset meta event, see the the Standard MIDI Files Specification PDF page 11 (printed page 9).


MIDI clocks and MIDI Time Code

MIDI clocks and MIDI Time Code are two different kinds of sync messages. These messages aren't stored in a MIDI file, but they might be sent from a MIDI sequencer to another device, or might be sent from another device to a MIDI sequencer, to help synchronize the two devices.

MIDI Clocks and Song Position Pointer are based on quarter notes:
• Clock messages are sent at a rate of 24 clocks per quarter note to indicate the current tempo.
• A Song Position Pointer message can be sent to change the current position in units of sixteenth notes.

MIDI Time Code is based on seconds:
• The Quarter Frame message is sent at a rate of four messages per frame. For example, when the frame rate is 30 frames per second, then the Quarter Frame messages happen 120 times per second. Quarter Frame messages contain information about the time position (hours:minutes:seconds:frames), but the information is spread out over 8 messages.
• The Full message is a Universal System Exclusive message that can be sent to change the current position to a specific hours:minutes:seconds:frames position.

For information about MIDI clock messages see the MIDI 1.0 Detailed Specification PDF pages 35 to 37 (printed pages 30 to 32).
For information about Song Position Pointer, see the MIDI 1.0 Detailed Specification PDF pages 32 to 34 (printed pages 27 to 29).
For information about MIDI Time Code, see the MIDI Time Code specification.


The division value of 480 ticks per quarter note [is] fairly high

It's always good to check the data types being used to make sure there's no overflow happening. But I believe 480 ticks per quarter note is a typical amount. My understanding is that it is common for the ticks per quarter note value to be some multiple of 24 up to about 960. For example, Cakewalk lets you choose the from the following values for ticks per quarter note: 48, 72, 96, 120, 144, 168, 192, 216, 240, 360, 384, 480, 600, 720, or 960. (The reason behind using a multiple of 24 is because it is helpful if MIDI clocks are used for synchronization. There are 24 MIDI clocks per quarter note, so when the ticks per quarter note is a multiple of 24, there will be an integer number of ticks per MIDI clock.)
1 year ago
·
#9257
0
Votes
Undo
```
C:\JZZ\test-midi-files>node . HALLOFMK.MID print
WARNING: offset 23 track 1 tick 0 -- Invalid SMPTE meta event: incorrect data (ff54 -- SMPTE Offset: 96:00:00:00:00)
SMF:
type: 0
ppqn: 480
tracks: 1
MTrk:
0: ff54 -- SMPTE Offset: 96:00:00:00:00
0: ff58 -- Time Signature: 4/4 24 8
0: ff59 -- Key Signature: C
0: ff51 -- Tempo: 120 bpm
0: b0 40 7f -- Damper Pedal On
0: 90 36 30 -- Note On
2: 90 42 2b -- Note On
...
```
Perhaps the problem is that the hour value in the SMPTE offset metaevent is more than 24.

Just FYI, I'm using this software: https://github.com/jazz-soft/test-midi-files
1 year ago
·
#9258
0
Votes
Undo
Correction: 96 in not an hour.
First SMPTE byte is the SMPTE type, valid values are 24, 25, 29, 30
1 year ago
·
#9259
0
Votes
Undo
Hm?

My information - don't recall where from now - was that the first three bits gives the Type, and the other 5 bits the hours. This allows for Types 0 to 7, and Hours up to 31. This use of the byte is a change from the original spec which was for all bits to be used for Hours.

Geoff
1 year ago
·
#9260
0
Votes
Undo
Perhaps the problem is that the hour value in the SMPTE offset metaevent is more than 24.
Correction: 96 in not an hour. First SMPTE byte is the SMPTE type, valid values are 24, 25, 29, 30

Just to clarify, Jason discovered the cause of his particular problem on his own, as he said in his first follow-up post in this thread, "I figured out my particular issue. [...] It only caused a load error if: the file was a Type 0 MIDI file, AND the file also had no program changes." But Jason still expressed interest in understanding SMPTE delta times and gathering MIDI files that use SMPTE.

In the Standard MIDI Files Specification PDF page 11 and 12 (printed page 9 and 10), the description for SMPTE Offset says:

SMPTE Offset

FF 54 05 hr mn se fr ff

[...] The hour must be encoded with the SMPTE format, just as it is in MIDI Time Code.
[...] The ff field contains fractional frames, in 100ths of a frame, even in SMPTE based tracks which specify a different frame subdivision for delta-times.

In the MIDI Time Code specification, PDF page 4 (printed page 2) explains bit meanings of the hour byte:

HOURS COUNT: x yy zzzzz

x   Undefined and reserved for future use. Transmitter must set this bit to 0 and receiver should ignore!

yy   Time Code Type:
0 = 24 Frames/Second
1 = 25 Frames/Second
2 = 30 Frames/Second (Drop-Frame)
3 = 30 Frames/Second (Non-Drop)

zzzzz   Hours Count (0-23)

Putting those together, my understanding is the the 5 bytes contained in the SMPTE Offset meta event are the hours, minutes, seconds, frames, and hundredths of a frame. And the hours byte uses some of the high bits to encode the frame rate.

If you examine the bytes of Jason's file, the 5 bytes contained in the SMPTE Offset meta event are hex 60 00 00 00 00. And in particular, that first byte is binary 01100000. This corresponds to an encoding representing 30 frames per second, non-drop, and a time of zero hours, minutes, seconds, frames, and hundredths. For example, Sekaiju displays the event's contents as "30[FPS] : 0[Hour] : 0[Minute] : 0[Second] : 0[Frame] : 0[SubFrame]".

Before the MMA made the official MIDI specifications available as free downloadable PDF files sometime in the first half of 2016, the unofficial source of MIDI specifications that I preferred was the MIDI Technical Fanatic's Brainwashing Center (mirror, original no longer online, see link at top of page). I notice that its description of the SMPTE Offset meta event is exactly the opposite (underline mine), "The hour should not be encoded with the SMPTE format as it is in MIDI Time Code."

I don't know if the Brainwashing Center's author got this wrong, or if there was some earlier version of the official specification that stated it that way. (The MMA hasn't released earlier versions as free PDF files, and the current version doesn't have a detailed revision history. The current version does say "Revised February 1996" and "Copyright © 1988, 1994, 1996 MIDI Manufacturers Association", so there might have been earlier versions in 1988 and 1994.)

I have a book The Musician's Guide to MIDI by Christian Braut, the 1994 English translation. It mentions the SMPTE Offset meta event on page 365 and 366 and describes the hour bits that encode the frame rate type. So that suggests these bits were likely official in 1994 or before.

In any case, I suspect some MIDI software developers based their understanding on the Brainwashing Center or another source (or possibly an earlier version of the official MIDI File Specification) that says the hours value does not include bits that encode the frame rate type. For example, in a previous post where the SMPTE Offset meta event came up, I remember pointing out a tool that Geoff used did not decode the type bits of the hour either, so that's an example of at least one other developer believing there were no type bits in the hour byte:

Geoff, be aware that the [DECODE] program you use to convert MIDI files to text seems to have the following issues: [...] 3. When it displays an SMPTE Offset meta event, it is incorrectly displaying the entire first byte as an hours value ("33 hours") instead of correctly interpreting the high bits as indicating the time code type (time code type is 25 frames per second and hour value is 1 hour).
As for the SMPTE, when did the spec change to allow for the use of the hight bits in the '[hour]' value for 'time code type'. Was this parameter active when the software was written in 1991/2.
Hm, I don't know. I don't use SMPTE time myself, but when I noticed the SMPTE Offset hour value in a sequencer I use [Sekaiju] was different than the hour value in text file you made, I peeked in the specs to see what could be going on.
1 year ago
·
#9262
0
Votes
Undo
Thanks for all the info. I have a much better understanding of how SMPTE works with MIDI, and also a little better grip on delta times. Hopefully I won't need any of it ;) But I also said that about a bunch of other stuff that I learned as I was in the earlier stages of my project, much of which will now be part of the final program :D Currently as is, when processing a file, I discard most of the data that I don't need or store it in variables that don't get used (including delta time values and SMPTE data, among many others). To skip, I read delta time, the next event type, then the v_length, then jump over that many bytes until I reach the next delta time byte(s). I do have a placeholder to add additional data extraction for every meta type as well as some other things just in case. With that last data extraction bug sorted out, I don't believe I have any files left over that cause any issues except for a truncated file which crashes it because I try to read outside of the file based on the file/track length in the file, but I can fix that with an appropriate fail-safe.
My project is for editing instruments, so much of the other "normal" info in the file is irrelevant to what I am doing and remains untouched.
1 year ago
·
#9263
0
Votes
Undo
Geoff: nice catch!
a fixed version is online.

C:\JZZ\test-midi-files>node . HALLOFMK.MID print
SMF:
type: 0
ppqn: 480
tracks: 1
MTrk:
0: ff54 -- SMPTE Offset: 00:00:00:00:00
0: ff58 -- Time Signature: 4/4 24 8
0: ff59 -- Key Signature: C
0: ff51 -- Tempo: 120 bpm
0: b0 40 7f -- Damper Pedal On
0: 90 36 30 -- Note On
2: 90 42 2b -- Note On
...
1 year ago
·
#9274
0
Votes
Undo
Geoff: nice catch!
a fixed version is online.

This is EXACTLY why I have so many different files to test my software ;) Sometimes you just never know it's broken or you are missing something until that case pops up!
1 year ago
·
#9275
0
Votes
Undo
Attaching a test file with a 1 minute SMPTE offset. MS Media Player ignores it.
I believe 99.99% of other players will ignore it too.
1 year ago
·
#9293
0
Votes
Undo
Attaching a test file with a 1 minute SMPTE offset. MS Media Player ignores it.
I believe 99.99% of other players will ignore it too.

Haha, well, it breaks my program :D A value that's supposed to get set is missing. Time to track down another issue (though again, probably will not be related to SMPTE) :P

My players ignored it.
1 year ago
·
#9294
0
Votes
Undo
Fixed. Oversight on my part when fixing my previous issue.

My program... ignores the SMPTE offset! As it should, because I do not need to deal with timing.
1 year ago
·
#9296
0
Votes
Undo
Try your program with the other test files at https://github.com/jazz-soft/test-midi-files
Or you can even add some more test cases to the repo.
1 year ago
·
#9307
0
Votes
Undo
Try your program with the other test files at https://github.com/jazz-soft/test-midi-files
Or you can even add some more test cases to the repo.

Interesting. I'm running through them right now.
I haven't found a single program that does this one correctly:
midi_test-control-00-20-bank-select

For my own, I think I am missing bank select 121 for GM, which I will add in. My program currently shows percussion on both channel 1 and 10. (It is an editor, not a player).
A player called Midi Player that uses the VSTi plugin of Yamaha S-YXG50 plays percussion on 1 and 10 as well.

Winamp, Anvil Studio, and Sekaiju all play it as instrument on ch 1, percussion on ch 10, using Coolsoft VirtualMIDISynth as my default MIDI device.

VLC plays instrument on both 1 and 10.

The only other one that causes a genuine issue for me is the one missing a byte, which is an issue I am already aware of, as I read the stated length in the track header, so it overflows.

Any of the files without instruments cause a "load failure" message as expected, because it is for editing instruments, and you can't edit what's not there ;)

Thanks for the helpful collection of test files.
1 year ago
·
#9311
0
Votes
Undo
Off the main topic now, but I added in support for GM Bank 121. In doing so, I found a spot where I needed to add an extra check for non-percussion on a (normally) percussion channel, so added that in as well.

The test file as is resets the channels to their original state after playing the notes. Is this a common thing to do? Meaning, I have set a channel to percussion, and now I am going to change it back to a melodic instrument? This causes display issues for me, because I set flags for whether or not a channel is percussion while parsing the file. It is an editor, so takes the MIDI file as a whole and can not distinguish different sections of the same channel being both percussion and non-percussion.

If I remove the bank selects that reset the channels at the end, it loads and displays properly, with percussion on 1 and melody on 10.
  • Page :
  • 1
There are no replies made for this post yet.