[WDMAUD.DRV]
[reactos.git] / reactos / dll / win32 / wdmaud.drv / wdmaud.c
index bd710a3..9b06369 100644 (file)
@@ -32,6 +32,15 @@ PWSTR UnknownMidiOut = L"Midi Output";
 HANDLE KernelHandle = INVALID_HANDLE_VALUE;
 DWORD OpenCount = 0;
 
+MMRESULT
+WriteFileEx_Remixer(
+    IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
+    IN  PVOID OffsetPtr,
+    IN  DWORD Length,
+    IN  PSOUND_OVERLAPPED Overlap,
+    IN  LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine);
+
+
 
 MMRESULT
 GetNumWdmDevs(
@@ -111,10 +120,24 @@ GetWdmDeviceCapabilities(
         return TranslateInternalMmResult(Result);
     }
 
+    SND_TRACE(L"WDMAUD Name %S\n", DeviceInfo.u.WaveOutCaps.szPname);
 
     /* This is pretty much a big hack right now */
     switch ( DeviceType )
     {
+        case MIXER_DEVICE_TYPE:
+        {
+            LPMIXERCAPS MixerCaps = (LPMIXERCAPS) Capabilities;
+
+            CopyWideString(MixerCaps->szPname, DeviceInfo.u.WaveOutCaps.szPname);
+
+            MixerCaps->cDestinations = DeviceInfo.u.MixCaps.cDestinations;
+            MixerCaps->fdwSupport = DeviceInfo.u.MixCaps.fdwSupport;
+            MixerCaps->vDriverVersion = DeviceInfo.u.MixCaps.vDriverVersion;
+            MixerCaps->wMid = DeviceInfo.u.MixCaps.wMid;
+            MixerCaps->wPid = DeviceInfo.u.MixCaps.wPid;
+            break;
+        }
         case WAVE_OUT_DEVICE_TYPE :
         {
             LPWAVEOUTCAPS WaveOutCaps = (LPWAVEOUTCAPS) Capabilities;
@@ -122,7 +145,7 @@ GetWdmDeviceCapabilities(
             WaveOutCaps->wPid = DeviceInfo.u.WaveOutCaps.wPid;
 
             WaveOutCaps->vDriverVersion = 0x0001;
-            CopyWideString(WaveOutCaps->szPname, UnknownWaveOut);
+            CopyWideString(WaveOutCaps->szPname, DeviceInfo.u.WaveOutCaps.szPname);
 
             WaveOutCaps->dwFormats = DeviceInfo.u.WaveOutCaps.dwFormats;
             WaveOutCaps->wChannels = DeviceInfo.u.WaveOutCaps.wChannels;
@@ -132,7 +155,7 @@ GetWdmDeviceCapabilities(
         case WAVE_IN_DEVICE_TYPE :
         {
             LPWAVEINCAPS WaveInCaps = (LPWAVEINCAPS) Capabilities;
-            CopyWideString(WaveInCaps->szPname, UnknownWaveIn);
+            CopyWideString(WaveInCaps->szPname, DeviceInfo.u.WaveOutCaps.szPname);
             /* TODO... other fields */
             break;
         }
@@ -205,6 +228,19 @@ CloseWdmSoundDevice(
         DeviceInfo.DeviceType = DeviceType;
         DeviceInfo.hDevice = SoundDeviceInstance->Handle;
 
+         /* First stop the stream */
+         if (DeviceType != MIXER_DEVICE_TYPE)
+         {
+             DeviceInfo.u.State = KSSTATE_STOP;
+             SyncOverlappedDeviceIoControl(KernelHandle,
+                                           IOCTL_SETDEVICE_STATE,
+                                           (LPVOID) &DeviceInfo,
+                                           sizeof(WDMAUD_DEVICE_INFO),
+                                           (LPVOID) &DeviceInfo,
+                                            sizeof(WDMAUD_DEVICE_INFO),
+                                            NULL);
+        }
+
         SyncOverlappedDeviceIoControl(KernelHandle,
                                       IOCTL_CLOSE_WDMAUD,
                                       (LPVOID) &DeviceInfo,
@@ -236,6 +272,67 @@ QueryWdmWaveDeviceFormatSupport(
     return MMSYSERR_NOERROR;
 }
 
+
+MMRESULT
+SetWdmMixerDeviceFormat(
+    IN  PSOUND_DEVICE_INSTANCE Instance,
+    IN  DWORD DeviceId,
+    IN  PWAVEFORMATEX WaveFormat,
+    IN  DWORD WaveFormatSize)
+{
+    MMRESULT Result;
+    PSOUND_DEVICE SoundDevice;
+    PVOID Identifier;
+    WDMAUD_DEVICE_INFO DeviceInfo;
+    MMDEVICE_TYPE DeviceType;
+
+    Result = GetSoundDeviceFromInstance(Instance, &SoundDevice);
+
+    if ( ! MMSUCCESS(Result) )
+    {
+        return TranslateInternalMmResult(Result);
+    }
+
+    Result = GetSoundDeviceIdentifier(SoundDevice, &Identifier);
+
+    if ( ! MMSUCCESS(Result) )
+    {
+        return TranslateInternalMmResult(Result);
+    }
+
+    if (Instance->Handle != KernelHandle)
+    {
+        /* device is already open */
+        return MMSYSERR_NOERROR;
+    }
+
+
+    Result = GetSoundDeviceType(SoundDevice, &DeviceType);
+    SND_ASSERT( Result == MMSYSERR_NOERROR );
+
+    ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
+    DeviceInfo.DeviceType = DeviceType;
+    DeviceInfo.DeviceIndex = DeviceId;
+
+    Result = SyncOverlappedDeviceIoControl(KernelHandle,
+                                           IOCTL_OPEN_WDMAUD,
+                                           (LPVOID) &DeviceInfo,
+                                           sizeof(WDMAUD_DEVICE_INFO),
+                                           (LPVOID) &DeviceInfo,
+                                           sizeof(WDMAUD_DEVICE_INFO),
+                                           NULL);
+
+    if ( ! MMSUCCESS(Result) )
+    {
+        return TranslateInternalMmResult(Result);
+    }
+
+    /* Store sound device handle instance handle */
+    Instance->Handle = (PVOID)DeviceInfo.hDevice;
+
+    return MMSYSERR_NOERROR;
+}
+
 MMRESULT
 SetWdmWaveDeviceFormat(
     IN  PSOUND_DEVICE_INSTANCE Instance,
@@ -278,11 +375,19 @@ SetWdmWaveDeviceFormat(
     DeviceInfo.DeviceIndex = DeviceId;
     DeviceInfo.u.WaveFormatEx.cbSize = WaveFormat->cbSize;
     DeviceInfo.u.WaveFormatEx.wFormatTag = WaveFormat->wFormatTag;
+#ifdef USERMODE_MIXER
+    DeviceInfo.u.WaveFormatEx.nChannels = 2;
+    DeviceInfo.u.WaveFormatEx.nSamplesPerSec = 44100;
+    DeviceInfo.u.WaveFormatEx.nBlockAlign = 4;
+    DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = 176400;
+    DeviceInfo.u.WaveFormatEx.wBitsPerSample = 16;
+#else
     DeviceInfo.u.WaveFormatEx.nChannels = WaveFormat->nChannels;
     DeviceInfo.u.WaveFormatEx.nSamplesPerSec = WaveFormat->nSamplesPerSec;
     DeviceInfo.u.WaveFormatEx.nBlockAlign = WaveFormat->nBlockAlign;
     DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = WaveFormat->nAvgBytesPerSec;
     DeviceInfo.u.WaveFormatEx.wBitsPerSample = WaveFormat->wBitsPerSample;
+#endif
 
     Result = SyncOverlappedDeviceIoControl(KernelHandle,
                                            IOCTL_OPEN_WDMAUD,
@@ -297,8 +402,47 @@ SetWdmWaveDeviceFormat(
         return TranslateInternalMmResult(Result);
     }
 
+    /* Store format */
+    Instance->WaveFormatEx.cbSize = WaveFormat->cbSize;
+    Instance->WaveFormatEx.wFormatTag = WaveFormat->wFormatTag;
+    Instance->WaveFormatEx.nChannels = WaveFormat->nChannels;
+    Instance->WaveFormatEx.nSamplesPerSec = WaveFormat->nSamplesPerSec;
+    Instance->WaveFormatEx.nBlockAlign = WaveFormat->nBlockAlign;
+    Instance->WaveFormatEx.nAvgBytesPerSec = WaveFormat->nAvgBytesPerSec;
+    Instance->WaveFormatEx.wBitsPerSample = WaveFormat->wBitsPerSample;
+
+    /* Store sound device handle instance handle */
     Instance->Handle = (PVOID)DeviceInfo.hDevice;
 
+    /* Now determine framing requirements */
+    Result = SyncOverlappedDeviceIoControl(KernelHandle,
+                                           IOCTL_GETFRAMESIZE,
+                                           (LPVOID) &DeviceInfo,
+                                           sizeof(WDMAUD_DEVICE_INFO),
+                                           (LPVOID) &DeviceInfo,
+                                           sizeof(WDMAUD_DEVICE_INFO),
+                                           NULL);
+
+    if ( MMSUCCESS(Result) )
+    {
+        if (DeviceInfo.u.FrameSize)
+        {
+            //Instance->FrameSize = DeviceInfo.u.FrameSize;
+            Instance->BufferCount = WaveFormat->nAvgBytesPerSec / Instance->FrameSize;
+            SND_TRACE(L"FrameSize %u BufferCount %u\n", Instance->FrameSize, Instance->BufferCount);
+        }
+    }
+
+    /* Now start the stream */
+    DeviceInfo.u.State = KSSTATE_RUN;
+    SyncOverlappedDeviceIoControl(KernelHandle,
+                                  IOCTL_SETDEVICE_STATE,
+                                  (LPVOID) &DeviceInfo,
+                                  sizeof(WDMAUD_DEVICE_INFO),
+                                  (LPVOID) &DeviceInfo,
+                                  sizeof(WDMAUD_DEVICE_INFO),
+                                  NULL);
+
     return MMSYSERR_NOERROR;
 }
 
@@ -324,10 +468,14 @@ WriteFileEx_Committer2(
     SND_ASSERT(Handle);
 
     ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
+    DeviceInfo.Header.FrameExtent = Length;
+    DeviceInfo.Header.DataUsed = Length;
+    DeviceInfo.Header.Data = OffsetPtr;
+    DeviceInfo.Header.Size = sizeof(KSSTREAM_HEADER);
+    DeviceInfo.Header.PresentationTime.Numerator = 1;
+    DeviceInfo.Header.PresentationTime.Denominator = 1;
     DeviceInfo.hDevice = Handle;
     DeviceInfo.DeviceType = WAVE_OUT_DEVICE_TYPE; //FIXME
-    DeviceInfo.Buffer = OffsetPtr;
-    DeviceInfo.BufferSize = Length;
 
     Overlap->Standard.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
 
@@ -431,10 +579,22 @@ PopulateWdmDeviceList(
         ZeroMemory(&FuncTable, sizeof(MMFUNCTION_TABLE));
         FuncTable.GetCapabilities = GetWdmDeviceCapabilities;
         FuncTable.QueryWaveFormatSupport = QueryWdmWaveDeviceFormatSupport;
-        FuncTable.SetWaveFormat = SetWdmWaveDeviceFormat;
+        if (DeviceType == MIXER_DEVICE_TYPE)
+        {
+            FuncTable.SetWaveFormat = SetWdmMixerDeviceFormat;
+        }
+        else
+        {
+            FuncTable.SetWaveFormat = SetWdmWaveDeviceFormat;
+        }
+
         FuncTable.Open = OpenWdmSoundDevice;
         FuncTable.Close = CloseWdmSoundDevice;
+#ifndef USERMODE_MIXER
         FuncTable.CommitWaveBuffer = WriteFileEx_Committer2;
+#else
+        FuncTable.CommitWaveBuffer = WriteFileEx_Remixer;
+#endif
         FuncTable.GetPos = GetWdmPosition;
 
         SetSoundDeviceFunctionTable(SoundDevice, &FuncTable);
@@ -445,7 +605,8 @@ PopulateWdmDeviceList(
 
 
 
-APIENTRY LONG
+LONG
+APIENTRY
 DriverProc(
     DWORD DriverId,
     HANDLE DriverHandle,