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
and 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
and 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:
-
Don’t use Csound opcodes that require multiple channels like
ins
andouts
. There might not be multiple channels available. Use opcodes likeinch
andoutch
instead. -
Always check the
nchnls_i
andnchnls
variables before usinginch
andoutch
to make sure the channel you want to read or write actually exists. Thenchnls_i
andnchnls
variables are changed by Cabbage internally and their values are updated at i-time, which means they will be set correctly when used ininstr
definitions. If only one output channel is available, thennchnls
will return 1 in your instrument. Do not write to output channel 2 ifnchnls
== 1.
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>