Objective c 当使用ExtAudioFile结合循环缓冲区读取数据时,会出现故障

Objective c 当使用ExtAudioFile结合循环缓冲区读取数据时,会出现故障,objective-c,core-audio,circular-buffer,extaudiofileread,Objective C,Core Audio,Circular Buffer,Extaudiofileread,我正在尝试处理使用ExtAudioFile读取的音频数据。然而,当我试图将这些数据放入循环缓冲区时,我听到了几个小故障 在下面的示例代码中,我将数据从“inBuffer”直接传递到“exputffer”(迈克尔·泰森的类型TPCircularBuffer)。两个缓冲区的大小均为10 xnumberOfFrames*sizeof(float)。客户端流格式是mono,带有浮点样本 为什么我没有处理任何数据就听到这些小故障?没有循环缓冲器,声音流得很好。我错了什么,或者另一种方法会更好 static

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

在下面的示例代码中,我将数据从“inBuffer”直接传递到“exputffer”(迈克尔·泰森的类型
TPCircularBuffer
)。两个缓冲区的大小均为10 x
numberOfFrames*sizeof(float)
。客户端流格式是mono,带有浮点样本

为什么我没有处理任何数据就听到这些小故障?没有循环缓冲器,声音流得很好。我错了什么,或者另一种方法会更好

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;
}
静态OSStatus记录回调(
在refcon中无效*,
AudioUnitRenderActionFlags*ioActionFlags,
常量音频时间戳*inTimeStamp,
UInt32 InBunsNumber,
UInt32数字帧,
音频缓冲列表*ioData){
PlayAudioFile*播放器=(桥牌PlayAudioFile*)在Refcon中;
Info*Info=(Info*)player.Info;
ExtAudioFileRead(信息->extAudioFile,&inNumberFrames,信息->输入缓冲区);
如果(inNumberFrames==0){
ExtAudioFileSeek(信息->extAudioFile,0);
}
//将数据放入循环缓冲区
TPCircularBufferProduceBytes(信息->输入缓冲区,信息->输入缓冲区->mBuffers[0]。mData,信息->输入缓冲区->mBuffers[0]。mDataByteSize);
UInt32 frameSize=inNumberFrames*sizeof(float);
如果(信息->缓冲->填充计数>=帧大小){
int32_t可用字节;
float*tail=TPCircularBufferTail(信息->缓冲区和可用字节);
如果(可用字节>帧大小){
memcpy(信息->临时缓冲区、尾部、帧大小);
TPCircularBufferConsume(信息->inBuffer,帧大小);
//目前,数据没有被处理,只是被放入输出缓冲区
TPCircularBufferProduceBytes(信息->突发,信息->临时缓冲区,帧大小);
}
}
返回noErr;
}
静态骨状态反馈(
在refcon中无效*,
AudioUnitRenderActionFlags*ioActionFlags,
常量音频时间戳*inTimeStamp,
UInt32 InBunsNumber,
UInt32数字帧,
音频缓冲列表*ioData){
PlayAudioFile*播放器=(桥牌PlayAudioFile*)在Refcon中;
Info*Info=(Info*)play.Info;
对于(int i=0;imNumberBuffers;i++){
AudioBuffer=ioData->mBuffers[i];
如果(信息->溢出->填充计数->ioData->MBuffer[0].mDataByteSize){
int32_t可用字节;
float*tail=TPCircularBufferTail(信息->溢出和可用字节);
memcpy(buffer.mData、tail、buffer.mDataByteSize);
TPCircularBufferConsume(信息->突发,缓冲区.mDataByteSize);
/*此示例不使用消息传递
//通知代表
if([player.delegate respondsToSelector:@selector(player:audioBuffer:bufferSize:)]))
{
[player.delegate player:player
audioBuffer:buffer.mData
缓冲区大小:inNumberFrames];
}
*/
}
否则{
memset((char*)ioData->mBuffers[i].mData,0,ioData->mBuffers[i].mDataByteSize*info->clientFormat.mBytesPerFrame);
}
}
返回noErr;
}
编辑
根据下面的答案,我修改了代码,在回调函数之外分配和释放内存,并增加了循环缓冲区的大小。不幸的是,声音仍然比没有圆形缓冲器时更糟糕。这些小故障还有其他原因吗

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


渲染回调应始终将数据放入缓冲区列表缓冲区。但是您的代码缺少执行此操作的else语句。请尝试使用更大的循环缓冲区,并确保在开始渲染回调之前已充分预填充。

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


渲染回调应始终将数据放入缓冲区列表缓冲区。但是您的代码缺少执行此操作的else语句。尝试使用更大的循环缓冲区,并确保在开始渲染回调之前已充分预填充。

我通过在回调函数之外分配和释放内存(请参见更新的问题)以及增加缓冲区大小来修改代码。然而,声音只有轻微的改善(但可能是主观的)。关于Objective-C消息,是否有其他方法通知学员新的音频?At已经有一段时间了,但似乎内存分配和Objective-C消息确实是故障的根源(不幸的是,我的代码中仍然有一些Objective-C消息)。你的答案对我很有价值!我通过在回调函数之外分配和释放内存(参见更新的问题)以及增加缓冲区大小来修改代码。然而,声音只有轻微的改善(但可能是主观的)。关于Objective-C消息,是否有其他方法通知学员新的音频?At已经有一段时间了,但似乎内存分配和Objective-C消息确实是故障的根源(不幸的是,我的代码中仍然有一些Objective-C消息)。你的答案对我很有价值!