Author: janderwald
Date: Fri Oct 15 02:24:35 2010
New Revision: 49151
URL:
http://svn.reactos.org/svn/reactos?rev=49151&view=rev
Log:
[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
Modified:
trunk/reactos/drivers/wdm/audio/legacy/wdmaud/mmixer.c
trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h
trunk/reactos/lib/drivers/sound/mmixer/controls.c
trunk/reactos/lib/drivers/sound/mmixer/mixer.c
trunk/reactos/lib/drivers/sound/mmixer/mmixer.h
trunk/reactos/lib/drivers/sound/mmixer/priv.h
trunk/reactos/lib/drivers/sound/mmixer/sup.c
Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/mmixer.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/w…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/mmixer.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/mmixer.c [iso-8859-1] Fri Oct 15
02:24:35 2010
@@ -318,6 +318,53 @@
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 @@
}
}
- 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 @@
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));
}
Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/w…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h [iso-8859-1] Fri Oct 15
02:24:35 2010
@@ -38,6 +38,14 @@
typedef struct
{
LIST_ENTRY Entry;
+ ULONG NotificationType;
+ ULONG Value;
+ HANDLE hMixer;
+}EVENT_ENTRY, *PEVENT_ENTRY;
+
+typedef struct
+{
+ LIST_ENTRY Entry;
UNICODE_STRING SymbolicLink;
}SYSAUDIO_ENTRY, *PSYSAUDIO_ENTRY;
Modified: trunk/reactos/lib/drivers/sound/mmixer/controls.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/mmixer/c…
==============================================================================
--- trunk/reactos/lib/drivers/sound/mmixer/controls.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/sound/mmixer/controls.c [iso-8859-1] Fri Oct 15 02:24:35
2010
@@ -1086,20 +1086,22 @@
MMixerAddEvent(
IN PMIXER_CONTEXT MixerContext,
IN OUT LPMIXER_INFO MixerInfo,
- IN ULONG NodeId)
-{
- KSE_NODE Property;
- LPEVENT_ITEM EventData;
- ULONG BytesReturned;
- MIXER_STATUS Status;
-
- EventData = (LPEVENT_ITEM)MixerContext->AllocEventData(sizeof(LIST_ENTRY));
+ IN PVOID MixerEventContext,
+ IN PMIXER_EVENT MixerEventRoutine)
+{
+ //KSE_NODE Property;
+ PEVENT_NOTIFICATION_ENTRY EventData;
+ //ULONG BytesReturned;
+ //MIXER_STATUS Status;
+
+ 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 @@
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;
}
+
Modified: trunk/reactos/lib/drivers/sound/mmixer/mixer.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/mmixer/m…
==============================================================================
--- trunk/reactos/lib/drivers/sound/mmixer/mixer.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/sound/mmixer/mixer.c [iso-8859-1] Fri Oct 15 02:24:35 2010
@@ -76,7 +76,7 @@
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 @@
return Status;
}
+ /* get mixer info */
MixerInfo = (LPMIXER_INFO)MMixerGetMixerInfoByIndex(MixerContext, MixerId);
if (!MixerInfo)
{
@@ -99,11 +100,8 @@
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 @@
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;
Modified: trunk/reactos/lib/drivers/sound/mmixer/mmixer.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/mmixer/m…
==============================================================================
--- trunk/reactos/lib/drivers/sound/mmixer/mmixer.h [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/sound/mmixer/mmixer.h [iso-8859-1] Fri Oct 15 02:24:35 2010
@@ -48,7 +48,10 @@
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 @@
MMixerOpen(
IN PMIXER_CONTEXT MixerContext,
IN ULONG MixerId,
- IN PVOID MixerEvent,
+ IN PVOID MixerEventContext,
IN PMIXER_EVENT MixerEventRoutine,
OUT PHANDLE MixerHandle);
Modified: trunk/reactos/lib/drivers/sound/mmixer/priv.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/mmixer/p…
==============================================================================
--- trunk/reactos/lib/drivers/sound/mmixer/priv.h [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/sound/mmixer/priv.h [iso-8859-1] Fri Oct 15 02:24:35 2010
@@ -61,13 +61,6 @@
PTOPOLOGY_NODE TopologyNodes;
}TOPOLOGY, *PTOPOLOGY;
-
-
-typedef struct
-{
- KSEVENTDATA EventData;
- LIST_ENTRY Entry;
-}EVENT_ITEM, *LPEVENT_ITEM;
typedef struct
{
@@ -141,6 +134,14 @@
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 @@
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 @@
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 @@
IN PULONG Pins);
MIXER_STATUS
-MMixerAddEvents(
- IN PMIXER_CONTEXT MixerContext,
- IN OUT LPMIXER_INFO MixerInfo);
+MMixerAddEvent(
+ IN PMIXER_CONTEXT MixerContext,
+ IN OUT LPMIXER_INFO MixerInfo,
+ IN PVOID MixerEvent,
+ IN PMIXER_EVENT MixerEventRoutine);
/* topology.c */
Modified: trunk/reactos/lib/drivers/sound/mmixer/sup.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/mmixer/s…
==============================================================================
--- trunk/reactos/lib/drivers/sound/mmixer/sup.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/sound/mmixer/sup.c [iso-8859-1] Fri Oct 15 02:24:35 2010
@@ -233,10 +233,38 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
MixerData->hDeviceInterfaceKey = hKey;
MixerData->Topology = NULL;
-
-
InsertTailList(&MixerList->MixerData, &MixerData->Entry);
MixerList->MixerDataCount++;
return MM_STATUS_SUCCESS;