mirror of
https://github.com/reactos/reactos.git
synced 2025-07-30 22:12:05 +00:00
[WDMAUD_KERNEL]
- Implement registering event routine which gets called when a topology node (volume / mute node) changes - Implement fetching event changes [MMIXER] - Implement support routines which get called when a topology node changes its state - Volume changes / mute on/off changes should now be broadcasted again to all listening applications svn path=/trunk/; revision=49151
This commit is contained in:
parent
8a0913d231
commit
8158082c80
7 changed files with 165 additions and 75 deletions
|
@ -318,6 +318,53 @@ FreeEventData(IN PVOID EventData)
|
|||
FreeItem(Data);
|
||||
}
|
||||
|
||||
VOID
|
||||
EventCallback(
|
||||
IN PVOID MixerEventContext,
|
||||
IN HANDLE hMixer,
|
||||
IN ULONG NotificationType,
|
||||
IN ULONG Value)
|
||||
{
|
||||
PWDMAUD_CLIENT ClientInfo;
|
||||
PEVENT_ENTRY Entry;
|
||||
ULONG Index;
|
||||
|
||||
/* get client context */
|
||||
ClientInfo = (PWDMAUD_CLIENT)MixerEventContext;
|
||||
|
||||
/* now search for the mixer which originated the request */
|
||||
for(Index = 0; Index < ClientInfo->NumPins; Index++)
|
||||
{
|
||||
if (ClientInfo->hPins[Index].Handle == hMixer && ClientInfo->hPins[Index].Type == MIXER_DEVICE_TYPE)
|
||||
{
|
||||
if (ClientInfo->hPins[Index].NotifyEvent)
|
||||
{
|
||||
/* allocate event entry */
|
||||
Entry = AllocateItem(NonPagedPool, sizeof(EVENT_ENTRY));
|
||||
if (!Entry)
|
||||
{
|
||||
/* no memory */
|
||||
break;
|
||||
}
|
||||
|
||||
/* setup event entry */
|
||||
Entry->NotificationType = NotificationType;
|
||||
Entry->Value = Value;
|
||||
Entry->hMixer = hMixer;
|
||||
|
||||
/* insert entry */
|
||||
InsertTailList(&ClientInfo->MixerEventList, &Entry->Entry);
|
||||
|
||||
/* now notify the client */
|
||||
KeSetEvent(ClientInfo->hPins[Index].NotifyEvent, 0, FALSE);
|
||||
}
|
||||
/* done */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
WdmAudMixerInitialize(
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
|
@ -378,7 +425,7 @@ WdmAudControlOpenMixer(
|
|||
}
|
||||
}
|
||||
|
||||
if (MMixerOpen(&MixerContext, DeviceInfo->DeviceIndex, EventObject, NULL /* FIXME */, &hMixer) != MM_STATUS_SUCCESS)
|
||||
if (MMixerOpen(&MixerContext, DeviceInfo->DeviceIndex, ClientInfo, EventCallback, &hMixer) != MM_STATUS_SUCCESS)
|
||||
{
|
||||
ObDereferenceObject(EventObject);
|
||||
DPRINT1("Failed to open mixer\n");
|
||||
|
@ -511,7 +558,39 @@ WdmAudGetMixerEvent(
|
|||
IN PWDMAUD_DEVICE_INFO DeviceInfo,
|
||||
IN PWDMAUD_CLIENT ClientInfo)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
PLIST_ENTRY Entry;
|
||||
PEVENT_ENTRY EventEntry;
|
||||
|
||||
/* enumerate event list and check if there is a new event */
|
||||
Entry = ClientInfo->MixerEventList.Flink;
|
||||
|
||||
while(Entry != &ClientInfo->MixerEventList)
|
||||
{
|
||||
/* grab event entry */
|
||||
EventEntry = (PEVENT_ENTRY)CONTAINING_RECORD(Entry, EVENT_ENTRY, Entry);
|
||||
|
||||
if (EventEntry->hMixer == DeviceInfo->hDevice)
|
||||
{
|
||||
/* found an entry */
|
||||
DeviceInfo->u.MixerEvent.hMixer = EventEntry->hMixer;
|
||||
DeviceInfo->u.MixerEvent.NotificationType = EventEntry->NotificationType;
|
||||
DeviceInfo->u.MixerEvent.Value = EventEntry->Value;
|
||||
|
||||
/* remove entry from list */
|
||||
RemoveEntryList(&EventEntry->Entry);
|
||||
|
||||
/* free event entry */
|
||||
FreeItem(EventEntry);
|
||||
|
||||
/* done */
|
||||
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
|
||||
}
|
||||
|
||||
/* move to next */
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
|
||||
/* no event entry available */
|
||||
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, sizeof(WDMAUD_DEVICE_INFO));
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,14 @@ typedef struct
|
|||
LIST_ENTRY MixerEventList;
|
||||
}WDMAUD_CLIENT, *PWDMAUD_CLIENT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LIST_ENTRY Entry;
|
||||
ULONG NotificationType;
|
||||
ULONG Value;
|
||||
HANDLE hMixer;
|
||||
}EVENT_ENTRY, *PEVENT_ENTRY;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LIST_ENTRY Entry;
|
||||
|
|
|
@ -1086,20 +1086,22 @@ MIXER_STATUS
|
|||
MMixerAddEvent(
|
||||
IN PMIXER_CONTEXT MixerContext,
|
||||
IN OUT LPMIXER_INFO MixerInfo,
|
||||
IN ULONG NodeId)
|
||||
IN PVOID MixerEventContext,
|
||||
IN PMIXER_EVENT MixerEventRoutine)
|
||||
{
|
||||
KSE_NODE Property;
|
||||
LPEVENT_ITEM EventData;
|
||||
ULONG BytesReturned;
|
||||
MIXER_STATUS Status;
|
||||
//KSE_NODE Property;
|
||||
PEVENT_NOTIFICATION_ENTRY EventData;
|
||||
//ULONG BytesReturned;
|
||||
//MIXER_STATUS Status;
|
||||
|
||||
EventData = (LPEVENT_ITEM)MixerContext->AllocEventData(sizeof(LIST_ENTRY));
|
||||
EventData = (PEVENT_NOTIFICATION_ENTRY)MixerContext->AllocEventData(sizeof(EVENT_NOTIFICATION_ENTRY));
|
||||
if (!EventData)
|
||||
{
|
||||
/* not enough memory */
|
||||
return MM_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* setup request */
|
||||
Property.Event.Set = KSEVENTSETID_AudioControlChange;
|
||||
Property.Event.Flags = KSEVENT_TYPE_TOPOLOGY|KSEVENT_TYPE_ENABLE;
|
||||
|
@ -1115,45 +1117,14 @@ MMixerAddEvent(
|
|||
MixerContext->FreeEventData(EventData);
|
||||
return Status;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* initialize notification entry */
|
||||
EventData->MixerEventContext = MixerEventContext;
|
||||
EventData->MixerEventRoutine;
|
||||
|
||||
/* store event */
|
||||
InsertTailList(&MixerInfo->EventList, &EventData->Entry);
|
||||
return Status;
|
||||
}
|
||||
|
||||
MIXER_STATUS
|
||||
MMixerAddEvents(
|
||||
IN PMIXER_CONTEXT MixerContext,
|
||||
IN OUT LPMIXER_INFO MixerInfo)
|
||||
{
|
||||
PKSMULTIPLE_ITEM NodeTypes;
|
||||
ULONG Index;
|
||||
MIXER_STATUS Status;
|
||||
LPGUID Guid;
|
||||
|
||||
/* get filter node types */
|
||||
Status = MMixerGetFilterTopologyProperty(MixerContext, MixerInfo->hMixer, KSPROPERTY_TOPOLOGY_NODES, &NodeTypes);
|
||||
|
||||
if (Status != MM_STATUS_SUCCESS)
|
||||
{
|
||||
/* failed */
|
||||
return Status;
|
||||
}
|
||||
|
||||
for(Index = 0; Index < NodeTypes->Count; Index++)
|
||||
{
|
||||
Guid = MMixerGetNodeType(NodeTypes, Index);
|
||||
if (IsEqualGUID(&KSNODETYPE_VOLUME, Guid) || IsEqualGUID(&KSNODETYPE_MUTE, Guid))
|
||||
{
|
||||
/* add an event for volume / mute controls
|
||||
* TODO: support extra control types
|
||||
*/
|
||||
MMixerAddEvent(MixerContext, MixerInfo, Index);
|
||||
}
|
||||
}
|
||||
|
||||
/* free node types */
|
||||
MixerContext->Free(NodeTypes);
|
||||
|
||||
return MM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ MIXER_STATUS
|
|||
MMixerOpen(
|
||||
IN PMIXER_CONTEXT MixerContext,
|
||||
IN ULONG MixerId,
|
||||
IN PVOID MixerEvent,
|
||||
IN PVOID MixerEventContext,
|
||||
IN PMIXER_EVENT MixerEventRoutine,
|
||||
OUT PHANDLE MixerHandle)
|
||||
{
|
||||
|
@ -92,6 +92,7 @@ MMixerOpen(
|
|||
return Status;
|
||||
}
|
||||
|
||||
/* get mixer info */
|
||||
MixerInfo = (LPMIXER_INFO)MMixerGetMixerInfoByIndex(MixerContext, MixerId);
|
||||
if (!MixerInfo)
|
||||
{
|
||||
|
@ -99,11 +100,8 @@ MMixerOpen(
|
|||
return MM_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* FIXME
|
||||
* handle event notification
|
||||
*/
|
||||
|
||||
Status = MMixerAddEvents(MixerContext, MixerInfo);
|
||||
/* add the event */
|
||||
Status = MMixerAddEvent(MixerContext, MixerInfo, MixerEventContext, MixerEventRoutine);
|
||||
|
||||
|
||||
/* store result */
|
||||
|
@ -396,10 +394,10 @@ MMixerGetControlDetails(
|
|||
switch(MixerControl->dwControlType)
|
||||
{
|
||||
case MIXERCONTROL_CONTROLTYPE_MUTE:
|
||||
Status = MMixerSetGetMuteControlDetails(MixerContext, MixerInfo->hMixer, NodeId, MixerLine->Line.dwLineID, MixerControlDetails, FALSE);
|
||||
Status = MMixerSetGetMuteControlDetails(MixerContext, MixerInfo, NodeId, MixerLine->Line.dwLineID, MixerControlDetails, FALSE);
|
||||
break;
|
||||
case MIXERCONTROL_CONTROLTYPE_VOLUME:
|
||||
Status = MMixerSetGetVolumeControlDetails(MixerContext, MixerInfo->hMixer, NodeId, FALSE, MixerControl, MixerControlDetails, MixerLine);
|
||||
Status = MMixerSetGetVolumeControlDetails(MixerContext, MixerInfo, NodeId, FALSE, MixerControl, MixerControlDetails, MixerLine);
|
||||
break;
|
||||
default:
|
||||
Status = MM_STATUS_NOT_IMPLEMENTED;
|
||||
|
|
|
@ -48,7 +48,10 @@ typedef MIXER_STATUS(*PMIXER_CLOSEKEY)(
|
|||
IN HANDLE hKey);
|
||||
|
||||
typedef VOID (*PMIXER_EVENT)(
|
||||
IN PVOID MixerEvent);
|
||||
IN PVOID MixerEventContext,
|
||||
IN HANDLE hMixer,
|
||||
IN ULONG NotificationType,
|
||||
IN ULONG Value);
|
||||
|
||||
typedef VOID (*PMIXER_COPY)(
|
||||
IN PVOID Dst,
|
||||
|
@ -130,7 +133,7 @@ MIXER_STATUS
|
|||
MMixerOpen(
|
||||
IN PMIXER_CONTEXT MixerContext,
|
||||
IN ULONG MixerId,
|
||||
IN PVOID MixerEvent,
|
||||
IN PVOID MixerEventContext,
|
||||
IN PMIXER_EVENT MixerEventRoutine,
|
||||
OUT PHANDLE MixerHandle);
|
||||
|
||||
|
|
|
@ -62,13 +62,6 @@ typedef struct
|
|||
|
||||
}TOPOLOGY, *PTOPOLOGY;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
KSEVENTDATA EventData;
|
||||
LIST_ENTRY Entry;
|
||||
}EVENT_ITEM, *LPEVENT_ITEM;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LIST_ENTRY Entry;
|
||||
|
@ -141,6 +134,14 @@ typedef struct
|
|||
LIST_ENTRY WaveOutList;
|
||||
}MIXER_LIST, *PMIXER_LIST;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LIST_ENTRY Entry;
|
||||
PVOID MixerEventContext;
|
||||
PMIXER_EVENT MixerEventRoutine;
|
||||
|
||||
}EVENT_NOTIFICATION_ENTRY, *PEVENT_NOTIFICATION_ENTRY;
|
||||
|
||||
#define DESTINATION_LINE 0xFFFF0000
|
||||
|
||||
ULONG
|
||||
|
@ -262,7 +263,7 @@ MMixerGetMixerControlById(
|
|||
MIXER_STATUS
|
||||
MMixerSetGetMuteControlDetails(
|
||||
IN PMIXER_CONTEXT MixerContext,
|
||||
IN HANDLE hMixer,
|
||||
IN LPMIXER_INFO MixerInfo,
|
||||
IN ULONG NodeId,
|
||||
IN ULONG dwLineID,
|
||||
IN LPMIXERCONTROLDETAILS MixerControlDetails,
|
||||
|
@ -271,7 +272,7 @@ MMixerSetGetMuteControlDetails(
|
|||
MIXER_STATUS
|
||||
MMixerSetGetVolumeControlDetails(
|
||||
IN PMIXER_CONTEXT MixerContext,
|
||||
IN HANDLE hMixer,
|
||||
IN LPMIXER_INFO MixerInfo,
|
||||
IN ULONG NodeId,
|
||||
IN ULONG bSet,
|
||||
LPMIXERCONTROLW MixerControl,
|
||||
|
@ -324,9 +325,11 @@ MMixerInitializeWaveInfo(
|
|||
IN PULONG Pins);
|
||||
|
||||
MIXER_STATUS
|
||||
MMixerAddEvents(
|
||||
MMixerAddEvent(
|
||||
IN PMIXER_CONTEXT MixerContext,
|
||||
IN OUT LPMIXER_INFO MixerInfo);
|
||||
IN OUT LPMIXER_INFO MixerInfo,
|
||||
IN PVOID MixerEvent,
|
||||
IN PMIXER_EVENT MixerEventRoutine);
|
||||
|
||||
/* topology.c */
|
||||
|
||||
|
|
|
@ -233,10 +233,38 @@ MMixerGetVolumeControlIndex(
|
|||
return VolumeData->InputSteppingDelta * (VolumeData->ValuesCount-1);
|
||||
}
|
||||
|
||||
VOID
|
||||
MMixerNotifyControlChange(
|
||||
IN PMIXER_CONTEXT MixerContext,
|
||||
IN LPMIXER_INFO MixerInfo,
|
||||
IN ULONG NotificationType,
|
||||
IN ULONG Value)
|
||||
{
|
||||
PLIST_ENTRY Entry;
|
||||
PEVENT_NOTIFICATION_ENTRY NotificationEntry;
|
||||
|
||||
/* enumerate list and add a notification entry */
|
||||
Entry = MixerInfo->LineList.Flink;
|
||||
while(Entry != &MixerInfo->EventList)
|
||||
{
|
||||
/* get notification entry offset */
|
||||
NotificationEntry = (PEVENT_NOTIFICATION_ENTRY)CONTAINING_RECORD(Entry, EVENT_NOTIFICATION_ENTRY, Entry);
|
||||
|
||||
if (NotificationEntry->MixerEventRoutine)
|
||||
{
|
||||
/* now perform the callback */
|
||||
NotificationEntry->MixerEventRoutine(NotificationEntry->MixerEventContext, (HANDLE)MixerInfo, NotificationType, Value);
|
||||
}
|
||||
|
||||
/* move to next notification entry */
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
}
|
||||
|
||||
MIXER_STATUS
|
||||
MMixerSetGetMuteControlDetails(
|
||||
IN PMIXER_CONTEXT MixerContext,
|
||||
IN HANDLE hMixer,
|
||||
IN LPMIXER_INFO MixerInfo,
|
||||
IN ULONG NodeId,
|
||||
IN ULONG dwLineID,
|
||||
IN LPMIXERCONTROLDETAILS MixerControlDetails,
|
||||
|
@ -257,7 +285,7 @@ MMixerSetGetMuteControlDetails(
|
|||
Value = Input->fValue;
|
||||
|
||||
/* set control details */
|
||||
Status = MMixerSetGetControlDetails(MixerContext, hMixer, NodeId, bSet, KSPROPERTY_AUDIO_MUTE, 0, &Value);
|
||||
Status = MMixerSetGetControlDetails(MixerContext, MixerInfo->hMixer, NodeId, bSet, KSPROPERTY_AUDIO_MUTE, 0, &Value);
|
||||
|
||||
if (Status != MM_STATUS_SUCCESS)
|
||||
return Status;
|
||||
|
@ -270,7 +298,8 @@ MMixerSetGetMuteControlDetails(
|
|||
}
|
||||
else
|
||||
{
|
||||
/* FIXME notify wdmaud clients MM_MIXM_LINE_CHANGE dwLineID */
|
||||
/* notify wdmaud clients MM_MIXM_LINE_CHANGE dwLineID */
|
||||
MMixerNotifyControlChange(MixerContext, MixerInfo, MM_MIXM_LINE_CHANGE, dwLineID);
|
||||
}
|
||||
|
||||
return Status;
|
||||
|
@ -279,7 +308,7 @@ MMixerSetGetMuteControlDetails(
|
|||
MIXER_STATUS
|
||||
MMixerSetGetVolumeControlDetails(
|
||||
IN PMIXER_CONTEXT MixerContext,
|
||||
IN HANDLE hMixer,
|
||||
IN LPMIXER_INFO MixerInfo,
|
||||
IN ULONG NodeId,
|
||||
IN ULONG bSet,
|
||||
LPMIXERCONTROLW MixerControl,
|
||||
|
@ -322,12 +351,12 @@ MMixerSetGetVolumeControlDetails(
|
|||
if (bSet)
|
||||
{
|
||||
/* TODO */
|
||||
Status = MMixerSetGetControlDetails(MixerContext, hMixer, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, 0, &Value);
|
||||
Status = MMixerSetGetControlDetails(MixerContext, hMixer, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, 1, &Value);
|
||||
Status = MMixerSetGetControlDetails(MixerContext, MixerInfo->hMixer, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, 0, &Value);
|
||||
Status = MMixerSetGetControlDetails(MixerContext, MixerInfo->hMixer, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, 1, &Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = MMixerSetGetControlDetails(MixerContext, hMixer, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, Channel, &Value);
|
||||
Status = MMixerSetGetControlDetails(MixerContext, MixerInfo->hMixer, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, Channel, &Value);
|
||||
}
|
||||
|
||||
if (!bSet)
|
||||
|
@ -339,6 +368,7 @@ MMixerSetGetVolumeControlDetails(
|
|||
else
|
||||
{
|
||||
/* notify clients of a line change MM_MIXM_CONTROL_CHANGE with MixerControl->dwControlID */
|
||||
MMixerNotifyControlChange(MixerContext, MixerInfo, MM_MIXM_CONTROL_CHANGE, MixerControl->dwControlID);
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
@ -407,8 +437,6 @@ MMixerCreateMixerData(
|
|||
MixerData->hDeviceInterfaceKey = hKey;
|
||||
MixerData->Topology = NULL;
|
||||
|
||||
|
||||
|
||||
InsertTailList(&MixerList->MixerData, &MixerData->Entry);
|
||||
MixerList->MixerDataCount++;
|
||||
return MM_STATUS_SUCCESS;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue