Midi Clash "Timestamper"
Hi all,
I am currently working on a patch that can detect when pitch clashes occur via MIDI in a DAW project. By this I basically mean a "clash" to be whenever the exact same MIDI note is being played at the same time on 2 separate MIDI channels, if MIDI channel 1 is playing a "C2" and MIDI channel 2 is playing "C2" simultaneously then this would be a clash. My idea is that MAX will timestamp any clashes whenever they occur with the user able to view the results before deciding if these clashes could be causing any potential frequency problems in their arrangement (building up of frequencies in one area etc.), however, I do understand that this isn't always a problem and can sometimes be desirable. My plan of action is to get the patch working with just 2 channels to start with although I seem to be at a bit of a hurdle.
By utilising External MIDI channels "using Logic Pro X" set to "MAX 1" (channels 1 and 2) I have managed to get MAX to recognise what notes are being played in the DAW and SOMETIMES detect when a clash is occouring. These clashes are recorded in the "coll" object at the end of the patch along with the amount of time passed taken from the "clocker" object. As far as I can tell the patch should be fully working, however, I am obviously missing something so I was hoping someone would be able to lend a hand!
On a side note am I right in saying the clocker object works in milliseconds? If so then does anyone have any idea how I would go about converting these milliseconds to the bars and beats / BPM of my logic project? With that being said I wish to try and get the fundamentals of the patch above working before i look into this, however any insight would be useful for the patch further down the line.
Thank you for your time!
As first You should use midi clock to sync logic and max.
Detecting same notes being held on 2 channels
could be done using list compare, and time stamp recorded
can be in form of ms or ticks.
Here is a patch to get You going.
It is set to detect same notes that are currently
held, and output is triggered whenever state changes.
Also example how to convert ms to tempo based progress.
One could also try to send midi from 2 tracks into Max
and send midi back to Logic, containing info
about matched notes.
That could than be recorded into separate track in Logic.
In than case there would be no need for sync
or capturing notes in Max
Hey thanks for your reply! The ms to tempo stuff is a big help thank you! However, the other side of the patch doesn't seem to be working for me?
I have changed out the "pack 0 0 0" object for a "pak i i" as I don't need any velocity information for the patch to work, only Midi and channel data.
From the "notein" I have "Midi Channel" going into "Element 1" of the "pak" and "pitch" going to "Element 2". Iv'e done this as the "route" object below matches it's arguments with the order of elements from the "pak".
By doing this the patch seems to be recognising when notes are coming in from my Logic External MIDI Channels but not when there is a clash.
Or am I misunderstanding how your patch works completely? That is entirely a possibility as I am a MAX newbie! Sorry for any inconvenience. Iv'e re-uploaded your patch with the changes spoken about so you can see what I mean, although, like I said I may just be misunderstanding how to use your patch!
I am really sorry for that mistake.
I forgot to rotate the list so that
midi channel is at beginning.
Here is corrected patch :
If You have any other questions, just post.
I am on the run and have no time to look at Your patch version at the moment,
but will do that later today
Hey man, thanks for all the help so far!
I'm currently breaking down your patch slice by slice so I can get my head around how the individual elements are working together. I'm starting with the portion of the patch from the "notein" to the "message" which displays clashing notes. Once I understand how this section is working I shall be moving onto the rest (I don't want to run before I can walk).
I believe I understand how everything is working apart from the section in between the "if" and "bondo" objects and so was hoping you would be able to clarify the process in that section for me! So that would include the "messages" from the "if" object's outputs as well as the "coll", "trigger" and "zl group" objects.
I have attempted to annotate this portion of the patch with a step by step guide of what is occurring (as far as I can understand it anyway). Does this look correct to yourself?
Thanks again for your time buddy!
I am still on the road, so have not much time to answer,.
Had a brief look into analyser.
Most is fine, but the coll object is a central point - it stores
held notes.
I´ll be back and post the details as soon as possible.
No worries buddy, I look forward to it!
Thanks again! :)
Back again.
Here is the explanation :
to do what You are after one needs to
form a list of currently held notes for each midi channel
and compare if they have common notes.
I used coll for that.
if object splits Note On and Note Off, so that Note On gets stored into coll,
Note Off removes it from Coll.
message :
$1 $1, dump means store item 1 of list and than dump all entries out.
message:
remove $1, dump removes released note from coll and dumps all entries .
That way we have current list of held notes whenever a note gets played or released.
Coll object dump outputs items itered, one by one.
We collect that into list using zl group.
Coll sends bang to rightmost outlet when dump is done.
That triggers t b - . ( or t b + for channel 2)
Trigger object outputs items in right to left order.
- in midi channel 1 and + in midi channel 2 are there just to replace
any previous list in bondo and zl sect . (that is needed because if there are no held notes
stored in the coll, there would be no output, and old list would still be there)
Anything else non numeric could have been used instead of + - , even a number out of midi note range.
Trigger object than outputs a bang, which makes zl group output so far collected list.
Both lists go to bondo so that both lists are sent out
no matter which one triggers it.
zl sect does the comparison and outputs a list of common items
to left outlet, or bangs at right outlet.
The message at the end which gets cleared by set message is just to display
common notes, if there were no common items, it would still display last matched items, so we have to clear it when no match.
That's all. You should look into help files of objects used, that helps.
-----------------
This works ok for 2 channels, if You want to use more, than something
different has to be done, to be able to compare multiple lists, and the question is
what infos would have to be included into "report" .