Init Midi with startup file [solved]

Hi,

I was under the impression that I could initialize midi from within my tidal startup file

My current startup file
(
    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)
            // load additional sample libraries
            // ~dirt.loadSoundFiles("~/projects/???/*");
            ~dirt.loadSoundFiles("~/projects/tidal/audio/samples/*");
            // s.sync; // optionally: wait for samples to be read
            ~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];
                );
        };

        // https://club.tidalcycles.org/t/way-to-limit-maximum-output-volume/2383
        Safety.all;
        Safety.setLimit(0.8);
        s.latency = 0.3; // increase this if you get "late" messages
    };
    );

I am running this file via command line ...

sclang ~/bin/superdirt/superdirt_startup.scd

... and tried to add these adapted lines from the userbase tutorial:

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

But I always get the following error:

ERROR: Message 'soundLibrary' not understood.

However, if I open Supercollider, paste and run my startup file and then run ...

MIDIClient.init; // 1
~midiOut = MIDIOut.newByName("Midi Through", "Midi Through Port-0"); // 2
~dirt.soundLibrary.addMIDI(\midi, ~midiOut); // 3

... line by line it will work.

So I guess it something to do with the order or rather point of execution.

Any tips whether and how I can incorporate the midi initialization into my startup file (without having to open Suercollider explicitely) would be very appreciated.

Here's mine :

SuperDirt.start;

s.waitForBoot {

	MIDIClient.init;
	~midiOut = MIDIOut.newByName("Tidal", "Tidal");
	~dirt.soundLibrary.addMIDI(\midi, ~midiOut);

};


	MIDIClient.init;
1 Like

Nice! Thanks a lot. I was not aware of the s.waitForBoot which did the trick.

1 Like

Glad I can help :slight_smile: I have to give credit to a fellow Tidal Cyclist on Toplap for sharing the solution a while ago though.

1 Like

Well, you could subsume this as a small example of: We all stand on the shoulders of giants, don't we?

Here's my .scd file, so I can run SuperCollider without the IDE on my Mac (works on M1 and macOS Ventura, installing TidalCycles, SuperCollider, etc with the bootstrap method on the official install documentation). I just run sclang startup.scd from the terminal. This is very similar to @nilhartman's approach.

On macOS I added 5 midi buses (80 MIDI channels) to the IAC Driver (Using Audio Midi Setup -> Window -> Show MIDI studio -> IAC Driver -> click "Device is online" -> + Add ports).

My startup.scd:

s.options.sampleRate = 44100;

s.waitForBoot {
    ~dirt = SuperDirt(2,s);
    ~dirt.start(57120, [0,0]);

    MIDIClient.init;

    ~midiOutA = MIDIOut.newByName("IAC Driver", "Bus 1");
    ~dirt.soundLibrary.addMIDI(\midi, ~midiOutA);

    ~midiOutB = MIDIOut.newByName("IAC Driver", "Bus 2");
    ~dirt.soundLibrary.addMIDI(\midi2, ~midiOutB);

    ~midiOutC = MIDIOut.newByName("IAC Driver", "Bus 3");
    ~dirt.soundLibrary.addMIDI(\midi3, ~midiOutC);

    ~midiOutD = MIDIOut.newByName("IAC Driver", "Bus 4");
    ~dirt.soundLibrary.addMIDI(\midi4, ~midiOutD);

    ~midiOutE = MIDIOut.newByName("IAC Driver", "Bus 5");
    ~dirt.soundLibrary.addMIDI(\midi5, ~midiOutE);
};

s.waitForBoot {} is necessary to make the ~dirt.soundLibrary part wait until SuperDirt finishes booting. s.options.sampleRate = 44100 is so i don't get errors about a mismatched 48000 Hz sample rate (an error i get sometimes when connected to HDMI or headphones)

Then, to send MIDI on bus 4 channel 12 ( 13 - 1) in TidalCycles:

d1 $ n "0 14 7 14" # s "midi4" # midichan "13"

:large_orange_diamond:

1 Like