*
*/
-#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"
PWSTR UnknownMidiIn = L"Midi Input";
PWSTR UnknownMidiOut = L"Midi Output";
+
HANDLE KernelHandle = INVALID_HANDLE_VALUE;
DWORD OpenCount = 0;
IN MMDEVICE_TYPE DeviceType,
OUT DWORD* DeviceCount)
{
+#ifdef USE_MMIXER_LIB
+
+ switch(DeviceType)
+ {
+ case MIXER_DEVICE_TYPE:
+ *DeviceCount = WdmAudGetMixerCount();
+ break;
+ case WAVE_OUT_DEVICE_TYPE:
+ *DeviceCount = WdmAudGetWaveOutCount();
+ break;
+ case WAVE_IN_DEVICE_TYPE:
+ *DeviceCount = WdmAudGetWaveInCount();
+ break;
+ default:
+ *DeviceCount = 0;
+ }
+ return MMSYSERR_NOERROR;
+#else
+
MMRESULT Result;
WDMAUD_DEVICE_INFO DeviceInfo;
*DeviceCount = DeviceInfo.DeviceCount;
return MMSYSERR_NOERROR;
+#endif
}
MMRESULT
SND_TRACE(L"WDMAUD - GetWdmDeviceCapabilities DeviceType %u DeviceId %u\n", DeviceType, DeviceId);
+#ifdef USE_MMIXER_LIB
+ if (DeviceType == MIXER_DEVICE_TYPE)
+ {
+ return WdmAudGetMixerCapabilities(DeviceId, (LPMIXERCAPSW)Capabilities);
+ }
+ else if (DeviceType == WAVE_OUT_DEVICE_TYPE)
+ {
+ return WdmAudGetWaveOutCapabilities(DeviceId, (LPWAVEOUTCAPSW)Capabilities);
+ }
+ else if (DeviceType == WAVE_IN_DEVICE_TYPE)
+ {
+ return WdmAudGetWaveInCapabilities(DeviceId, (LPWAVEINCAPSW)Capabilities);
+ }
+
+#endif
+
+
ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
DeviceInfo.DeviceType = DeviceType;
DeviceInfo.DeviceIndex = DeviceId;
MixerCaps->vDriverVersion = DeviceInfo.u.MixCaps.vDriverVersion;
MixerCaps->wMid = DeviceInfo.u.MixCaps.wMid;
MixerCaps->wPid = DeviceInfo.u.MixCaps.wPid;
- break;y
+ break;
}
case WAVE_OUT_DEVICE_TYPE :
{
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,
NULL);
}
+ if (DeviceType == MIXER_DEVICE_TYPE)
+ {
+ SetEvent(SoundDeviceInstance->hStopEvent);
+ CloseHandle(SoundDeviceInstance->hStopEvent);
+ CloseHandle(SoundDeviceInstance->hNotifyEvent);
+ }
+
--OpenCount;
if ( OpenCount < 1 )
}
+
+
+
MMRESULT
SetWdmMixerDeviceFormat(
IN PSOUND_DEVICE_INSTANCE Instance,
{
MMRESULT Result;
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)
{
return MMSYSERR_NOERROR;
}
+ Instance->hStopEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
+ if ( ! Instance->hStopEvent )
+ return MMSYSERR_NOMEM;
ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
DeviceInfo.DeviceType = MIXER_DEVICE_TYPE;
DeviceInfo.DeviceIndex = DeviceId;
+ DeviceInfo.u.hNotifyEvent = Instance->hNotifyEvent;
Result = SyncOverlappedDeviceIoControl(KernelHandle,
IOCTL_OPEN_WDMAUD,
if ( ! MMSUCCESS(Result) )
{
+ CloseHandle(Instance->hNotifyEvent);
+ CloseHandle(Instance->hStopEvent);
return TranslateInternalMmResult(Result);
}
+ hThread = CreateThread(NULL, 0, MixerEventThreadRoutine, (LPVOID)Instance, 0, NULL);
+ if ( hThread )
+ {
+ CloseHandle(hThread);
+ }
+
/* Store sound device handle instance handle */
Instance->Handle = (PVOID)DeviceInfo.hDevice;
return MMSYSERR_NOERROR;
}
-
Result = GetSoundDeviceType(SoundDevice, &DeviceType);
+
+#ifdef USE_MMIXER_LIB
+ return WdmAudOpenWavePin(Instance, DeviceId, WaveFormat, DeviceType);
+#endif
+
+
SND_ASSERT( Result == MMSYSERR_NOERROR );
ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
DeviceInfo.DeviceType = DeviceType;
DeviceInfo.DeviceIndex = DeviceId;
- DeviceInfo.u.WaveFormatEx.cbSize = WaveFormat->cbSize;
+ DeviceInfo.u.WaveFormatEx.cbSize = sizeof(WAVEFORMATEX); //WaveFormat->cbSize;
DeviceInfo.u.WaveFormatEx.wFormatTag = WaveFormat->wFormatTag;
#ifdef USERMODE_MIXER
DeviceInfo.u.WaveFormatEx.nChannels = 2;
Instance->BufferCount = 100;
}
-
- /* 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);
+ if (DeviceType == WAVE_OUT_DEVICE_TYPE)
+ {
+ /* 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;
}
+
MMRESULT
-WriteFileEx_Committer2(
- IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
- IN PVOID OffsetPtr,
- IN DWORD Length,
- IN PSOUND_OVERLAPPED Overlap,
- IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine)
+SetWdmWaveState(
+ IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
+ IN BOOL bStart)
{
- HANDLE Handle;
MMRESULT Result;
- WDMAUD_DEVICE_INFO DeviceInfo;
PSOUND_DEVICE SoundDevice;
+ WDMAUD_DEVICE_INFO DeviceInfo;
MMDEVICE_TYPE DeviceType;
- BOOL Ret;
-
- VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance );
- VALIDATE_MMSYS_PARAMETER( OffsetPtr );
- VALIDATE_MMSYS_PARAMETER( Overlap );
- VALIDATE_MMSYS_PARAMETER( CompletionRoutine );
-
- GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
-
+ HANDLE Handle;
Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
Result = GetSoundDeviceType(SoundDevice, &DeviceType);
SND_ASSERT( Result == MMSYSERR_NOERROR );
- SND_ASSERT(Handle);
+ Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
+ SND_ASSERT( Result == MMSYSERR_NOERROR );
ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
+ DeviceInfo.hDevice = Handle;
+ DeviceInfo.DeviceType = DeviceType;
- DeviceInfo.Header.FrameExtent = Length;
- if (DeviceType == WAVE_OUT_DEVICE_TYPE)
+ if (bStart)
+ DeviceInfo.u.State = KSSTATE_RUN;
+ else
+ DeviceInfo.u.State = KSSTATE_PAUSE;
+ Result = SyncOverlappedDeviceIoControl(KernelHandle,
+ IOCTL_SETDEVICE_STATE,
+ (LPVOID) &DeviceInfo,
+ sizeof(WDMAUD_DEVICE_INFO),
+ (LPVOID) &DeviceInfo,
+ sizeof(WDMAUD_DEVICE_INFO),
+ NULL);
+
+ return Result;
+}
+
+MMRESULT
+GetDeviceInterfaceString(
+ IN MMDEVICE_TYPE DeviceType,
+ IN DWORD DeviceId,
+ IN LPWSTR Interface,
+ IN DWORD InterfaceLength,
+ OUT DWORD * InterfaceSize)
+{
+ WDMAUD_DEVICE_INFO DeviceInfo;
+ MMRESULT Result;
+
+ ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
+ DeviceInfo.DeviceType = DeviceType;
+ DeviceInfo.DeviceIndex = DeviceId;
+
+
+ Result = SyncOverlappedDeviceIoControl(KernelHandle,
+ IOCTL_QUERYDEVICEINTERFACESTRING,
+ (LPVOID) &DeviceInfo,
+ sizeof(WDMAUD_DEVICE_INFO),
+ (LPVOID) &DeviceInfo,
+ sizeof(WDMAUD_DEVICE_INFO),
+ NULL);
+
+
+ if ( ! MMSUCCESS(Result) )
{
- DeviceInfo.Header.DataUsed = Length;
+ return TranslateInternalMmResult(Result);
}
- DeviceInfo.Header.Data = OffsetPtr;
- DeviceInfo.Header.Size = sizeof(WDMAUD_DEVICE_INFO);
- DeviceInfo.Header.PresentationTime.Numerator = 1;
- DeviceInfo.Header.PresentationTime.Denominator = 1;
- DeviceInfo.hDevice = Handle;
- DeviceInfo.DeviceType = DeviceType;
- Overlap->Standard.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
- if (DeviceType == WAVE_OUT_DEVICE_TYPE)
+ if (!Interface)
{
- Ret = WriteFileEx(KernelHandle, &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPOVERLAPPED)Overlap, CompletionRoutine);
- if (Ret)
- WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE);
+ SND_ASSERT(InterfaceSize);
+
+ *InterfaceSize = DeviceInfo.u.Interface.DeviceInterfaceStringSize;
+ return MMSYSERR_NOERROR;
}
- else if (DeviceType == WAVE_IN_DEVICE_TYPE)
+
+ if (InterfaceLength < DeviceInfo.u.Interface.DeviceInterfaceStringSize)
{
- Ret = ReadFileEx(KernelHandle, &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPOVERLAPPED)Overlap, CompletionRoutine);
- if (Ret)
- WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE);
+ /* buffer is too small */
+ return MMSYSERR_MOREDATA;
}
- return MMSYSERR_NOERROR;
+ DeviceInfo.u.Interface.DeviceInterfaceStringSize = InterfaceLength;
+ DeviceInfo.u.Interface.DeviceInterfaceString = Interface;
+
+ Result = SyncOverlappedDeviceIoControl(KernelHandle,
+ IOCTL_QUERYDEVICEINTERFACESTRING,
+ (LPVOID) &DeviceInfo,
+ sizeof(WDMAUD_DEVICE_INFO),
+ (LPVOID) &DeviceInfo,
+ sizeof(WDMAUD_DEVICE_INFO),
+ NULL);
+
+ if ( MMSUCCESS(Result) && InterfaceLength > 2)
+ {
+ Interface[1] = L'\\';
+ Interface[InterfaceLength-1] = L'\0';
+ }
+
+ return Result;
}
MMRESULT
return MMSYSERR_NOERROR;
}
+MMRESULT
+ResetStream(
+ IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
+ IN MMDEVICE_TYPE DeviceType,
+ IN BOOLEAN bStartReset)
+{
+ MMRESULT Result;
+ HANDLE Handle;
+ WDMAUD_DEVICE_INFO DeviceInfo;
+
+ Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
+ SND_ASSERT( Result == MMSYSERR_NOERROR );
+
+ ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
+ DeviceInfo.hDevice = Handle;
+ DeviceInfo.DeviceType = DeviceType;
+ DeviceInfo.u.ResetStream = (bStartReset ? KSRESET_BEGIN : KSRESET_END);
+
+ Result = SyncOverlappedDeviceIoControl(KernelHandle,
+ IOCTL_RESET_STREAM,
+ (LPVOID) &DeviceInfo,
+ sizeof(WDMAUD_DEVICE_INFO),
+ (LPVOID) &DeviceInfo,
+ sizeof(WDMAUD_DEVICE_INFO),
+ NULL);
+ return Result;
+}
+
+
MMRESULT
QueryMixerInfo(
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
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:
break;
default:
SND_ASSERT(0);
+ return MMSYSERR_NOTSUPPORTED;
}
Result = SyncOverlappedDeviceIoControl(KernelHandle,
if ( ! MMSUCCESS(Result) )
{
- return TranslateInternalMmResult(Result);
+ return Result;
}
switch(uMsg)
for ( i = 0; i < DeviceCount; ++ i )
{
- Result = ListSoundDevice(DeviceType, (PVOID) i, &SoundDevice);
+ Result = ListSoundDevice(DeviceType, UlongToPtr(i), &SoundDevice);
if ( ! MMSUCCESS(Result) )
{
FuncTable.SetWaveFormat = SetWdmWaveDeviceFormat;
}
+ if (DeviceType == WAVE_IN_DEVICE_TYPE || DeviceType == WAVE_OUT_DEVICE_TYPE)
+ {
+ FuncTable.SetState = SetWdmWaveState;
+ FuncTable.ResetStream = ResetStream;
+ }
+
FuncTable.Open = OpenWdmSoundDevice;
FuncTable.Close = CloseWdmSoundDevice;
+ FuncTable.GetDeviceInterfaceString = GetDeviceInterfaceString;
#ifndef USERMODE_MIXER
FuncTable.CommitWaveBuffer = WriteFileEx_Committer2;
#else
if ( Handle == INVALID_HANDLE_VALUE )
{
- SND_ERR(L"Failed to open %s\n", KERNEL_DEVICE_NAME);
+ SND_ERR(L"Failed to open \\\\.\\wdmaud\n");
CleanupEntrypointMutexes();
//UnlistAllSoundDevices();
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 :