在运行时更改setPreferredIOBufferDuration会导致Core Audio Error -50

时间:2016-02-15 23:45:11

标签: objective-c avfoundation core-audio audiounit avaudiosession

我正在编写一个基于音频单元(远程IO)的应用程序,它以给定的缓冲区大小显示波形。应用程序最初以优选的缓冲区大小0.0001开始,这导致非常小的缓冲区帧大小(我认为它的14帧)。比运行时我有一个UI元素,允许通过AVAudioSession的方法setPreferredIOBufferDuration:Error:切换缓冲帧大小。

以下是前两种情况从较小的缓冲区更改为较大的缓冲区的代码。 3-5尚未指定。但该应用程序在AudioUnitRender崩溃时出现-50错误代码。

- (void)setBufferSizeFromMode:(int)mode {

   NSTimeInterval bufferDuration;

   switch (mode) {
      case 1:
         bufferDuration = 0.0001;
         break;
      case 2:
         bufferDuration = 0.001;
         break;
      case 3:
         bufferDuration = 0.0; // reserved
         break;
      case 4:
         bufferDuration = 0.0; // reserved
         break;
      case 5:
         bufferDuration = 0.0; // reserved
         break;
      default:
         break;
   }

   AVAudioSession *session = [AVAudioSession sharedInstance];
   NSError * audioSessionError = nil;

   [session setPreferredIOBufferDuration:bufferDuration error:&audioSessionError];
   if (audioSessionError) {
      NSLog(@"Error %ld, %@",
            (long)audioSessionError.code, audioSessionError.localizedDescription);
   }

}

基于阅读CoreAudio和AVFoundation文档,我被认为可以在运行时更改音频硬件配置。音频或失真可能存在一些差距,但我现在很好。这次崩溃有明显的原因吗?或者我必须为缓冲持续时间的每次更改重新初始化所有内容(我的音频会话,音频单元,音频缓冲区等等)吗?

编辑:我在更改会话缓冲区持续时间之前尝试调用AudioOutputUnitStop(self.myRemoteIO);,而不是在设置之后再次启动。我也尝试将会话设置为非活动状态,而不是重新激活它,但两者都是在我的AU输入回调中使用来自AudioUnitRender()的-50 OSStatus。

1 个答案:

答案 0 :(得分:3)

A -50错误通常表示音频单元代码试图设置或使用无效的参数值。

某些iOS设备不支持低于5.3 mS的实际缓冲持续时间(或旧设备上的0.0058秒)。 iOS设备似乎可以自由切换到实际缓冲持续时间4倍,甚至可以交替稍微不同的值,有时不在应用程序控制之下。

inNumberFrames作为参数提供给音频单元回调,您的应用无法随意指定该值。

如果要处理给定的缓冲区大小,请将它们从中间无锁循环FIFO中取出,音频单元回调可以将其输入。

另外:在更改参数或重新启动之前,请在调用音频停止后等待一秒左右。在您调用停止和硬件实际停止之间似乎存在延迟。