Reputation: 199
I'm trying to build an appilcation with GUI to record some audio using PortAudio library, therefore I'm using Qt (c++). To do thath, I have to wrap the PortAudio library to give it an object oriented style and I'm encountering some problemas with the audiocallback.
Preliminary explanation:
PortAudio uses a callback function like this:
static int recCallback(const void *inputBuffer,
void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData)
Then, this callback is called in the PortAudio function Pa_OpenStream:
Pa_OpenStream(
&stream,
&inputParameters,
NULL,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff,
recordCallback,
&data );
*userData in the callback function is the same pointer as &data in Pa_OpenStream, which is an array to store the audiobuffer so the audio can be writeen to a file. This can be done in the recCallback as:
static int recordCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
//POINTER TO DATA DESTINATION
paTestData *data = (paTestData*)userData;
//POINTER TO INPUT BUFFER
SAMPLE *rptr = (SAMPLE*)inputBuffer;
... //MANIPUALTE AUDIO HERE
The problem arises when making the callback function a member of a class, for instance WrapperClass. I took a template for the wrapping from here.
class WrapperClass
{
virtual int processingCallback(const void *inputBuffer,
void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags);
//portaudio need a static member function as callback,
//this calls the non-static processing callback
method bypassing the object via userData
static int paStaticCallback(const void *inputBuffer,
void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData)
{return((WrapperClass*)userData)->processingCallback(inputBuffer, outputBuffer, framesPerBuffer, timeInfo, statusFlags,data);
}
So, the static callback takes de *userdata argument as an object for the other callback. Now, the callback function is called in Pa_OpenStream as follows:
Pa_OpenStream(&stream,
&inputStreamParam,
&outputStreamParam,
sampleRate,
frameLength,
paNoFlag,
&WrapperClass::paStaticCallback,
this);
I think that in that way I'm sending the staticCallback a WrapperClass object, and then calling the virtual callback.
What I dont understand is that now I missed the argument *userData for storing the audio in the non-static callback, I can't figure out how to manage to have the pointer to the array in the "efective" callback function (the non-static one)
Thank you, hope have beeing clear enough
Upvotes: 0
Views: 708
Reputation: 4173
The PortAudio distribution includes a C++ wraper in the bindings/cpp
directory.
You don't have to wrap PortAudio to give it an OO style. The PortAudio C API works perfectly well in C++.
To answer your question: I would expect that the client of your code would subclass WrapperClass, override the processingCallback function, and have their data (e.g. array) as a member variable.
Upvotes: 1