Author: janderwald
Date: Sun Dec 13 16:36:19 2009
New Revision: 44562
URL:
http://svn.reactos.org/svn/reactos?rev=44562&view=rev
Log:
[WDMAUD.DRV]
- Integrate mmixer library into wdmaud.drv
- Library is not yet used
Added:
trunk/reactos/dll/win32/wdmaud.drv/mmixer.c (with props)
trunk/reactos/dll/win32/wdmaud.drv/wdmaud.h (with props)
Modified:
trunk/reactos/dll/win32/wdmaud.drv/wdmaud.c
trunk/reactos/dll/win32/wdmaud.drv/wdmaud.rbuild
Added: trunk/reactos/dll/win32/wdmaud.drv/mmixer.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/wdmaud.drv/mmixe…
==============================================================================
--- trunk/reactos/dll/win32/wdmaud.drv/mmixer.c (added)
+++ trunk/reactos/dll/win32/wdmaud.drv/mmixer.c [iso-8859-1] Sun Dec 13 16:36:19 2009
@@ -1,0 +1,329 @@
+/*
+ * PROJECT: ReactOS Sound System
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: dll/win32/wdmaud.drv/mmixer.c
+ *
+ * PURPOSE: WDM Audio Mixer API (User-mode part)
+ * PROGRAMMERS: Johannes Anderwald
+ */
+
+#include "wdmaud.h"
+
+
+PVOID Alloc(ULONG NumBytes);
+MIXER_STATUS Close(HANDLE hDevice);
+VOID Free(PVOID Block);
+VOID Copy(PVOID Src, PVOID Dst, ULONG NumBytes);
+MIXER_STATUS Open(IN LPWSTR DevicePath, OUT PHANDLE hDevice);
+MIXER_STATUS Control(IN HANDLE hMixer, IN ULONG dwIoControlCode, IN PVOID lpInBuffer, IN
ULONG nInBufferSize, OUT PVOID lpOutBuffer, ULONG nOutBufferSize, PULONG
lpBytesReturned);
+MIXER_STATUS Enum(IN PVOID EnumContext, IN ULONG DeviceIndex, OUT LPWSTR * DeviceName,
OUT PHANDLE OutHandle);
+
+MIXER_CONTEXT MixerContext =
+{
+ sizeof(MIXER_CONTEXT),
+ NULL,
+ Alloc,
+ Control,
+ Free,
+ Open,
+ Close,
+ Copy
+};
+
+GUID CategoryGuid = {STATIC_KSCATEGORY_AUDIO};
+
+PVOID Alloc(ULONG NumBytes)
+{
+ return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, NumBytes);
+}
+
+MIXER_STATUS
+Close(HANDLE hDevice)
+{
+ if (CloseHandle(hDevice))
+ return MM_STATUS_SUCCESS;
+ else
+ return MM_STATUS_UNSUCCESSFUL;
+}
+
+VOID
+Free(PVOID Block)
+{
+ HeapFree(GetProcessHeap(), 0, Block);
+}
+
+VOID
+Copy(PVOID Src, PVOID Dst, ULONG NumBytes)
+{
+ CopyMemory(Src, Dst, NumBytes);
+}
+
+MIXER_STATUS
+Open(
+ IN LPWSTR DevicePath,
+ OUT PHANDLE hDevice)
+{
+ DevicePath[1] = L'\\';
+ *hDevice = CreateFileW(DevicePath,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_OVERLAPPED,
+ NULL);
+ if (*hDevice == INVALID_HANDLE_VALUE)
+ {
+ return MM_STATUS_UNSUCCESSFUL;
+ }
+
+ return MM_STATUS_SUCCESS;
+}
+
+MIXER_STATUS
+Control(
+ IN HANDLE hMixer,
+ IN ULONG dwIoControlCode,
+ IN PVOID lpInBuffer,
+ IN ULONG nInBufferSize,
+ OUT PVOID lpOutBuffer,
+ ULONG nOutBufferSize,
+ PULONG lpBytesReturned)
+{
+ OVERLAPPED Overlapped;
+ BOOLEAN IoResult;
+ DWORD Transferred = 0;
+
+ /* Overlapped I/O is done here - this is used for waiting for completion */
+ ZeroMemory(&Overlapped, sizeof(OVERLAPPED));
+ Overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+
+ if ( ! Overlapped.hEvent )
+ return MM_STATUS_NO_MEMORY;
+
+ /* Talk to the device */
+ IoResult = DeviceIoControl(hMixer,
+ dwIoControlCode,
+ lpInBuffer,
+ nInBufferSize,
+ lpOutBuffer,
+ nOutBufferSize,
+ &Transferred,
+ &Overlapped);
+
+ /* If failure occurs, make sure it's not just due to the overlapped I/O */
+ if ( ! IoResult )
+ {
+ if ( GetLastError() != ERROR_IO_PENDING )
+ {
+ CloseHandle(Overlapped.hEvent);
+
+ if (GetLastError() == ERROR_MORE_DATA || GetLastError() ==
ERROR_INSUFFICIENT_BUFFER)
+ {
+ if ( lpBytesReturned )
+ *lpBytesReturned = Transferred;
+ return MM_STATUS_MORE_ENTRIES;
+ }
+
+ return MM_STATUS_UNSUCCESSFUL;
+ }
+ }
+
+ /* Wait for the I/O to complete */
+ IoResult = GetOverlappedResult(hMixer,
+ &Overlapped,
+ &Transferred,
+ TRUE);
+
+ /* Don't need this any more */
+ CloseHandle(Overlapped.hEvent);
+
+ if ( ! IoResult )
+ return MM_STATUS_UNSUCCESSFUL;
+
+ if ( lpBytesReturned )
+ *lpBytesReturned = Transferred;
+
+ return MM_STATUS_SUCCESS;
+}
+
+MIXER_STATUS
+Enum(
+ IN PVOID EnumContext,
+ IN ULONG DeviceIndex,
+ OUT LPWSTR * DeviceName,
+ OUT PHANDLE OutHandle)
+{
+ SP_DEVICE_INTERFACE_DATA InterfaceData;
+ SP_DEVINFO_DATA DeviceData;
+ PSP_DEVICE_INTERFACE_DETAIL_DATA_W DetailData;
+ BOOL Result;
+ DWORD Length;
+
+ //printf("Enum EnumContext %p DeviceIndex %lu OutHandle %p\n", EnumContext,
DeviceIndex, OutHandle);
+
+ InterfaceData.cbSize = sizeof(InterfaceData);
+ InterfaceData.Reserved = 0;
+
+ Result = SetupDiEnumDeviceInterfaces(EnumContext,
+ NULL,
+ &CategoryGuid,
+ DeviceIndex,
+ &InterfaceData);
+
+ if (!Result)
+ {
+ if (GetLastError() == ERROR_NO_MORE_ITEMS)
+ {
+ return MM_STATUS_NO_MORE_DEVICES;
+ }
+ return MM_STATUS_UNSUCCESSFUL;
+ }
+
+ Length = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) + MAX_PATH * sizeof(WCHAR);
+ DetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA_W)HeapAlloc(GetProcessHeap(),
+ 0,
+ Length);
+ DetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
+ DeviceData.cbSize = sizeof(DeviceData);
+ DeviceData.Reserved = 0;
+
+ Result = SetupDiGetDeviceInterfaceDetailW(EnumContext,
+ &InterfaceData,
+ DetailData,
+ Length,
+ NULL,
+ &DeviceData);
+
+ if (!Result)
+ {
+ return MM_STATUS_UNSUCCESSFUL;
+ }
+
+ // copy path
+ *DeviceName = (LPWSTR)&DetailData->DevicePath[0];
+ return Open(DetailData->DevicePath, OutHandle);
+}
+
+BOOL
+WdmAudInitUserModeMixer()
+{
+ HDEVINFO DeviceHandle;
+ MIXER_STATUS Status;
+
+ /* create a device list */
+ DeviceHandle = SetupDiGetClassDevs(&CategoryGuid,
+ NULL,
+ NULL,
+ DIGCF_DEVICEINTERFACE|DIGCF_PRESENT);
+
+ if (DeviceHandle == INVALID_HANDLE_VALUE)
+ {
+ /* failed to create a device list */
+ return FALSE;
+ }
+
+
+ /* initialize the mixer library */
+ Status = MMixerInitialize(&MixerContext, Enum, (PVOID)DeviceHandle);
+
+ /* free device list */
+ SetupDiDestroyDeviceInfoList(DeviceHandle);
+
+ if (Status != MM_STATUS_SUCCESS)
+ {
+ /* failed to initialize mixer library */
+ DPRINT1("Failed to initialize mixer library with %x\n", Status);
+ return FALSE;
+ }
+
+ /* completed successfully */
+ return TRUE;
+}
+
+ULONG
+WdmAudGetMixerCount()
+{
+ /* return number of mixers available */
+ return MMixerGetCount(&MixerContext);
+}
+
+MMRESULT
+WdmAudGetMixerCapabilties(
+ IN ULONG DeviceId,
+ LPMIXERCAPSW Capabilities)
+{
+ if (MMixerGetCapabilities(&MixerContext, DeviceId, Capabilities) ==
MM_STATUS_SUCCESS)
+ return MMSYSERR_NOERROR;
+
+ return MMSYSERR_BADDEVICEID;
+}
+
+MMRESULT
+WdmAudCloseMixer(
+ IN HMIXER Handle,
+ IN HANDLE hNotifyEvent)
+{
+ /* FIXME */
+ return MMSYSERR_NOERROR;
+}
+
+MMRESULT
+WdmAudOpenMixer(
+ IN PHANDLE hMixer,
+ IN ULONG DeviceId,
+ IN HANDLE hNotifyEvent)
+{
+ if (MMixerOpen(&MixerContext, DeviceId, hNotifyEvent, NULL /* FIXME */, hMixer)
== MM_STATUS_SUCCESS)
+ return MMSYSERR_NOERROR;
+
+ return MMSYSERR_BADDEVICEID;
+}
+
+MMRESULT
+WdmAudGetLineInfo(
+ IN HANDLE hMixer,
+ IN LPMIXERLINE MixLine,
+ IN ULONG Flags)
+{
+ if (MMixerGetLineInfo(&MixerContext, hMixer, Flags, MixLine) ==
MM_STATUS_SUCCESS)
+ return MMSYSERR_NOERROR;
+
+ return MMSYSERR_ERROR;
+}
+
+MMRESULT
+WdmAudGetLineControls(
+ IN HANDLE hMixer,
+ IN LPMIXERLINECONTROLSW MixControls,
+ IN ULONG Flags)
+{
+ if (MMixerGetLineControls(&MixerContext, hMixer, Flags, MixControls) ==
MM_STATUS_SUCCESS)
+ return MMSYSERR_NOERROR;
+
+ return MMSYSERR_ERROR;
+}
+
+MMRESULT
+WdmAudSetControlDetails(
+ IN HANDLE hMixer,
+ IN LPMIXERCONTROLDETAILS MixDetails,
+ IN ULONG Flags)
+{
+ if (MMixerSetControlDetails(&MixerContext, hMixer, Flags, MixDetails) ==
MM_STATUS_SUCCESS)
+ return MMSYSERR_NOERROR;
+
+ return MMSYSERR_ERROR;
+
+}
+
+MMRESULT
+WdmAudGetControlDetails(
+ IN HANDLE hMixer,
+ IN LPMIXERCONTROLDETAILS MixDetails,
+ IN ULONG Flags)
+{
+ if (MMixerGetControlDetails(&MixerContext, hMixer, Flags, MixDetails) ==
MM_STATUS_SUCCESS)
+ return MMSYSERR_NOERROR;
+
+ return MMSYSERR_ERROR;
+}
Propchange: trunk/reactos/dll/win32/wdmaud.drv/mmixer.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/dll/win32/wdmaud.drv/wdmaud.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/wdmaud.drv/wdmau…
==============================================================================
--- trunk/reactos/dll/win32/wdmaud.drv/wdmaud.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/wdmaud.drv/wdmaud.c [iso-8859-1] Sun Dec 13 16:36:19 2009
@@ -12,15 +12,8 @@
*
*/
-#include <windows.h>
-#include <ntddsnd.h>
-#include <sndtypes.h>
-#include <mmddk.h>
-#include <mmebuddy.h>
-
-#include <ks.h>
-#include <ksmedia.h>
-#include "interface.h"
+#include "wdmaud.h"
+
#define KERNEL_DEVICE_NAME L"\\\\.\\wdmaud"
@@ -28,6 +21,7 @@
PWSTR UnknownWaveOut = L"Wave Output";
PWSTR UnknownMidiIn = L"Midi Input";
PWSTR UnknownMidiOut = L"Midi Output";
+
HANDLE KernelHandle = INVALID_HANDLE_VALUE;
DWORD OpenCount = 0;
@@ -48,6 +42,12 @@
IN MMDEVICE_TYPE DeviceType,
OUT DWORD* DeviceCount)
{
+#ifdef USE_MMIXER_LIB
+
+ *DeviceCount = WdmAudGetMixerCount();
+ return MMSYSERR_NOERROR;
+#else
+
MMRESULT Result;
WDMAUD_DEVICE_INFO DeviceInfo;
@@ -76,6 +76,7 @@
*DeviceCount = DeviceInfo.DeviceCount;
return MMSYSERR_NOERROR;
+#endif
}
MMRESULT
@@ -101,6 +102,14 @@
return Result;
SND_TRACE(L"WDMAUD - GetWdmDeviceCapabilities DeviceType %u DeviceId %u\n",
DeviceType, DeviceId);
+
+#ifdef USE_MMIXER_LIB
+ if (DeviceType == MIXER_DEVICE_TYPE)
+ {
+ return WdmAudGetMixerCapabilties(DeviceId, (LPMIXERCAPSW)Capabilities);
+ }
+#endif
+
ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
DeviceInfo.DeviceType = DeviceType;
@@ -250,6 +259,12 @@
sizeof(WDMAUD_DEVICE_INFO),
NULL);
}
+#ifdef USE_MMIXER_LIB
+ if (DeviceType == MIXER_DEVICE_TYPE)
+ {
+ return WdmAudCloseMixer(SoundDeviceInstance->Handle,
SoundDeviceInstance->hNotifyEvent);
+ }
+#endif
SyncOverlappedDeviceIoControl(KernelHandle,
IOCTL_CLOSE_WDMAUD,
@@ -360,15 +375,20 @@
WDMAUD_DEVICE_INFO DeviceInfo;
HANDLE hThread;
- if (Instance->Handle != KernelHandle)
- {
- /* device is already open */
- return MMSYSERR_NOERROR;
- }
Instance->hNotifyEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
if ( ! Instance->hNotifyEvent )
return MMSYSERR_NOMEM;
+
+#ifdef USE_MMIXER_LIB
+ return WdmAudOpenMixer(&Instance->Handle, DeviceId,
Instance->hNotifyEvent);
+#endif
+
+ if (Instance->Handle != KernelHandle)
+ {
+ /* device is already open */
+ return MMSYSERR_NOERROR;
+ }
Instance->hStopEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
if ( ! Instance->hStopEvent )
@@ -807,6 +827,26 @@
MixControls = (LPMIXERLINECONTROLSW)Parameter;
MixDetails = (LPMIXERCONTROLDETAILS)Parameter;
+#ifdef USE_MMIXER_LIB
+ switch(uMsg)
+ {
+ case MXDM_GETLINEINFO:
+ return WdmAudGetLineInfo(SoundDeviceInstance->Handle, MixLine, Flags);
+ case MXDM_GETLINECONTROLS:
+ return WdmAudGetLineControls(SoundDeviceInstance->Handle, MixControls,
Flags);
+ case MXDM_SETCONTROLDETAILS:
+ return WdmAudSetControlDetails(SoundDeviceInstance->Handle, MixDetails,
Flags);
+ break;
+ case MXDM_GETCONTROLDETAILS:
+ return WdmAudGetControlDetails(SoundDeviceInstance->Handle, MixDetails,
Flags);
+ break;
+ default:
+ SND_ASSERT(0);
+ return MMSYSERR_NOTSUPPORTED;
+ }
+#endif
+
+
switch(uMsg)
{
case MXDM_GETLINEINFO:
@@ -1040,6 +1080,9 @@
switch ( fdwReason )
{
case DLL_PROCESS_ATTACH :
+#ifdef USE_MMIXER_LIB
+ WdmAudInitUserModeMixer();
+#endif
SND_TRACE(L"WDMAUD.DRV - Process attached\n");
break;
case DLL_PROCESS_DETACH :
Added: trunk/reactos/dll/win32/wdmaud.drv/wdmaud.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/wdmaud.drv/wdmau…
==============================================================================
--- trunk/reactos/dll/win32/wdmaud.drv/wdmaud.h (added)
+++ trunk/reactos/dll/win32/wdmaud.drv/wdmaud.h [iso-8859-1] Sun Dec 13 16:36:19 2009
@@ -1,0 +1,63 @@
+#ifndef WDMAUD_H__
+#define WDMAUD_H__
+
+#include <windows.h>
+#include <ntddsnd.h>
+#include <sndtypes.h>
+#include <setupapi.h>
+#include <mmddk.h>
+#include <mmebuddy.h>
+
+#include <ks.h>
+#include <ksmedia.h>
+#include "interface.h"
+#include "mmixer.h"
+#include <debug.h>
+
+BOOL
+WdmAudInitUserModeMixer();
+
+ULONG
+WdmAudGetMixerCount();
+
+MMRESULT
+WdmAudGetMixerCapabilties(
+ IN ULONG DeviceId,
+ LPMIXERCAPSW Capabilities);
+
+MMRESULT
+WdmAudCloseMixer(
+ IN HMIXER Handle,
+ IN HANDLE hNotifyEvent);
+
+MMRESULT
+WdmAudOpenMixer(
+ IN PHANDLE hMixer,
+ IN ULONG DeviceId,
+ IN HANDLE hNotifyEvent);
+
+MMRESULT
+WdmAudGetLineInfo(
+ IN HANDLE hMixer,
+ IN LPMIXERLINE MixLine,
+ IN ULONG Flags);
+
+MMRESULT
+WdmAudGetLineControls(
+ IN HANDLE hMixer,
+ IN LPMIXERLINECONTROLSW MixControls,
+ IN ULONG Flags);
+
+MMRESULT
+WdmAudSetControlDetails(
+ IN HANDLE hMixer,
+ IN LPMIXERCONTROLDETAILS MixDetails,
+ IN ULONG Flags);
+
+MMRESULT
+WdmAudGetControlDetails(
+ IN HANDLE hMixer,
+ IN LPMIXERCONTROLDETAILS MixDetails,
+ IN ULONG Flags);
+
+#endif
Propchange: trunk/reactos/dll/win32/wdmaud.drv/wdmaud.h
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/dll/win32/wdmaud.drv/wdmaud.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/wdmaud.drv/wdmau…
==============================================================================
--- trunk/reactos/dll/win32/wdmaud.drv/wdmaud.rbuild [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/wdmaud.drv/wdmaud.rbuild [iso-8859-1] Sun Dec 13 16:36:19
2009
@@ -3,6 +3,7 @@
<include base="wdmaud.drv">.</include>
<include base="ReactOS">include/reactos/libs/sound</include>
<include base="wdmaud_kernel">.</include>
+ <include base="mmixer">.</include>
<include base="libsamplerate">.</include>
<define name="NDEBUG">1</define>
<!-- <define name="USERMODE_MIXER" /> Enable this line to for
usermode mixing support -->
@@ -13,7 +14,10 @@
<library>advapi32</library>
<library>libsamplerate</library>
<library>msvcrt</library>
+ <library>mmixer</library>
+ <library>setupapi</library>
<file>wdmaud.c</file>
<file>mixer.c</file>
+ <file>mmixer.c</file>
<file>wdmaud.rc</file>
</module>