Midi sequencing in Max
So after my last topic, I'm completely baffled that Max (which prides itself with having "midi data at your fingertips") actually has worse midi sequencing capabilities than a 30-year old keyboard I picked up at a yard sale for 10€ (e.g. seq and detonate can't even loop a part of a midi sequence or jump to a specified position). So are there any good polyphonic sequencers for Max out there? I've already found the following, but they all have significant drawbacks.
Note~ for Max, latest version is now almost 5 years old. Over a year ago the creator stated that a new version was coming and that starting with the old version was discouraged. Can be considered dead?
Max4Life, Ableton looks great, but being a student I simply do not have that kind of cash lying around. Besides, spending 600€ to get some midi sequencing capabilities seems a little, uhm, steep.
RS.delos, looks interesting and could be sufficient, but is 25€. For several reasons I would rather use something that is free and open source.
Bach, seems powerful but complicated. Also only seems to offer classical notation, while I would rather have a piano roll?
SeqPlayer (Eric Singer), really old and doesn't fit my requirements.
So how do you do sequencing? Should I just roll my own (seeing that I just need very basic functionality)? If so, where would you advise me to start? Javascript, the C-API or, if I understood correctly, I could even use Java? However, how would my object output precisely timed midi data? I couldn't find anything about any midi buffers I could fill, which seems to be the standard way for midi.
I doubt Max is the correct tool for full-on MIDI sequencing, to be honest. That's what a DAW is for. And there are plenty of cheaper (and better) alternatives than Ableton Live. Though, yeah, it has the Max integration.
The MIDI buffer you are looking for is [detonate]. It does have a way of jumping to a particular position, but I have never used it.
What are you trying to do that a DAW won't?
Thanks for your reply. I'm trying to build an experimental piece dealing with audio and video, where small loops of midi will play an important role.
If there are indeed no good sequencers for Max (such a shame), I'm considering writing my own (as I only need very basic functionality). This is also what I meant with midi buffer. If I would start to write a Max external, how can I get it to send midi with precise timing? I'm guessing that there is some sort of buffering going on, but I could find very little about that.
By "Max external" do you mean writing something in C that acts as an external for Max? If so, I cannot help. Or do you mean writing a utility in Max to use in coordination with some other program? So that Max is external to it?
In Max, [detonate] is the most fully-featured MIDI object. If you look through the nested help files you will see that this even comes with a piano roll interface. You can programmatically position the cursor and so can set up loops. It's possible to ignore the timing in the file itself, or speed it up / slow down by your own factor. There would be a fair amount of logic to handle, but it appears that this can be done with built-in Max objects.
One of these day I really must investigate this more.
Yeah, apparently there is a C-API, which can be used to create custom objects. As far as I understood those are referred to as "externals".
That sounds very interesting, but where did you get that info? I could not find a reasonable way to set the cursor in detonate. I found "startat", which basically searches for a certain note and sets the cursor there, and "nth", which sets the cursor at a specified event. Both of them are not really useful for looping. As far as I could see there is no way to set the cursor based on a time, which really would be a shame.
Once you've read a file into [detonate], use (next) repeatedly to cycle through all MIDI events. As you do so, the first outlet gives you the duration of that event. Compile this list of events and their times into a [coll] that will act as your index. Choose any one of these as your loop start. When playing back the loop, keep track of cumulative time until your loop length is reached. If your loop length does not fall on an event border, you will need some trickery to shorten the final note.
You can send [pianoroll] a message (bar 3) to locate the play head in seconds. Not sure if that is useful.
OK here's a bunch of code. I won't be able to finish debugging it, but it should give some idea. Hope it helps.
If You really want to use midi files in max, despite all the limits,
maybe a faster option is to first convert Midi into text format,
and than use text file in coll for playback.
Have a look here:
https://code.google.com/archive/p/midi2text/wikis/ProgDescription.wiki
It is then a matter of editing text files and place them into coll,
route note info etc
---------
Or have a look here:
http://compusition.com/software/maxmsp/ajm-objects
I'll have to get a better grasp of detonate
.seq~
has some interesting examples. I suppose - but it looks super straightforward. A sequence is from 0. - 1.0 and the text is damn near the same as a coll. maybe it is a coll, I can't tell.
they have a MIDI
tab in its help file. good for arbitrary midi info in general but... I almost like the idea of having a different seq~ for tons of different information types (even a seq~ for each type of note in a sequence that gates played in) with the thought that you could sync them with the same phasor or slide all the pieces apart with separate phasers almost parallax style. its flexibility seems really fuckin cool tbh.
detonate´s help file looks overwhelming at first but in fact it only shows the basic pricinple of howto write - and read from it, using the delta time of the last event it was outputting.
after you mastered it and run your own custom abstractions to operate it, you will be rewarded with a 32 channel object and a pianoroll.
Why not live.step?