我正在尝试使用GUI构建一个appilcation来使用PortAudio库录制一些音频,因此我使用的是Qt(c ++)。要做到这一点,我必须包装PortAudio库以使其具有面向对象的样式,并且我遇到了一些使用audiocallback的问题。
初步解释:
PortAudio使用这样的回调函数:
static int recCallback(const void *inputBuffer,
void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData)
然后,在PortAudio函数Pa_OpenStream中调用此回调:
Pa_OpenStream(
&stream,
&inputParameters,
NULL,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff,
recordCallback,
&data );
*回调函数中的userData与Pa_OpenStream中的&数据是相同的指针,Pa_OpenStream是一个存储audiobuffer的数组,因此可以将音频写入文件。这可以在recCallback中完成:
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
当使回调函数成为类的成员(例如WrapperClass)时会出现问题。我从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);
}
因此,静态回调将de * userdata参数作为另一个回调的对象。 现在,在Pa_OpenStream中调用回调函数,如下所示:
Pa_OpenStream(&stream,
&inputStreamParam,
&outputStreamParam,
sampleRate,
frameLength,
paNoFlag,
&WrapperClass::paStaticCallback,
this);
我认为以这种方式我将staticCallback发送给WrapperClass对象,然后调用虚拟回调。
我不明白的是,现在我错过了用于将音频存储在非静态回调中的参数* userData,我无法弄清楚如何在“有效”回调函数中设置指向数组的指针(非静态的)
谢谢你,希望已经足够清楚了
答案 0 :(得分:1)
PortAudio发行版在bindings/cpp
目录中包含一个C ++包装器。
你没有拥有来包装PortAudio以赋予它OO风格。 PortAudio C API在C ++中运行良好。
回答你的问题:我希望你的代码的客户端能够继承WrapperClass,覆盖processingCallback函数,并将他们的数据(例如数组)作为成员变量。