使用环形缓冲区读取音频块
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 倍,清空前检查,打印前清空缓冲区,并使用更少的打印语句。
我想分析一秒钟的音频数据块。为此,我实现了一个填充环形缓冲区的音频单元(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 倍,清空前检查,打印前清空缓冲区,并使用更少的打印语句。