From dc3fae64cd3424cbda8c05d4acb5c1c290d5d29b Mon Sep 17 00:00:00 2001 From: Paul Adenot Date: Mon, 27 May 2024 16:17:36 +0200 Subject: [PATCH] When playing stereo, address the channels by name rather than using index 0 and 1 --- src/backend/mod.rs | 66 +++++++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 18 deletions(-) diff --git a/src/backend/mod.rs b/src/backend/mod.rs index eda2eb76..1e3306ec 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -3906,26 +3906,56 @@ impl<'ctx> CoreStreamData<'ctx> { device_layout ); - // The mixer will be set up when - // 1. using aggregate device whose input device has output channels - // 2. output device has more channels than we need - // 3. output device has different layout than the one we have - self.mixer = if self.output_dev_desc.mChannelsPerFrame - != self.output_stream_params.channels() - || device_layout != mixer::get_channel_order(self.output_stream_params.layout()) + // Simple case of stereo output only, map to the stereo pair (that might not be the first two channels) + if !self.has_input() + && self.output_stream_params.channels() == 2 + && self.output_stream_params.layout() == ChannelLayout::STEREO { - cubeb_log!("Incompatible channel layouts detected, setting up remixer"); - // We will be remixing the data before it reaches the output device. - Some(Mixer::new( - self.output_stream_params.format(), - self.output_stream_params.channels() as usize, - self.output_stream_params.layout(), - self.output_dev_desc.mChannelsPerFrame as usize, - device_layout, - )) + let mut layout = AudioChannelLayout::default(); + if self.output_stream_params.channels() == 2 { + layout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo; + } else { + layout.mChannelLayoutTag = kAudioChannelLayoutTag_Mono; + } + + let r = audio_unit_set_property( + self.output_unit, + kAudioUnitProperty_AudioChannelLayout, + kAudioUnitScope_Input, + AU_OUT_BUS, + &layout, + mem::size_of::(), + ); + if r != NO_ERR { + cubeb_log!( + "AudioUnitSetProperty/output/kAudioUnitProperty_AudioChannelLayout rv={}", + r + ); + return Err(Error::error()); + } } else { - None - }; + // The mixer will be set up when + // 0. not playing simply stereo + // 1. using aggregate device whose input device has output channels + // 2. output device has more channels than we need, and stream isn't simply mono or stereo + // 3. output device has different layout than the one we have + self.mixer = if self.output_dev_desc.mChannelsPerFrame + != self.output_stream_params.channels() + || device_layout != mixer::get_channel_order(self.output_stream_params.layout()) + { + cubeb_log!("Incompatible channel layouts detected, setting up remixer"); + // We will be remixing the data before it reaches the output device. + Some(Mixer::new( + self.output_stream_params.format(), + self.output_stream_params.channels() as usize, + self.output_stream_params.layout(), + self.output_dev_desc.mChannelsPerFrame as usize, + device_layout, + )) + } else { + None + }; + } let r = audio_unit_set_property( self.output_unit,