Multichannel routing to Ableton via Soundflower

Hello! I am trying (in vain) to send separate voices / tracks (d1, d2, etc…) to different output channels through Soundflower (as virtual audio interface) to Ableton to record individual tracks. I have tried a myriad of alterations in the startupcode to make this work… I keep getting this message:

WARNING: SuperDirt: event falls out of existining orbits, index (2)

Please help I’ve been trying for days… bahhhh.

Hi @oobobbypinoo,

It takes a while to click as there’s a couple of things to change to configure this.

Starting from the example: https://github.com/musikinformatik/SuperDirt/blob/develop/superdirt_startup.scd

Lets assume you want eight outputs, each one stereo (two channels each).

That’s 16 channels total, so s.options.numOutputBusChannels needs to be 16.

Each output is stereo, so leave this line as-is ~dirt = SuperDirt(2, s);. You might be tempted to change it, but this is configuring the number of channels per output, not the total number or channels or the number of outputs.

The final line to change is this one:

~dirt.start(57120, [0, 0]);

The default [0, 0] means two ‘orbits’, both sending to channels with no offset. I.e. both orbits go to the first two channels. You probably want eight orbits, each one offset so that they go to different pairs of channels. I.e.:

~dirt.start(57120, [0, 2, 4, 6, 8, 10, 12, 14]);

That’s it! You can test in tidal with e.g.:

d1 $ slow 4 $ orbit "0 1 2 3 4 5 6 7" # n "0 1 2 3 4 5 6 7" # sound "alphabet"

The full superdirt startup code for eight stereo outputs is shown below.

 (
// 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 * 16; // increase this if you get "alloc failed" messages
s.options.maxNodes = 1024 * 32; // increase this if you are getting drop outs and the message "too many nodes"
s.options.numOutputBusChannels = 16; // 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 read

~dirt.start(57120, [0, 2, 4, 6, 8, 10, 12, 14]); // start listening on port 57120, create two busses each sending audio to channel 0

// optional, needed for the sclang tests only:

(

~d1 = ~dirt.orbits[0]; // one orbit

~d2 = ~dirt.orbits[1];

);

};

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

);
2 Likes

One thing I like to do on the Tidal side is redefine d1 … d8 so they automatically go to a different orbit. You can do that by running the following:

let d1 = p 1 . (|< orbit 0) 
    d2 = p 2 . (|< orbit 1) 
    d3 = p 3 . (|< orbit 2) 
    d4 = p 4 . (|< orbit 3) 
    d5 = p 5 . (|< orbit 4) 
    d6 = p 6 . (|< orbit 5) 
    d7 = p 7 . (|< orbit 6) 
    d8 = p 8 . (|< orbit 7) 

You can put that in your BootTidal.hs startup like this:

:{
let d1 = p 1 . (|< orbit 0) 
    d2 = p 2 . (|< orbit 1) 
    d3 = p 3 . (|< orbit 2) 
    d4 = p 4 . (|< orbit 3) 
    d5 = p 5 . (|< orbit 4) 
    d6 = p 6 . (|< orbit 5) 
    d7 = p 7 . (|< orbit 6) 
    d8 = p 8 . (|< orbit 7) 
:}
2 Likes

Thanks for your quick reply! Unfortunately I’m still geting the same warning message in supercollider… Something else must be wrong…

Make sure you run this instead of any other method for starting superdirt. restarting supercollider first is a good idea too

oh so instead of doing SuperDirt.start I just run :

(
// 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 * 16; // increase this if you get “alloc failed” messages
s.options.maxNodes = 1024 * 32; // increase this if you are getting drop outs and the message “too many nodes”
s.options.numOutputBusChannels = 16; // 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 read

~dirt.start(57120, [0, 2, 4, 6, 8, 10, 12, 14]); // start listening on port 57120, create two busses each sending audio to channel 0

// optional, needed for the sclang tests only:

(

~d1 = ~dirt.orbits[0]; // one orbit

~d2 = ~dirt.orbits[1];

);

};

s.latency = 0.3; // increase this if you get “late” messages

);
… in Supercollider? ok

Sweet! Thanks it worked! :smiley::star_struck:

Can it be configured so some outputs are stereo and some are mono (one channel)?

Where are you supposed to place the startup configuration for Tidal?

I tried placing it:
/home/awright/.vim/plugged/vim-tidal/BootTidal.hs

/Users/yourUser/Library/Application Support/SuperCollider/startup.scd

Hi. I am trying the same, only on Windows 10 with Bitwig. I tried it with Jack and Loopbeaudio, but cant get it to work.
Wish i was on mac, Soundflower (now Loopback) seems so easy. (I used to be on mac, but switched with my newly built desktop)
I understood Supercollider can be a pain with Jack. Anyone tried Loopbeaudio?
Thanks. :slight_smile:

Edit. O jeez, found more: Synchronous Audio Router and Breakawayone. Will try those too

Since this method for routing orbits separately doesn’t seem to work smoothly for everyone according to their OS and other stuff, I think it should be best to find a way of recording all orbits inside SC itself, so that we don’t need to rely on soundflower or other routing systems. We were talking about this with @torotumbo and @ritchse, there is already some code for doing this, even if I couldn’t be able to make it work on my machine. I will open a discussion on the SuperCollider section since I think this could be useful for everyone.

I think that the aproach that @leandroyako made is interesting cause you got the SC channels recorded and then you can put them in any daw. Although you might think about directly recording supercollider channels (tidal orbits, audio in the soundcard -like hardware synths- or in -like pbindef or stuff inside supercollider-) directly to your daw (ableton, protools, reaper, whatever).

Here is a video tutorial for Mac + Soundflower combination solution with Reaper used as a DAW

2 Likes

Hello everyone. Routing in Windows is problematic so I decided to record as separet channels in Supercollider. I’ve changed the startup file for 6 stereo audio output, 12 in total; but when I play in tidalcycles after first three channels (after d3 or orbit 2), I am not getting any sound. Is there anyone who also facing this issue? Thank you in advance.

If you share your superdirt startup, I can have a look

Sure, thank you.

(
s.options.numBuffers = 1024 * 6;
s.options.memSize = 8192 * 16;
s.options.maxNodes = 1024 * 64;

s.options.numOutputBusChannels = 12;

s.waitForBoot{

~dirt = SuperDirt(2,s);
~dirt.loadSoundFiles;
// wait until load is done
s.sync;

//configure your bus routes
~dirt.start(57120, [0,2,4,6,8,10]);
s.meter;
s.latency = 0.0;
}
)

Actually I figured it out with s.meter that Supercollider gets the multichannel audio as it is defined. But the most channel default audio device gives to Supercollider is 6 (so 3 stereo). I’ve changed the audio device the most I could have was 8 channels. I think Windows has some kind of limitations…

This doesn’t have to do with output channels, but one suggestion here: setting latency to 0 means that every message to scsynth will be late.

The consequence is that scsynth can evaluate the message only at the next hardware buffer boundary. This may be acceptable if you’re using a small audio buffer size (128 or 256) but if you’re hitting performance problems and need to raise the buffer size, then you lose timing resolution of musical events.

The best for musical timing is to set latency to hardware buffer latency + a small amount to account for network transmission – if the hardware buffer is 256 samples, 256/44100 = 0.0058, plus 10-20 ms for network, so s.latency = 0.02 or so.

If you really want “as soon as possible,” s.latency = nil may be better (but events’ timing relative to each other will suffer).

hjh

I’ve not noticed that s.latency has any effect. My guess is that because tidal sends trigger messages to sclang ahead of time according to its (tidal’s) own latency setting, sclang passes this onwards to superdirt ahead of time regardless of what s.latency says.