mirror of
https://github.com/reactos/reactos.git
synced 2025-04-22 05:00:27 +00:00
[AUDIO-BRINGUP]
- Fix error message when mmixer library has failed to initialize - Remove device handle from MIXER_INFO as a mixer can span over more than one device (i.e. mixer, wave) - Add device handle to mixer control struct - Store mixer controls in list than in array. Will later be used to add hacks (i.e wave line must have volume controls etc) - Add reserved member to topology pin struct and mark used pins as reserved. It is then used to add alternative mixers destination lines svn path=/branches/audio-bringup/; revision=49967
This commit is contained in:
parent
4256033623
commit
6a0327f62c
7 changed files with 354 additions and 173 deletions
|
@ -111,7 +111,6 @@ DriverProc(
|
||||||
{
|
{
|
||||||
case DRV_LOAD :
|
case DRV_LOAD :
|
||||||
{
|
{
|
||||||
HANDLE Handle;
|
|
||||||
MMRESULT Result;
|
MMRESULT Result;
|
||||||
SND_TRACE(L"DRV_LOAD\n");
|
SND_TRACE(L"DRV_LOAD\n");
|
||||||
|
|
||||||
|
@ -120,11 +119,11 @@ DriverProc(
|
||||||
if ( ! MMSUCCESS(Result) )
|
if ( ! MMSUCCESS(Result) )
|
||||||
return 0L;
|
return 0L;
|
||||||
|
|
||||||
Result = WdmAudOpenSoundDeviceByMMixer(NULL, &Handle);
|
Result = WdmAudOpenSoundDeviceByMMixer();
|
||||||
|
|
||||||
if ( Result != MMSYSERR_NOERROR )
|
if ( Result != MMSYSERR_NOERROR )
|
||||||
{
|
{
|
||||||
SND_ERR(L"Failed to open \\\\.\\wdmaud\n");
|
SND_ERR(L"Failed to initialize MMixer Library");
|
||||||
//UnlistAllSoundDevices();
|
//UnlistAllSoundDevices();
|
||||||
|
|
||||||
return 0L;
|
return 0L;
|
||||||
|
|
|
@ -57,9 +57,7 @@ WdmAudGetCapabilitiesByMMixer(
|
||||||
IN DWORD CapabilitiesSize);
|
IN DWORD CapabilitiesSize);
|
||||||
|
|
||||||
MMRESULT
|
MMRESULT
|
||||||
WdmAudOpenSoundDeviceByMMixer(
|
WdmAudOpenSoundDeviceByMMixer();
|
||||||
IN struct _SOUND_DEVICE* SoundDevice,
|
|
||||||
OUT PVOID* Handle);
|
|
||||||
|
|
||||||
MMRESULT
|
MMRESULT
|
||||||
WdmAudCloseSoundDeviceByMMixer(
|
WdmAudCloseSoundDeviceByMMixer(
|
||||||
|
|
|
@ -32,28 +32,42 @@ MIXER_STATUS
|
||||||
MMixerAddMixerControl(
|
MMixerAddMixerControl(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
IN LPMIXER_INFO MixerInfo,
|
IN LPMIXER_INFO MixerInfo,
|
||||||
|
IN HANDLE hMixer,
|
||||||
IN PTOPOLOGY Topology,
|
IN PTOPOLOGY Topology,
|
||||||
IN ULONG NodeIndex,
|
IN ULONG NodeIndex,
|
||||||
IN LPMIXERLINE_EXT MixerLine,
|
IN LPMIXERLINE_EXT MixerLine)
|
||||||
OUT LPMIXERCONTROLW MixerControl)
|
|
||||||
{
|
{
|
||||||
LPGUID NodeType;
|
LPGUID NodeType;
|
||||||
KSP_NODE Node;
|
KSP_NODE Node;
|
||||||
ULONG BytesReturned;
|
ULONG BytesReturned;
|
||||||
MIXER_STATUS Status;
|
MIXER_STATUS Status;
|
||||||
LPWSTR Name;
|
LPWSTR Name;
|
||||||
|
LPMIXERCONTROL_EXT MixerControl;
|
||||||
|
|
||||||
|
/* allocate mixer control */
|
||||||
|
MixerControl = MixerContext->Alloc(sizeof(MIXERCONTROL_EXT));
|
||||||
|
if (!MixerControl)
|
||||||
|
{
|
||||||
|
/* no memory */
|
||||||
|
return MM_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* initialize mixer control */
|
/* initialize mixer control */
|
||||||
MixerControl->cbStruct = sizeof(MIXERCONTROLW);
|
MixerControl->hDevice = hMixer;
|
||||||
MixerControl->dwControlID = MixerInfo->ControlId;
|
MixerControl->NodeID = NodeIndex;
|
||||||
|
MixerControl->ExtraData = NULL;
|
||||||
|
|
||||||
|
MixerControl->Control.cbStruct = sizeof(MIXERCONTROLW);
|
||||||
|
MixerControl->Control.dwControlID = MixerInfo->ControlId;
|
||||||
|
|
||||||
/* get node type */
|
/* get node type */
|
||||||
NodeType = MMixerGetNodeTypeFromTopology(Topology, NodeIndex);
|
NodeType = MMixerGetNodeTypeFromTopology(Topology, NodeIndex);
|
||||||
/* store control type */
|
/* store control type */
|
||||||
MixerControl->dwControlType = MMixerGetControlTypeFromTopologyNode(NodeType);
|
MixerControl->Control.dwControlType = MMixerGetControlTypeFromTopologyNode(NodeType);
|
||||||
|
|
||||||
MixerControl->fdwControl = MIXERCONTROL_CONTROLF_UNIFORM; /* FIXME */
|
MixerControl->Control.fdwControl = MIXERCONTROL_CONTROLF_UNIFORM; /* FIXME */
|
||||||
MixerControl->cMultipleItems = 0;
|
MixerControl->Control.cMultipleItems = 0;
|
||||||
|
|
||||||
/* setup request to retrieve name */
|
/* setup request to retrieve name */
|
||||||
Node.NodeId = NodeIndex;
|
Node.NodeId = NodeIndex;
|
||||||
|
@ -63,7 +77,7 @@ MMixerAddMixerControl(
|
||||||
Node.Reserved = 0;
|
Node.Reserved = 0;
|
||||||
|
|
||||||
/* get node name size */
|
/* get node name size */
|
||||||
Status = MixerContext->Control(MixerInfo->hMixer, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), NULL, 0, &BytesReturned);
|
Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), NULL, 0, &BytesReturned);
|
||||||
|
|
||||||
if (Status == MM_STATUS_MORE_ENTRIES)
|
if (Status == MM_STATUS_MORE_ENTRIES)
|
||||||
{
|
{
|
||||||
|
@ -76,24 +90,28 @@ MMixerAddMixerControl(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get node name */
|
/* get node name */
|
||||||
Status = MixerContext->Control(MixerInfo->hMixer, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), (LPVOID)Name, BytesReturned, &BytesReturned);
|
Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), (LPVOID)Name, BytesReturned, &BytesReturned);
|
||||||
|
|
||||||
if (Status == MM_STATUS_SUCCESS)
|
if (Status == MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
MixerContext->Copy(MixerControl->szShortName, Name, (min(MIXER_SHORT_NAME_CHARS, wcslen(Name)+1)) * sizeof(WCHAR));
|
MixerContext->Copy(MixerControl->Control.szShortName, Name, (min(MIXER_SHORT_NAME_CHARS, wcslen(Name)+1)) * sizeof(WCHAR));
|
||||||
MixerControl->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
|
MixerControl->Control.szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
|
||||||
|
|
||||||
MixerContext->Copy(MixerControl->szName, Name, (min(MIXER_LONG_NAME_CHARS, wcslen(Name)+1)) * sizeof(WCHAR));
|
MixerContext->Copy(MixerControl->Control.szName, Name, (min(MIXER_LONG_NAME_CHARS, wcslen(Name)+1)) * sizeof(WCHAR));
|
||||||
MixerControl->szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
|
MixerControl->Control.szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free name buffer */
|
/* free name buffer */
|
||||||
MixerContext->Free(Name);
|
MixerContext->Free(Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* increment control count */
|
||||||
MixerInfo->ControlId++;
|
MixerInfo->ControlId++;
|
||||||
|
|
||||||
if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_MUX)
|
/* insert control */
|
||||||
|
InsertTailList(&MixerLine->ControlsList, &MixerControl->Entry);
|
||||||
|
|
||||||
|
if (MixerControl->Control.dwControlType == MIXERCONTROL_CONTROLTYPE_MUX)
|
||||||
{
|
{
|
||||||
ULONG NodesCount;
|
ULONG NodesCount;
|
||||||
PULONG Nodes;
|
PULONG Nodes;
|
||||||
|
@ -114,24 +132,24 @@ MMixerAddMixerControl(
|
||||||
MixerContext->Free(Nodes);
|
MixerContext->Free(Nodes);
|
||||||
|
|
||||||
/* setup mux bounds */
|
/* setup mux bounds */
|
||||||
MixerControl->Bounds.dwMinimum = 0;
|
MixerControl->Control.Bounds.dwMinimum = 0;
|
||||||
MixerControl->Bounds.dwMaximum = NodesCount - 1;
|
MixerControl->Control.Bounds.dwMaximum = NodesCount - 1;
|
||||||
MixerControl->Metrics.dwReserved[0] = NodesCount;
|
MixerControl->Control.Metrics.dwReserved[0] = NodesCount;
|
||||||
MixerControl->cMultipleItems = NodesCount;
|
MixerControl->Control.cMultipleItems = NodesCount;
|
||||||
MixerControl->fdwControl |= MIXERCONTROL_CONTROLF_MULTIPLE;
|
MixerControl->Control.fdwControl |= MIXERCONTROL_CONTROLF_MULTIPLE;
|
||||||
}
|
}
|
||||||
else if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE)
|
else if (MixerControl->Control.dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE)
|
||||||
{
|
{
|
||||||
MixerControl->Bounds.dwMinimum = 0;
|
MixerControl->Control.Bounds.dwMinimum = 0;
|
||||||
MixerControl->Bounds.dwMaximum = 1;
|
MixerControl->Control.Bounds.dwMaximum = 1;
|
||||||
}
|
}
|
||||||
else if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_ONOFF)
|
else if (MixerControl->Control.dwControlType == MIXERCONTROL_CONTROLTYPE_ONOFF)
|
||||||
{
|
{
|
||||||
/* only needs to set bounds */
|
/* only needs to set bounds */
|
||||||
MixerControl->Bounds.dwMinimum = 0;
|
MixerControl->Control.Bounds.dwMinimum = 0;
|
||||||
MixerControl->Bounds.dwMaximum = 1;
|
MixerControl->Control.Bounds.dwMaximum = 1;
|
||||||
}
|
}
|
||||||
else if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME)
|
else if (MixerControl->Control.dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME)
|
||||||
{
|
{
|
||||||
KSNODEPROPERTY_AUDIO_CHANNEL Property;
|
KSNODEPROPERTY_AUDIO_CHANNEL Property;
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
|
@ -139,9 +157,9 @@ MMixerAddMixerControl(
|
||||||
PKSPROPERTY_MEMBERSHEADER Members;
|
PKSPROPERTY_MEMBERSHEADER Members;
|
||||||
PKSPROPERTY_STEPPING_LONG Range;
|
PKSPROPERTY_STEPPING_LONG Range;
|
||||||
|
|
||||||
MixerControl->Bounds.dwMinimum = 0;
|
MixerControl->Control.Bounds.dwMinimum = 0;
|
||||||
MixerControl->Bounds.dwMaximum = 0xFFFF;
|
MixerControl->Control.Bounds.dwMaximum = 0xFFFF;
|
||||||
MixerControl->Metrics.cSteps = 0xC0; /* FIXME */
|
MixerControl->Control.Metrics.cSteps = 0xC0; /* FIXME */
|
||||||
|
|
||||||
Length = sizeof(KSPROPERTY_DESCRIPTION) + sizeof(KSPROPERTY_MEMBERSHEADER) + sizeof(KSPROPERTY_STEPPING_LONG);
|
Length = sizeof(KSPROPERTY_DESCRIPTION) + sizeof(KSPROPERTY_MEMBERSHEADER) + sizeof(KSPROPERTY_STEPPING_LONG);
|
||||||
Desc = (PKSPROPERTY_DESCRIPTION)MixerContext->Alloc(Length);
|
Desc = (PKSPROPERTY_DESCRIPTION)MixerContext->Alloc(Length);
|
||||||
|
@ -156,7 +174,7 @@ MMixerAddMixerControl(
|
||||||
Property.NodeProperty.Property.Set = KSPROPSETID_Audio;
|
Property.NodeProperty.Property.Set = KSPROPSETID_Audio;
|
||||||
|
|
||||||
/* get node volume level info */
|
/* get node volume level info */
|
||||||
Status = MixerContext->Control(MixerInfo->hMixer, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSNODEPROPERTY_AUDIO_CHANNEL), Desc, Length, &BytesReturned);
|
Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSNODEPROPERTY_AUDIO_CHANNEL), Desc, Length, &BytesReturned);
|
||||||
|
|
||||||
if (Status == MM_STATUS_SUCCESS)
|
if (Status == MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -181,7 +199,7 @@ MMixerAddMixerControl(
|
||||||
Steps = MaxRange / Range->SteppingDelta + 1;
|
Steps = MaxRange / Range->SteppingDelta + 1;
|
||||||
|
|
||||||
/* store mixer control info there */
|
/* store mixer control info there */
|
||||||
VolumeData->Header.dwControlID = MixerControl->dwControlID;
|
VolumeData->Header.dwControlID = MixerControl->Control.dwControlID;
|
||||||
VolumeData->SignedMaximum = Range->Bounds.SignedMaximum;
|
VolumeData->SignedMaximum = Range->Bounds.SignedMaximum;
|
||||||
VolumeData->SignedMinimum = Range->Bounds.SignedMinimum;
|
VolumeData->SignedMinimum = Range->Bounds.SignedMinimum;
|
||||||
VolumeData->SteppingDelta = Range->SteppingDelta;
|
VolumeData->SteppingDelta = Range->SteppingDelta;
|
||||||
|
@ -202,13 +220,13 @@ MMixerAddMixerControl(
|
||||||
VolumeData->Values[Index] = Value;
|
VolumeData->Values[Index] = Value;
|
||||||
Value += Range->SteppingDelta;
|
Value += Range->SteppingDelta;
|
||||||
}
|
}
|
||||||
InsertTailList(&MixerLine->LineControlsExtraData, &VolumeData->Header.Entry);
|
MixerControl->ExtraData = VolumeData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MixerContext->Free(Desc);
|
MixerContext->Free(Desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("Status %x Name %S\n", Status, MixerControl->szName);
|
DPRINT("Status %x Name %S\n", Status, MixerControl->Control.szName);
|
||||||
return MM_STATUS_SUCCESS;
|
return MM_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +277,7 @@ MMixerCreateDestinationLine(
|
||||||
wcscpy(DestinationLine->Line.Target.szPname, MixerInfo->MixCaps.szPname);
|
wcscpy(DestinationLine->Line.Target.szPname, MixerInfo->MixCaps.szPname);
|
||||||
|
|
||||||
/* initialize extra line */
|
/* initialize extra line */
|
||||||
InitializeListHead(&DestinationLine->LineControlsExtraData);
|
InitializeListHead(&DestinationLine->ControlsList);
|
||||||
|
|
||||||
/* insert into mixer info */
|
/* insert into mixer info */
|
||||||
InsertTailList(&MixerInfo->LineList, &DestinationLine->Entry);
|
InsertTailList(&MixerInfo->LineList, &DestinationLine->Entry);
|
||||||
|
@ -275,6 +293,7 @@ MIXER_STATUS
|
||||||
MMixerGetPinName(
|
MMixerGetPinName(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
IN LPMIXER_INFO MixerInfo,
|
IN LPMIXER_INFO MixerInfo,
|
||||||
|
IN HANDLE hMixer,
|
||||||
IN ULONG PinId,
|
IN ULONG PinId,
|
||||||
IN OUT LPWSTR * OutBuffer)
|
IN OUT LPWSTR * OutBuffer)
|
||||||
{
|
{
|
||||||
|
@ -291,7 +310,7 @@ MMixerGetPinName(
|
||||||
Pin.Property.Id = KSPROPERTY_PIN_NAME;
|
Pin.Property.Id = KSPROPERTY_PIN_NAME;
|
||||||
|
|
||||||
/* try get pin name size */
|
/* try get pin name size */
|
||||||
Status = MixerContext->Control(MixerInfo->hMixer, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), NULL, 0, &BytesReturned);
|
Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), NULL, 0, &BytesReturned);
|
||||||
|
|
||||||
/* check if buffer overflowed */
|
/* check if buffer overflowed */
|
||||||
if (Status == MM_STATUS_MORE_ENTRIES)
|
if (Status == MM_STATUS_MORE_ENTRIES)
|
||||||
|
@ -305,7 +324,7 @@ MMixerGetPinName(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* try get pin name */
|
/* try get pin name */
|
||||||
Status = MixerContext->Control(MixerInfo->hMixer, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)Buffer, BytesReturned, &BytesReturned);
|
Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)Buffer, BytesReturned, &BytesReturned);
|
||||||
if (Status != MM_STATUS_SUCCESS)
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
/* failed to get pin name */
|
/* failed to get pin name */
|
||||||
|
@ -326,6 +345,7 @@ MIXER_STATUS
|
||||||
MMixerBuildMixerDestinationLine(
|
MMixerBuildMixerDestinationLine(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
IN OUT LPMIXER_INFO MixerInfo,
|
IN OUT LPMIXER_INFO MixerInfo,
|
||||||
|
IN HANDLE hMixer,
|
||||||
IN ULONG PinId,
|
IN ULONG PinId,
|
||||||
IN ULONG bInput)
|
IN ULONG bInput)
|
||||||
{
|
{
|
||||||
|
@ -333,7 +353,7 @@ MMixerBuildMixerDestinationLine(
|
||||||
MIXER_STATUS Status;
|
MIXER_STATUS Status;
|
||||||
|
|
||||||
/* try get pin name */
|
/* try get pin name */
|
||||||
Status = MMixerGetPinName(MixerContext, MixerInfo, PinId, &PinName);
|
Status = MMixerGetPinName(MixerContext, MixerInfo, hMixer, PinId, &PinName);
|
||||||
if (Status == MM_STATUS_SUCCESS)
|
if (Status == MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
/* create mixer destination line */
|
/* create mixer destination line */
|
||||||
|
@ -503,6 +523,7 @@ MIXER_STATUS
|
||||||
MMixerGetChannelCountEnhanced(
|
MMixerGetChannelCountEnhanced(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
IN LPMIXER_INFO MixerInfo,
|
IN LPMIXER_INFO MixerInfo,
|
||||||
|
IN HANDLE hMixer,
|
||||||
IN ULONG NodeId,
|
IN ULONG NodeId,
|
||||||
OUT PULONG MaxChannels)
|
OUT PULONG MaxChannels)
|
||||||
{
|
{
|
||||||
|
@ -522,7 +543,7 @@ MMixerGetChannelCountEnhanced(
|
||||||
|
|
||||||
|
|
||||||
/* get description */
|
/* get description */
|
||||||
Status = MixerContext->Control(MixerInfo->hMixer, IOCTL_KS_PROPERTY, (PVOID)&Request, sizeof(KSP_NODE), (PVOID)&Description, sizeof(KSPROPERTY_DESCRIPTION), &BytesReturned);
|
Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Request, sizeof(KSP_NODE), (PVOID)&Description, sizeof(KSPROPERTY_DESCRIPTION), &BytesReturned);
|
||||||
if (Status == MM_STATUS_SUCCESS)
|
if (Status == MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
if (Description.DescriptionSize >= sizeof(KSPROPERTY_DESCRIPTION) + sizeof(KSPROPERTY_MEMBERSHEADER) && (Description.MembersListCount > 0))
|
if (Description.DescriptionSize >= sizeof(KSPROPERTY_DESCRIPTION) + sizeof(KSPROPERTY_MEMBERSHEADER) && (Description.MembersListCount > 0))
|
||||||
|
@ -537,7 +558,7 @@ MMixerGetChannelCountEnhanced(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get description */
|
/* get description */
|
||||||
Status = MixerContext->Control(MixerInfo->hMixer, IOCTL_KS_PROPERTY, (PVOID)&Request, sizeof(KSP_NODE), (PVOID)NewDescription, Description.DescriptionSize, &BytesReturned);
|
Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Request, sizeof(KSP_NODE), (PVOID)NewDescription, Description.DescriptionSize, &BytesReturned);
|
||||||
if (Status == MM_STATUS_SUCCESS)
|
if (Status == MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
/* get header */
|
/* get header */
|
||||||
|
@ -572,6 +593,7 @@ VOID
|
||||||
MMixerGetChannelCountLegacy(
|
MMixerGetChannelCountLegacy(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
IN LPMIXER_INFO MixerInfo,
|
IN LPMIXER_INFO MixerInfo,
|
||||||
|
IN HANDLE hMixer,
|
||||||
IN ULONG NodeId,
|
IN ULONG NodeId,
|
||||||
OUT PULONG MaxChannels)
|
OUT PULONG MaxChannels)
|
||||||
{
|
{
|
||||||
|
@ -592,7 +614,7 @@ MMixerGetChannelCountLegacy(
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
/* get channel volume */
|
/* get channel volume */
|
||||||
Status = MixerContext->Control(MixerInfo->hMixer, IOCTL_KS_PROPERTY, (PVOID)&Channel, sizeof(KSNODEPROPERTY_AUDIO_CHANNEL), (PVOID)&Volume, sizeof(LONG), &BytesReturned);
|
Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Channel, sizeof(KSNODEPROPERTY_AUDIO_CHANNEL), (PVOID)&Volume, sizeof(LONG), &BytesReturned);
|
||||||
if (Status != MM_STATUS_SUCCESS)
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -610,18 +632,19 @@ VOID
|
||||||
MMixerGetMaxChannelsForNode(
|
MMixerGetMaxChannelsForNode(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
IN LPMIXER_INFO MixerInfo,
|
IN LPMIXER_INFO MixerInfo,
|
||||||
|
IN HANDLE hMixer,
|
||||||
IN ULONG NodeId,
|
IN ULONG NodeId,
|
||||||
OUT PULONG MaxChannels)
|
OUT PULONG MaxChannels)
|
||||||
{
|
{
|
||||||
MIXER_STATUS Status;
|
MIXER_STATUS Status;
|
||||||
|
|
||||||
/* try to get it enhanced */
|
/* try to get it enhanced */
|
||||||
Status = MMixerGetChannelCountEnhanced(MixerContext, MixerInfo, NodeId, MaxChannels);
|
Status = MMixerGetChannelCountEnhanced(MixerContext, MixerInfo, hMixer, NodeId, MaxChannels);
|
||||||
|
|
||||||
if (Status != MM_STATUS_SUCCESS)
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
/* get it old-fashioned way */
|
/* get it old-fashioned way */
|
||||||
MMixerGetChannelCountLegacy(MixerContext, MixerInfo, NodeId, MaxChannels);
|
MMixerGetChannelCountLegacy(MixerContext, MixerInfo, hMixer, NodeId, MaxChannels);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -629,6 +652,7 @@ MIXER_STATUS
|
||||||
MMixerAddMixerControlsToMixerLineByNodeIndexArray(
|
MMixerAddMixerControlsToMixerLineByNodeIndexArray(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
IN LPMIXER_INFO MixerInfo,
|
IN LPMIXER_INFO MixerInfo,
|
||||||
|
IN HANDLE hMixer,
|
||||||
IN PTOPOLOGY Topology,
|
IN PTOPOLOGY Topology,
|
||||||
IN OUT LPMIXERLINE_EXT DstLine,
|
IN OUT LPMIXERLINE_EXT DstLine,
|
||||||
IN ULONG NodesCount,
|
IN ULONG NodesCount,
|
||||||
|
@ -639,18 +663,6 @@ MMixerAddMixerControlsToMixerLineByNodeIndexArray(
|
||||||
LPGUID NodeType;
|
LPGUID NodeType;
|
||||||
ULONG MaxChannels;
|
ULONG MaxChannels;
|
||||||
|
|
||||||
/* store nodes array */
|
|
||||||
DstLine->NodeIds = Nodes;
|
|
||||||
|
|
||||||
/* allocate MIXERCONTROLSW array */
|
|
||||||
DstLine->LineControls = MixerContext->Alloc(NodesCount * sizeof(MIXERCONTROLW));
|
|
||||||
|
|
||||||
if (!DstLine->LineControls)
|
|
||||||
{
|
|
||||||
/* out of memory */
|
|
||||||
return MM_STATUS_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize control count */
|
/* initialize control count */
|
||||||
Count = 0;
|
Count = 0;
|
||||||
|
|
||||||
|
@ -674,16 +686,15 @@ MMixerAddMixerControlsToMixerLineByNodeIndexArray(
|
||||||
if (IsEqualGUIDAligned(NodeType, &KSNODETYPE_VOLUME))
|
if (IsEqualGUIDAligned(NodeType, &KSNODETYPE_VOLUME))
|
||||||
{
|
{
|
||||||
/* calculate maximum channel count for node */
|
/* calculate maximum channel count for node */
|
||||||
MMixerGetMaxChannelsForNode(MixerContext, MixerInfo, Nodes[Index], &MaxChannels);
|
MMixerGetMaxChannelsForNode(MixerContext, MixerInfo, hMixer, Nodes[Index], &MaxChannels);
|
||||||
|
|
||||||
DPRINT("NodeId %lu MaxChannels %lu Line %S Id %lu\n", Nodes[Index], MaxChannels, DstLine->Line.szName, DstLine->Line.dwLineID);
|
DPRINT("NodeId %lu MaxChannels %lu Line %S Id %lu\n", Nodes[Index], MaxChannels, DstLine->Line.szName, DstLine->Line.dwLineID);
|
||||||
/* calculate maximum channels */
|
/* calculate maximum channels */
|
||||||
DstLine->Line.cChannels = min(DstLine->Line.cChannels, MaxChannels);
|
DstLine->Line.cChannels = min(DstLine->Line.cChannels, MaxChannels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* now add the mixer control */
|
/* now add the mixer control */
|
||||||
Status = MMixerAddMixerControl(MixerContext, MixerInfo, Topology, Nodes[Index], DstLine, &DstLine->LineControls[Count]);
|
Status = MMixerAddMixerControl(MixerContext, MixerInfo, hMixer, Topology, Nodes[Index], DstLine);
|
||||||
|
|
||||||
if (Status == MM_STATUS_SUCCESS)
|
if (Status == MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -703,6 +714,7 @@ MIXER_STATUS
|
||||||
MMixerGetComponentAndTargetType(
|
MMixerGetComponentAndTargetType(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
IN OUT LPMIXER_INFO MixerInfo,
|
IN OUT LPMIXER_INFO MixerInfo,
|
||||||
|
IN HANDLE hMixer,
|
||||||
IN ULONG PinId,
|
IN ULONG PinId,
|
||||||
OUT PULONG ComponentType,
|
OUT PULONG ComponentType,
|
||||||
OUT PULONG TargetType)
|
OUT PULONG TargetType)
|
||||||
|
@ -717,7 +729,7 @@ MMixerGetComponentAndTargetType(
|
||||||
PKSPIN_PHYSICALCONNECTION Connection;
|
PKSPIN_PHYSICALCONNECTION Connection;
|
||||||
|
|
||||||
/* first dataflow type */
|
/* first dataflow type */
|
||||||
Status = MMixerGetPinDataFlowAndCommunication(MixerContext, MixerInfo->hMixer, PinId, &DataFlow, &Communication);
|
Status = MMixerGetPinDataFlowAndCommunication(MixerContext, hMixer, PinId, &DataFlow, &Communication);
|
||||||
|
|
||||||
if (Status != MM_STATUS_SUCCESS)
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -734,7 +746,7 @@ MMixerGetComponentAndTargetType(
|
||||||
|
|
||||||
|
|
||||||
/* get pin category */
|
/* get pin category */
|
||||||
Status = MixerContext->Control(MixerInfo->hMixer, IOCTL_KS_PROPERTY, (PVOID)&Request, sizeof(KSP_PIN), &Guid, sizeof(GUID), &BytesReturned);
|
Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Request, sizeof(KSP_PIN), &Guid, sizeof(GUID), &BytesReturned);
|
||||||
if (Status != MM_STATUS_SUCCESS)
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
/* failed to get dataflow */
|
/* failed to get dataflow */
|
||||||
|
@ -742,7 +754,7 @@ MMixerGetComponentAndTargetType(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if it has a physical connection */
|
/* check if it has a physical connection */
|
||||||
Status = MMixerGetPhysicalConnection(MixerContext, MixerInfo->hMixer, PinId, &Connection);
|
Status = MMixerGetPhysicalConnection(MixerContext, hMixer, PinId, &Connection);
|
||||||
if (Status == MM_STATUS_SUCCESS)
|
if (Status == MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
/* pin is a brige pin */
|
/* pin is a brige pin */
|
||||||
|
@ -901,6 +913,7 @@ MIXER_STATUS
|
||||||
MMixerBuildMixerSourceLine(
|
MMixerBuildMixerSourceLine(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
IN OUT LPMIXER_INFO MixerInfo,
|
IN OUT LPMIXER_INFO MixerInfo,
|
||||||
|
IN HANDLE hMixer,
|
||||||
IN PTOPOLOGY Topology,
|
IN PTOPOLOGY Topology,
|
||||||
IN ULONG PinId,
|
IN ULONG PinId,
|
||||||
IN ULONG NodesCount,
|
IN ULONG NodesCount,
|
||||||
|
@ -914,7 +927,7 @@ MMixerBuildMixerSourceLine(
|
||||||
ULONG ComponentType, TargetType;
|
ULONG ComponentType, TargetType;
|
||||||
|
|
||||||
/* get component and target type */
|
/* get component and target type */
|
||||||
Status = MMixerGetComponentAndTargetType(MixerContext, MixerInfo, PinId, &ComponentType, &TargetType);
|
Status = MMixerGetComponentAndTargetType(MixerContext, MixerInfo, hMixer, PinId, &ComponentType, &TargetType);
|
||||||
if (Status != MM_STATUS_SUCCESS)
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
/* failed to get component status */
|
/* failed to get component status */
|
||||||
|
@ -936,9 +949,7 @@ MMixerBuildMixerSourceLine(
|
||||||
ASSERT(DstLine);
|
ASSERT(DstLine);
|
||||||
|
|
||||||
/* initialize mixer src line */
|
/* initialize mixer src line */
|
||||||
SrcLine->hDevice = MixerInfo->hMixer;
|
|
||||||
SrcLine->PinId = PinId;
|
SrcLine->PinId = PinId;
|
||||||
SrcLine->NodeIds = Nodes;
|
|
||||||
|
|
||||||
/* initialize mixer line */
|
/* initialize mixer line */
|
||||||
SrcLine->Line.cbStruct = sizeof(MIXERLINEW);
|
SrcLine->Line.cbStruct = sizeof(MIXERLINEW);
|
||||||
|
@ -955,14 +966,14 @@ MMixerBuildMixerSourceLine(
|
||||||
SrcLine->Line.Target.wMid = MixerInfo->MixCaps.wMid;
|
SrcLine->Line.Target.wMid = MixerInfo->MixCaps.wMid;
|
||||||
SrcLine->Line.Target.wPid = MixerInfo->MixCaps.wPid;
|
SrcLine->Line.Target.wPid = MixerInfo->MixCaps.wPid;
|
||||||
SrcLine->Line.Target.vDriverVersion = MixerInfo->MixCaps.vDriverVersion;
|
SrcLine->Line.Target.vDriverVersion = MixerInfo->MixCaps.vDriverVersion;
|
||||||
InitializeListHead(&SrcLine->LineControlsExtraData);
|
InitializeListHead(&SrcLine->ControlsList);
|
||||||
|
|
||||||
/* copy name */
|
/* copy name */
|
||||||
ASSERT(MixerInfo->MixCaps.szPname[MAXPNAMELEN-1] == L'\0');
|
ASSERT(MixerInfo->MixCaps.szPname[MAXPNAMELEN-1] == L'\0');
|
||||||
wcscpy(SrcLine->Line.Target.szPname, MixerInfo->MixCaps.szPname);
|
wcscpy(SrcLine->Line.Target.szPname, MixerInfo->MixCaps.szPname);
|
||||||
|
|
||||||
/* get pin name */
|
/* get pin name */
|
||||||
Status = MMixerGetPinName(MixerContext, MixerInfo, PinId, &PinName);
|
Status = MMixerGetPinName(MixerContext, MixerInfo, hMixer, PinId, &PinName);
|
||||||
|
|
||||||
if (Status == MM_STATUS_SUCCESS)
|
if (Status == MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -978,7 +989,7 @@ MMixerBuildMixerSourceLine(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add the controls to mixer line */
|
/* add the controls to mixer line */
|
||||||
Status = MMixerAddMixerControlsToMixerLineByNodeIndexArray(MixerContext, MixerInfo, Topology, SrcLine, NodesCount, Nodes);
|
Status = MMixerAddMixerControlsToMixerLineByNodeIndexArray(MixerContext, MixerInfo, hMixer, Topology, SrcLine, NodesCount, Nodes);
|
||||||
if (Status != MM_STATUS_SUCCESS)
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
/* failed */
|
/* failed */
|
||||||
|
@ -995,6 +1006,7 @@ MIXER_STATUS
|
||||||
MMixerAddMixerSourceLines(
|
MMixerAddMixerSourceLines(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
IN OUT LPMIXER_INFO MixerInfo,
|
IN OUT LPMIXER_INFO MixerInfo,
|
||||||
|
IN HANDLE hMixer,
|
||||||
IN PTOPOLOGY Topology,
|
IN PTOPOLOGY Topology,
|
||||||
IN ULONG DestinationLineID,
|
IN ULONG DestinationLineID,
|
||||||
IN ULONG LineTerminator)
|
IN ULONG LineTerminator)
|
||||||
|
@ -1091,7 +1103,7 @@ MMixerAddMixerSourceLines(
|
||||||
ULONG TempIndex;
|
ULONG TempIndex;
|
||||||
#endif
|
#endif
|
||||||
/* now build the mixer source line */
|
/* now build the mixer source line */
|
||||||
Status = MMixerBuildMixerSourceLine(MixerContext, MixerInfo, Topology, PinId, AllPinNodesCount, AllPinNodes, DestinationLineID, &SrcLine);
|
Status = MMixerBuildMixerSourceLine(MixerContext, MixerInfo, hMixer, Topology, PinId, AllPinNodesCount, AllPinNodes, DestinationLineID, &SrcLine);
|
||||||
|
|
||||||
if (Status == MM_STATUS_SUCCESS)
|
if (Status == MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -1100,6 +1112,10 @@ MMixerAddMixerSourceLines(
|
||||||
|
|
||||||
/* increment destination line count */
|
/* increment destination line count */
|
||||||
DstLine->Line.cConnections++;
|
DstLine->Line.cConnections++;
|
||||||
|
|
||||||
|
/* mark pin as reserved */
|
||||||
|
MMixerSetTopologyPinReserved(Topology, PinId);
|
||||||
|
|
||||||
#ifdef MMIXER_DEBUG
|
#ifdef MMIXER_DEBUG
|
||||||
DPRINT1("Adding PinId %lu AllPinNodesCount %lu to DestinationLine %lu\n", PinId, AllPinNodesCount, DestinationLineID);
|
DPRINT1("Adding PinId %lu AllPinNodesCount %lu to DestinationLine %lu\n", PinId, AllPinNodesCount, DestinationLineID);
|
||||||
for(TempIndex = 0; TempIndex < AllPinNodesCount; TempIndex++)
|
for(TempIndex = 0; TempIndex < AllPinNodesCount; TempIndex++)
|
||||||
|
@ -1124,6 +1140,7 @@ MIXER_STATUS
|
||||||
MMixerAddMixerControlsToDestinationLine(
|
MMixerAddMixerControlsToDestinationLine(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
IN OUT LPMIXER_INFO MixerInfo,
|
IN OUT LPMIXER_INFO MixerInfo,
|
||||||
|
IN HANDLE hMixer,
|
||||||
IN PTOPOLOGY Topology,
|
IN PTOPOLOGY Topology,
|
||||||
IN ULONG PinId,
|
IN ULONG PinId,
|
||||||
IN ULONG bInput,
|
IN ULONG bInput,
|
||||||
|
@ -1165,7 +1182,7 @@ MMixerAddMixerControlsToDestinationLine(
|
||||||
if (NodesCount > 0)
|
if (NodesCount > 0)
|
||||||
{
|
{
|
||||||
/* add all nodes as mixer controls to the destination line */
|
/* add all nodes as mixer controls to the destination line */
|
||||||
Status = MMixerAddMixerControlsToMixerLineByNodeIndexArray(MixerContext, MixerInfo, Topology, DstLine, NodesCount, Nodes);
|
Status = MMixerAddMixerControlsToMixerLineByNodeIndexArray(MixerContext, MixerInfo, hMixer, Topology, DstLine, NodesCount, Nodes);
|
||||||
if (Status != MM_STATUS_SUCCESS)
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
/* failed to add controls */
|
/* failed to add controls */
|
||||||
|
@ -1185,6 +1202,7 @@ VOID
|
||||||
MMixerApplyOutputFilterHack(
|
MMixerApplyOutputFilterHack(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
IN LPMIXER_DATA MixerData,
|
IN LPMIXER_DATA MixerData,
|
||||||
|
IN HANDLE hMixer,
|
||||||
IN OUT PULONG PinsCount,
|
IN OUT PULONG PinsCount,
|
||||||
IN OUT PULONG Pins)
|
IN OUT PULONG Pins)
|
||||||
{
|
{
|
||||||
|
@ -1195,7 +1213,7 @@ MMixerApplyOutputFilterHack(
|
||||||
for(Index = 0; Index < *PinsCount; Index++)
|
for(Index = 0; Index < *PinsCount; Index++)
|
||||||
{
|
{
|
||||||
/* check if it has a physical connection */
|
/* check if it has a physical connection */
|
||||||
Status = MMixerGetPhysicalConnection(MixerContext, MixerData->hDevice, Pins[Index], &Connection);
|
Status = MMixerGetPhysicalConnection(MixerContext, hMixer, Pins[Index], &Connection);
|
||||||
|
|
||||||
if (Status == MM_STATUS_SUCCESS)
|
if (Status == MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -1249,16 +1267,6 @@ MMixerHandlePhysicalConnection(
|
||||||
|
|
||||||
DPRINT1("Name %S, Pin %lu bInput %lu\n", OutConnection->SymbolicLinkName, OutConnection->Pin, bInput);
|
DPRINT1("Name %S, Pin %lu bInput %lu\n", OutConnection->SymbolicLinkName, OutConnection->Pin, bInput);
|
||||||
|
|
||||||
if (MixerInfo->hMixer != NULL)
|
|
||||||
{
|
|
||||||
/* dont replace mixer destination handles */
|
|
||||||
DPRINT1("MixerInfo hDevice %p MixerData hDevice %p\n", MixerInfo->hMixer, MixerData->hDevice);
|
|
||||||
ASSERT(MixerInfo->hMixer == MixerData->hDevice);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* store connected mixer handle */
|
|
||||||
MixerInfo->hMixer = MixerData->hDevice;
|
|
||||||
|
|
||||||
if (MixerData->Topology == NULL)
|
if (MixerData->Topology == NULL)
|
||||||
{
|
{
|
||||||
/* construct new topology */
|
/* construct new topology */
|
||||||
|
@ -1278,12 +1286,19 @@ MMixerHandlePhysicalConnection(
|
||||||
Topology = MixerData->Topology;
|
Topology = MixerData->Topology;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate pin index array which will hold all referenced pins */
|
/* mark pin as consumed */
|
||||||
Status = MMixerAllocateTopologyPinArray(MixerContext, Topology, &Pins);
|
MMixerSetTopologyPinReserved(Topology, OutConnection->Pin);
|
||||||
ASSERT(Status == MM_STATUS_SUCCESS);
|
|
||||||
|
|
||||||
if (!bInput)
|
if (!bInput)
|
||||||
{
|
{
|
||||||
|
/* allocate pin index array which will hold all referenced pins */
|
||||||
|
Status = MMixerAllocateTopologyPinArray(MixerContext, Topology, &Pins);
|
||||||
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
/* failed to create topology */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/* the mixer is an output mixer
|
/* the mixer is an output mixer
|
||||||
* find end pin of the node path
|
* find end pin of the node path
|
||||||
*/
|
*/
|
||||||
|
@ -1305,14 +1320,14 @@ MMixerHandlePhysicalConnection(
|
||||||
* WorkArround: remove all pin ids which have a physical connection
|
* WorkArround: remove all pin ids which have a physical connection
|
||||||
* because bridge pins may belong to different render paths
|
* because bridge pins may belong to different render paths
|
||||||
*/
|
*/
|
||||||
MMixerApplyOutputFilterHack(MixerContext, MixerData, &PinsCount, Pins);
|
MMixerApplyOutputFilterHack(MixerContext, MixerData, MixerData->hDevice, &PinsCount, Pins);
|
||||||
|
|
||||||
/* sanity checks */
|
/* sanity checks */
|
||||||
ASSERT(PinsCount != 0);
|
ASSERT(PinsCount != 0);
|
||||||
ASSERT(PinsCount == 1);
|
ASSERT(PinsCount == 1);
|
||||||
|
|
||||||
/* create destination line */
|
/* create destination line */
|
||||||
Status = MMixerBuildMixerDestinationLine(MixerContext, MixerInfo, Pins[0], bInput);
|
Status = MMixerBuildMixerDestinationLine(MixerContext, MixerInfo, MixerData->hDevice, Pins[0], bInput);
|
||||||
|
|
||||||
/* calculate destination line id */
|
/* calculate destination line id */
|
||||||
DestinationLineID = (DESTINATION_LINE + MixerInfo->MixCaps.cDestinations-1);
|
DestinationLineID = (DESTINATION_LINE + MixerInfo->MixCaps.cDestinations-1);
|
||||||
|
@ -1327,13 +1342,19 @@ MMixerHandlePhysicalConnection(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add mixer controls to destination line */
|
/* add mixer controls to destination line */
|
||||||
Status = MMixerAddMixerControlsToDestinationLine(MixerContext, MixerInfo, Topology, Pins[0], bInput, DestinationLineID, &LineTerminator);
|
Status = MMixerAddMixerControlsToDestinationLine(MixerContext, MixerInfo, MixerData->hDevice, Topology, Pins[0], bInput, DestinationLineID, &LineTerminator);
|
||||||
|
|
||||||
if (Status == MM_STATUS_SUCCESS)
|
if (Status == MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
/* now add the rest of the source lines */
|
/* now add the rest of the source lines */
|
||||||
Status = MMixerAddMixerSourceLines(MixerContext, MixerInfo, Topology, DestinationLineID, LineTerminator);
|
Status = MMixerAddMixerSourceLines(MixerContext, MixerInfo, MixerData->hDevice, Topology, DestinationLineID, LineTerminator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* mark pin as consumed */
|
||||||
|
MMixerSetTopologyPinReserved(Topology, Pins[0]);
|
||||||
|
|
||||||
|
/* free topology pin array */
|
||||||
|
MixerContext->Free(Pins);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1341,12 +1362,12 @@ MMixerHandlePhysicalConnection(
|
||||||
DestinationLineID = (DESTINATION_LINE + MixerInfo->MixCaps.cDestinations-1);
|
DestinationLineID = (DESTINATION_LINE + MixerInfo->MixCaps.cDestinations-1);
|
||||||
|
|
||||||
/* add mixer controls */
|
/* add mixer controls */
|
||||||
Status = MMixerAddMixerControlsToDestinationLine(MixerContext, MixerInfo, Topology, OutConnection->Pin, bInput, DestinationLineID, &LineTerminator);
|
Status = MMixerAddMixerControlsToDestinationLine(MixerContext, MixerInfo, MixerData->hDevice, Topology, OutConnection->Pin, bInput, DestinationLineID, &LineTerminator);
|
||||||
|
|
||||||
if (Status == MM_STATUS_SUCCESS)
|
if (Status == MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
/* now add the rest of the source lines */
|
/* now add the rest of the source lines */
|
||||||
Status = MMixerAddMixerSourceLines(MixerContext, MixerInfo, Topology, DestinationLineID, LineTerminator);
|
Status = MMixerAddMixerSourceLines(MixerContext, MixerInfo, MixerData->hDevice, Topology, DestinationLineID, LineTerminator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1364,7 +1385,7 @@ MMixerInitializeFilter(
|
||||||
IN ULONG bInputMixer,
|
IN ULONG bInputMixer,
|
||||||
IN OUT LPMIXER_INFO * OutMixerInfo)
|
IN OUT LPMIXER_INFO * OutMixerInfo)
|
||||||
{
|
{
|
||||||
|
ULONG Index;
|
||||||
MIXER_STATUS Status;
|
MIXER_STATUS Status;
|
||||||
PKSPIN_PHYSICALCONNECTION OutConnection;
|
PKSPIN_PHYSICALCONNECTION OutConnection;
|
||||||
ULONG * Pins;
|
ULONG * Pins;
|
||||||
|
@ -1431,10 +1452,16 @@ MMixerInitializeFilter(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* mark all found pins as reserved */
|
||||||
|
for(Index = 0; Index < PinsFound; Index++)
|
||||||
|
{
|
||||||
|
MMixerSetTopologyPinReserved(Topology, Pins[Index]);
|
||||||
|
}
|
||||||
|
|
||||||
if (bInputMixer)
|
if (bInputMixer)
|
||||||
{
|
{
|
||||||
/* pre create the mixer destination line for input mixers */
|
/* pre create the mixer destination line for input mixers */
|
||||||
Status = MMixerBuildMixerDestinationLine(MixerContext, MixerInfo, Pins[0], bInputMixer);
|
Status = MMixerBuildMixerDestinationLine(MixerContext, MixerInfo, MixerData->hDevice, Pins[0], bInputMixer);
|
||||||
|
|
||||||
if (Status != MM_STATUS_SUCCESS)
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -1468,6 +1495,9 @@ MMixerInitializeFilter(
|
||||||
|
|
||||||
if (Status == MM_STATUS_SUCCESS)
|
if (Status == MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
|
/* mark pin as reserved */
|
||||||
|
MMixerSetTopologyPinReserved(Topology, Pins[0]);
|
||||||
|
|
||||||
/* topology on the topoloy filter */
|
/* topology on the topoloy filter */
|
||||||
Status = MMixerHandlePhysicalConnection(MixerContext, MixerList, MixerData, MixerInfo, bInputMixer, OutConnection);
|
Status = MMixerHandlePhysicalConnection(MixerContext, MixerList, MixerData, MixerInfo, bInputMixer, OutConnection);
|
||||||
|
|
||||||
|
@ -1480,7 +1510,6 @@ MMixerInitializeFilter(
|
||||||
* handle drivers which expose their topology on the same filter
|
* handle drivers which expose their topology on the same filter
|
||||||
*/
|
*/
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
MixerInfo->hMixer = MixerData->hDevice;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free pins */
|
/* free pins */
|
||||||
|
@ -1498,6 +1527,32 @@ MMixerInitializeFilter(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MMixerHandleAlternativeMixers(
|
||||||
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN PMIXER_LIST MixerList,
|
||||||
|
IN LPMIXER_DATA MixerData,
|
||||||
|
IN PTOPOLOGY Topology)
|
||||||
|
{
|
||||||
|
ULONG Index, PinCount, Reserved;
|
||||||
|
|
||||||
|
DPRINT1("DeviceName %S\n", MixerData->DeviceName);
|
||||||
|
|
||||||
|
/* get topology pin count */
|
||||||
|
MMixerGetTopologyPinCount(Topology, &PinCount);
|
||||||
|
|
||||||
|
for(Index = 0; Index < PinCount; Index++)
|
||||||
|
{
|
||||||
|
MMixerIsTopologyPinReserved(Topology, Index, &Reserved);
|
||||||
|
|
||||||
|
/* check if it has already been reserved */
|
||||||
|
if (Reserved == FALSE)
|
||||||
|
{
|
||||||
|
DPRINT1("MixerName %S Available PinID %lu\n", MixerData->DeviceName, Index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MIXER_STATUS
|
MIXER_STATUS
|
||||||
MMixerSetupFilter(
|
MMixerSetupFilter(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
@ -1567,7 +1622,7 @@ MMixerSetupFilter(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: handle alternative mixer types + apply hacks for Wave source line */
|
/* TODO: apply hacks for Wave source line */
|
||||||
|
|
||||||
/* activate midi devices */
|
/* activate midi devices */
|
||||||
MMixerInitializeMidiForFilter(MixerContext, MixerList, MixerData, Topology);
|
MMixerInitializeMidiForFilter(MixerContext, MixerList, MixerData, Topology);
|
||||||
|
|
|
@ -306,8 +306,9 @@ MMixerGetLineControls(
|
||||||
{
|
{
|
||||||
LPMIXER_INFO MixerInfo;
|
LPMIXER_INFO MixerInfo;
|
||||||
LPMIXERLINE_EXT MixerLineSrc;
|
LPMIXERLINE_EXT MixerLineSrc;
|
||||||
LPMIXERCONTROLW MixerControl;
|
LPMIXERCONTROL_EXT MixerControl;
|
||||||
MIXER_STATUS Status;
|
MIXER_STATUS Status;
|
||||||
|
PLIST_ENTRY Entry;
|
||||||
ULONG Index;
|
ULONG Index;
|
||||||
|
|
||||||
/* verify mixer context */
|
/* verify mixer context */
|
||||||
|
@ -319,6 +320,20 @@ MMixerGetLineControls(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (MixerLineControls->cbStruct != sizeof(MIXERLINECONTROLSW))
|
||||||
|
{
|
||||||
|
DPRINT1("Invalid MixerLineControls cbStruct passed %lu expected %lu\n", MixerLineControls->cbStruct, sizeof(MIXERLINECONTROLSW));
|
||||||
|
/* invalid parameter */
|
||||||
|
return MM_STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MixerLineControls->cbmxctrl != sizeof(MIXERCONTROLW))
|
||||||
|
{
|
||||||
|
DPRINT1("Invalid MixerLineControls cbmxctrl passed %lu expected %lu\n", MixerLineControls->cbStruct, sizeof(MIXERLINECONTROLSW));
|
||||||
|
/* invalid parameter */
|
||||||
|
return MM_STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
if ((Flags & (MIXER_OBJECTF_MIXER | MIXER_OBJECTF_HMIXER)) == MIXER_OBJECTF_MIXER)
|
if ((Flags & (MIXER_OBJECTF_MIXER | MIXER_OBJECTF_HMIXER)) == MIXER_OBJECTF_MIXER)
|
||||||
{
|
{
|
||||||
/* caller passed mixer id */
|
/* caller passed mixer id */
|
||||||
|
@ -335,12 +350,12 @@ MMixerGetLineControls(
|
||||||
|
|
||||||
DPRINT("MMixerGetLineControls MixerId %lu Flags %lu\n", MixerId, Flags);
|
DPRINT("MMixerGetLineControls MixerId %lu Flags %lu\n", MixerId, Flags);
|
||||||
|
|
||||||
|
|
||||||
if (Flags == MIXER_GETLINECONTROLSF_ALL)
|
if (Flags == MIXER_GETLINECONTROLSF_ALL)
|
||||||
{
|
{
|
||||||
/* cast to mixer info */
|
/* cast to mixer info */
|
||||||
MixerInfo = (LPMIXER_INFO)MixerHandle;
|
MixerInfo = (LPMIXER_INFO)MixerHandle;
|
||||||
|
|
||||||
|
/* get mixer line */
|
||||||
MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, MixerLineControls->dwLineID);
|
MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, MixerLineControls->dwLineID);
|
||||||
|
|
||||||
if (!MixerLineSrc)
|
if (!MixerLineSrc)
|
||||||
|
@ -349,9 +364,31 @@ MMixerGetLineControls(
|
||||||
DPRINT("MMixerGetLineControls Line not found %lx\n", MixerLineControls->dwLineID);
|
DPRINT("MMixerGetLineControls Line not found %lx\n", MixerLineControls->dwLineID);
|
||||||
return MM_STATUS_INVALID_PARAMETER;
|
return MM_STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
/* copy line control(s) */
|
|
||||||
MixerContext->Copy(MixerLineControls->pamxctrl, MixerLineSrc->LineControls, min(MixerLineSrc->Line.cControls, MixerLineControls->cControls) * sizeof(MIXERCONTROLW));
|
|
||||||
|
|
||||||
|
if (MixerLineSrc->Line.cControls != MixerLineControls->cControls)
|
||||||
|
{
|
||||||
|
/* invalid parameter */
|
||||||
|
DPRINT1("Invalid control count %lu expected %lu\n", MixerLineControls->cControls, MixerLineSrc->Line.cControls);
|
||||||
|
return MM_STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy line control(s) */
|
||||||
|
Entry = MixerLineSrc->ControlsList.Flink;
|
||||||
|
Index = 0;
|
||||||
|
while(Entry != &MixerLineSrc->ControlsList)
|
||||||
|
{
|
||||||
|
/* get mixer control */
|
||||||
|
MixerControl = (LPMIXERCONTROL_EXT)CONTAINING_RECORD(Entry, MIXERCONTROL_EXT, Entry);
|
||||||
|
|
||||||
|
/* copy mixer control */
|
||||||
|
MixerContext->Copy(&MixerLineControls->pamxctrl[Index], &MixerControl->Control, sizeof(MIXERCONTROLW));
|
||||||
|
|
||||||
|
/* move to next */
|
||||||
|
Entry = Entry->Flink;
|
||||||
|
|
||||||
|
/* increment mixer control offset */
|
||||||
|
Index++;
|
||||||
|
}
|
||||||
return MM_STATUS_SUCCESS;
|
return MM_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
else if (Flags == MIXER_GETLINECONTROLSF_ONEBYTYPE)
|
else if (Flags == MIXER_GETLINECONTROLSF_ONEBYTYPE)
|
||||||
|
@ -374,19 +411,23 @@ MMixerGetLineControls(
|
||||||
ASSERT(MixerLineControls->cbmxctrl == sizeof(MIXERCONTROLW));
|
ASSERT(MixerLineControls->cbmxctrl == sizeof(MIXERCONTROLW));
|
||||||
ASSERT(MixerLineControls->pamxctrl != NULL);
|
ASSERT(MixerLineControls->pamxctrl != NULL);
|
||||||
|
|
||||||
Index = 0;
|
Entry = MixerLineSrc->ControlsList.Flink;
|
||||||
for(Index = 0; Index < MixerLineSrc->Line.cControls; Index++)
|
while(Entry != &MixerLineSrc->ControlsList)
|
||||||
{
|
{
|
||||||
DPRINT1("dwControlType %x\n", MixerLineSrc->LineControls[Index].dwControlType);
|
MixerControl = (LPMIXERCONTROL_EXT)CONTAINING_RECORD(Entry, MIXERCONTROL_EXT, Entry);
|
||||||
if (MixerLineControls->dwControlType == MixerLineSrc->LineControls[Index].dwControlType)
|
if (MixerLineControls->dwControlType == MixerControl->Control.dwControlType)
|
||||||
{
|
{
|
||||||
/* found a control with that type */
|
/* found a control with that type */
|
||||||
MixerContext->Copy(MixerLineControls->pamxctrl, &MixerLineSrc->LineControls[Index], sizeof(MIXERCONTROLW));
|
MixerContext->Copy(MixerLineControls->pamxctrl, &MixerControl->Control, sizeof(MIXERCONTROLW));
|
||||||
return MM_STATUS_SUCCESS;
|
return MM_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
DPRINT("DeviceInfo->u.MixControls.dwControlType %x not found in Line %x cControls %u \n", MixerLineControls->dwControlType, MixerLineControls->dwLineID, MixerLineSrc->Line.cControls);
|
/* move to next entry */
|
||||||
return MM_STATUS_UNSUCCESSFUL;
|
Entry = Entry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT("DeviceInfo->u.MixControls.dwControlType %x not found in Line %x cControls %u \n", MixerLineControls->dwControlType, MixerLineControls->dwLineID, MixerLineSrc->Line.cControls);
|
||||||
|
return MM_STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
else if (Flags == MIXER_GETLINECONTROLSF_ONEBYID)
|
else if (Flags == MIXER_GETLINECONTROLSF_ONEBYID)
|
||||||
{
|
{
|
||||||
|
@ -406,10 +447,10 @@ MMixerGetLineControls(
|
||||||
ASSERT(MixerLineControls->cbmxctrl == sizeof(MIXERCONTROLW));
|
ASSERT(MixerLineControls->cbmxctrl == sizeof(MIXERCONTROLW));
|
||||||
ASSERT(MixerLineControls->pamxctrl != NULL);
|
ASSERT(MixerLineControls->pamxctrl != NULL);
|
||||||
|
|
||||||
DPRINT("MMixerGetLineControls ControlID %lx ControlType %lx Name %S\n", MixerControl->dwControlID, MixerControl->dwControlType, MixerControl->szName);
|
DPRINT("MMixerGetLineControls ControlID %lx ControlType %lx Name %S\n", MixerControl->Control.dwControlID, MixerControl->Control.dwControlType, MixerControl->Control.szName);
|
||||||
|
|
||||||
/* copy the controls */
|
/* copy the controls */
|
||||||
MixerContext->Copy(MixerLineControls->pamxctrl, MixerControl, sizeof(MIXERCONTROLW));
|
MixerContext->Copy(MixerLineControls->pamxctrl, &MixerControl->Control, sizeof(MIXERCONTROLW));
|
||||||
MixerLineControls->pamxctrl->szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
|
MixerLineControls->pamxctrl->szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
|
||||||
MixerLineControls->pamxctrl->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
|
MixerLineControls->pamxctrl->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
|
||||||
|
|
||||||
|
@ -431,7 +472,7 @@ MMixerSetControlDetails(
|
||||||
ULONG NodeId;
|
ULONG NodeId;
|
||||||
LPMIXER_INFO MixerInfo;
|
LPMIXER_INFO MixerInfo;
|
||||||
LPMIXERLINE_EXT MixerLine;
|
LPMIXERLINE_EXT MixerLine;
|
||||||
LPMIXERCONTROLW MixerControl;
|
LPMIXERCONTROL_EXT MixerControl;
|
||||||
|
|
||||||
/* verify mixer context */
|
/* verify mixer context */
|
||||||
Status = MMixerVerifyContext(MixerContext);
|
Status = MMixerVerifyContext(MixerContext);
|
||||||
|
@ -439,6 +480,7 @@ MMixerSetControlDetails(
|
||||||
if (Status != MM_STATUS_SUCCESS)
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
/* invalid context passed */
|
/* invalid context passed */
|
||||||
|
DPRINT1("invalid context\n");
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,6 +492,7 @@ MMixerSetControlDetails(
|
||||||
if (!MixerHandle)
|
if (!MixerHandle)
|
||||||
{
|
{
|
||||||
/* invalid parameter */
|
/* invalid parameter */
|
||||||
|
DPRINT1("invalid handle\n");
|
||||||
return MM_STATUS_INVALID_PARAMETER;
|
return MM_STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -464,18 +507,21 @@ MMixerSetControlDetails(
|
||||||
if (Status != MM_STATUS_SUCCESS)
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
/* failed to find control id */
|
/* failed to find control id */
|
||||||
|
DPRINT1("invalid control id %lu\n", MixerControlDetails->dwControlID);
|
||||||
return MM_STATUS_INVALID_PARAMETER;
|
return MM_STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(MixerControl->dwControlType)
|
DPRINT1("MMixerSetControlDetails ControlType %lx MixerControlName %S MixerLineName %S NodeID %lu\n", MixerControl->Control.dwControlType, MixerControl->Control.szName, MixerLine->Line.szName, NodeId);
|
||||||
|
switch(MixerControl->Control.dwControlType)
|
||||||
{
|
{
|
||||||
case MIXERCONTROL_CONTROLTYPE_MUTE:
|
case MIXERCONTROL_CONTROLTYPE_MUTE:
|
||||||
Status = MMixerSetGetMuteControlDetails(MixerContext, MixerInfo->hMixer, NodeId, MixerLine->Line.dwLineID, MixerControlDetails, TRUE);
|
Status = MMixerSetGetMuteControlDetails(MixerContext, MixerInfo, MixerControl, MixerLine->Line.dwLineID, MixerControlDetails, TRUE);
|
||||||
break;
|
break;
|
||||||
case MIXERCONTROL_CONTROLTYPE_VOLUME:
|
case MIXERCONTROL_CONTROLTYPE_VOLUME:
|
||||||
Status = MMixerSetGetVolumeControlDetails(MixerContext, MixerInfo->hMixer, NodeId, TRUE, MixerControl, MixerControlDetails, MixerLine);
|
Status = MMixerSetGetVolumeControlDetails(MixerContext, MixerInfo, NodeId, TRUE, MixerControl, MixerControlDetails, MixerLine);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
ASSERT(0);
|
||||||
Status = MM_STATUS_NOT_IMPLEMENTED;
|
Status = MM_STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,7 +540,7 @@ MMixerGetControlDetails(
|
||||||
ULONG NodeId;
|
ULONG NodeId;
|
||||||
LPMIXER_INFO MixerInfo;
|
LPMIXER_INFO MixerInfo;
|
||||||
LPMIXERLINE_EXT MixerLine;
|
LPMIXERLINE_EXT MixerLine;
|
||||||
LPMIXERCONTROLW MixerControl;
|
LPMIXERCONTROL_EXT MixerControl;
|
||||||
|
|
||||||
/* verify mixer context */
|
/* verify mixer context */
|
||||||
Status = MMixerVerifyContext(MixerContext);
|
Status = MMixerVerifyContext(MixerContext);
|
||||||
|
@ -530,21 +576,60 @@ MMixerGetControlDetails(
|
||||||
return MM_STATUS_INVALID_PARAMETER;
|
return MM_STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(MixerControl->dwControlType)
|
switch(MixerControl->Control.dwControlType)
|
||||||
{
|
{
|
||||||
case MIXERCONTROL_CONTROLTYPE_MUTE:
|
case MIXERCONTROL_CONTROLTYPE_MUTE:
|
||||||
Status = MMixerSetGetMuteControlDetails(MixerContext, MixerInfo, NodeId, MixerLine->Line.dwLineID, MixerControlDetails, FALSE);
|
Status = MMixerSetGetMuteControlDetails(MixerContext, MixerInfo, MixerControl, MixerLine->Line.dwLineID, MixerControlDetails, FALSE);
|
||||||
break;
|
break;
|
||||||
case MIXERCONTROL_CONTROLTYPE_VOLUME:
|
case MIXERCONTROL_CONTROLTYPE_VOLUME:
|
||||||
Status = MMixerSetGetVolumeControlDetails(MixerContext, MixerInfo, NodeId, FALSE, MixerControl, MixerControlDetails, MixerLine);
|
Status = MMixerSetGetVolumeControlDetails(MixerContext, MixerInfo, NodeId, FALSE, MixerControl, MixerControlDetails, MixerLine);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Status = MM_STATUS_NOT_IMPLEMENTED;
|
Status = MM_STATUS_NOT_IMPLEMENTED;
|
||||||
|
DPRINT1("ControlType %lu not implemented\n", MixerControl->Control.dwControlType);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MMixerPrintMixerLineControls(
|
||||||
|
IN LPMIXERLINE_EXT MixerLine)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY Entry;
|
||||||
|
LPMIXERCONTROL_EXT MixerControl;
|
||||||
|
ULONG Index = 0;
|
||||||
|
|
||||||
|
Entry = MixerLine->ControlsList.Flink;
|
||||||
|
while(Entry != &MixerLine->ControlsList)
|
||||||
|
{
|
||||||
|
MixerControl = (LPMIXERCONTROL_EXT)CONTAINING_RECORD(Entry, MIXERCONTROL_EXT, Entry);
|
||||||
|
|
||||||
|
DPRINT1("\n");
|
||||||
|
DPRINT1("Control Index: %lu\n", Index);
|
||||||
|
DPRINT("\n");
|
||||||
|
DPRINT1("cbStruct %u\n", MixerControl->Control.cbStruct);
|
||||||
|
DPRINT1("dwControlID %lu\n", MixerControl->Control.dwControlID);
|
||||||
|
DPRINT1("dwControlType %lx\n", MixerControl->Control.dwControlType);
|
||||||
|
DPRINT1("fdwControl %lu\n", MixerControl->Control.fdwControl);
|
||||||
|
DPRINT1("cMultipleItems %lu\n", MixerControl->Control.cMultipleItems);
|
||||||
|
DPRINT1("szShortName %S\n", MixerControl->Control.szShortName);
|
||||||
|
DPRINT1("szName %S\n", MixerControl->Control.szName);
|
||||||
|
DPRINT1("Bounds.dwMinimum %lu\n", MixerControl->Control.Bounds.dwMinimum);
|
||||||
|
DPRINT1("Bounds.dwMaximum %lu\n", MixerControl->Control.Bounds.dwMaximum);
|
||||||
|
|
||||||
|
DPRINT1("Metrics.Reserved[0] %lu\n", MixerControl->Control.Metrics.dwReserved[0]);
|
||||||
|
DPRINT1("Metrics.Reserved[1] %lu\n", MixerControl->Control.Metrics.dwReserved[1]);
|
||||||
|
DPRINT1("Metrics.Reserved[2] %lu\n", MixerControl->Control.Metrics.dwReserved[2]);
|
||||||
|
DPRINT1("Metrics.Reserved[3] %lu\n", MixerControl->Control.Metrics.dwReserved[3]);
|
||||||
|
DPRINT1("Metrics.Reserved[4] %lu\n", MixerControl->Control.Metrics.dwReserved[4]);
|
||||||
|
DPRINT1("Metrics.Reserved[5] %lu\n", MixerControl->Control.Metrics.dwReserved[5]);
|
||||||
|
|
||||||
|
Entry = Entry->Flink;
|
||||||
|
Index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MMixerPrintMixers(
|
MMixerPrintMixers(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
@ -583,6 +668,9 @@ MMixerPrintMixers(
|
||||||
|
|
||||||
/* get destination line */
|
/* get destination line */
|
||||||
DstMixerLine = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID);
|
DstMixerLine = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID);
|
||||||
|
DPRINT1("//----------------------------------------------------------------------------------------------\n");
|
||||||
|
DPRINT1("\n");
|
||||||
|
DPRINT1("Destination Index %lu\n", SubIndex);
|
||||||
DPRINT1("\n");
|
DPRINT1("\n");
|
||||||
DPRINT1("cChannels %lu\n", DstMixerLine->Line.cChannels);
|
DPRINT1("cChannels %lu\n", DstMixerLine->Line.cChannels);
|
||||||
DPRINT1("cConnections %lu\n", DstMixerLine->Line.cConnections);
|
DPRINT1("cConnections %lu\n", DstMixerLine->Line.cConnections);
|
||||||
|
@ -601,7 +689,7 @@ MMixerPrintMixers(
|
||||||
DPRINT1("Target.vDriverVersion %lx\n", DstMixerLine->Line.Target.vDriverVersion);
|
DPRINT1("Target.vDriverVersion %lx\n", DstMixerLine->Line.Target.vDriverVersion);
|
||||||
DPRINT1("Target.wMid %lx\n", DstMixerLine->Line.Target.wMid );
|
DPRINT1("Target.wMid %lx\n", DstMixerLine->Line.Target.wMid );
|
||||||
DPRINT1("Target.wPid %lx\n", DstMixerLine->Line.Target.wPid);
|
DPRINT1("Target.wPid %lx\n", DstMixerLine->Line.Target.wPid);
|
||||||
|
MMixerPrintMixerLineControls(DstMixerLine);
|
||||||
|
|
||||||
for(SrcIndex = 0; SrcIndex < DstMixerLine->Line.cConnections; SrcIndex++)
|
for(SrcIndex = 0; SrcIndex < DstMixerLine->Line.cConnections; SrcIndex++)
|
||||||
{
|
{
|
||||||
|
@ -610,8 +698,9 @@ MMixerPrintMixers(
|
||||||
|
|
||||||
/* get source line */
|
/* get source line */
|
||||||
SrcMixerLine = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID);
|
SrcMixerLine = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID);
|
||||||
|
DPRINT1("//==============================================================================================\n");
|
||||||
DPRINT1("\n");
|
DPRINT1("\n");
|
||||||
DPRINT1("SourceIndex: %lu\n", SrcIndex);
|
DPRINT1("SrcLineIndex : %lu\n", SrcIndex);
|
||||||
DPRINT1("\n");
|
DPRINT1("\n");
|
||||||
DPRINT1("cChannels %lu\n", SrcMixerLine->Line.cChannels);
|
DPRINT1("cChannels %lu\n", SrcMixerLine->Line.cChannels);
|
||||||
DPRINT1("cConnections %lu\n", SrcMixerLine->Line.cConnections);
|
DPRINT1("cConnections %lu\n", SrcMixerLine->Line.cConnections);
|
||||||
|
@ -630,6 +719,7 @@ MMixerPrintMixers(
|
||||||
DPRINT1("Target.vDriverVersion %lx\n", SrcMixerLine->Line.Target.vDriverVersion);
|
DPRINT1("Target.vDriverVersion %lx\n", SrcMixerLine->Line.Target.vDriverVersion);
|
||||||
DPRINT1("Target.wMid %lx\n", SrcMixerLine->Line.Target.wMid );
|
DPRINT1("Target.wMid %lx\n", SrcMixerLine->Line.Target.wMid );
|
||||||
DPRINT1("Target.wPid %lx\n", SrcMixerLine->Line.Target.wPid);
|
DPRINT1("Target.wPid %lx\n", SrcMixerLine->Line.Target.wPid);
|
||||||
|
MMixerPrintMixerLineControls(SrcMixerLine);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -736,7 +826,17 @@ MMixerInitialize(
|
||||||
Entry = Entry->Flink;
|
Entry = Entry->Flink;
|
||||||
}
|
}
|
||||||
|
|
||||||
MMixerPrintMixers(MixerContext, MixerList);
|
Entry = MixerList->MixerData.Flink;
|
||||||
|
while(Entry != &MixerList->MixerData)
|
||||||
|
{
|
||||||
|
MixerData = (LPMIXER_DATA)CONTAINING_RECORD(Entry, MIXER_DATA, Entry);
|
||||||
|
|
||||||
|
/* now handle alternative mixer types */
|
||||||
|
MMixerHandleAlternativeMixers(MixerContext, MixerList, MixerData, MixerData->Topology);
|
||||||
|
Entry = Entry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
//MMixerPrintMixers(MixerContext, MixerList);
|
||||||
|
|
||||||
/* done */
|
/* done */
|
||||||
return MM_STATUS_SUCCESS;
|
return MM_STATUS_SUCCESS;
|
||||||
|
|
|
@ -55,8 +55,8 @@ typedef struct
|
||||||
ULONG PinConnectedToCount;
|
ULONG PinConnectedToCount;
|
||||||
PULONG PinConnectedTo;
|
PULONG PinConnectedTo;
|
||||||
|
|
||||||
|
|
||||||
ULONG Visited;
|
ULONG Visited;
|
||||||
|
ULONG Reserved;
|
||||||
}PIN, *PPIN;
|
}PIN, *PPIN;
|
||||||
|
|
||||||
|
|
||||||
|
@ -74,7 +74,6 @@ typedef struct
|
||||||
{
|
{
|
||||||
LIST_ENTRY Entry;
|
LIST_ENTRY Entry;
|
||||||
MIXERCAPSW MixCaps;
|
MIXERCAPSW MixCaps;
|
||||||
HANDLE hMixer;
|
|
||||||
LIST_ENTRY LineList;
|
LIST_ENTRY LineList;
|
||||||
ULONG ControlId;
|
ULONG ControlId;
|
||||||
LIST_ENTRY EventList;
|
LIST_ENTRY EventList;
|
||||||
|
@ -83,12 +82,19 @@ typedef struct
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
LIST_ENTRY Entry;
|
LIST_ENTRY Entry;
|
||||||
ULONG PinId;
|
MIXERCONTROLW Control;
|
||||||
|
ULONG NodeID;
|
||||||
HANDLE hDevice;
|
HANDLE hDevice;
|
||||||
|
PVOID ExtraData;
|
||||||
|
}MIXERCONTROL_EXT, *LPMIXERCONTROL_EXT;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
LIST_ENTRY Entry;
|
||||||
|
ULONG PinId;
|
||||||
MIXERLINEW Line;
|
MIXERLINEW Line;
|
||||||
LPMIXERCONTROLW LineControls;
|
LIST_ENTRY ControlsList;
|
||||||
PULONG NodeIds;
|
|
||||||
LIST_ENTRY LineControlsExtraData;
|
|
||||||
}MIXERLINE_EXT, *LPMIXERLINE_EXT;
|
}MIXERLINE_EXT, *LPMIXERLINE_EXT;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -272,14 +278,14 @@ MMixerGetMixerControlById(
|
||||||
LPMIXER_INFO MixerInfo,
|
LPMIXER_INFO MixerInfo,
|
||||||
DWORD dwControlID,
|
DWORD dwControlID,
|
||||||
LPMIXERLINE_EXT *MixerLine,
|
LPMIXERLINE_EXT *MixerLine,
|
||||||
LPMIXERCONTROLW *MixerControl,
|
LPMIXERCONTROL_EXT *MixerControl,
|
||||||
PULONG NodeId);
|
PULONG NodeId);
|
||||||
|
|
||||||
MIXER_STATUS
|
MIXER_STATUS
|
||||||
MMixerSetGetMuteControlDetails(
|
MMixerSetGetMuteControlDetails(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
IN LPMIXER_INFO MixerInfo,
|
IN LPMIXER_INFO MixerInfo,
|
||||||
IN ULONG NodeId,
|
IN LPMIXERCONTROL_EXT MixerControl,
|
||||||
IN ULONG dwLineID,
|
IN ULONG dwLineID,
|
||||||
IN LPMIXERCONTROLDETAILS MixerControlDetails,
|
IN LPMIXERCONTROLDETAILS MixerControlDetails,
|
||||||
IN ULONG bSet);
|
IN ULONG bSet);
|
||||||
|
@ -290,7 +296,7 @@ MMixerSetGetVolumeControlDetails(
|
||||||
IN LPMIXER_INFO MixerInfo,
|
IN LPMIXER_INFO MixerInfo,
|
||||||
IN ULONG NodeId,
|
IN ULONG NodeId,
|
||||||
IN ULONG bSet,
|
IN ULONG bSet,
|
||||||
LPMIXERCONTROLW MixerControl,
|
LPMIXERCONTROL_EXT MixerControl,
|
||||||
IN LPMIXERCONTROLDETAILS MixerControlDetails,
|
IN LPMIXERCONTROLDETAILS MixerControlDetails,
|
||||||
LPMIXERLINE_EXT MixerLine);
|
LPMIXERLINE_EXT MixerLine);
|
||||||
|
|
||||||
|
@ -359,6 +365,13 @@ MMixerGetPinDataFlowAndCommunication(
|
||||||
OUT PKSPIN_DATAFLOW DataFlow,
|
OUT PKSPIN_DATAFLOW DataFlow,
|
||||||
OUT PKSPIN_COMMUNICATION Communication);
|
OUT PKSPIN_COMMUNICATION Communication);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MMixerHandleAlternativeMixers(
|
||||||
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN PMIXER_LIST MixerList,
|
||||||
|
IN LPMIXER_DATA MixerData,
|
||||||
|
IN PTOPOLOGY Topology);
|
||||||
|
|
||||||
|
|
||||||
/* topology.c */
|
/* topology.c */
|
||||||
|
|
||||||
|
@ -472,6 +485,17 @@ MMixerIsTopologyNodeReserved(
|
||||||
IN ULONG NodeIndex,
|
IN ULONG NodeIndex,
|
||||||
OUT PULONG bReserved);
|
OUT PULONG bReserved);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MMixerSetTopologyPinReserved(
|
||||||
|
IN PTOPOLOGY Topology,
|
||||||
|
IN ULONG PinId);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MMixerIsTopologyPinReserved(
|
||||||
|
IN PTOPOLOGY Topology,
|
||||||
|
IN ULONG PinId,
|
||||||
|
OUT PULONG bReserved);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MMixerGetTopologyPinCount(
|
MMixerGetTopologyPinCount(
|
||||||
IN PTOPOLOGY Topology,
|
IN PTOPOLOGY Topology,
|
||||||
|
|
|
@ -100,29 +100,6 @@ MMixerGetMixerInfoByIndex(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
LPMIXERCONTROL_DATA
|
|
||||||
MMixerGetMixerControlDataById(
|
|
||||||
PLIST_ENTRY ListHead,
|
|
||||||
DWORD dwControlId)
|
|
||||||
{
|
|
||||||
PLIST_ENTRY Entry;
|
|
||||||
LPMIXERCONTROL_DATA Control;
|
|
||||||
|
|
||||||
/* get first entry */
|
|
||||||
Entry = ListHead->Flink;
|
|
||||||
|
|
||||||
while(Entry != ListHead)
|
|
||||||
{
|
|
||||||
Control = (LPMIXERCONTROL_DATA)CONTAINING_RECORD(Entry, MIXERCONTROL_DATA, Entry);
|
|
||||||
DPRINT("dwSource %x dwSource %x\n", Control->dwControlID, dwControlId);
|
|
||||||
if (Control->dwControlID == dwControlId)
|
|
||||||
return Control;
|
|
||||||
|
|
||||||
Entry = Entry->Flink;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
LPMIXERLINE_EXT
|
LPMIXERLINE_EXT
|
||||||
MMixerGetSourceMixerLineByLineId(
|
MMixerGetSourceMixerLineByLineId(
|
||||||
LPMIXER_INFO MixerInfo,
|
LPMIXER_INFO MixerInfo,
|
||||||
|
@ -187,13 +164,13 @@ MIXER_STATUS
|
||||||
MMixerGetMixerControlById(
|
MMixerGetMixerControlById(
|
||||||
LPMIXER_INFO MixerInfo,
|
LPMIXER_INFO MixerInfo,
|
||||||
DWORD dwControlID,
|
DWORD dwControlID,
|
||||||
LPMIXERLINE_EXT *MixerLine,
|
LPMIXERLINE_EXT *OutMixerLine,
|
||||||
LPMIXERCONTROLW *MixerControl,
|
LPMIXERCONTROL_EXT *OutMixerControl,
|
||||||
PULONG NodeId)
|
PULONG NodeId)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY Entry;
|
PLIST_ENTRY Entry, ControlEntry;
|
||||||
LPMIXERLINE_EXT MixerLineSrc;
|
LPMIXERLINE_EXT MixerLineSrc;
|
||||||
ULONG Index;
|
LPMIXERCONTROL_EXT MixerControl;
|
||||||
|
|
||||||
/* get first entry */
|
/* get first entry */
|
||||||
Entry = MixerInfo->LineList.Flink;
|
Entry = MixerInfo->LineList.Flink;
|
||||||
|
@ -202,18 +179,21 @@ MMixerGetMixerControlById(
|
||||||
{
|
{
|
||||||
MixerLineSrc = (LPMIXERLINE_EXT)CONTAINING_RECORD(Entry, MIXERLINE_EXT, Entry);
|
MixerLineSrc = (LPMIXERLINE_EXT)CONTAINING_RECORD(Entry, MIXERLINE_EXT, Entry);
|
||||||
|
|
||||||
for(Index = 0; Index < MixerLineSrc->Line.cControls; Index++)
|
ControlEntry = MixerLineSrc->ControlsList.Flink;
|
||||||
|
while(ControlEntry != &MixerLineSrc->ControlsList)
|
||||||
{
|
{
|
||||||
if (MixerLineSrc->LineControls[Index].dwControlID == dwControlID)
|
MixerControl = (LPMIXERCONTROL_EXT)CONTAINING_RECORD(ControlEntry, MIXERCONTROL_EXT, Entry);
|
||||||
|
if (MixerControl->Control.dwControlID == dwControlID)
|
||||||
{
|
{
|
||||||
if (MixerLine)
|
if (OutMixerLine)
|
||||||
*MixerLine = MixerLineSrc;
|
*OutMixerLine = MixerLineSrc;
|
||||||
if (MixerControl)
|
if (OutMixerControl)
|
||||||
*MixerControl = &MixerLineSrc->LineControls[Index];
|
*OutMixerControl = MixerControl;
|
||||||
if (NodeId)
|
if (NodeId)
|
||||||
*NodeId = MixerLineSrc->NodeIds[Index];
|
*NodeId = MixerControl->NodeID;
|
||||||
return MM_STATUS_SUCCESS;
|
return MM_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
ControlEntry = ControlEntry->Flink;
|
||||||
}
|
}
|
||||||
Entry = Entry->Flink;
|
Entry = Entry->Flink;
|
||||||
}
|
}
|
||||||
|
@ -270,7 +250,7 @@ MIXER_STATUS
|
||||||
MMixerSetGetMuteControlDetails(
|
MMixerSetGetMuteControlDetails(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
IN LPMIXER_INFO MixerInfo,
|
IN LPMIXER_INFO MixerInfo,
|
||||||
IN ULONG NodeId,
|
IN LPMIXERCONTROL_EXT MixerControl,
|
||||||
IN ULONG dwLineID,
|
IN ULONG dwLineID,
|
||||||
IN LPMIXERCONTROLDETAILS MixerControlDetails,
|
IN LPMIXERCONTROLDETAILS MixerControlDetails,
|
||||||
IN ULONG bSet)
|
IN ULONG bSet)
|
||||||
|
@ -290,7 +270,7 @@ MMixerSetGetMuteControlDetails(
|
||||||
Value = Input->fValue;
|
Value = Input->fValue;
|
||||||
|
|
||||||
/* set control details */
|
/* set control details */
|
||||||
Status = MMixerSetGetControlDetails(MixerContext, MixerInfo->hMixer, NodeId, bSet, KSPROPERTY_AUDIO_MUTE, 0, &Value);
|
Status = MMixerSetGetControlDetails(MixerContext, MixerControl->hDevice, MixerControl->NodeID, bSet, KSPROPERTY_AUDIO_MUTE, 0, &Value);
|
||||||
|
|
||||||
if (Status != MM_STATUS_SUCCESS)
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -316,7 +296,7 @@ MMixerSetGetVolumeControlDetails(
|
||||||
IN LPMIXER_INFO MixerInfo,
|
IN LPMIXER_INFO MixerInfo,
|
||||||
IN ULONG NodeId,
|
IN ULONG NodeId,
|
||||||
IN ULONG bSet,
|
IN ULONG bSet,
|
||||||
LPMIXERCONTROLW MixerControl,
|
LPMIXERCONTROL_EXT MixerControl,
|
||||||
IN LPMIXERCONTROLDETAILS MixerControlDetails,
|
IN LPMIXERCONTROLDETAILS MixerControlDetails,
|
||||||
LPMIXERLINE_EXT MixerLine)
|
LPMIXERLINE_EXT MixerLine)
|
||||||
{
|
{
|
||||||
|
@ -329,7 +309,7 @@ MMixerSetGetVolumeControlDetails(
|
||||||
if (MixerControlDetails->cbDetails != sizeof(MIXERCONTROLDETAILS_SIGNED))
|
if (MixerControlDetails->cbDetails != sizeof(MIXERCONTROLDETAILS_SIGNED))
|
||||||
return MM_STATUS_INVALID_PARAMETER;
|
return MM_STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
VolumeData = (LPMIXERVOLUME_DATA)MMixerGetMixerControlDataById(&MixerLine->LineControlsExtraData, MixerControl->dwControlID);
|
VolumeData = (LPMIXERVOLUME_DATA)MixerControl->ExtraData;
|
||||||
if (!VolumeData)
|
if (!VolumeData)
|
||||||
return MM_STATUS_UNSUCCESSFUL;
|
return MM_STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
|
@ -355,12 +335,12 @@ MMixerSetGetVolumeControlDetails(
|
||||||
if (bSet)
|
if (bSet)
|
||||||
{
|
{
|
||||||
/* TODO */
|
/* TODO */
|
||||||
Status = MMixerSetGetControlDetails(MixerContext, MixerInfo->hMixer, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, 0, &Value);
|
Status = MMixerSetGetControlDetails(MixerContext, MixerControl->hDevice, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, 0, &Value);
|
||||||
Status = MMixerSetGetControlDetails(MixerContext, MixerInfo->hMixer, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, 1, &Value);
|
Status = MMixerSetGetControlDetails(MixerContext, MixerControl->hDevice, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, 1, &Value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Status = MMixerSetGetControlDetails(MixerContext, MixerInfo->hMixer, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, Channel, &Value);
|
Status = MMixerSetGetControlDetails(MixerContext, MixerControl->hDevice, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, Channel, &Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bSet)
|
if (!bSet)
|
||||||
|
@ -372,7 +352,7 @@ MMixerSetGetVolumeControlDetails(
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* notify clients of a line change MM_MIXM_CONTROL_CHANGE with MixerControl->dwControlID */
|
/* notify clients of a line change MM_MIXM_CONTROL_CHANGE with MixerControl->dwControlID */
|
||||||
MMixerNotifyControlChange(MixerContext, MixerInfo, MM_MIXM_CONTROL_CHANGE, MixerControl->dwControlID);
|
MMixerNotifyControlChange(MixerContext, MixerInfo, MM_MIXM_CONTROL_CHANGE, MixerControl->Control.dwControlID);
|
||||||
}
|
}
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1173,6 +1173,31 @@ MMixerGetNodeTypeFromTopology(
|
||||||
return &Topology->TopologyNodes[NodeIndex].NodeType;
|
return &Topology->TopologyNodes[NodeIndex].NodeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MMixerSetTopologyPinReserved(
|
||||||
|
IN PTOPOLOGY Topology,
|
||||||
|
IN ULONG PinId)
|
||||||
|
{
|
||||||
|
/* sanity check */
|
||||||
|
ASSERT(PinId < Topology->TopologyPinsCount);
|
||||||
|
|
||||||
|
/* set reserved */
|
||||||
|
Topology->TopologyPins[PinId].Reserved = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MMixerIsTopologyPinReserved(
|
||||||
|
IN PTOPOLOGY Topology,
|
||||||
|
IN ULONG PinId,
|
||||||
|
OUT PULONG bReserved)
|
||||||
|
{
|
||||||
|
/* sanity check */
|
||||||
|
ASSERT(PinId < Topology->TopologyPinsCount);
|
||||||
|
|
||||||
|
/* get reserved status */
|
||||||
|
*bReserved = Topology->TopologyPins[PinId].Reserved;
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MMixerSetTopologyNodeReserved(
|
MMixerSetTopologyNodeReserved(
|
||||||
IN PTOPOLOGY Topology,
|
IN PTOPOLOGY Topology,
|
||||||
|
|
Loading…
Reference in a new issue