这个让我保持清醒:
我有一个OS X音频应用程序,如果用户更改设备的当前采样率,它必须做出反应
为此,我在"kAudioDevicePropertyNominalSampleRate"上为输入和输出设备注册了一个回调
因此,如果其中一个设备的采样率发生了更改,我会得到回调,并在设备上设置新的采样率,并将"AudioObjectSetPropertyData"one_answers"kAudioDevicePropertyNominalSampleRate"作为选择器
苹果邮件列表上提到了接下来的步骤,我遵循了它们:
- 停止输入AudioUnit和由混音器和输出AudioUnit组成的AUGraph
- 将两者都取消资本化
- 检查节点计数,跨过它们,使用AUGraphDisconnectNodeInput断开混合器与输出的连接
- 现在在输入单元的输出范围上设置新的采样率
- 以及混合器单元上的输入和输出范围
- 将混合器节点重新连接到输出单元
- 更新图形
- init输入和图形
- 启动输入和图形
渲染和输出回调再次启动,但现在音频失真。我相信是输入渲染回调对信号负责,但我不确定
我忘了什么
据我所知,采样率不会影响缓冲区大小
如果我以其他采样率启动应用程序,则一切正常,这是导致信号失真的变化
我查看前后的流格式(kAudioUnitProperty_StreamFormat)。除了采样率(当然采样率会更改为新值)之外,所有内容都保持不变。
正如我所说,我认为需要更改的是输入渲染回调。我必须通知回调需要更多的样本吗?我检查了44k和48k的回调和缓冲区大小,没有什么不同。
我写了一个小的测试应用程序,所以如果你想让我提供代码,我可以给你看。
编辑:我录制了失真的音频(正弦),并在Audacity中查看了它
我发现,每495个样本后,音频就会下降17个样本。我想你已经明白了:495个样本+17个样本=512个样本。这是我的设备的缓冲区大小
但我仍然不知道我能用这个发现做些什么
我检查了我的输入和输出渲染进程以及它们对RingBuffer的访问(我使用的是固定版本的CARingBuffer)
存储和提取512帧,所以这里什么都不缺。。。
明白了
断开Graph后,似乎有必要告诉两个设备新的采样率
我在回调之前已经这样做了,但似乎必须在以后再做。