audio - AudioUnit(Mac)AudioUnitRender内部缓冲区冲突

标签 audio core-audio latency audiounit circular-buffer

我最近在Mac上使用AudioUnits设计了一个录音机。它的设计类似于视频安全系统,可以连续记录,并带有图形化的功率电平显示,以供回放浏览。
我注意到,每85分钟就会出现3分钟的失真。消除了一天之后,似乎在调用回调之前发生的声音获取使用了循环缓冲区,并且回调的audioUnitRender函数从该缓冲区中提取,但速度稍慢,最终导致内部缓冲区写回绕并被捕获与audioUnitRender读取有关。双工操作测试显示等待时间不断增加,在85分钟后,您听到了大约200-300ms的等待时间,并且噪声随着渲染缓冲区帧在缓冲区的开始和结尾具有缓冲区段的组合而开始,即长和短等待时间。当指针移开时,噪音消失,您会听到干净的音频,但延迟很短,然后在85分钟后再次重复。即使使用低影响的回调处理,这种情况仍然会发生。我看过一些有关延迟的帖子,但没有关于冲突的帖子,有人看过吗?

osx 10.9.5,xcode 6.1.1
代码详细信息:-

//modes 1=playback, 2=record, 3=both
AudioComponentDescription outputcd = {0}; // 10.6 version  
outputcd.componentType = kAudioUnitType_Output;  
outputcd.componentSubType = kAudioUnitSubType_HALOutput; //allows duplex  
outputcd.componentManufacturer = kAudioUnitManufacturer_Apple;  
AudioComponent comp = AudioComponentFindNext (NULL, &outputcd);  
if (comp == NULL) {printf ("can't get output unit");exit (-1);}  
CheckError (AudioComponentInstanceNew(comp, au),"Couldn't open component for outputUnit");  
//tell input bus that its's input, tell output it's an output  
if(mode==1 || mode==3) r=[self setAudioMode:*au :0];//play  
if(mode==2 || mode==3) r=[self setAudioMode:*au :1];//rec      
// register render callback  
if(mode==1 || mode==3) [self setCallBack:*au :0];  
if(mode==2 || mode==3) [self setCallBack:*au :1];  
// if(mode==2 || mode==3) [self setAllocBuffer:*au];  
// get default stream, change amt of channels  
AudioStreamBasicDescription audioFormat;  
UInt32 k=sizeof(audioFormat);  
r= AudioUnitGetProperty(*au,
                              kAudioUnitProperty_StreamFormat,
                              kAudioUnitScope_Output,
                              1,
                              &audioFormat,
                        &k);  
audioFormat.mChannelsPerFrame=1;  
r= AudioUnitSetProperty(*au,
                        kAudioUnitProperty_StreamFormat,
                        kAudioUnitScope_Output,
                        1,
                        &audioFormat,
                        k);  
//start  
CheckError (AudioUnitInitialize(outputUnit),"Couldn't initialize output unit");  

//record callback  
OSStatus RecProc(void *inRefCon,
             AudioUnitRenderActionFlags *ioActionFlags,
             const AudioTimeStamp *inTimeStamp,
             UInt32 inBusNumber,
             UInt32 inNumberFrames,
             AudioBufferList * ioData)  
{  
myView * mv2=(__bridge myView*)inRefCon;  
AudioBuffer buffer,buffer2;  
OSStatus status;  
buffer.mDataByteSize = inNumberFrames *4 ;// buffer size  
buffer.mNumberChannels = 1; // one channel  
buffer.mData =mv2->rdata;  
buffer2.mDataByteSize = inNumberFrames *4 ;// buffer size  
buffer2.mNumberChannels = 1; // one channel  
buffer2.mData =mv2->rdata2;  
AudioBufferList bufferList;  
bufferList.mNumberBuffers = 2;  
bufferList.mBuffers[0] = buffer;  
bufferList.mBuffers[1] = buffer2;  
status = AudioUnitRender(mv2->outputUnit, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, &bufferList);  

[mv2 recproc :mv->rdata :mv->rdata2 :inNumberFrames];  
return noErr;  
}  

最佳答案

您似乎正在使用HAL输出单元来拉动输入。可能无法保证输入设备和输出设备的采样率完全锁定。任何一个设备的采样率的任何缓慢的轻微漂移最终都可能导致缓冲区下溢或溢出。

一种解决方案可能是为单独的输入音频单元查找和设置输入设备,而不是依赖于默认输出单元。尝试使用USB麦克风。

关于audio - AudioUnit(Mac)AudioUnitRender内部缓冲区冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35401872/

相关文章:

ios - 如何检查 MPMediaItem 是否只有音频的 MPMediaType?

delphi - Delphi XE2中调用 "IAudioSessionManager2.GetSessionEnumerator()"时出现异常

javascript - 查找上传到React应用程序的音频文件的持续时间/长度

matlab - 如何使用Matlab检查视频中的音频信号

ios - 即使链接似乎正确,也无法通过AVPlayer打开远程音频文件

c++ - _mm256_setr_epi32() 的延迟和吞吐量

networking - Comet 服务器和网络延迟时间

ruby-on-rails - Nagios 和 Rails 监控

android - 如何在Android中播放RTMP的音频链接?

macos - 使用 afconvert 对 wav (LEI16) 文件进行低采样