用ringbuffer读取音频块

时间:2016-01-28 10:23:55

标签: core-audio audiounit circular-buffer

我想分析一秒钟的音频数据块。为此,我实现了一个填充环形缓冲区的音频单元(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-&gt; fillCount&gt; = 0),函数TPCircularBufferConsume,file ... / TPCircularBuffer.h,第142行。

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

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

1 个答案:

答案 0 :(得分:2)

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