Midi Splitter

I have been playing with various DAWs for years now, both Windows and Linux, but have roughly settled on Ardour and QTractor at the moment. As I am remixing all my old tunes, I am presented with a midi file all in one track (old Yamaha QX7 if you know what that is!).

This causes problems as you cannot split out the tracks easily. So after looking and looking I thought to myself, write one.

So I am teaching myself Lua for the Ardour system. So far, my script iterates over selected regions and creates a list of midi channels used in them all.

It them throws up a dialogue and asks 0 for all, or type in the channel to extract. A the same time it asks if you want to split a drum track (to eight new tracks is the thought) or extract just one note from the regions.

  1. if channel = 0 - split every channel into a new track called ‘midi channel 1’ etc.
  2. if channel != 0 - only create the one 1-16 specified channel.
  3. if bool drums = create eight tracks of standard drums and extract regions into those tracks.
  4. if note specified, only extract that one note to the new track (essentially (3) is 8 of these).

One big region for each track is the idea.

Now the logic is there - the analysis happens and everything is printing happily to the screen.

But how the hell do I create a new_midi_track please - I appear to be missing the vital ingredient?? Can someone please point me to some information on this? I have been through the class and Ardour help on Lua but am still puzzled (ASM/C# background)

Thanks all, and especially Paul.

It might help to look at the declaration and implementation of that method (new_midi_track) in the C++ source. Here it is on GitHub: https://github.com/Ardour/ardour/blob/master/libs/ardour/session.cc#L2517

Maybe that gets you going in the right direction until someone with more knowledge about the internals comes along.

Best of luck, sounds like a very useful script.

Many thanks adotm, been there tried that.

I must say that Ardour plain crashes when I try using the method - and have tried about 30 permutations now so have something very wrong I think. Almost certain I have done everything correctly so it must be one of those “you must have exactly these settings”.

Also, how are you meant to get answers on the IRC channel - I posted a question there but am not online always, so how do I know if it was answered? Do I ask again hoping someone has the answer from previously?

Many thanks to all who help.


Best option is to leave the IRC window open in the background, often times people with the answer may not be looking at IRC when you ask, but might later and respond later, which you can then see when you look at the window again. Many IRC clients also support some form of notification to the OS to draw your attention when your name is mentioned, which is standard practice for responding to someone in IRC to help draw your attention to it quicker so you might be able to respond while they are around.


Creating a new MIDI track via Lua needs a monster line because Lua is not a typed language while Ardour’s C++ API expects objects as parameters (ChanCount for Input+output).

To create one MIDI track with 1 MIDI input, 2 audio outputs, no synth plugin and call it “MIDI Track Name”:

Session:new_midi_track (ARDOUR.ChanCount(ARDOUR.DataType ("midi"), 1),  ARDOUR.ChanCount(ARDOUR.DataType ("audio"), 2), true, ARDOUR.PluginInfo(), nil, nil, 1, "MIDI Track Name", ARDOUR.PresentationInfo.max_order, ARDOUR.TrackMode.Normal)

This returns a TrackList that which you can iterate over (it’s a list because you can create many tracks with one call), compare to the C++ API:

  std::list<boost::shared_ptr<MidiTrack> > new_midi_track (
    const ChanCount& input, const ChanCount& output, bool strict_io,
    boost::shared_ptr instrument,
    Plugin::PresetRecord* pset,
    RouteGroup* route_group, uint32_t how_many, std::string name_template,
    TrackMode mode = Normal


Many many thanks x42. For some daft reason I didn’t have the how_many variable!!

It all works when I add that one field in. Computers don’t like not being told some information :slight_smile:

Now hopefully to finish off in the next few weeks.

Again thanks.

Was this ever finished? I could really use a splitting function. I’m trying to figure out a decent workflow for my drum machine with Ardour, and being able to split the recorded MIDI would help a lot.

1 Like

Hey - I got past a huge amount of problems - but I kept getting stuck in trying to create objects.

Basically no is the answer - I couldnt create tracks, then channels, then what ever else I got stuck with. The actual pseudo code is written - I just couldn’t write it anywhere. Will maybe take a look again.

To solve it badly, just record a new midi channel for each channel you have and run through the file, increase the BPM makes it quicker!


1 Like

Maybe this script will help you: https://wiki.linuxaudio.org/apps/all/midi_splitter

If you have a MIDI file, Ardour can split MIDI channels onto separate tracks on Import. Since Ardour does directly use .mid you can simply re-import existing files and split them to separate tracks, then remove the original track. I guess that is just not very convenient, compared to @mickeyb’s Lua script doing this automatically.

Ok - sorry to bring this up again, but I needed something to do this again. So this time I have accomplished it, and attach the LUA script for you all. But please note that it isn’t exactly what I was after, but it does the job. So, there is no way I can find to create a midi region. Tracks yes (and that is in the code just waiting to be used :slight_smile: ).

So the ‘hack’. You copy the region manually. Then run this script against the new region(s). The script removes the offending notes. So, you have a track with 3 midi channels. Copy paste it so you have three copies. Run the script on the first region, removing the channels you don’t want.

You can also remove all notes above or below a point you specify.

Finally, you can isolate a base drum for example. On the region, keep midi port 10 (for example) and keep only the note you require (which it tries to suggest) - see example below.


In the above example (and clip in the background) the window opens and tells you all midi channels it found, and all notes it found. If you just hit run now NOTHING happens as all notes are selected and all channels are included. If you want to remove channel 10, just remove the number from the midi port and click run.

Or if you want only the lowest note, then leave the midi alone (or not - your choice) and remove all the other numbers in the note list. If you want to remove everything above note 40, put 40 into the middle box and uncheck the box. Simplez.

The moment Paul et al tells me I can create a midi region (Or copy paste an existing one into a new track) I will finish this off properly.

But for now, and sorry for the delay…here it isn’t. (How do I upload a LUA script please??)


Ok - I hosted the file on GitHub.

Here it is - don’t laugh at the coding - it works!

Lua Script on Github