From 140c408d7b16f7be86d302e8d390933f4e5aafbf Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Fri, 3 Sep 2021 11:13:29 -0400 Subject: [PATCH] usb_audio: Correct mixup between Input terminals and Input streams. An "Input" terminal in USB audio terms refers to any stream of audio going "in" to the USB device, whether that be from the outside world (e.g. a line in jack) or from the computer (e.g. via USB OUT endpoints.) So we cannot rely on the terminal type to tell us whether it is an in or an out for our purposes, we have to check the stream type, and then use that to declare to multi_audio what kind of stream we have. Fixes USB audio mixing up inputs and outputs, especially on devices that only have one or the other and not both. (QEMU manifested this problem.) --- .../drivers/audio/usb/AudioControlInterface.cpp | 13 +++++-------- .../drivers/audio/usb/AudioControlInterface.h | 3 ++- src/add-ons/kernel/drivers/audio/usb/Device.cpp | 13 +++++++------ 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/add-ons/kernel/drivers/audio/usb/AudioControlInterface.cpp b/src/add-ons/kernel/drivers/audio/usb/AudioControlInterface.cpp index f703f74d73..b646986765 100644 --- a/src/add-ons/kernel/drivers/audio/usb/AudioControlInterface.cpp +++ b/src/add-ons/kernel/drivers/audio/usb/AudioControlInterface.cpp @@ -1066,15 +1066,12 @@ AudioControlInterface::InitACHeader(size_t interface, uint32 AudioControlInterface::GetChannelsDescription( - Vector& Channels, multi_description* Description, - Vector<_AudioControl*>&Terminals) + Vector& Channels, multi_description* Description, + Vector<_AudioControl*>& Terminals, bool isForInput) { uint32 addedChannels = 0; for (int32 i = 0; i < Terminals.Count(); i++) { - bool bIsInputTerminal - = Terminals[i]->SubType() == USB_AUDIO_AC_INPUT_TERMINAL; - AudioChannelCluster* cluster = Terminals[i]->OutCluster(); if (cluster == NULL || cluster->ChannelsCount() <= 0) { TRACE(ERR, "Terminal #%d ignored due null " @@ -1083,9 +1080,9 @@ AudioControlInterface::GetChannelsDescription( } uint32 channels = GetTerminalChannels(Channels, cluster, - bIsInputTerminal ? B_MULTI_INPUT_CHANNEL : B_MULTI_OUTPUT_CHANNEL); + isForInput ? B_MULTI_INPUT_CHANNEL : B_MULTI_OUTPUT_CHANNEL); - if (bIsInputTerminal) + if (isForInput) Description->input_channel_count += channels; else Description->output_channel_count += channels; @@ -1134,7 +1131,7 @@ AudioControlInterface::GetTerminalChannels(Vector& Channels, uint32 AudioControlInterface::GetBusChannelsDescription( - Vector& Channels, multi_description* Description) + Vector& Channels, multi_description* Description) { uint32 addedChannels = 0; diff --git a/src/add-ons/kernel/drivers/audio/usb/AudioControlInterface.h b/src/add-ons/kernel/drivers/audio/usb/AudioControlInterface.h index 5935ced6a5..82023ed292 100644 --- a/src/add-ons/kernel/drivers/audio/usb/AudioControlInterface.h +++ b/src/add-ons/kernel/drivers/audio/usb/AudioControlInterface.h @@ -283,7 +283,8 @@ public: uint32 GetChannelsDescription( Vector& Channels, multi_description* Description, - Vector<_AudioControl*>& USBTerminals); + Vector<_AudioControl*>& USBTerminals, + bool isForInput); uint32 GetBusChannelsDescription( Vector& Channels, multi_description* Description); diff --git a/src/add-ons/kernel/drivers/audio/usb/Device.cpp b/src/add-ons/kernel/drivers/audio/usb/Device.cpp index 2271df3568..5e4cce114b 100644 --- a/src/add-ons/kernel/drivers/audio/usb/Device.cpp +++ b/src/add-ons/kernel/drivers/audio/usb/Device.cpp @@ -493,17 +493,18 @@ Device::_MultiGetDescription(multi_description* multiDescription) Description.control_panel[0] = '\0'; - Vector<_AudioControl*> USBTerminals; + Vector Channels; - // channels (USB I/O terminals) are already in fStreams - // in outputs->inputs order, use them. + // channels (USB I/O terminals) are already in fStreams in outputs->inputs order. for (int i = 0; i < fStreams.Count(); i++) { - USBTerminals.PushBack(fAudioControl.Find(fStreams[i]->TerminalLink())); + Vector<_AudioControl*> USBTerminal; + USBTerminal.PushBack(fAudioControl.Find(fStreams[i]->TerminalLink())); + + fAudioControl.GetChannelsDescription(Channels, &Description, USBTerminal, + fStreams[i]->IsInput()); fStreams[i]->GetFormatsAndRates(&Description); } - Vector Channels; - fAudioControl.GetChannelsDescription(Channels, &Description, USBTerminals); fAudioControl.GetBusChannelsDescription(Channels, &Description); // Description.request_channel_count = channels + bus_channels;