c - 端口音频回调,并在其他地方更改变量



我正在使用PortAudio的回调API来设计信号处理环回库。

我想添加一个依赖于回调中标志的分支,所以像

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_something_flag在我的程序中的其他地方定期设置

端口音频回调文档指出:

在我们开始之前,重要的是要意识到回调是一个 精致的地方。这是因为某些系统在 特殊线程或中断处理程序,很少处理 与代码的其余部分相同。对于大多数现代系统,您不会 能够通过在回调中进行不允许的调用来导致崩溃,但是 如果您希望代码产生无故障音频,则必须 确保避免可能需要无限量的函数调用 执行时间。具体是什么取决于您的平台,但是 几乎可以肯定包括以下内容:内存 分配/解除分配、I/O(包括文件 I/O 以及控制台) I/O,如 printf()),上下文切换(如 exec() 或 yield()), 互斥操作,或任何其他可能依赖于操作系统的操作。如果你 认为简短的关键部分是安全的,请阅读优先级 倒置。

我不在乎do_something_flag的原子性. 也就是说,我不在乎需要多少个周期才能获得正确的值(在合理范围内)。根据文档,看起来我不能使用互斥体来设置/读取该变量。

1) 我有哪些选择?

2)如果我将其全局化并将其设置为程序的另一部分(另一个线程),那么绝对最糟糕的情况是什么? 同样,我的意思是将数据损坏到程序失败/等地步。

有没有正确的方法可以做到这一点?

我不完全确定你到底想做什么,但我猜这就是你的标题所要求的 - "在其他地方更改变量"。

让我们举个例子:你有一个随时间变化的变量frequency。你如何访问这个?好吧,您在回调中有一个名为 userData 的通用指针。这可以指向任何东西 - 数据结构、数组等。我真的不记得回调函数多久被调用一次(它经常......我不会担心速度),但是userData允许您拥有可以在主线程中更改的变量,而音频线程中的指针允许您直接在内存中访问它......我对线程安全的知识不是最好的,如果这不是最好的解释,我很抱歉,但我至少可以通过代码向您展示如何做到这一点(如下)。

这就是我通常的做法,但你不需要自己做;我在文件顶部设置了一个结构,如下所示:

typedef struct {
    float freq;
    float vol;
}paData;

显然,您将在代码中的某个地方(可能在main函数调用中)初始化它并打开音频流(data类型为 paData):

/* Open audio stream */
err = Pa_OpenStream(&(*stream),
        &inputParameters,
        &outputParameters,
        SAMPLE_RATE, bufSize, paNoFlag, 
        paCallback, &data);

打开它后,您可以像这样进行回调:

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("%fn", data->freq);
    /* Do something with your code here */
    return paContinue;
}

希望有帮助。

最新更新