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/mmixer... ============================================================================== --- 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/wdmaud... ============================================================================== --- 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/wdmaud... ============================================================================== --- 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/wdmaud... ============================================================================== --- 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>