Tapping along with a metronome - [metro] not stable
Dear Max community,
I am designing a patch to test the tapping/timing abilities of participants in a study.
A [metro] object should generate metronome beats with an interval of 1000 ms and the participants have to fill in taps between the metronome beats using [button]. Everything is recorded as midi events with [seq] and written to a text file.
A trial with a good participant could look like this (assuming the metronome had a pitch value of 75 and the participant 60):
0 144 75 119;
300 144 75 0;
503 144 60 119;
803 144 60 0;
1000 144 75 119;
1300 144 75 0;
1495 144 60 119;
1795 144 60 0;
2000 144 75 119;
2300 144 75 0;
2502 144 60 119;
2802 144 60 0;
etc.
My Problem:
When there are no [button] presses from the participant the metronome values have the timestamps 0, 1000, 2000, 3000, but when the participant produces clicks in between, they start to be off, like: 0, 999, 1998, 2997
Note that they seem to occur "earlier".
Thanks for helping,
Thomas
Scheduler in Overdrive: On
Audio Interrupt: Off
Max 7.2.3
Mac OSX 10.11.5
Here is a simplified version of my patch, with which I could reproduce the problem:
Stay away from midi when measuring timing. Organise Collection of metro and tapped events
before any midi objects.
If midi is needed for Audio Monitoring of metronome, place it after addition of events into
list, being text or seq.
What is the sense of using pack > unpack > pack before filling midiformat/seq with data ?
And what is the use of noteout and midiout at same time ?
I have just realized that whenever there is a [button] press the metronome interval is reduced by 1 ms.
Setting the metronome to 1001 ms in addition with [button] presses results in timestamps that are exactly 1000 ms apart.
Without [button] presses the timestamps are 1001 ms apart.
Furthermore, an increase of [button] presses seems to result in an increase of the interval reduction.
1 [button] press between metro events: 0, 999, 1998, 2997, 3996
2 [button] presses between metro events: 0, 998, 1997, 2996, 3994
3 [button] presses between metro events: 0, 999, 1996, 2993, 3989
Thanks for your reply!
Easy answers first:
- What is the sense of using pack > unpack > pack before filling midiformat/seq with data ?
These are just remaining from the original setup where lists are passed between different subpatches. Sorry, I forgot to remove them.
- And what is the use of noteout and midiout at same time ?
The same is true for noteout and midiout. Midiout is a remaining object from when I tried the playback function of the [seq]. Sorry again, I will edit the sample patch right away.
I will try to implement your suggestions right away!
Thank you!
Here is the updated example patch (without irritating remainders of the original):
How can I fill the [seq] without [midiformat]?
[midiformat] is the last midi object in my patch now and the problem persists.
PS: Sorry for the posting mess. I am still new when it comes to forum postings. Trying to do everything super correct and messing the thread up in the process.
I'd suspect that [seq] is the culprit.
Using [coll] instead gives perfect timing.
This is beautiful! Seriously, seeing the correct numbers in the timestamps is beautiful! Thank you so much, Broc!
After Source Audio's reply I started to realize that I was wrong in blaming [metro], but I was unsure about how to best implement the timestamps without [seq].
Thank you so much!
Just out of curiosity:
Does this mean that there is a problem with [seq] or was I using it incorrectly?
Another addition:
Source Audio was right. Adding [noteout] creates problems with the timestamps even when I use [coll] instead of [seq].
The way around, as Source Audio suggested, is to first store the note in [coll] and then send it to [noteout].
This works fine for me in this case, but is it not worrying that using midi in a max patch creates problems with timing??
For me the timing remains correct even when sending to [noteout] before storing to [coll].
But I've noticed a possible error of 1ms due to the timestamp integer calculation (truncation).
This can be solved by float calculation and rounding.
Hi Thomas,
the main problem is that You are trying to measure events which trigger
midi notes which have higher priority than measurement itself.
So simply collect metronome and trigger events into seq object before sending notes.
Midiformat is not the problem, it is makenote object.
This way You also don't need to record Note Offs, so looking into result would
be easier...
Anyway, one shot drum samples don't need note off at all...
Replacing midiformat with a message 144, 75, 119 would also do
as comma separated items in a list get output as a que, just as midiformat does.
On could also send that to midiout object, instead of makenote/noteout combination,
but midiout sometimes does not work properly with Au DLS Synth
Seq is handy if You want to play back recorded midi, if that is not needed,
simple clocker is prcise enough to insert time stamp into coll, text or similar
here is modified patch, also with simple clocker as control
and add +1 after clocker output to display elapsed milis as 1000 and not 999...
the main problem is that You are trying to measure events which trigger
midi notes which have higher priority than measurement itself
Thanks for not only showing me how it's done, but also why it's done like that (or better: why it isn't done like I did it)!!
And sorry for not thinking about the rounding myself.
For the sake of completeness I've added a 'playback' button.