Author: janderwald
Date: Mon Dec 7 11:28:49 2009
New Revision: 44452
URL:
http://svn.reactos.org/svn/reactos?rev=44452&view=rev
Log:
- Start implementing a mixer library. The mixer library is based directly on the code in
the wdmaud driver. The purpose is to provide a generic library which can be used in
usermode (wdmaud.drv (Vista Driver Model)/ dsound) or in kernel mode. In addition, it can
be used to test mixer implementation.
Added:
trunk/reactos/lib/drivers/sound/mmixer/ (with props)
trunk/reactos/lib/drivers/sound/mmixer/mixer.c (with props)
trunk/reactos/lib/drivers/sound/mmixer/mmixer.h (with props)
trunk/reactos/lib/drivers/sound/mmixer/mmixer.rbuild (with props)
trunk/reactos/lib/drivers/sound/mmixer/priv.h (with props)
Propchange: trunk/reactos/lib/drivers/sound/mmixer/
------------------------------------------------------------------------------
--- bugtraq:logregex (added)
+++ bugtraq:logregex Mon Dec 7 11:28:49 2009
@@ -1,0 +1,2 @@
+([Ii]ssue|[Bb]ug)s? #?(\d+)(,? ?#?(\d+))*(,? ?(and |or )?#?(\d+))?
+(\d+)
Propchange: trunk/reactos/lib/drivers/sound/mmixer/
------------------------------------------------------------------------------
bugtraq:message = See issue #%BUGID% for more details.
Propchange: trunk/reactos/lib/drivers/sound/mmixer/
------------------------------------------------------------------------------
bugtraq:url =
http://www.reactos.org/bugzilla/show_bug.cgi?id=%BUGID%
Propchange: trunk/reactos/lib/drivers/sound/mmixer/
------------------------------------------------------------------------------
tsvn:logminsize = 10
Added: 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 (added)
+++ trunk/reactos/lib/drivers/sound/mmixer/mixer.c [iso-8859-1] Mon Dec 7 11:28:49 2009
@@ -1,0 +1,376 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel Streaming
+ * FILE: lib/drivers/sound/mmixer/mmixer.c
+ * PURPOSE: Mixer Handling Functions
+ * PROGRAMMER: Johannes Anderwald
+ */
+
+
+
+#include "priv.h"
+
+MIXER_STATUS
+MMixerVerifyContext(
+ IN PMIXER_CONTEXT MixerContext)
+{
+ if (MixerContext->SizeOfStruct != sizeof(MIXER_CONTEXT))
+ return MM_STATUS_INVALID_PARAMETER;
+
+ if (!MixerContext->Alloc || !MixerContext->Control || !MixerContext->Free)
+ return MM_STATUS_INVALID_PARAMETER;
+
+ if (!MixerContext->MixerContext)
+ return MM_STATUS_INVALID_PARAMETER;
+
+ return MM_STATUS_SUCCESS;
+}
+
+VOID
+MMixerFreeMixerInfo(
+ IN PMIXER_CONTEXT MixerContext,
+ IN LPMIXER_INFO MixerInfo)
+{
+ //UNIMPLEMENTED
+ // FIXME
+ // free all lines
+
+ MixerContext->Free((PVOID)MixerInfo);
+}
+
+ULONG
+MMixerGetFilterPinCount(
+ IN PMIXER_CONTEXT MixerContext,
+ IN HANDLE hMixer)
+{
+ KSPROPERTY Pin;
+ MIXER_STATUS Status;
+ ULONG NumPins, BytesReturned;
+
+ // setup property request
+ Pin.Flags = KSPROPERTY_TYPE_GET;
+ Pin.Set = KSPROPSETID_Pin;
+ Pin.Id = KSPROPERTY_PIN_CTYPES;
+
+ // query pin count
+ Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Pin,
sizeof(KSPROPERTY), (PVOID)&NumPins, sizeof(ULONG), (PULONG)&BytesReturned);
+
+ // check for success
+ if (Status != MM_STATUS_SUCCESS)
+ return 0;
+
+ return NumPins;
+}
+
+ULONG
+MMixerGetIndexOfGuid(
+ PKSMULTIPLE_ITEM MultipleItem,
+ LPCGUID NodeType)
+{
+ ULONG Index;
+ LPGUID Guid;
+
+ Guid = (LPGUID)(MultipleItem+1);
+
+ /* iterate through node type array */
+ for(Index = 0; Index < MultipleItem->Count; Index++)
+ {
+ if (IsEqualGUIDAligned(NodeType, Guid))
+ {
+ /* found matching guid */
+ return Index;
+ }
+ Guid++;
+ }
+ return MAXULONG;
+}
+
+
+MIXER_STATUS
+MMixerGetFilterTopologyProperty(
+ IN PMIXER_CONTEXT MixerContext,
+ IN HANDLE hMixer,
+ IN ULONG PropertyId,
+ OUT PKSMULTIPLE_ITEM * OutMultipleItem)
+{
+ KSPROPERTY Property;
+ PKSMULTIPLE_ITEM MultipleItem;
+ MIXER_STATUS Status;
+ ULONG BytesReturned;
+
+ // setup property request
+ Property.Id = PropertyId;
+ Property.Flags = KSPROPERTY_TYPE_GET;
+ Property.Set = KSPROPSETID_Topology;
+
+ // query for the size
+ Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Property,
sizeof(KSPROPERTY), NULL, 0, &BytesReturned);
+
+ if (Status != MM_STATUS_MORE_ENTRIES)
+ return Status;
+
+ // allocate an result buffer
+ MultipleItem = (PKSMULTIPLE_ITEM)MixerContext->Alloc(BytesReturned);
+
+ if (!MultipleItem)
+ {
+ // not enough memory
+ return MM_STATUS_NO_MEMORY;
+ }
+
+ // query again with allocated buffer
+ Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Property,
sizeof(KSPROPERTY), (PVOID)MultipleItem, BytesReturned, &BytesReturned);
+
+ if (Status != MM_STATUS_SUCCESS)
+ {
+ // failed
+ MixerContext->Free((PVOID)MultipleItem);
+ return Status;
+ }
+
+ // store result
+ *OutMultipleItem = MultipleItem;
+
+ // done
+ return Status;
+}
+
+MIXER_STATUS
+MMixerCreateDestinationLine(
+ IN PMIXER_CONTEXT MixerContext,
+ IN LPMIXER_INFO MixerInfo,
+ IN ULONG bInputMixer)
+{
+ LPMIXERLINE_EXT DestinationLine;
+
+ // allocate a mixer destination line
+ DestinationLine = (LPMIXERLINE_EXT) MixerContext->Alloc(sizeof(MIXERLINE_EXT));
+ if (!MixerInfo)
+ {
+ // no memory
+ return MM_STATUS_NO_MEMORY;
+ }
+
+ /* initialize mixer destination line */
+ DestinationLine->Line.cbStruct = sizeof(MIXERLINEW);
+ DestinationLine->Line.dwSource = MAXULONG;
+ DestinationLine->Line.dwLineID = DESTINATION_LINE;
+ DestinationLine->Line.fdwLine = MIXERLINE_LINEF_ACTIVE;
+ DestinationLine->Line.dwUser = 0;
+ DestinationLine->Line.dwComponentType = (bInputMixer == 0 ?
MIXERLINE_COMPONENTTYPE_DST_SPEAKERS : MIXERLINE_COMPONENTTYPE_DST_WAVEIN);
+ DestinationLine->Line.cChannels = 2; //FIXME
+ wcscpy(DestinationLine->Line.szShortName, L"Summe"); //FIXME
+ wcscpy(DestinationLine->Line.szName, L"Summe"); //FIXME
+ DestinationLine->Line.Target.dwType = (bInputMixer == 0 ?
MIXERLINE_TARGETTYPE_WAVEOUT : MIXERLINE_TARGETTYPE_WAVEIN);
+ DestinationLine->Line.Target.dwDeviceID = !bInputMixer;
+ DestinationLine->Line.Target.wMid = MixerInfo->MixCaps.wMid;
+ DestinationLine->Line.Target.wPid = MixerInfo->MixCaps.wPid;
+ DestinationLine->Line.Target.vDriverVersion =
MixerInfo->MixCaps.vDriverVersion;
+ wcscpy(DestinationLine->Line.Target.szPname, MixerInfo->MixCaps.szPname);
+
+
+ // insert into mixer info
+ InsertHeadList(&MixerInfo->LineList, &DestinationLine->Entry);
+
+ // done
+ return MM_STATUS_SUCCESS;
+}
+
+MIXER_STATUS
+MMixerInitializeFilter(
+ IN PMIXER_CONTEXT MixerContext,
+ IN HANDLE hMixer,
+ IN LPWSTR DeviceName,
+ IN PKSMULTIPLE_ITEM NodeTypes,
+ IN PKSMULTIPLE_ITEM NodeConnections,
+ IN ULONG PinCount,
+ IN ULONG NodeIndex,
+ IN ULONG bInputMixer)
+{
+ LPMIXER_INFO MixerInfo;
+ MIXER_STATUS Status;
+ ULONG * Pins;
+
+ // allocate a mixer info struct
+ MixerInfo = (LPMIXER_INFO) MixerContext->Alloc(sizeof(MIXER_INFO));
+ if (!MixerInfo)
+ {
+ // no memory
+ return MM_STATUS_NO_MEMORY;
+ }
+
+ // intialize mixer caps */
+ MixerInfo->MixCaps.wMid = MM_MICROSOFT; //FIXME
+ MixerInfo->MixCaps.wPid = MM_PID_UNMAPPED; //FIXME
+ MixerInfo->MixCaps.vDriverVersion = 1; //FIXME
+ MixerInfo->MixCaps.fdwSupport = 0;
+ MixerInfo->MixCaps.cDestinations = 1;
+ MixerInfo->hMixer = hMixer;
+
+ // initialize line list
+ InitializeListHead(&MixerInfo->LineList);
+
+ /* FIXME find mixer name */
+
+ Status = MMixerCreateDestinationLine(MixerContext, MixerInfo, bInputMixer);
+ if (Status != MM_STATUS_SUCCESS)
+ {
+ // failed to create destination line
+ MixerContext->Free(MixerInfo);
+ return Status;
+ }
+
+
+ // now allocate an array which will receive the indices of the pin
+ // which has a ADC / DAC nodetype in its path
+ Pins = (PULONG)MixerContext->Alloc(PinCount * sizeof(ULONG));
+
+ if (!Pins)
+ {
+ // no memory
+ MMixerFreeMixerInfo(MixerContext, MixerInfo);
+ return MM_STATUS_NO_MEMORY;
+ }
+
+
+ //UNIMPLEMENTED
+ // get target pins and find all nodes
+ return MM_STATUS_NOT_IMPLEMENTED;
+}
+
+MIXER_STATUS
+MMixerSetupFilter(
+ IN PMIXER_CONTEXT MixerContext,
+ IN HANDLE hMixer,
+ IN PULONG DeviceCount,
+ IN LPWSTR DeviceName)
+{
+ PKSMULTIPLE_ITEM NodeTypes, NodeConnections;
+ MIXER_STATUS Status;
+ ULONG PinCount;
+ ULONG NodeIndex;
+
+ // get number of pins
+ PinCount = MMixerGetFilterPinCount(MixerContext, hMixer);
+ ASSERT(PinCount);
+
+
+ // get filter node types
+ Status = MMixerGetFilterTopologyProperty(MixerContext, hMixer,
KSPROPERTY_TOPOLOGY_NODES, &NodeTypes);
+ if (Status != MM_STATUS_SUCCESS)
+ {
+ // failed
+ return Status;
+ }
+
+ // get filter node connections
+ Status = MMixerGetFilterTopologyProperty(MixerContext, hMixer,
KSPROPERTY_TOPOLOGY_CONNECTIONS, &NodeConnections);
+ if (Status != MM_STATUS_SUCCESS)
+ {
+ // failed
+ MixerContext->Free(NodeTypes);
+ return Status;
+ }
+
+ // check if the filter has an wave out node
+ NodeIndex = MMixerGetIndexOfGuid(NodeTypes, &KSNODETYPE_DAC);
+ if (NodeIndex != MAXULONG)
+ {
+ // it has
+ Status = MMixerInitializeFilter(MixerContext, hMixer, DeviceName, NodeTypes,
NodeConnections, PinCount, NodeIndex, FALSE);
+
+ // check for success
+ if (Status == MM_STATUS_SUCCESS)
+ {
+ // increment mixer count
+ (*DeviceCount)++;
+ }
+
+ }
+
+ // check if the filter has an wave in node
+ NodeIndex = MMixerGetIndexOfGuid(NodeTypes, &KSNODETYPE_ADC);
+ if (NodeIndex != MAXULONG)
+ {
+ // it has
+ Status = MMixerInitializeFilter(MixerContext, hMixer, DeviceName, NodeTypes,
NodeConnections, PinCount, NodeIndex, TRUE);
+
+ // check for success
+ if (Status == MM_STATUS_SUCCESS)
+ {
+ // increment mixer count
+ (*DeviceCount)++;
+ }
+
+ }
+
+ //free resources
+ MixerContext->Free((PVOID)NodeTypes);
+ MixerContext->Free((PVOID)NodeConnections);
+
+ // done
+ return Status;
+}
+
+
+MIXER_STATUS
+MMixerInitialize(
+ IN PMIXER_CONTEXT MixerContext,
+ IN PMIXER_ENUM EnumFunction,
+ IN PVOID EnumContext)
+{
+ MIXER_STATUS Status;
+ HANDLE hMixer;
+ ULONG DeviceIndex, Count;
+ LPWSTR DeviceName;
+
+ if (!MixerContext || !EnumFunction || !EnumContext)
+ {
+ // invalid parameter
+ return MM_STATUS_INVALID_PARAMETER;
+ }
+
+ if (!MixerContext->Alloc || !MixerContext->Control || !MixerContext->Free)
+ {
+ // invalid parameter
+ return MM_STATUS_INVALID_PARAMETER;
+ }
+
+
+ // start enumerating all available devices
+ Count = 0;
+ DeviceIndex = 0;
+
+ do
+ {
+ // enumerate a device
+ Status = EnumFunction(EnumContext, DeviceIndex, &DeviceName, &hMixer);
+
+ if (Status != MM_STATUS_SUCCESS)
+ {
+ //check error code
+ if (Status != MM_STATUS_NO_MORE_DEVICES)
+ {
+ // enumeration has failed
+ return Status;
+ }
+ // last device
+ break;
+ }
+
+
+ // increment device index
+ DeviceIndex++;
+
+ Status = MMixerSetupFilter(MixerContext, hMixer, &Count, DeviceName);
+
+ if (Status != MM_STATUS_SUCCESS)
+ break;
+
+ }while(TRUE);
+
+ // done
+ return Status;
+}
+
+
Propchange: trunk/reactos/lib/drivers/sound/mmixer/mixer.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: 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 (added)
+++ trunk/reactos/lib/drivers/sound/mmixer/mmixer.h [iso-8859-1] Mon Dec 7 11:28:49 2009
@@ -1,0 +1,108 @@
+#ifndef MIXER_H__
+#define MIXER_H__
+
+typedef enum
+{
+ MM_STATUS_SUCCESS = 0,
+ MM_STATUS_NOTINITIALIZED,
+ MM_STATUS_NOT_IMPLEMENTED,
+ MM_STATUS_NO_MORE_DEVICES,
+ MM_STATUS_MORE_ENTRIES,
+ MM_STATUS_INVALID_PARAMETER,
+ MM_STATUS_UNSUCCESSFUL,
+ MM_STATUS_NO_MEMORY
+
+
+}MIXER_STATUS;
+
+
+typedef PVOID (*PMIXER_ALLOC)(
+ IN ULONG NumberOfBytes);
+
+typedef VOID (*PMIXER_FREE)(
+ IN PVOID Block);
+
+typedef MIXER_STATUS (*PMIXER_ENUM)(
+ IN PVOID EnumContext,
+ IN ULONG DeviceIndex,
+ OUT LPWSTR * DeviceName,
+ OUT PHANDLE OutHandle);
+
+typedef MIXER_STATUS(*PMIXER_DEVICE_CONTROL)(
+ IN HANDLE hMixer,
+ IN ULONG dwIoControlCode,
+ IN PVOID lpInBuffer,
+ IN ULONG nInBufferSize,
+ OUT PVOID lpOutBuffer,
+ ULONG nOutBufferSize,
+ PULONG lpBytesReturned);
+
+
+
+typedef VOID (*PMIXER_EVENT)(
+ IN PVOID MixerEvent);
+
+
+typedef struct
+{
+ ULONG SizeOfStruct;
+ PVOID MixerContext;
+
+ PMIXER_ALLOC Alloc;
+ PMIXER_DEVICE_CONTROL Control;
+ PMIXER_FREE Free;
+}MIXER_CONTEXT, *PMIXER_CONTEXT;
+
+
+
+
+
+MIXER_STATUS
+MMixerInitialize(
+ IN PMIXER_CONTEXT MixerContext,
+ IN PMIXER_ENUM EnumFunction,
+ IN PVOID EnumContext);
+
+
+ULONG
+MMixerGetCount(
+ IN PMIXER_CONTEXT MixerContext);
+
+MIXER_STATUS
+MMixerGetCapabilities(
+ IN PMIXER_CONTEXT MixerContext,
+ IN ULONG MixerIndex,
+ OUT MIXERCAPSW MixerCaps);
+
+MIXER_STATUS
+MMixerOpen(
+ IN PMIXER_CONTEXT MixerContext,
+ IN PVOID MixerEvent,
+ IN PMIXER_EVENT MixerEventRoutine,
+ OUT PHANDLE MixerHandle);
+
+MIXER_STATUS
+MMixerGetLineInfo(
+ IN HANDLE MixerHandle,
+ IN ULONG Flags,
+ OUT LPMIXERLINEW MixerLine);
+
+MIXER_STATUS
+MMixerGetLineControls(
+ IN HANDLE MixerHandle,
+ IN ULONG Flags,
+ OUT LPMIXERLINECONTROLS MixerLineControls);
+
+MIXER_STATUS
+MMixerSetControlDetails(
+ IN HANDLE MixerHandle,
+ IN ULONG Flags,
+ OUT LPMIXERCONTROLDETAILS MixerControlDetails);
+
+MIXER_STATUS
+MMixerGetControlDetails(
+ IN HANDLE MixerHandle,
+ IN ULONG Flags,
+ OUT LPMIXERCONTROLDETAILS MixerControlDetails);
+
+#endif
Propchange: trunk/reactos/lib/drivers/sound/mmixer/mmixer.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/lib/drivers/sound/mmixer/mmixer.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/mmixer/m…
==============================================================================
--- trunk/reactos/lib/drivers/sound/mmixer/mmixer.rbuild (added)
+++ trunk/reactos/lib/drivers/sound/mmixer/mmixer.rbuild [iso-8859-1] Mon Dec 7 11:28:49
2009
@@ -1,0 +1,7 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../../tools/rbuild/project.dtd">
+<module name="mmixer" type="staticlibrary"
allowwarnings="false" unicode="yes">
+ <include base="ReactOS">include/reactos/libs/sound</include>
+ <define name="NDEBUG">1</define>
+ <file>mixer.c</file>
+</module>
Propchange: trunk/reactos/lib/drivers/sound/mmixer/mmixer.rbuild
------------------------------------------------------------------------------
svn:eol-style = native
Added: 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 (added)
+++ trunk/reactos/lib/drivers/sound/mmixer/priv.h [iso-8859-1] Mon Dec 7 11:28:49 2009
@@ -1,0 +1,38 @@
+#ifndef PRIV_H__
+#define PRIV_H__
+
+#include <pseh/pseh2.h>
+#include <ntddk.h>
+
+#include <windef.h>
+#define NOBITMAP
+#include <mmreg.h>
+#include <ks.h>
+#include <ksmedia.h>
+#include <mmreg.h>
+#include <mmsystem.h>
+
+#include "mmixer.h"
+
+typedef struct
+{
+ MIXERCAPSW MixCaps;
+ HANDLE hMixer;
+ LIST_ENTRY LineList;
+ ULONG ControlId;
+}MIXER_INFO, *LPMIXER_INFO;
+
+typedef struct
+{
+ LIST_ENTRY Entry;
+ ULONG PinId;
+ ULONG DeviceIndex;
+ MIXERLINEW Line;
+ LPMIXERCONTROLW LineControls;
+ PULONG NodeIds;
+ LIST_ENTRY LineControlsExtraData;
+}MIXERLINE_EXT, *LPMIXERLINE_EXT;
+
+#define DESTINATION_LINE 0xFFFF0000
+
+#endif
Propchange: trunk/reactos/lib/drivers/sound/mmixer/priv.h
------------------------------------------------------------------------------
svn:eol-style = native