mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 13:27:11 +00:00
[AUDIO-BRINGUP]
- Implement determination of the channel count for source mixer lines svn path=/branches/audio-bringup/; revision=49960
This commit is contained in:
parent
4a8590e0d6
commit
3da0b30d8a
1 changed files with 142 additions and 0 deletions
|
@ -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]);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue