首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用ExtAudioFile结合循环缓冲区读取数据时会出现故障。

使用ExtAudioFile结合循环缓冲区读取数据时会出现故障。
EN

Stack Overflow用户
提问于 2016-03-01 13:55:37
回答 1查看 100关注 0票数 1

我正在尝试处理使用ExtAudioFile读取的音频数据。然而,当我试图将这些数据放入循环缓冲区时,我会听到一些小故障。

在下面的示例代码中,我直接将数据从"inBuffer“传递给"outBuffer”( Michael的两种类型的TPCircularBuffer )。两个缓冲器都是大小为10×numberOfFrames * sizeof(float)的。客户端流格式是单一的浮点样本。

为什么我在没有处理任何数据的情况下就听到这些故障?没有一个圆形缓冲,声音流很好。我错了什么,或者另一种方法会更好?

代码语言:javascript
复制
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;
}

基于下面的答案的编辑修改了代码,在回调函数之外分配和释放内存,并增加循环缓冲区的大小。不幸的是,声音仍然比没有圆形缓冲器差。这些小故障还有别的原因吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-01 15:34:06

不应在音频回调中分配或释放内存。也不应发送目标C信息。

呈现回调应该始终将数据放入缓冲区列表缓冲区。但是,您的代码缺少了一个code语句来执行此操作。在开始呈现回调之前,尝试一个更大的循环缓冲区,并确保它已经足够的预先填充。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35724836

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档