[英]Glitches occur when data is read using ExtAudioFile in combination with a circular buffer
我正在嘗試處理使用ExtAudioFile
讀取的音頻數據。 但是,當我嘗試將這些數據放入循環緩沖區時,我聽到了一些小故障。
在下面的示例代碼中,我將數據從“ inBuffer”直接傳遞到“ outBuffer”(均為Michael Tyson的TPCircularBuffer
類型)。 兩個緩沖區的大小均為10 x numberOfFrames * sizeof(float)
。 客戶端流格式為帶浮點樣本的單聲道。
為什么我什至沒有處理任何數據就聽到這些故障? 如果沒有圓形緩沖器,聲音將流暢地播放。 我錯了什么,或者其他方法會更好?
static OSStatus recordingCallback(
void* inRefCon,
AudioUnitRenderActionFlags* ioActionFlags,
const AudioTimeStamp* inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList* ioData){
PlayAudioFile* player = (__bridge PlayAudioFile*)inRefCon;
Info *info = (Info *)player.info;
ExtAudioFileRead(info->extAudioFile, &inNumberFrames, info->inputBuffer);
if (inNumberFrames == 0) {
ExtAudioFileSeek(info->extAudioFile, 0);
}
// Put data in circular buffer
TPCircularBufferProduceBytes(info->inBuffer, info->inputBuffer->mBuffers[0].mData, info->inputBuffer->mBuffers[0].mDataByteSize);
UInt32 frameSize = inNumberFrames*sizeof(float);
if (info->inBuffer->fillCount >= frameSize) {
int32_t availableBytes;
float *tail = TPCircularBufferTail(info->inBuffer, &availableBytes);
if (availableBytes > frameSize){
memcpy(info->tempBuffer, tail, frameSize);
TPCircularBufferConsume(info->inBuffer, frameSize);
// Currently, data is not processed but just put to the output buffer
TPCircularBufferProduceBytes(info->outBuffer, info->tempBuffer, frameSize);
}
}
return noErr;
}
static OSStatus renderCallback(
void* inRefCon,
AudioUnitRenderActionFlags* ioActionFlags,
const AudioTimeStamp* inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList* ioData){
PlayAudioFile* player = (__bridge PlayAudioFile*)inRefCon;
Info *info = (Info *)play.info;
for (int i=0; i < ioData->mNumberBuffers; i++) {
AudioBuffer buffer = ioData->mBuffers[i];
if (info->outBuffer->fillCount > ioData->mBuffers[0].mDataByteSize) {
int32_t availableBytes;
float *tail = TPCircularBufferTail(info->outBuffer, &availableBytes);
memcpy(buffer.mData, tail, buffer.mDataByteSize);
TPCircularBufferConsume(info->outBuffer, buffer.mDataByteSize);
/* Messaging is not used for this example
// Notify delegate
if ([player.delegate respondsToSelector:@selector(player:audioBuffer:bufferSize:)])
{
[player.delegate player:player
audioBuffer:buffer.mData
bufferSize:inNumberFrames];
}
*/
}
else {
memset((char*)ioData->mBuffers[i].mData, 0, ioData->mBuffers[i].mDataByteSize * info->clientFormat.mBytesPerFrame);
}
}
return noErr;
}
編輯根據下面的答案,我通過在回調函數之外分配和釋放內存以及增加循環緩沖區的大小來修改了代碼。 不幸的是,聲音仍然比沒有圓形緩沖器還要差。 這些故障可能還有其他原因嗎?
分配或釋放內存不應在音頻回調中完成。 也不應該發送Objective C消息。
渲染回調應始終將數據放入緩沖區列表緩沖區。 但是您的代碼缺少這樣做的else語句。 嘗試使用更大的循環緩沖區,並確保在開始渲染回調之前已將其充分填充。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.