执行内存分配以存储在中断处理程序中获得的数据

Perform Memory Allocation To Store Data Obtained In Interrupt Handler

我正在编写一个程序,该程序使用 PortAudio 将音频从计算机输入到我的程序中。 PortAudio 在他们的 Writing a Callback 教程中说回调是作为 Interrupt Handler 触发的,并解释说回调中编写的代码不需要做:

memory allocation/deallocation, I/O (including file I/O as well as console I/O, such as printf()), context switching (such as exec() or yield()), mutex operations, or anything else that might rely on the OS

我遇到的问题是如何在无法使用 malloc 的情况下处理来自回调的音频。我当前(和工作中)的回调看起来像这样。

int Audio::paCallback( const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData ) {
    // Cast data passed through stream to our structure.
    auto *in = (uint16_t *) inputBuffer;
    // Get number of audio channels, for instance stereo would be two
    int numberOfChannels = Pa_GetDeviceInfo(Pa_GetDefaultOutputDevice())->maxInputChannels;
    for (int i = 0; i < numberOfChannels; i++) {
        auto storedStream = (uint16_t *) malloc(sizeof(uint16_t) * (framesPerBuffer + 2));
        storedStream[0] = uint16_t(i);
        storedStream[1] = uint16_t(framesPerBuffer);
        for (int j = 0; j < storedStream[1]; j++) {
            storedStream[j + 2] = in[numberOfChannels*j+i];
        }
        audioQueue->push(&storedStream);
    }
    return 0;
}

我知道我不应该使用 malloc,那么我该如何解决这个问题?

在查找代码示例时,我发现免费音频编辑软件Audacity 使用的是PortAudio。我看过 Audacity's PortAudio callbackAudioIO.cpp 中的第 2391 行),它们所做的只是调用两个函数。在第二个函数中,他们调用 alloca,分配内存。

是否可以从中断处理程序调用函数然后进行内存分配,或者这些函数是否也可以在中断上下文中执行?

通常为了避免 dynamically-allocated 内存,我们将使用各种 'static containers.' 东西,例如 pre-allocated 的 circular buffer 和保留数据,或 blit 缓冲区(两个静态缓冲区,其中新数据被添加到一个缓冲区,而 previously-added 数据从第二个缓冲区处理。定期它们的角色是 'swapped' 当 'processing' 缓冲区中的所有数据是空的)。在这两种情况下,了解您可能需要的 'maximum' 数据量以及 pre-allocate 那么多数据都会有所帮助。

Is it ok to call functions from an interrupt handler that then do memory allocation, or would the functions also be executed within the interrupt context?

这实际上取决于您的目标平台。有时避免动态内存分配非常重要,有时在现代嵌入式平台上,这种担忧有点过分了。