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(
MMRESULT
GetWdmDeviceCapabilities(
IN PSOUND_DEVICE SoundDevice,
+ IN DWORD DeviceId,
OUT PVOID Capabilities,
IN DWORD CapabilitiesSize)
{
ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
DeviceInfo.DeviceType = DeviceType;
- DeviceInfo.DeviceIndex = 0; //FIXME
+ DeviceInfo.DeviceIndex = DeviceId;
Result = SyncOverlappedDeviceIoControl(KernelHandle,
IOCTL_GETCAPABILITIES,
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;
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;
case WAVE_IN_DEVICE_TYPE :
{
LPWAVEINCAPS WaveInCaps = (LPWAVEINCAPS) Capabilities;
- CopyWideString(WaveInCaps->szPname, UnknownWaveIn);
+ CopyWideString(WaveInCaps->szPname, DeviceInfo.u.WaveOutCaps.szPname);
/* TODO... other fields */
break;
}
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
IN PVOID Handle)
{
+ WDMAUD_DEVICE_INFO DeviceInfo;
+ MMRESULT Result;
+ MMDEVICE_TYPE DeviceType;
+ PSOUND_DEVICE SoundDevice;
+
+ Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
+
+ if ( ! MMSUCCESS(Result) )
+ {
+ return TranslateInternalMmResult(Result);
+ }
+
if ( OpenCount == 0 )
{
return MMSYSERR_NOERROR;
SND_ASSERT( KernelHandle != INVALID_HANDLE_VALUE );
+ Result = GetSoundDeviceType(SoundDevice, &DeviceType);
+ SND_ASSERT( Result == MMSYSERR_NOERROR );
+
if (SoundDeviceInstance->Handle != (PVOID)KernelHandle)
{
- CloseHandle((HANDLE)SoundDeviceInstance->Handle);
+ ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
+
+ 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,
+ sizeof(WDMAUD_DEVICE_INFO),
+ (LPVOID) &DeviceInfo,
+ sizeof(WDMAUD_DEVICE_INFO),
+ NULL);
}
--OpenCount;
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,
+ IN DWORD DeviceId,
IN PWAVEFORMATEX WaveFormat,
IN DWORD WaveFormatSize)
{
ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
DeviceInfo.DeviceType = DeviceType;
- DeviceInfo.DeviceIndex = 0; //FIXME
+ 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,
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;
}
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);
return MMSYSERR_NOERROR;
}
+MMRESULT
+GetWdmPosition(
+ IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
+ IN MMTIME* Time)
+{
+ MMRESULT Result;
+ PSOUND_DEVICE SoundDevice;
+ WDMAUD_DEVICE_INFO DeviceInfo;
+ MMDEVICE_TYPE DeviceType;
+ HANDLE Handle;
+
+ Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
+
+ if ( ! MMSUCCESS(Result) )
+ {
+ return TranslateInternalMmResult(Result);
+ }
+
+ Result = GetSoundDeviceType(SoundDevice, &DeviceType);
+ SND_ASSERT( Result == MMSYSERR_NOERROR );
+
+ Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
+ SND_ASSERT( Result == MMSYSERR_NOERROR );
+
+ ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
+ DeviceInfo.hDevice = Handle;
+ DeviceInfo.DeviceType = DeviceType;
+
+ 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);
+ }
+
+ Time->wType = TIME_BYTES;
+ Time->u.cb = (DWORD)DeviceInfo.u.Position;
+
+ return MMSYSERR_NOERROR;
+}
+
MMRESULT
PopulateWdmDeviceList(
for ( i = 0; i < DeviceCount; ++ i )
{
- Result = ListSoundDevice(DeviceType, UlongToPtr(i), &SoundDevice);
+ Result = ListSoundDevice(DeviceType, (PVOID) i, &SoundDevice);
if ( ! MMSUCCESS(Result) )
{
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);
}
-APIENTRY LONG
+LONG
+APIENTRY
DriverProc(
DWORD DriverId,
HANDLE DriverHandle,