How can I implement a Csound plugin opcode with array of audio signals (using Csound Plugin Opcode Framework (CPOF))?
I’ve tried this and it’s not working
// Declaration of input and output variables
static constexpr char const *otypes = "a[]";
static constexpr char const *itypes = "a[]";
// Plugin declaration
csnd::plugin<MyPlug>(csound, "myplug", "a[]", "a[]", csnd::thread::a);
// only working on a-rate
int aperf() {
csnd::Vector<csnd::AudioSig> &in = inargs.vector_data<csnd::AudioSig>(0);
csnd::Vector<csnd::AudioSig> &out = outargs.vector_data<csnd::AudioSig>(0);
// simply copy input to output -> doesn’t work
for (int ch_index = 0; ch_index < csound->nchnls_i(); ch_index++)
for (int sample_index = 0; sample_index < in[ch_index].GetNsmps(); sample_index++)
out[ch_index][sample_index] = in[ch_index][sample_index];
return OK;
}
When I’m doing this I get access violation error. I think that this isn’t the right way to do this because i.e. in[0] doesn’t point me to audio signal from mic 1.
Hi @Lovre. You need to iterate over the input arguments, and you also need to initialise the size of the output array as it is not known. I would do something like this (keep in mind I’ve never used audio variables with this framework!):
csnd::Vector<csnd::AudioSig> &in = inargs.vector_data<csnd::AudioSig>(0);
csnd::Vector<csnd::AudioSig> &out = outargs.vector_data<csnd::AudioSig>(0);
//set the size of the output array
out.init(csound, (int)in.len());
//iterate over input signals
for ( int i = 0 ; i < in.len() ; i++)
{
//do you assignment here, I'm not sure, but maybe you can do:
out[i] = in[i];
//if that doesn't work you probably need to assign the size and data member individually:
//out[i].size = in[i].size;
//out[i].data = in[i].data;
}
It’s rare that would ever query nchnls in a plugin opcode. Opcodes are nchnls agnostic for the most part. Assuming that the input and output arrays somehow match nchnls could lead to all sorts of access violations.
Ok, let me take a look and see if I can find the solution before annoying Victor about it
So you will access the microphone channels using one of the in-family of opcodes, and then do some further processing? Or are you looking to access the raw mic data, directly from the audio drivers? If it’s the latter than I am not sure you will be able to do it with this framework…
“So you will access the microphone channels using one of the in-family of opcodes, and then do some further processing?” → yes.
I know that csound isn’t typical choice for this kind of stuff but I’m working on one application implemented (at least for now) in python and then, for real-time audio, python binding for csound is pretty cool and powerful.
When I run the code above I get audio but it’s noisy. I’ve checked nsmps and it seems to report the wrong size, I guess this might be what’s causing the noise. Anyhow, I reached out to Victor to see what’s the most CPOF esque way of doing this.
Just for the sake of better overview here is the interesting code snippet from the file above (part of the SimpleArrayA strucut)
int aperf() {
csnd::Vector<MYFLT> &out = outargs.vector_data<MYFLT>(0);
csnd::Vector<MYFLT> &in = inargs.vector_data<MYFLT>(0);
// copy each a-var ksmps vector in turn
// NB: copying the whole memory block
// from in.begin() to in.end() also works
for (int i = 0; i < in.len(); i++)
std::copy(in.begin() + i * in.elem_offset(),
in.begin() + (i + 1) * in.elem_offset(),
out.begin() + i * in.elem_offset());
return OK;
}