1
我正在嘗試處理使用ExtAudioFile
讀取的音頻數據。但是,當我嘗試將這些數據放入循環緩衝區時,我聽到幾個故障。當使用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消息,是否有另一種方式通知代表新的音頻? – Gerard
At已經有一段時間了,但似乎分配內存和objective-c消息確實是潛在的故障(不幸的是,我的代碼中仍然有一些Objective-C消息)。你的回答對我很有價值! – Gerard