Hey all, just a heads up to be careful when reading and writing audio in your .csd files if you’re going to be making AudioUnit plugins. When apps like Logic Pro find new AudioUnits, they test them several times with different audio channel configurations. When this happens, Cabbage sets the
nchnls_i settings in your .csd file internally to match the audio channel configuration of each test. Do not assume the number of audio channels available matches what you set the
nchnls_i variables to in the global section of your .csd file.
Reading and writing to more channels than are available may cause problems in your .csd that will make the AU plugin fail to validate, and the scan being done by Logic Pro may hang forever requiring the user to press the “Abort” button or use the “Force Quit” option. This will make your plugin unavailable for use in these DAWs.
Here are some tips to avoid this in your .csd files:
Always check the
nchnlsvariables before using
outchto make sure the channel you want to read or write actually exists. The
nchnlsvariables are changed by Cabbage internally and their values are updated at i-time, which means they will be set correctly when used in
instrdefinitions. If only one output channel is available, then
nchnlswill return 1 in your instrument. Do not write to output channel 2 if
Here is an example pass-through effect .csd that shows how to avoid reading and writing to more channels than the host DAW provides:
<Cabbage> form caption("Untitled") size(400, 300), colour(58, 110, 182), pluginid("def1") </Cabbage> <CsoundSynthesizer> <CsOptions> --midi-device=0 --nodisplays --nosound -+rtmidi=null </CsOptions> <CsInstruments> // sr is set by host DAW // nchnls_i might be changed to match host DAW input channel count. nchnls_i = 2 // nchnls might be changed to match host DAW output channel count. nchnls = 2 ksmps = 64 0dbfs = 1 // Pass through instrument. // // Safely passes audio from input to output using the `inch` and `outch` // opcodes to avoid writing to Csound channels that don't exist. // // Note that the `nchnls_i` and `nchnls` variables might not be the same // as what they were set to in the global section above. // instr 1 // Create an array of signals. One for each output channel. a_signal init nchnls // For each output channel that has a matching input channel, read // the host DAW input channel into the signal array. // // Note that the `k_chnl` variable used in the `inch` opcode is // always less than `nchnls_i`. // k_chnl = 0 while (k_chnl < nchnls && k_chnl < nchnls_i) do a_signal[k_chnl] = inch(k_chnl + 1) k_chnl += 1 od // Output the signals to the host DAW. k_chnl = 0 while (k_chnl < nchnls) do outch(k_chnl + 1, a_signal[k_chnl]) k_chnl += 1 od endin </CsInstruments> <CsScore> i1 0 z </CsScore> </CsoundSynthesizer>