簡體   English   中英

當使用ExtAudioFile結合循環緩沖區讀取數據時,會發生毛刺

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM