使用环形缓冲区读取音频块

Reading chunks of audio with ringbuffer

我想分析一秒钟的音频数据块。为此,我实现了一个填充环形缓冲区的音频单元(Michael Tyson 的 TPCircularBuffer)。在另一个文件中,我尝试使用 NStimer 读取一秒钟的块。不幸的是,我在使用这些数据时收到错误。

缓冲区已填充 kAudioOutputUnitProperty_SetInputCallback 并且工作正常

Device * THIS = (__bridge Device *)inRefCon;
// Render audio into buffer
AudioBufferList bufferList;
bufferList.mNumberBuffers = 1;
bufferList.mBuffers[0].mNumberChannels = 2;
bufferList.mBuffers[0].mData = NULL;
bufferList.mBuffers[0].mDataByteSize = inNumberFrames * sizeof(SInt16) * 2;
CheckError(AudioUnitRender(THIS -> rioUnit, ioActionFlags, inTimeStamp, 1, inNumberFrames, &bufferList), "AudioUnitRender");

// Put audio into circular buffer
TPCircularBufferProduceBytes(&circBuffer, bufferList.mBuffers[0].mData, inNumberFrames * 2 * sizeof(SInt16));

为了读取一秒钟的样本,我实现了以下代码:

    - (void)initializeTimer {
        timer = [NSTimer scheduledTimerWithTimeInterval:1
                                                 target:self
                                               selector:@selector(timerFired:)
                                               userInfo:nil
                                                repeats:YES];
    }

    - (void) timerFired:(NSTimer *)theTimer {
        NSLog(@"Reading %i second(s) from ring",1);

        int32_t availableBytes;
        SInt16 *tail = TPCircularBufferTail(&circBuffer, &availableBytes);
        int availableSamples = availableBytes / sizeof(SInt16);
        NSLog(@"Available samples %i", availableSamples);

        for (int i = 0; i < availableSamples; i++) {
            printf("%i\n",tail[i]);
        }

        TPCircularBufferConsume(&circBuffer, sizeof(SInt16) * availableBytes);
    }

但是,当我 运行 此代码打印样本数时,我收到以下错误: 断言失败:(buffer->fillCount >= 0),函数 TPCircularBufferConsume,文件 …/TPCircularBuffer.h,第 142 行。

不幸的是,我不知道消费数据出了什么问题。缓冲区长度设置为 samplerate * 2 足够长。

如果有人知道这里出了什么问题,我会很高兴。

您的循环缓冲区不够长。您不会在清空之前检查可用大小是否为正,并且所有打印语句所花费的时间都会让缓冲区过度填充。 使缓冲区至少比计时器大 2 倍,清空前检查,打印前清空缓冲区,并使用更少的打印语句。