I have a function audioReceived (float * input, int bufferSize, int nChannels) inside of which I want to call a function from a library that needs const float *const *inputBuffers.
Obviously casting const float *const *inputBuffers = (const float* const*)input; compiles but is a terrible idea, crashes the program, kills kittens, etc. Nobody ever needs to modify the original float* input, it’s incoming audio data that’s being processed.
How do I do it the right way?
EDIT: Here’s some more code. audioReceived is:
void testApp::audioReceived (float * input, int bufferSize, int nChannels){
Vamp::RealTime rt = Vamp::RealTime::fromMilliseconds(ofGetSystemTime());
float const *const tmp[] = { input, 0 };
Vamp::Plugin::FeatureSet fs = myPlugin->process(tmp, rt);
}
Library function process is virtually defined in base class:
/**
* Process a single block of input data.
*
* If the plugin's inputDomain is TimeDomain, inputBuffers will
* point to one array of floats per input channel, and each of
* these arrays will contain blockSize consecutive audio samples
* (the host will zero-pad as necessary). The timestamp in this
* case will be the real time in seconds of the start of the
* supplied block of samples.
*
* If the plugin's inputDomain is FrequencyDomain, inputBuffers
* will point to one array of floats per input channel, and each
* of these arrays will contain blockSize/2+1 consecutive pairs of
* real and imaginary component floats corresponding to bins
* 0..(blockSize/2) of the FFT output. That is, bin 0 (the first
* pair of floats) contains the DC output, up to bin blockSize/2
* which contains the Nyquist-frequency output. There will
* therefore be blockSize+2 floats per channel in total. The
* timestamp will be the real time in seconds of the centre of the
* FFT input window (i.e. the very first block passed to process
* might contain the FFT of half a block of zero samples and the
* first half-block of the actual data, with a timestamp of zero).
*
* Return any features that have become available after this
* process call. (These do not necessarily have to fall within
* the process block, except for OneSamplePerStep outputs.)
*/
virtual FeatureSet process(const float *const *inputBuffers,
RealTime timestamp) = 0;
and here in the actual header:
FeatureSet process(const float *const *inputBuffers, Vamp::RealTime timestamp);
I think the EXC_BAD_ACCESS may be stemming from the library function wanting a zero-padded array, and my not giving it one. (a) Does that sound reasonable, and (b) If so, is it time to ask a different SO question?
Thanks all for your help so far, it’s very enlightening/clarifying/educational/interesting.
Semantics is important here. From the parameter names, I can guess that the function you want to call accepts multiple buffers, so it wants an array of pointers to float (i.e. an array of arrays). Since you only have an array, you need to create an array that contains the original pointer, and pass that to the function.
If the function has a separate argument for the length of the array it is being passed (i.e. the number of buffers), then taking the address using the unary
&operator and passing a length of 1 should be enough, otherwise you need to create a temporary null terminated array:and pass that to the function.