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.)
This commit is contained in:
@@ -1066,15 +1066,12 @@ AudioControlInterface::InitACHeader(size_t interface,
|
|||||||
|
|
||||||
uint32
|
uint32
|
||||||
AudioControlInterface::GetChannelsDescription(
|
AudioControlInterface::GetChannelsDescription(
|
||||||
Vector<multi_channel_info>& Channels, multi_description* Description,
|
Vector<multi_channel_info>& Channels, multi_description* Description,
|
||||||
Vector<_AudioControl*>&Terminals)
|
Vector<_AudioControl*>& Terminals, bool isForInput)
|
||||||
{
|
{
|
||||||
uint32 addedChannels = 0;
|
uint32 addedChannels = 0;
|
||||||
|
|
||||||
for (int32 i = 0; i < Terminals.Count(); i++) {
|
for (int32 i = 0; i < Terminals.Count(); i++) {
|
||||||
bool bIsInputTerminal
|
|
||||||
= Terminals[i]->SubType() == USB_AUDIO_AC_INPUT_TERMINAL;
|
|
||||||
|
|
||||||
AudioChannelCluster* cluster = Terminals[i]->OutCluster();
|
AudioChannelCluster* cluster = Terminals[i]->OutCluster();
|
||||||
if (cluster == NULL || cluster->ChannelsCount() <= 0) {
|
if (cluster == NULL || cluster->ChannelsCount() <= 0) {
|
||||||
TRACE(ERR, "Terminal #%d ignored due null "
|
TRACE(ERR, "Terminal #%d ignored due null "
|
||||||
@@ -1083,9 +1080,9 @@ AudioControlInterface::GetChannelsDescription(
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32 channels = GetTerminalChannels(Channels, cluster,
|
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;
|
Description->input_channel_count += channels;
|
||||||
else
|
else
|
||||||
Description->output_channel_count += channels;
|
Description->output_channel_count += channels;
|
||||||
@@ -1134,7 +1131,7 @@ AudioControlInterface::GetTerminalChannels(Vector<multi_channel_info>& Channels,
|
|||||||
|
|
||||||
uint32
|
uint32
|
||||||
AudioControlInterface::GetBusChannelsDescription(
|
AudioControlInterface::GetBusChannelsDescription(
|
||||||
Vector<multi_channel_info>& Channels, multi_description* Description)
|
Vector<multi_channel_info>& Channels, multi_description* Description)
|
||||||
{
|
{
|
||||||
uint32 addedChannels = 0;
|
uint32 addedChannels = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -283,7 +283,8 @@ public:
|
|||||||
uint32 GetChannelsDescription(
|
uint32 GetChannelsDescription(
|
||||||
Vector<multi_channel_info>& Channels,
|
Vector<multi_channel_info>& Channels,
|
||||||
multi_description* Description,
|
multi_description* Description,
|
||||||
Vector<_AudioControl*>& USBTerminals);
|
Vector<_AudioControl*>& USBTerminals,
|
||||||
|
bool isForInput);
|
||||||
uint32 GetBusChannelsDescription(
|
uint32 GetBusChannelsDescription(
|
||||||
Vector<multi_channel_info>& Channels,
|
Vector<multi_channel_info>& Channels,
|
||||||
multi_description* Description);
|
multi_description* Description);
|
||||||
|
|||||||
@@ -493,17 +493,18 @@ Device::_MultiGetDescription(multi_description* multiDescription)
|
|||||||
|
|
||||||
Description.control_panel[0] = '\0';
|
Description.control_panel[0] = '\0';
|
||||||
|
|
||||||
Vector<_AudioControl*> USBTerminals;
|
Vector<multi_channel_info> Channels;
|
||||||
|
|
||||||
// channels (USB I/O terminals) are already in fStreams
|
// channels (USB I/O terminals) are already in fStreams in outputs->inputs order.
|
||||||
// in outputs->inputs order, use them.
|
|
||||||
for (int i = 0; i < fStreams.Count(); i++) {
|
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);
|
fStreams[i]->GetFormatsAndRates(&Description);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<multi_channel_info> Channels;
|
|
||||||
fAudioControl.GetChannelsDescription(Channels, &Description, USBTerminals);
|
|
||||||
fAudioControl.GetBusChannelsDescription(Channels, &Description);
|
fAudioControl.GetBusChannelsDescription(Channels, &Description);
|
||||||
|
|
||||||
// Description.request_channel_count = channels + bus_channels;
|
// Description.request_channel_count = channels + bus_channels;
|
||||||
|
|||||||
Reference in New Issue
Block a user