Generating MIDI files

Simon Assmann's icon

Hi everyone,

I would like to input MIDI note data into the seq object via a list, rather than realtime note playing or loading a MIDI file. In other words, I want to immediately generate a long midi sequence in the seq object from scratch (using randomized input for the timing, velocities, etc.). In even other words, I want to generate MIDI files immediately.

Is this possible? I can already generate coll lists and then use timing objects to direct these lists into a makenote object, etc., but I want to create the MIDI files themselves and import them into another application for a project that I am working on. Maybe the seq object isn't the best way to go? And maybe I'm just missing the obvious?

Thank you,

Simon

jvkr's icon

It's not necessary to do it in real time. The documentation on seq says: It can also read and write text files in which each line consists of a start time in milliseconds (the time elapsed since the beginning of the sequence) followed by the (space-separated) bytes of a MIDI message recorded at that start time.

You could generate such a text file--non real time-- and have it automated open with seq and save as a midi file.

_
johan

Simon Assmann's icon

Hi johan,

Thanks a lot!

I had read that, but the simple thing that I was missing was that I can generate text files in Max that are not coll files. So I was interpreting this as loading existing text that Max did not generate (which to me was a similar option to loading an existing MIDI file).

So ok, I'll generate the text file with the text object, save it, immediately open it in seq, then save it again as a MIDI file.

Cheers,
-Simon

BenCello's icon

One year later...

Same question here but I'll reformulate it.

Is there a way (with seq or another object) to write a MIDI file without recording it in realtime? Meaning, I already have the timestamps of every MIDI event (notes) and I just want to format all that info and save it as MIDI so I can reload it later.

Of course, an obvious solution is to "replay" all in real time directly into seq. But that takes twice the time of my sequence ! (one time to acquire it, one time to get it into seq).

The seq documentation says you can read and write text files formatted with date and MIDI code. But seq doesn't seem to actually understand this in its inlet.

So another option is to do what Simon Assmann said a year a go: put the raw infos in a text object, save as a text file then reload it in seq to convert as a MIDI file. But it seems a bit... stupid to have an intermediary text file.

Maybe some of you know a better way ?
Or maybe we could request that as a feature for the seq object ?

Thank's

seejayjames's icon

Probably do need the text file, unless you're generating the events one by one (even super-fast). Maybe [detonate] will help you out? Should be able to pump the events into it however fast you want, with a way to set the timing between events. Haven't tried it though.

BenCello's icon

Hi !

Thank's for your reply.
I am actually generating the events at normal speed first and storing them in a custom data structure. So they can be accessed any time, however fast.
What I would like is avoiding having them recorded at 1:1 speed to seq while generating them for two reasons: 1st, it takes some CPU resources I could use for something else, 2nd, I already have the timing of the events and it is a complicated timing system. So the idea is that the saving has to be totally separated from the rest of the system, it occurs only at the end of the process and on demand only. Exactly as a save mechanism.

I'll have a look to detonate. Maybe it can pump the events super-fast as you said.
I'll give it a try. Thank's for the pointer

Christopher Dobrian's icon
Max Patch
Copy patch and select New From Clipboard in Max.

Are you aware of the text object? Put lines of text into it, read lines of text out of it, save to a file, read from a file, use the file with any other object that can use text files (such as seq).

BenCello's icon

Are you aware of the text object?

Are you aware of the previous posts in the same thread ?

So another option is to do what Simon Assmann said a year a go: put the raw infos in a text object, save as a text file then reload it in seq to convert as a MIDI file. But it seems a bit... stupid to have an intermediary text file.

Thank's for the patch anyway...

Christopher Dobrian's icon

I read all the posts of the thread, and was trying to be helpful. Sorry for assuming that you would be able to infer that saving the text as a file is optional. You could easily generate the score, place it in RAM with text, and recall it with line messages. (You wouldn't need seq, in that case; you would just devise your own score-playing system, which is quite easy to do.) I'm not sure why saving to a file seems "stupid" to you, but if you need to avoid it for some reason, you can just hold the info in RAM.

BenCello's icon

Ow ! Sorry ! My mistake, I didn't want to be rude.

The possibility to keep the text in RAM and recall with the object text without going through seq is not really an option for what I'm trying to do. Because the idea is that, if we save the data as MIDI at end of a session, it may be read by any other software and used as is, as a note (& features) sequence.
It's really a save mechanism at the end of a process that I am looking for. And, as the data has meaning on its own (I mean independently from what I am doing with it) as a sequence of notes, I'm trying to save it as a usable format (independently form my system or even Max).

Does that make clearer why saving with text only is not convincing for me ?

As for saving a text file, then reloading it into seq that would work but there is a (maybe) unnecessary (that's what I called "stupid" even if it is not literally stupid) step.

In the meantime, I had a look to detonate and it seems that it can do what I would like: gathering all the event (super-fast at the end) and writing them into a proper MIDI file.
I still have a timing issue though, apparently the milliseconds times i feed in detonate are not interpreted correctly. It gives me a 5hours long MIDI file when the actual sequence last 10 minutes. But that's probably easy to debug.

Thank you for your answer, and again, sorry if I've been rough. I really didn't mean to, I just didn't see what your point was.

Christopher Dobrian's icon

For producing the score out of time and then saving as a standard MIDI file, detonate is indeed the best way to go, and it can save in either format 0 or format 1. You could save a format 0 MIDI file with text and seq by writing the text file, reading it back into seq, then writing that as MIDI, and it could all happen in a few milliseconds, but admittedly that would not meet your elegance criterion. :)

Your timing problem sounds like it might be due to the fact that detonate requires delta times from the preceding event, rather than start times calculated from the beginning of the sequence. If you're using the latter, then your note spacing will just get wider and wider, and could get awfully slow awfully quickly.

Max Patch
Copy patch and select New From Clipboard in Max.

Just for fun, here's an excerpted detonate example from the old school Max Tutorial.

BenCello's icon

Hi !

For producing the score out of time and then saving as a standard MIDI file, detonate is indeed the best way to go, and it can save in either format 0 or format 1. You could save a format 0 MIDI file with text and seq by writing the text file, reading it back into seq, then writing that as MIDI, and it could all happen in a few milliseconds, but admittedly that would not meet your elegance criterion. :)

Yes, exactly... I do like the "elegance criterion" :) That's pretty much the thing !

Your timing problem sounds like it might be due to the fact that detonate requires delta times from the preceding event, rather than start times calculated from the beginning of the sequence. If you're using the latter, then your note spacing will just get wider and wider, and could get awfully slow awfully quickly.

Sound that could be the problem indeed. My timing is from beginning... I'll correct that and let you know. Thx

Just for fun, here's an excerpted detonate example from the old school Max Tutorial.

Aw !! That's really old school !
Funny !

Thank's Christopher

BenCello's icon

Ok!
That works... Thank's to all of you !

Max Patch
Copy patch and select New From Clipboard in Max.

Here is the patch.
You'll miss the external of my custom data structure to make it work. But I thought that may still be helpful if somebody wants (one day) to do the same kind of thing.