mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 13:56:05 +00:00
[MMIXER]
- Implement MMixerGetLineInfo, MMixerGetLineControls, MMixerSetControlDetails, MMixerGetControlDetails, MMixerOpen - MMixer library is now ready for testing svn path=/trunk/; revision=44482
This commit is contained in:
parent
81125deea0
commit
91b69c9d1d
6 changed files with 538 additions and 7 deletions
|
@ -203,10 +203,10 @@ MMixerAddMixerControl(
|
||||||
Status = MixerContext->Control(hDevice, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), (LPVOID)Name, BytesReturned, &BytesReturned);
|
Status = MixerContext->Control(hDevice, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), (LPVOID)Name, BytesReturned, &BytesReturned);
|
||||||
if (Status != MM_STATUS_SUCCESS)
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
RtlMoveMemory(MixerControl->szShortName, Name, (min(MIXER_SHORT_NAME_CHARS, wcslen(Name)+1)) * sizeof(WCHAR));
|
MixerContext->Copy(MixerControl->szShortName, Name, (min(MIXER_SHORT_NAME_CHARS, wcslen(Name)+1)) * sizeof(WCHAR));
|
||||||
MixerControl->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
|
MixerControl->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
|
||||||
|
|
||||||
RtlMoveMemory(MixerControl->szName, Name, (min(MIXER_LONG_NAME_CHARS, wcslen(Name)+1)) * sizeof(WCHAR));
|
MixerContext->Copy(MixerControl->szName, Name, (min(MIXER_LONG_NAME_CHARS, wcslen(Name)+1)) * sizeof(WCHAR));
|
||||||
MixerControl->szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
|
MixerControl->szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,10 +512,10 @@ MMixerAddMixerSourceLine(
|
||||||
|
|
||||||
if (Status != MM_STATUS_SUCCESS)
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
RtlMoveMemory(SrcLine->Line.szShortName, PinName, (min(MIXER_SHORT_NAME_CHARS, wcslen(PinName)+1)) * sizeof(WCHAR));
|
MixerContext->Copy(SrcLine->Line.szShortName, PinName, (min(MIXER_SHORT_NAME_CHARS, wcslen(PinName)+1)) * sizeof(WCHAR));
|
||||||
SrcLine->Line.szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
|
SrcLine->Line.szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
|
||||||
|
|
||||||
RtlMoveMemory(SrcLine->Line.szName, PinName, (min(MIXER_LONG_NAME_CHARS, wcslen(PinName)+1)) * sizeof(WCHAR));
|
MixerContext->Copy(SrcLine->Line.szName, PinName, (min(MIXER_LONG_NAME_CHARS, wcslen(PinName)+1)) * sizeof(WCHAR));
|
||||||
SrcLine->Line.szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
|
SrcLine->Line.szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
|
||||||
}
|
}
|
||||||
MixerContext->Free(PinName);
|
MixerContext->Free(PinName);
|
||||||
|
|
|
@ -205,3 +205,48 @@ MMixerGetControlTypeFromTopologyNode(
|
||||||
UNIMPLEMENTED
|
UNIMPLEMENTED
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MIXER_STATUS
|
||||||
|
MMixerSetGetControlDetails(
|
||||||
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN HANDLE hMixer,
|
||||||
|
IN ULONG NodeId,
|
||||||
|
IN ULONG bSet,
|
||||||
|
IN ULONG PropertyId,
|
||||||
|
IN ULONG Channel,
|
||||||
|
IN PLONG InputValue)
|
||||||
|
{
|
||||||
|
KSNODEPROPERTY_AUDIO_CHANNEL Property;
|
||||||
|
MIXER_STATUS Status;
|
||||||
|
LONG Value;
|
||||||
|
ULONG BytesReturned;
|
||||||
|
|
||||||
|
if (bSet)
|
||||||
|
Value = *InputValue;
|
||||||
|
|
||||||
|
/* setup the request */
|
||||||
|
RtlZeroMemory(&Property, sizeof(KSNODEPROPERTY_AUDIO_CHANNEL));
|
||||||
|
|
||||||
|
Property.NodeProperty.NodeId = NodeId;
|
||||||
|
Property.NodeProperty.Property.Id = PropertyId;
|
||||||
|
Property.NodeProperty.Property.Flags = KSPROPERTY_TYPE_TOPOLOGY;
|
||||||
|
Property.NodeProperty.Property.Set = KSPROPSETID_Audio;
|
||||||
|
Property.Channel = Channel;
|
||||||
|
Property.Reserved = 0;
|
||||||
|
|
||||||
|
if (bSet)
|
||||||
|
Property.NodeProperty.Property.Flags |= KSPROPERTY_TYPE_SET;
|
||||||
|
else
|
||||||
|
Property.NodeProperty.Property.Flags |= KSPROPERTY_TYPE_GET;
|
||||||
|
|
||||||
|
/* send the request */
|
||||||
|
Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSNODEPROPERTY_AUDIO_CHANNEL), (PVOID)&Value, sizeof(LONG), &BytesReturned);
|
||||||
|
|
||||||
|
if (!bSet && Status == MM_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
*InputValue = Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT("Status %x bSet %u NodeId %u Value %d PropertyId %u\n", Status, bSet, NodeId, Value, PropertyId);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
|
@ -73,11 +73,13 @@ MMixerGetCapabilities(
|
||||||
MIXER_STATUS
|
MIXER_STATUS
|
||||||
MMixerOpen(
|
MMixerOpen(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN ULONG MixerId,
|
||||||
IN PVOID MixerEvent,
|
IN PVOID MixerEvent,
|
||||||
IN PMIXER_EVENT MixerEventRoutine,
|
IN PMIXER_EVENT MixerEventRoutine,
|
||||||
OUT PHANDLE MixerHandle)
|
OUT PHANDLE MixerHandle)
|
||||||
{
|
{
|
||||||
MIXER_STATUS Status;
|
MIXER_STATUS Status;
|
||||||
|
LPMIXER_INFO MixerInfo;
|
||||||
|
|
||||||
// verify mixer context
|
// verify mixer context
|
||||||
Status = MMixerVerifyContext(MixerContext);
|
Status = MMixerVerifyContext(MixerContext);
|
||||||
|
@ -88,7 +90,20 @@ MMixerOpen(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
return MM_STATUS_NOT_IMPLEMENTED;
|
MixerInfo = (LPMIXER_INFO)MMixerGetMixerInfoByIndex(MixerContext, MixerId);
|
||||||
|
if (!MixerInfo)
|
||||||
|
{
|
||||||
|
// invalid mixer id
|
||||||
|
return MM_STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME
|
||||||
|
// handle event notification
|
||||||
|
|
||||||
|
// store result
|
||||||
|
*MixerHandle = (HANDLE)MixerInfo;
|
||||||
|
|
||||||
|
return MM_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
MIXER_STATUS
|
MIXER_STATUS
|
||||||
|
@ -99,6 +114,8 @@ MMixerGetLineInfo(
|
||||||
OUT LPMIXERLINEW MixerLine)
|
OUT LPMIXERLINEW MixerLine)
|
||||||
{
|
{
|
||||||
MIXER_STATUS Status;
|
MIXER_STATUS Status;
|
||||||
|
LPMIXER_INFO MixerInfo;
|
||||||
|
LPMIXERLINE_EXT MixerLineSrc;
|
||||||
|
|
||||||
// verify mixer context
|
// verify mixer context
|
||||||
Status = MMixerVerifyContext(MixerContext);
|
Status = MMixerVerifyContext(MixerContext);
|
||||||
|
@ -108,6 +125,88 @@ MMixerGetLineInfo(
|
||||||
// invalid context passed
|
// invalid context passed
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clear hmixer from flags
|
||||||
|
Flags &=~MIXER_OBJECTF_HMIXER;
|
||||||
|
|
||||||
|
if (Flags == MIXER_GETLINEINFOF_DESTINATION)
|
||||||
|
{
|
||||||
|
// cast to mixer info
|
||||||
|
MixerInfo = (LPMIXER_INFO)MixerHandle;
|
||||||
|
|
||||||
|
if (MixerLine->dwDestination != 0)
|
||||||
|
{
|
||||||
|
// destination line member must be zero
|
||||||
|
return MM_STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, DESTINATION_LINE);
|
||||||
|
ASSERT(MixerLineSrc);
|
||||||
|
MixerContext->Copy(MixerLine, &MixerLineSrc->Line, sizeof(MIXERLINEW));
|
||||||
|
|
||||||
|
return MM_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else if (Flags == MIXER_GETLINEINFOF_SOURCE)
|
||||||
|
{
|
||||||
|
// cast to mixer info
|
||||||
|
MixerInfo = (LPMIXER_INFO)MixerHandle;
|
||||||
|
|
||||||
|
|
||||||
|
MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, DESTINATION_LINE);
|
||||||
|
ASSERT(MixerLineSrc);
|
||||||
|
|
||||||
|
if (MixerLine->dwSource >= MixerLineSrc->Line.cConnections)
|
||||||
|
{
|
||||||
|
DPRINT1("dwSource %u > Destinations %u\n", MixerLine->dwSource, MixerLineSrc->Line.cConnections);
|
||||||
|
|
||||||
|
// invalid parameter
|
||||||
|
return MM_STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, MixerLine->dwSource);
|
||||||
|
if (MixerLineSrc)
|
||||||
|
{
|
||||||
|
DPRINT("Line %u Name %S\n", MixerLineSrc->Line.dwSource, MixerLineSrc->Line.szName);
|
||||||
|
MixerContext->Copy(MixerLine, &MixerLineSrc->Line, sizeof(MIXERLINEW));
|
||||||
|
return MM_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
return MM_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
else if (Flags == MIXER_GETLINEINFOF_LINEID)
|
||||||
|
{
|
||||||
|
// cast to mixer info
|
||||||
|
MixerInfo = (LPMIXER_INFO)MixerHandle;
|
||||||
|
|
||||||
|
MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, MixerLine->dwLineID);
|
||||||
|
if (!MixerLineSrc)
|
||||||
|
{
|
||||||
|
// invalid parameter
|
||||||
|
return MM_STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy cached data */
|
||||||
|
MixerContext->Copy(MixerLine, &MixerLineSrc->Line, sizeof(MIXERLINEW));
|
||||||
|
return MM_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else if (Flags == MIXER_GETLINEINFOF_COMPONENTTYPE)
|
||||||
|
{
|
||||||
|
// cast to mixer info
|
||||||
|
MixerInfo = (LPMIXER_INFO)MixerHandle;
|
||||||
|
|
||||||
|
MixerLineSrc = MMixerGetSourceMixerLineByComponentType(MixerInfo, MixerLine->dwComponentType);
|
||||||
|
if (!MixerLineSrc)
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to find component type %x\n", MixerLine->dwComponentType);
|
||||||
|
return MM_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(MixerLineSrc);
|
||||||
|
|
||||||
|
/* copy cached data */
|
||||||
|
MixerContext->Copy(MixerLine, &MixerLineSrc->Line, sizeof(MIXERLINEW));
|
||||||
|
return MM_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
return MM_STATUS_NOT_IMPLEMENTED;
|
return MM_STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +217,11 @@ MMixerGetLineControls(
|
||||||
IN ULONG Flags,
|
IN ULONG Flags,
|
||||||
OUT LPMIXERLINECONTROLS MixerLineControls)
|
OUT LPMIXERLINECONTROLS MixerLineControls)
|
||||||
{
|
{
|
||||||
|
LPMIXER_INFO MixerInfo;
|
||||||
|
LPMIXERLINE_EXT MixerLineSrc;
|
||||||
|
LPMIXERCONTROLW MixerControl;
|
||||||
MIXER_STATUS Status;
|
MIXER_STATUS Status;
|
||||||
|
ULONG Index;
|
||||||
|
|
||||||
// verify mixer context
|
// verify mixer context
|
||||||
Status = MMixerVerifyContext(MixerContext);
|
Status = MMixerVerifyContext(MixerContext);
|
||||||
|
@ -129,6 +232,73 @@ MMixerGetLineControls(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Flags &= ~MIXER_OBJECTF_HMIXER;
|
||||||
|
|
||||||
|
if (Flags == MIXER_GETLINECONTROLSF_ALL)
|
||||||
|
{
|
||||||
|
// cast to mixer info
|
||||||
|
MixerInfo = (LPMIXER_INFO)MixerHandle;
|
||||||
|
|
||||||
|
MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, MixerLineControls->dwLineID);
|
||||||
|
|
||||||
|
if (!MixerLineSrc)
|
||||||
|
{
|
||||||
|
// invalid line id
|
||||||
|
return MM_STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
// copy line control(s)
|
||||||
|
MixerContext->Copy(MixerLineControls->pamxctrl, MixerLineSrc->LineControls, min(MixerLineSrc->Line.cControls, MixerLineControls->cControls) * sizeof(MIXERCONTROLW));
|
||||||
|
|
||||||
|
return MM_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else if (Flags == MIXER_GETLINECONTROLSF_ONEBYTYPE)
|
||||||
|
{
|
||||||
|
// cast to mixer info
|
||||||
|
MixerInfo = (LPMIXER_INFO)MixerHandle;
|
||||||
|
|
||||||
|
MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, MixerLineControls->dwLineID);
|
||||||
|
|
||||||
|
if (!MixerLineSrc)
|
||||||
|
{
|
||||||
|
// invalid line id
|
||||||
|
return MM_STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(MixerLineSrc);
|
||||||
|
|
||||||
|
Index = 0;
|
||||||
|
for(Index = 0; Index < MixerLineSrc->Line.cControls; Index++)
|
||||||
|
{
|
||||||
|
DPRINT("dwControlType %x\n", MixerLineSrc->LineControls[Index].dwControlType);
|
||||||
|
if (MixerLineControls->dwControlType == MixerLineSrc->LineControls[Index].dwControlType)
|
||||||
|
{
|
||||||
|
// found a control with that type
|
||||||
|
MixerContext->Copy(MixerLineControls->pamxctrl, &MixerLineSrc->LineControls[Index], sizeof(MIXERCONTROLW));
|
||||||
|
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);
|
||||||
|
return MM_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
else if (Flags == MIXER_GETLINECONTROLSF_ONEBYID)
|
||||||
|
{
|
||||||
|
// cast to mixer info
|
||||||
|
MixerInfo = (LPMIXER_INFO)MixerHandle;
|
||||||
|
|
||||||
|
Status = MMixerGetMixerControlById(MixerInfo, MixerLineControls->dwControlID, NULL, &MixerControl, NULL);
|
||||||
|
|
||||||
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
// invalid parameter
|
||||||
|
return MM_STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy the controls
|
||||||
|
MixerContext->Copy(MixerLineControls->pamxctrl, MixerControl, sizeof(MIXERCONTROLW));
|
||||||
|
return MM_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return MM_STATUS_NOT_IMPLEMENTED;
|
return MM_STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,6 +310,10 @@ MMixerSetControlDetails(
|
||||||
OUT LPMIXERCONTROLDETAILS MixerControlDetails)
|
OUT LPMIXERCONTROLDETAILS MixerControlDetails)
|
||||||
{
|
{
|
||||||
MIXER_STATUS Status;
|
MIXER_STATUS Status;
|
||||||
|
ULONG NodeId;
|
||||||
|
LPMIXER_INFO MixerInfo;
|
||||||
|
LPMIXERLINE_EXT MixerLine;
|
||||||
|
LPMIXERCONTROLW MixerControl;
|
||||||
|
|
||||||
// verify mixer context
|
// verify mixer context
|
||||||
Status = MMixerVerifyContext(MixerContext);
|
Status = MMixerVerifyContext(MixerContext);
|
||||||
|
@ -149,7 +323,33 @@ MMixerSetControlDetails(
|
||||||
// invalid context passed
|
// invalid context passed
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
return MM_STATUS_NOT_IMPLEMENTED;
|
|
||||||
|
// get mixer info
|
||||||
|
MixerInfo = (LPMIXER_INFO)MixerHandle;
|
||||||
|
|
||||||
|
// get mixer control
|
||||||
|
Status = MMixerGetMixerControlById(MixerInfo, MixerControlDetails->dwControlID, &MixerLine, &MixerControl, &NodeId);
|
||||||
|
|
||||||
|
// check for success
|
||||||
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
// failed to find control id
|
||||||
|
return MM_STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(MixerControl->dwControlType)
|
||||||
|
{
|
||||||
|
case MIXERCONTROL_CONTROLTYPE_MUTE:
|
||||||
|
Status = MMixerSetGetMuteControlDetails(MixerContext, MixerInfo->hMixer, NodeId, MixerLine->Line.dwLineID, MixerControlDetails, TRUE);
|
||||||
|
break;
|
||||||
|
case MIXERCONTROL_CONTROLTYPE_VOLUME:
|
||||||
|
Status = MMixerSetGetVolumeControlDetails(MixerContext, MixerInfo->hMixer, NodeId, TRUE, MixerControl, MixerControlDetails, MixerLine);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Status = MM_STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
MIXER_STATUS
|
MIXER_STATUS
|
||||||
|
@ -160,6 +360,10 @@ MMixerGetControlDetails(
|
||||||
OUT LPMIXERCONTROLDETAILS MixerControlDetails)
|
OUT LPMIXERCONTROLDETAILS MixerControlDetails)
|
||||||
{
|
{
|
||||||
MIXER_STATUS Status;
|
MIXER_STATUS Status;
|
||||||
|
ULONG NodeId;
|
||||||
|
LPMIXER_INFO MixerInfo;
|
||||||
|
LPMIXERLINE_EXT MixerLine;
|
||||||
|
LPMIXERCONTROLW MixerControl;
|
||||||
|
|
||||||
// verify mixer context
|
// verify mixer context
|
||||||
Status = MMixerVerifyContext(MixerContext);
|
Status = MMixerVerifyContext(MixerContext);
|
||||||
|
@ -170,7 +374,32 @@ MMixerGetControlDetails(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
return MM_STATUS_NOT_IMPLEMENTED;
|
// get mixer info
|
||||||
|
MixerInfo = (LPMIXER_INFO)MixerHandle;
|
||||||
|
|
||||||
|
// get mixer control
|
||||||
|
Status = MMixerGetMixerControlById(MixerInfo, MixerControlDetails->dwControlID, &MixerLine, &MixerControl, &NodeId);
|
||||||
|
|
||||||
|
// check for success
|
||||||
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
// failed to find control id
|
||||||
|
return MM_STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(MixerControl->dwControlType)
|
||||||
|
{
|
||||||
|
case MIXERCONTROL_CONTROLTYPE_MUTE:
|
||||||
|
Status = MMixerSetGetMuteControlDetails(MixerContext, MixerInfo->hMixer, NodeId, MixerLine->Line.dwLineID, MixerControlDetails, FALSE);
|
||||||
|
break;
|
||||||
|
case MIXERCONTROL_CONTROLTYPE_VOLUME:
|
||||||
|
Status = MMixerSetGetVolumeControlDetails(MixerContext, MixerInfo->hMixer, NodeId, FALSE, MixerControl, MixerControlDetails, MixerLine);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Status = MM_STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
MIXER_STATUS
|
MIXER_STATUS
|
||||||
|
|
|
@ -47,6 +47,11 @@ typedef MIXER_STATUS(*PMIXER_CLOSE)(
|
||||||
typedef VOID (*PMIXER_EVENT)(
|
typedef VOID (*PMIXER_EVENT)(
|
||||||
IN PVOID MixerEvent);
|
IN PVOID MixerEvent);
|
||||||
|
|
||||||
|
typedef VOID (*PMIXER_COPY)(
|
||||||
|
IN PVOID Dst,
|
||||||
|
IN PVOID Src,
|
||||||
|
IN ULONG Length);
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -58,6 +63,7 @@ typedef struct
|
||||||
PMIXER_FREE Free;
|
PMIXER_FREE Free;
|
||||||
PMIXER_OPEN Open;
|
PMIXER_OPEN Open;
|
||||||
PMIXER_CLOSE Close;
|
PMIXER_CLOSE Close;
|
||||||
|
PMIXER_COPY Copy;
|
||||||
}MIXER_CONTEXT, *PMIXER_CONTEXT;
|
}MIXER_CONTEXT, *PMIXER_CONTEXT;
|
||||||
|
|
||||||
MIXER_STATUS
|
MIXER_STATUS
|
||||||
|
@ -79,6 +85,7 @@ MMixerGetCapabilities(
|
||||||
MIXER_STATUS
|
MIXER_STATUS
|
||||||
MMixerOpen(
|
MMixerOpen(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN ULONG MixerId,
|
||||||
IN PVOID MixerEvent,
|
IN PVOID MixerEvent,
|
||||||
IN PMIXER_EVENT MixerEventRoutine,
|
IN PMIXER_EVENT MixerEventRoutine,
|
||||||
OUT PHANDLE MixerHandle);
|
OUT PHANDLE MixerHandle);
|
||||||
|
|
|
@ -164,5 +164,46 @@ MMixerGetMixerInfoByIndex(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
IN ULONG MixerIndex);
|
IN ULONG MixerIndex);
|
||||||
|
|
||||||
|
LPMIXERLINE_EXT
|
||||||
|
MMixerGetSourceMixerLineByComponentType(
|
||||||
|
LPMIXER_INFO MixerInfo,
|
||||||
|
DWORD dwComponentType);
|
||||||
|
|
||||||
|
MIXER_STATUS
|
||||||
|
MMixerGetMixerControlById(
|
||||||
|
LPMIXER_INFO MixerInfo,
|
||||||
|
DWORD dwControlID,
|
||||||
|
LPMIXERLINE_EXT *MixerLine,
|
||||||
|
LPMIXERCONTROLW *MixerControl,
|
||||||
|
PULONG NodeId);
|
||||||
|
|
||||||
|
MIXER_STATUS
|
||||||
|
MMixerSetGetMuteControlDetails(
|
||||||
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN HANDLE hMixer,
|
||||||
|
IN ULONG NodeId,
|
||||||
|
IN ULONG dwLineID,
|
||||||
|
IN LPMIXERCONTROLDETAILS MixerControlDetails,
|
||||||
|
IN ULONG bSet);
|
||||||
|
|
||||||
|
MIXER_STATUS
|
||||||
|
MMixerSetGetVolumeControlDetails(
|
||||||
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN HANDLE hMixer,
|
||||||
|
IN ULONG NodeId,
|
||||||
|
IN ULONG bSet,
|
||||||
|
LPMIXERCONTROLW MixerControl,
|
||||||
|
IN LPMIXERCONTROLDETAILS MixerControlDetails,
|
||||||
|
LPMIXERLINE_EXT MixerLine);
|
||||||
|
|
||||||
|
MIXER_STATUS
|
||||||
|
MMixerSetGetControlDetails(
|
||||||
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN HANDLE hMixer,
|
||||||
|
IN ULONG NodeId,
|
||||||
|
IN ULONG bSet,
|
||||||
|
IN ULONG PropertyId,
|
||||||
|
IN ULONG Channel,
|
||||||
|
IN PLONG InputValue);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -71,6 +71,28 @@ 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(
|
||||||
|
@ -314,3 +336,190 @@ MMixerGetTargetPins(
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LPMIXERLINE_EXT
|
||||||
|
MMixerGetSourceMixerLineByComponentType(
|
||||||
|
LPMIXER_INFO MixerInfo,
|
||||||
|
DWORD dwComponentType)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY Entry;
|
||||||
|
LPMIXERLINE_EXT MixerLineSrc;
|
||||||
|
|
||||||
|
/* get first entry */
|
||||||
|
Entry = MixerInfo->LineList.Flink;
|
||||||
|
|
||||||
|
while(Entry != &MixerInfo->LineList)
|
||||||
|
{
|
||||||
|
MixerLineSrc = (LPMIXERLINE_EXT)CONTAINING_RECORD(Entry, MIXERLINE_EXT, Entry);
|
||||||
|
if (MixerLineSrc->Line.dwComponentType == dwComponentType)
|
||||||
|
return MixerLineSrc;
|
||||||
|
|
||||||
|
Entry = Entry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
MIXER_STATUS
|
||||||
|
MMixerGetMixerControlById(
|
||||||
|
LPMIXER_INFO MixerInfo,
|
||||||
|
DWORD dwControlID,
|
||||||
|
LPMIXERLINE_EXT *MixerLine,
|
||||||
|
LPMIXERCONTROLW *MixerControl,
|
||||||
|
PULONG NodeId)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY Entry;
|
||||||
|
LPMIXERLINE_EXT MixerLineSrc;
|
||||||
|
ULONG Index;
|
||||||
|
|
||||||
|
/* get first entry */
|
||||||
|
Entry = MixerInfo->LineList.Flink;
|
||||||
|
|
||||||
|
while(Entry != &MixerInfo->LineList)
|
||||||
|
{
|
||||||
|
MixerLineSrc = (LPMIXERLINE_EXT)CONTAINING_RECORD(Entry, MIXERLINE_EXT, Entry);
|
||||||
|
|
||||||
|
for(Index = 0; Index < MixerLineSrc->Line.cControls; Index++)
|
||||||
|
{
|
||||||
|
if (MixerLineSrc->LineControls[Index].dwControlID == dwControlID)
|
||||||
|
{
|
||||||
|
if (MixerLine)
|
||||||
|
*MixerLine = MixerLineSrc;
|
||||||
|
if (MixerControl)
|
||||||
|
*MixerControl = &MixerLineSrc->LineControls[Index];
|
||||||
|
if (NodeId)
|
||||||
|
*NodeId = MixerLineSrc->NodeIds[Index];
|
||||||
|
return MM_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Entry = Entry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MM_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
MMixerGetVolumeControlIndex(
|
||||||
|
LPMIXERVOLUME_DATA VolumeData,
|
||||||
|
LONG Value)
|
||||||
|
{
|
||||||
|
ULONG Index;
|
||||||
|
|
||||||
|
for(Index = 0; Index < VolumeData->ValuesCount; Index++)
|
||||||
|
{
|
||||||
|
if (VolumeData->Values[Index] > Value)
|
||||||
|
{
|
||||||
|
return VolumeData->InputSteppingDelta * Index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return VolumeData->InputSteppingDelta * (VolumeData->ValuesCount-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
MIXER_STATUS
|
||||||
|
MMixerSetGetMuteControlDetails(
|
||||||
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN HANDLE hMixer,
|
||||||
|
IN ULONG NodeId,
|
||||||
|
IN ULONG dwLineID,
|
||||||
|
IN LPMIXERCONTROLDETAILS MixerControlDetails,
|
||||||
|
IN ULONG bSet)
|
||||||
|
{
|
||||||
|
LPMIXERCONTROLDETAILS_BOOLEAN Input;
|
||||||
|
LONG Value;
|
||||||
|
MIXER_STATUS Status;
|
||||||
|
|
||||||
|
if (MixerControlDetails->cbDetails != sizeof(MIXERCONTROLDETAILS_BOOLEAN))
|
||||||
|
return MM_STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
/* get input */
|
||||||
|
Input = (LPMIXERCONTROLDETAILS_BOOLEAN)MixerControlDetails->paDetails;
|
||||||
|
|
||||||
|
/* FIXME SEH */
|
||||||
|
if (bSet)
|
||||||
|
Value = Input->fValue;
|
||||||
|
|
||||||
|
/* set control details */
|
||||||
|
Status = MMixerSetGetControlDetails(MixerContext, hMixer, NodeId, bSet, KSPROPERTY_AUDIO_MUTE, 0, &Value);
|
||||||
|
|
||||||
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
/* FIXME SEH */
|
||||||
|
if (!bSet)
|
||||||
|
{
|
||||||
|
Input->fValue = Value;
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// FIXME notify wdmaud clients MM_MIXM_LINE_CHANGE dwLineID
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
MIXER_STATUS
|
||||||
|
MMixerSetGetVolumeControlDetails(
|
||||||
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN HANDLE hMixer,
|
||||||
|
IN ULONG NodeId,
|
||||||
|
IN ULONG bSet,
|
||||||
|
LPMIXERCONTROLW MixerControl,
|
||||||
|
IN LPMIXERCONTROLDETAILS MixerControlDetails,
|
||||||
|
LPMIXERLINE_EXT MixerLine)
|
||||||
|
{
|
||||||
|
LPMIXERCONTROLDETAILS_UNSIGNED Input;
|
||||||
|
LONG Value, Index, Channel = 0;
|
||||||
|
ULONG dwValue;
|
||||||
|
MIXER_STATUS Status;
|
||||||
|
LPMIXERVOLUME_DATA VolumeData;
|
||||||
|
|
||||||
|
if (MixerControlDetails->cbDetails != sizeof(MIXERCONTROLDETAILS_SIGNED))
|
||||||
|
return MM_STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
VolumeData = (LPMIXERVOLUME_DATA)MMixerGetMixerControlDataById(&MixerLine->LineControlsExtraData, MixerControl->dwControlID);
|
||||||
|
if (!VolumeData)
|
||||||
|
return MM_STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
|
/* get input */
|
||||||
|
Input = (LPMIXERCONTROLDETAILS_UNSIGNED)MixerControlDetails->paDetails;
|
||||||
|
|
||||||
|
if (bSet)
|
||||||
|
{
|
||||||
|
/* FIXME SEH */
|
||||||
|
Value = Input->dwValue;
|
||||||
|
Index = Value / VolumeData->InputSteppingDelta;
|
||||||
|
|
||||||
|
if (Index >= VolumeData->ValuesCount)
|
||||||
|
{
|
||||||
|
DPRINT1("Index %u out of bounds %u \n", Index, VolumeData->ValuesCount);
|
||||||
|
DbgBreakPoint();
|
||||||
|
return MM_STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
Value = VolumeData->Values[Index];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set control details */
|
||||||
|
if (bSet)
|
||||||
|
{
|
||||||
|
Status = MMixerSetGetControlDetails(MixerContext, hMixer, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, 0, &Value);
|
||||||
|
Status = MMixerSetGetControlDetails(MixerContext, hMixer, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, 1, &Value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = MMixerSetGetControlDetails(MixerContext, hMixer, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, Channel, &Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bSet)
|
||||||
|
{
|
||||||
|
dwValue = MMixerGetVolumeControlIndex(VolumeData, (LONG)Value);
|
||||||
|
/* FIXME SEH */
|
||||||
|
Input->dwValue = dwValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* notify clients of a line change MM_MIXM_CONTROL_CHANGE with MixerControl->dwControlID */
|
||||||
|
}
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue