From: Johannes Anderwald Date: Mon, 6 Dec 2010 02:15:33 +0000 (+0000) Subject: [AUDIO-BRINGUP] X-Git-Tag: backups/ros-branch-0_3_13@51035~84^2~27 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=3da0b30d8ab698db87d25ce25708c293c494abd3;hp=4a8590e0d6916469b648dece94ab128a2261601e [AUDIO-BRINGUP] - Implement determination of the channel count for source mixer lines svn path=/branches/audio-bringup/; revision=49960 --- diff --git a/lib/drivers/sound/mmixer/controls.c b/lib/drivers/sound/mmixer/controls.c index 7cae4261f82..b94c59ce6ea 100644 --- a/lib/drivers/sound/mmixer/controls.c +++ b/lib/drivers/sound/mmixer/controls.c @@ -489,6 +489,132 @@ MMixerCountMixerControls( return MM_STATUS_SUCCESS; } +MIXER_STATUS +MMixerGetChannelCountEnhanced( + IN PMIXER_CONTEXT MixerContext, + IN LPMIXER_INFO MixerInfo, + IN ULONG NodeId, + OUT PULONG MaxChannels) +{ + KSPROPERTY_DESCRIPTION Description; + PKSPROPERTY_DESCRIPTION NewDescription; + PKSPROPERTY_MEMBERSHEADER Header; + ULONG BytesReturned; + KSP_NODE Request; + MIXER_STATUS Status; + + /* try #1 obtain it via description */ + Request.NodeId = NodeId; + Request.Reserved = 0; + Request.Property.Set = KSPROPSETID_Audio; + Request.Property.Flags = KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_TOPOLOGY; + Request.Property.Id = KSPROPERTY_AUDIO_VOLUMELEVEL; + + + /* get description */ + Status = MixerContext->Control(MixerInfo->hMixer, IOCTL_KS_PROPERTY, (PVOID)&Request, sizeof(KSP_NODE), (PVOID)&Description, sizeof(KSPROPERTY_DESCRIPTION), &BytesReturned); + if (Status == MM_STATUS_SUCCESS) + { + if (Description.DescriptionSize >= sizeof(KSPROPERTY_DESCRIPTION) + sizeof(KSPROPERTY_MEMBERSHEADER) && (Description.MembersListCount > 0)) + { + /* allocate new description */ + NewDescription = MixerContext->Alloc(Description.DescriptionSize); + + if (!NewDescription) + { + /* not enough memory */ + return MM_STATUS_NO_MEMORY; + } + + /* get description */ + Status = MixerContext->Control(MixerInfo->hMixer, IOCTL_KS_PROPERTY, (PVOID)&Request, sizeof(KSP_NODE), (PVOID)NewDescription, Description.DescriptionSize, &BytesReturned); + if (Status == MM_STATUS_SUCCESS) + { + /* get header */ + Header = (PKSPROPERTY_MEMBERSHEADER)(NewDescription + 1); + + if (Header->Flags & KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL) + { + /* found enhanced flag */ + ASSERT(Header->MembersCount > 1); + + /* store channel count */ + *MaxChannels = Header->MembersCount; + + /* free description */ + MixerContext->Free(NewDescription); + + /* done */ + return MM_STATUS_SUCCESS; + } + } + + /* free description */ + MixerContext->Free(NewDescription); + } + } + + /* failed to get channel count enhanced */ + return MM_STATUS_UNSUCCESSFUL; +} + +VOID +MMixerGetChannelCountLegacy( + IN PMIXER_CONTEXT MixerContext, + IN LPMIXER_INFO MixerInfo, + IN ULONG NodeId, + OUT PULONG MaxChannels) +{ + ULONG BytesReturned; + MIXER_STATUS Status; + KSNODEPROPERTY_AUDIO_CHANNEL Channel; + LONG Volume; + + /* setup request */ + Channel.Reserved = 0; + Channel.NodeProperty.NodeId = NodeId; + Channel.NodeProperty.Reserved = 0; + Channel.NodeProperty.Property.Flags = KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_TOPOLOGY; + Channel.NodeProperty.Property.Set = KSPROPSETID_Audio; + Channel.Channel = 0; + Channel.NodeProperty.Property.Id = KSPROPERTY_AUDIO_VOLUMELEVEL; + + do + { + /* get channel volume */ + Status = MixerContext->Control(MixerInfo->hMixer, IOCTL_KS_PROPERTY, (PVOID)&Channel, sizeof(KSNODEPROPERTY_AUDIO_CHANNEL), (PVOID)&Volume, sizeof(LONG), &BytesReturned); + if (Status != MM_STATUS_SUCCESS) + break; + + /* increment channel count */ + Channel.Channel++; + + }while(TRUE); + + /* store channel count */ + *MaxChannels = Channel.Channel; + +} + +VOID +MMixerGetMaxChannelsForNode( + IN PMIXER_CONTEXT MixerContext, + IN LPMIXER_INFO MixerInfo, + IN ULONG NodeId, + OUT PULONG MaxChannels) +{ + MIXER_STATUS Status; + + /* try to get it enhanced */ + Status = MMixerGetChannelCountEnhanced(MixerContext, MixerInfo, NodeId, MaxChannels); + + if (Status != MM_STATUS_SUCCESS) + { + /* get it old-fashioned way */ + MMixerGetChannelCountLegacy(MixerContext, MixerInfo, NodeId, MaxChannels); + } +} + MIXER_STATUS MMixerAddMixerControlsToMixerLineByNodeIndexArray( IN PMIXER_CONTEXT MixerContext, @@ -500,6 +626,8 @@ MMixerAddMixerControlsToMixerLineByNodeIndexArray( { ULONG Index, Count, bReserved; MIXER_STATUS Status; + LPGUID NodeType; + ULONG MaxChannels; /* store nodes array */ DstLine->NodeIds = Nodes; @@ -530,6 +658,20 @@ MMixerAddMixerControlsToMixerLineByNodeIndexArray( /* set node status as used */ MMixerSetTopologyNodeReserved(Topology, Nodes[Index]); + /* query node type */ + NodeType = MMixerGetNodeTypeFromTopology(Topology, Nodes[Index]); + + if (IsEqualGUIDAligned(NodeType, &KSNODETYPE_VOLUME)) + { + /* calculate maximum channel count for node */ + MMixerGetMaxChannelsForNode(MixerContext, MixerInfo, Nodes[Index], &MaxChannels); + + DPRINT("NodeId %lu MaxChannels %lu Line %S Id %lu\n", Nodes[Index], MaxChannels, DstLine->Line.szName, DstLine->Line.dwLineID); + /* calculate maximum channels */ + DstLine->Line.cChannels = min(DstLine->Line.cChannels, MaxChannels); + } + + /* now add the mixer control */ Status = MMixerAddMixerControl(MixerContext, MixerInfo, Topology, Nodes[Index], DstLine, &DstLine->LineControls[Count]);