[WDMAUD.DRV]
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Sun, 13 Dec 2009 15:36:19 +0000 (15:36 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Sun, 13 Dec 2009 15:36:19 +0000 (15:36 +0000)
- Integrate mmixer library into wdmaud.drv
- Library is not yet used

svn path=/trunk/; revision=44562

reactos/dll/win32/wdmaud.drv/mmixer.c [new file with mode: 0644]
reactos/dll/win32/wdmaud.drv/wdmaud.c
reactos/dll/win32/wdmaud.drv/wdmaud.h [new file with mode: 0644]
reactos/dll/win32/wdmaud.drv/wdmaud.rbuild

diff --git a/reactos/dll/win32/wdmaud.drv/mmixer.c b/reactos/dll/win32/wdmaud.drv/mmixer.c
new file mode 100644 (file)
index 0000000..3f5fa1b
--- /dev/null
@@ -0,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;
+}
index 9d3922f..41211da 100644 (file)
  *
  */
 
-#include <windows.h>
-#include <ntddsnd.h>
-#include <sndtypes.h>
-#include <mmddk.h>
-#include <mmebuddy.h>
+#include "wdmaud.h"
 
-#include <ks.h>
-#include <ksmedia.h>
-#include "interface.h"
 
 #define KERNEL_DEVICE_NAME      L"\\\\.\\wdmaud"
 
@@ -29,6 +22,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 @@ GetNumWdmDevs(
     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 @@ GetNumWdmDevs(
     *DeviceCount = DeviceInfo.DeviceCount;
 
     return MMSYSERR_NOERROR;
+#endif
 }
 
 MMRESULT
@@ -102,6 +103,14 @@ GetWdmDeviceCapabilities(
 
     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;
     DeviceInfo.DeviceIndex = DeviceId;
@@ -250,6 +259,12 @@ CloseWdmSoundDevice(
                                             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,16 +375,21 @@ SetWdmMixerDeviceFormat(
     WDMAUD_DEVICE_INFO DeviceInfo;
     HANDLE hThread;
 
+
+    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->hNotifyEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
-    if ( ! Instance->hNotifyEvent )
-        return MMSYSERR_NOMEM;
-
     Instance->hStopEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
     if ( ! Instance->hStopEvent )
         return MMSYSERR_NOMEM;
@@ -807,6 +827,26 @@ QueryMixerInfo(
     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 @@ BOOL WINAPI DllMain(
     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 :
diff --git a/reactos/dll/win32/wdmaud.drv/wdmaud.h b/reactos/dll/win32/wdmaud.drv/wdmaud.h
new file mode 100644 (file)
index 0000000..366c17a
--- /dev/null
@@ -0,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
index c6cf6ab..a2d0ccc 100644 (file)
@@ -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 -->
        <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>