我有一个 motu UltraLite mk4 USB 音频接口连接到运行 MacOS 10.13.3 的 Mac。
我正在尝试播放三个立体声文件,每个文件都有自己的立体声扬声器。
为了降低复杂性,我只是试图让一个 AVAudioPlayerNode 的立体声从默认输出通道 0 和 1 以外的其他东西中发出。
我希望通过 AVAudioEngine + 一些低级核心音频来实现这一点。
到目前为止,通过配置 AVAudioEngine 的输出节点,我已经成功地将音频播放到我的 USB 音频接口:
AudioUnit audioUnit = [[self.avAudioEngine outputNode] audioUnit];
OSStatus error = AudioUnitSetProperty(audioUnit,
kAudioOutputUnitProperty_CurrentDevice,
kAudioUnitScope_Global,
0,
&deviceID,
sizeof(deviceID));
if (error) {
NSLog(@"Failed to set desired output audio device: %d", (int)
}
我还成功地设置了一个通道映射,它允许一个播放器将立体声文件播放到我的 USB 音频接口的通道 4+5,正如 theanalogkid 在 Apple 开发论坛中所描述的那样。
通道映射的问题在于它被全局应用于 AVAudioEngine 的输出,并且它会影响所有 AVAudioPlayerNode。所以这不是解决方案。
因此,我没有在 AVAudioEngine 的 outputNode 的 AudioUnit 上使用该通道映射,而是尝试使用自定义通道布局创建一个 AVAudioFormat,该布局指定离散通道索引 4 和 5:
// Create audio channel layout struct with two channels
int numChannels = 2;
AudioChannelLayout *audioChannelLayout = calloc(1, sizeof(AudioChannelLayout) + (numChannels - 1) * sizeof(AudioChannelDescription));
audioChannelLayout->mNumberChannelDescriptions = numChannels;
audioChannelLayout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
audioChannelLayout->mChannelBitmap = 0;
// Configure channel descriptions
audioChannelLayout->mChannelDescriptions[0].mChannelFlags = kAudioChannelFlags_AllOff;
audioChannelLayout->mChannelDescriptions[0].mChannelLabel = kAudioChannelLabel_Discrete_4;
audioChannelLayout->mChannelDescriptions[0].mCoordinates[0] = 0;
audioChannelLayout->mChannelDescriptions[0].mCoordinates[1] = 0;
audioChannelLayout->mChannelDescriptions[0].mCoordinates[2] = 0;
audioChannelLayout->mChannelDescriptions[1].mChannelFlags = kAudioChannelFlags_AllOff;
audioChannelLayout->mChannelDescriptions[1].mChannelLabel = kAudioChannelLabel_Discrete_5;
audioChannelLayout->mChannelDescriptions[1].mCoordinates[0] = 0;
audioChannelLayout->mChannelDescriptions[1].mCoordinates[1] = 0;
audioChannelLayout->mChannelDescriptions[1].mCoordinates[2] = 0;
// Create AVAudioChannelLayout
AVAudioChannelLayout *avAudioChannelLayout = [[AVAudioChannelLayout alloc] initWithLayout:audioChannelLayout];
// Create AVAudioFormat
AVAudioOutputNode *outputNode = engine.avAudioEngine.outputNode;
AVAudioFormat *outputHWFormat = [outputNode outputFormatForBus:0];
AVAudioFormat *targetFormat = [[AVAudioFormat alloc] initWithStreamDescription:player.avAudioFile.processingFormat.streamDescription
channelLayout:avAudioChannelLayout];
然后我将播放器的混音器连接到引擎的主混音器,使用输出硬件格式:
[engine connect:speakerMixer to:[engine mainMixerNode] format:outputHWFormat];
以及播放器到它的混音器,使用带有调整通道布局的自定义 AVAudioFormat:
[engine connect:player to:speakerMixer format:targetFormat];
结果?声音播放,但仍只出 USB 音频接口默认的 0 和 1 声道。
如果我将 targetFormat 应用于混音器到 mainMixer 的连接,USB 音频接口根本不会收到任何声音。
我还尝试将通道映射应用于 AVAudioMixerNode 的底层 AVAudioUnit,但是我似乎无法从 AVAudioUnit 获取底层裸机 AudioUnit 以应用通道映射。也许这对于 AVAudioEngine 是不可能的。如果是这样,您是否知道任何其他方法可以做到这一点?
可能我忽略了一些关键的东西。我花了很多天研究这个,感觉卡住了。感谢我能得到的任何帮助。