seq and tempo
Hello!
I need to play a 10 minute long MIDI filetype 1 using MAX/MSP
The original midi file was recorded at 112.5bpm in Reaper.
I'm using the [seq] object, together with [tempo].
When using [tempo 112.5 1 96] the file is being played far slower than the original, and is unusable. Weirdly, when using [tempo 120 1 96] it gets better, but there's slight inaccuracies in the tempo handling which offset the whole score by a 16th note after 1 minute... and it obviously gets even worse after when arriving at the end of the file.
I also tried using the seq object without tempo, by playing at normal speed (start 1024), but i get the same results than with [tempo 120 1 96].
I need timing on this project to be rock solid, as the MIDI composition needs to be tightly synchronized with video, and i would preffer not to rely on a DAW to play the MIDI file....
Any ideas on what's happening?
Thank you very much!
I think the problem is that the timing of [seq] is based on milliseconds. So the timing data of MIDI files (based on beats and ticks) must be converted and accumulation of rounding/truncation errors may lead to drifting playback.
Unfortunately Max doesn't have a perfect MIDI file player.
wow... if based on ms i can understand why all this is happening.
I just discovered that if I uncheck the option "embed tempo/timesignature changes" when exporting MIDI from reaper, i can get better accuracy when playing using seq with message "start 1024", although it is still not perfect.
Tried again using tempo, but the midi played is very unsynchronized when playing with settings [tempo 112.5 1 96], and better when using [tempo 120 1 96]... but still not usable in my situation....
i hope i don't need to switch to a midi daw to do this properly!!!!
Max NEVER had any serious Midi File Playback capabilities.
Don't waist Your time, go for whatever other solutions, Max is not going to
do what You want, at least not with seq or seq˜ objects, by all means not with type 1
multitrack midi files.
Sorry to say it this way, but that is my experience.
Did You turn overdrive on ?
What are You syncing midi playback to ? It is not obvious in the patch You posted.
for playing midi (the nowadays officially obsolete) [detonate] object works somehow, but detonate sucks for exporting otoh because it can create only low resolution midi files.
if you want a proper midiplayer in max/msp you must build that around [filein]. then you can interpret the ticks and bpm data from the file in any form of "realtime" you wish and play it with super high precision.
while it is a shame that basic things like playing midi (or filehandling for that matter) are still a mess in max, one must also take into account that half the problem here is MIDI in general.
MIDI always was a low resolution, bad timing, idiosynchratic organinized protocol (you will also run into trouble when you try to interchange midi tracks between certain DAWs, did you know that?) so if oyu have the chance, try to avoid it and create something better.
It’s quite sad, that max don’t play midi-files in a reliable way, but I won’t give up.
I just made a patch last week to play and record midifiles with seq. As long as the midifile is exported in 120BpM from the DAW, it’s somehow in sync, I can change the play tempo and have even the ability to record. The start is quantized to 4n in combination with global transport. This is a work in progress patch and is made for my special needs. Comments are desired.
how can i convince you from my [filein] religion?
@source audio: i'm syncing with a video file by sending an OSC message to trigger play in madmapper. the OSC message is sent when i press the bang button which also starts playing MIDI, with some latency adjustment using delay. The MIDI data is sent to a pipe organ, and the video file is projection-mapped on the ceiling of an art-nuveau architecture by Antoni Gaudí.
@ben sonic: i just tried your approach using transport.... and it works perfect!!! I didn't have the offset shift during the 10 minutes of duration of my midi file. Thank you very much!! i'm going to study how your player is done and adapt it to my needs... :-DDD happy now!
@roman thilenius: the filein strategy you suggest sounds yummy.... if it wasn't because ben's patch is already working flawlessly, i guess that would have been the way to go. I agree with your comments regarding MIDI protocol outdated features... it's not the first time i find problems in managing aspects of MIDI data, and also not the first time i post MIDI related questions to this forum....
Thank you everyone for your suggestions and help, this had been unvaluable, as always...
I might be up for the filein religion XD
I need something where the tempo isn't fixed at 120 at the point of export. Can filein be used to read the tempo from a midi file?
since 2017, max seq changed to better.
About your question :
seq file parses standard midi file using tempo info(s)from midi file header
and uses internaly milisecond based playback.
So whatever tempo midi file has, it will be played correctly
using initial seq speed.
----------
You can extract tempo from midi file using filein.
tempo header starts with 255 81 3 nn nn nn - DECIMAL
3 nn numbers create microsecond divider
if midi file has tempo map automation, each tempo change will be composed same way
@source audio: Hi. You seem to be the only person on the planet who knows how to extract the tempo from a midifile in Max. I tried your method of using filein. My problem is I have no idea how to use filein or or how to interpret the data.
I loaded a midifile into the first inlet. Then used an int to scroll through some data and print it. I do see the sequence 255 81 3 . Are the next 3 numbers the nn nn nn you referenced? And if so how do you use it? Is that one beat in milliseconds? One tick?
If you don't mind, could you describe an example?
to find a certain set of bytes or words, you´d read out the file byte by byte (or word by word), then you can compare the data against the string you are searching for.
so read file, then use a counter, and if it is fgound, read the next 3 and then stop and good bye. (it is all in the helpfile - just ignore "spool", the rest is this process)
255 (meta)
81 (tempo) (you found it. this only only exist once in a midi file)
3 (size of data) (what it says. this is the number of bytes you have to read from here.)
the next three might look like this:
8 50 B4
these three together are a 24 bit signed number decribing microseconds(!) per beat.
first you have to create that integer number...

...then you have to do [!/ 600000.] to get the BPM.
some programs might ignore tempo when the midi file also has SMPTE tempo. filein will not. :)
(i havent checked if that image is right.)
that about being the only person on the planet ...
seems a bit exaggerated, at least inventor of midi tempo string should know something about it
joke aside, Roman explained it allready, but in case that you don't immediatelly
catch that abstraction 110.hexabyte2decim is actually single object sprintf 0x%s
on the green table
here is a patch I have laying arround since ages
note that i did not say "all you have to do". such things are a complete mess! i´ve used filein and sprintf for the first time after 5 years of max.
that is why they gave us seq and detonate in addition to filein. they might be limited, but you dont need to be a cosmonaut to use them. :)
aha, [match] is a good idea. completely underused here.