C PortAudio回调,并在别处更改变量
我正在使用PortAudio的回调API设计一个信号处理环回库 我想添加一个分支,它依赖于回调中的标志,如下所示C PortAudio回调,并在别处更改变量,c,thread-safety,portaudio,C,Thread Safety,Portaudio,我正在使用PortAudio的回调API设计一个信号处理环回库 我想添加一个分支,它依赖于回调中的标志,如下所示 int pa_callback(const void *inputuffer, void *outputBuffer, unsigned long frameCount, const PaStreamCallbackTimeInfo *timeInfo,
int pa_callback(const void *inputuffer,
void *outputBuffer,
unsigned long frameCount,
const PaStreamCallbackTimeInfo *timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData)
{
if (do_something_flag) {
do_something(inputBuffer, outputBuffer, frameCount);
} else {
do_something_else(inputBuffer, outputBuffer, frameCount);
}
return paContinue;
}
其中,do\u something\u标志
在我的程序中的其他地方定期设置
PortAudio回调文档说明:
在开始之前,重要的是要认识到回调是一个
微妙的地方。这是因为某些系统在
特殊的线程,或中断处理程序,它很少被
与代码的其余部分相同。对于大多数现代系统,您不会
能够通过在回调中进行不允许的调用而导致崩溃,但是
如果你想让你的代码产生无故障的音频,你必须
请确保避免可能占用无限量的函数调用
有足够的时间来执行。具体是什么取决于您的平台,但
几乎可以肯定包括以下内容:内存
分配/解除分配、I/O(包括文件I/O和控制台
I/O,如printf()),上下文切换(如exec()或yield()),
互斥操作,或任何其他可能依赖操作系统的操作。如果你
认为短的关键部分是安全的,请阅读有关优先级的内容
倒置
我不关心do\u something\u标志的原子性。也就是说,我不在乎需要多少个周期才能得到正确的值(在合理范围内)。
根据文档,看起来我无法使用互斥体来设置/读取该变量
1) 我有什么选择
2) 如果我将其设置为全局,并将其设置在程序的另一部分(另一个线程),那么最糟糕的情况是什么?同样,我指的是破坏数据,导致程序失败等
有没有一种正确的方法可以做到这一点?我不完全确定您到底想做什么,但我猜这就是您的标题所要求的——“在其他地方更改变量”
让我们举个例子:您有一个随时间变化的变量频率。你如何访问这个?在回调中有一个名为userData
的通用指针。这可以指向任何东西——数据结构、数组等等。我真的不记得回调函数被调用的频率(通常……我不担心速度)但是userData
允许您在主线程中更改变量,而音频线程中的指针允许您直接在内存中访问它。。。我在线程安全方面的知识不是最好的,如果这不是最好的解释,那么很抱歉,但我至少可以通过代码(如下)向您展示如何做到这一点
这是我通常做的,但你不需要自己做;我在文件顶部设置了一个结构,如下所示:
typedef struct {
float freq;
float vol;
}paData;
显然,您将在代码中的某个地方初始化它(可能在main
函数调用中),并打开音频流(data
类型为paData
):
打开后,您可以按如下方式进行回调:
static int pa_callback(const void *inputBffer,
void *outputBuffer,
unsigned long frameCount,
const PaStreamCallbackTimeInfo *timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData)
{
// cast data so we can use it
paData *data = (paData *)userData;
// what's our frequency?
printf("%f\n", data->freq);
/* Do something with your code here */
return paContinue;
}
希望能有帮助。是的,太好了。我非常关心线程安全性、原子性和全局变量,我没有看到简单的答案:PA给了你这个机制。你不用担心,你自己学习一个新的API很难。。。幸运的是,当我学习PortAudio时,我有一位很棒的老师,所以这让事情变得容易多了。祝你好运!您好@yun.cloud,我最近开始使用portaudio进行语音采集和处理,在实现过程中遇到了一些问题。我已经在stackoverflow上发布了这个问题()。非常感谢您的任何帮助。
static int pa_callback(const void *inputBffer,
void *outputBuffer,
unsigned long frameCount,
const PaStreamCallbackTimeInfo *timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData)
{
// cast data so we can use it
paData *data = (paData *)userData;
// what's our frequency?
printf("%f\n", data->freq);
/* Do something with your code here */
return paContinue;
}