The blog of a juvenile Geekus biologicus

How to interface TidalCycle with LMMS via MIDI ?

TidalCycle is a livecoding environment enabling live performance of code-generated music. LMMS is a digital audio workstation software. Both are free-libre opensource softwares. TidalCycle typically use SuperCollider to generate audio based on the patterns of Tidal. We can also use any device that can handle MIDI input to generate sound from Tidal patterns.

Procedure

On SuperCollider window, open startup file (File > Open startup file), then add the following code:

MIDIClient.init;

In the section where SuperDirt server starts, add the following before the ~dirt.start command:

~midiOut = MIDIOut.newByName("Midi Through", "Midi Through Port-0");
~dirt.soundLibrary.addMIDI(\mydevice, ~midiOut);
~midiOut.latency = 0;

My complete SuperCollider config as time of writing is:

Server.program = "pw-jack scsynth";
/*
This is an example startup file. You can load it from your startup file
(to be found in Platform.userAppSupportDir +/+ "startup.scd")
*/

MIDIClient.init;

(
s.reboot { // server options are only updated on reboot
    // configure the sound server: here you could add hardware specific options
    // see http://doc.sccode.org/Classes/ServerOptions.html
    s.options.numBuffers = 1024 * 256; // increase this if you need to load more samples
    s.options.memSize = 8192 * 32; // increase this if you get "alloc failed" messages
    s.options.numWireBufs = 64; // increase this if you get "exceeded number of interconnect buffers" messages
    s.options.maxNodes = 1024 * 32; // increase this if you are getting drop outs and the message "too many nodes"
    s.options.numOutputBusChannels = 2; // set this to your hardware output channel size, if necessary
    s.options.numInputBusChannels = 2; // set this to your hardware output channel size, if necessary
    // boot the server and start SuperDirt
    s.waitForBoot {
        ~dirt = SuperDirt(2, s); // two output channels, increase if you want to pan across more channels
        ~dirt.loadSoundFiles;   // load samples (path containing a wildcard can be passed in)
        // for example: ~dirt.loadSoundFiles("/Users/myUserName/Dirt/samples/*");
        // s.sync; // optionally: wait for samples to be
		// Setup a single MIDI synth, because we'll setup different instruments by channels
		~midiOut = MIDIOut.newByName("Midi Through", "Midi Through Port-0");
		~dirt.soundLibrary.addMIDI(\mydevice, ~midiOut);
		~midiOut.latency = 0;
        ~dirt.start(57120, 0 ! 12);   // start listening on port 57120, create two busses each sending audio to channel 0

        // optional, needed for convenient access from sclang:
        (
            ~d1 = ~dirt.orbits[0]; ~d2 = ~dirt.orbits[1]; ~d3 = ~dirt.orbits[2];
            ~d4 = ~dirt.orbits[3]; ~d5 = ~dirt.orbits[4]; ~d6 = ~dirt.orbits[5];
            ~d7 = ~dirt.orbits[6]; ~d8 = ~dirt.orbits[7]; ~d9 = ~dirt.orbits[8];
            ~d10 = ~dirt.orbits[9]; ~d11 = ~dirt.orbits[10]; ~d12 = ~dirt.orbits[11];
        );
    };

    s.latency = 0.3; // increase this if you get "late" messages
};
);

Then, launch Tidal in your favorite IDE/text-editor, and to send Tidal patterns to the MIDI device, use sound "mydevice" command: For example:

d1
  $ slow 2
  $ n "<c4 g4 h4 h6>" # sound "mydevice" # midichan 1

The Tidal instruction midichan 1 enables to select the channel of the MIDI device.

To use this MIDI channel in your LMMS window, add an instrument in the song editor and select the proper MIDI input channel for the track (in my case, on Linux, it is Midi Through:Midi through Port-0). You can specify a specific channel for each instrument, hence have multiple instruments playing at the same time. To change the MIDI channel of an instrument on LMMS, open the general settings window of the instrument, by clicking on the name of the track, and in the MIDI config tab (with piano clavier icon), you can update the channel number.

Sources