From c17e7adfbdc1651fb963bc2c5d49e7436d1e2db0 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Thu, 24 Sep 2009 18:11:22 +0000 Subject: [PATCH] [WDMAUD.DRV] - Implement opening / closing of mixer devices [AUDIO_TEST] - Add DirectKs sample test function [WDMAUD_KERNEL] - Use KSSTREAM header of the changed interface svn path=/trunk/; revision=43133 --- reactos/dll/win32/wdmaud.drv/mixer.c | 8 +- reactos/dll/win32/wdmaud.drv/wdmaud.c | 100 ++++++- .../wdm/audio/backpln/audio_test/audio_test.c | 248 +++++++++++++++++- .../backpln/audio_test/audio_test.rbuild | 5 +- .../drivers/wdm/audio/legacy/wdmaud/control.c | 19 +- .../wdm/audio/legacy/wdmaud/interface.h | 7 +- .../drivers/wdm/audio/legacy/wdmaud/mixer.c | 2 + .../drivers/sound/mmebuddy/deviceinstance.c | 13 +- .../drivers/sound/mmebuddy/mixer/mxdMessage.c | 104 +++++++- 9 files changed, 468 insertions(+), 38 deletions(-) diff --git a/reactos/dll/win32/wdmaud.drv/mixer.c b/reactos/dll/win32/wdmaud.drv/mixer.c index ebb7e371059..687af373039 100644 --- a/reactos/dll/win32/wdmaud.drv/mixer.c +++ b/reactos/dll/win32/wdmaud.drv/mixer.c @@ -520,8 +520,12 @@ WriteFileEx_Remixer( ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); DeviceInfo.hDevice = Handle; DeviceInfo.DeviceType = WAVE_OUT_DEVICE_TYPE; //FIXME - DeviceInfo.Buffer = BufferOut; - DeviceInfo.BufferSize = BufferLength; + DeviceInfo.Header.FrameExtent = BufferLength; + DeviceInfo.Header.DataUsed = BufferLength; + DeviceInfo.Header.Data = BufferOut; + DeviceInfo.Header.Size = sizeof(KSSTREAM_HEADER); + DeviceInfo.Header.PresentationTime.Numerator = 1; + DeviceInfo.Header.PresentationTime.Denominator = 1; Overlap->OriginalBufferSize = Length; Overlap->OriginalCompletionRoutine = CompletionRoutine; diff --git a/reactos/dll/win32/wdmaud.drv/wdmaud.c b/reactos/dll/win32/wdmaud.drv/wdmaud.c index 8bd68e46b69..a4a0f7458d2 100644 --- a/reactos/dll/win32/wdmaud.drv/wdmaud.c +++ b/reactos/dll/win32/wdmaud.drv/wdmaud.c @@ -216,14 +216,17 @@ CloseWdmSoundDevice( DeviceInfo.hDevice = SoundDeviceInstance->Handle; /* First stop the stream */ - DeviceInfo.u.State = KSSTATE_STOP; - SyncOverlappedDeviceIoControl(KernelHandle, - IOCTL_SETDEVICE_STATE, - (LPVOID) &DeviceInfo, - sizeof(WDMAUD_DEVICE_INFO), - (LPVOID) &DeviceInfo, - sizeof(WDMAUD_DEVICE_INFO), - NULL); + 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, @@ -256,6 +259,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, @@ -350,7 +414,7 @@ SetWdmWaveDeviceFormat( { if (DeviceInfo.u.FrameSize) { - Instance->FrameSize = 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); } @@ -391,10 +455,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); @@ -498,7 +566,15 @@ 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 diff --git a/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c b/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c index 609d1de13b8..e5abe66014d 100644 --- a/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c +++ b/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c @@ -1,16 +1,252 @@ #define _UNICODE #define UNICODE +#define WIN32_NO_STATUS +#define _KSDDK_ + #include #include #include #include - -#define _2pi 6.283185307179586476925286766559 - +#include +#include #include #include #include "interface.h" + +#define _2pi 6.283185307179586476925286766559 + + + +#include + + +GUID CategoryGuid = {STATIC_KSCATEGORY_AUDIO}; + + +const GUID KSPROPSETID_Pin = {0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}}; +const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +const GUID KSPROPSETID_Sysaudio = {0xCBE3FAA0L, 0xCC75, 0x11D0, {0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6}}; +const GUID KSPROPSETID_General = {0x1464EDA5L, 0x6A8F, 0x11D1, {0x9A, 0xA7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +const GUID KSINTERFACESETID_Standard = {0x1A8766A0L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +const GUID KSMEDIUMSETID_Standard = {0x4747B320L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +const GUID KSDATAFORMAT_TYPE_AUDIO = {0x73647561L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; +const GUID KSDATAFORMAT_SUBTYPE_PCM = {0x00000001L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; +const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX = {0x05589f81L, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}; + + +VOID +TestKs() +{ + SP_DEVICE_INTERFACE_DATA InterfaceData; + SP_DEVINFO_DATA DeviceData; + PSP_DEVICE_INTERFACE_DETAIL_DATA DetailData; + HDEVINFO DeviceHandle; + PKSDATAFORMAT_WAVEFORMATEX DataFormat; + PKSPIN_CONNECT PinConnect; + PKSSTREAM_HEADER Packet; + PKSPROPERTY Property; + KSSTATE State; + DWORD Length; + HANDLE FilterHandle; + HANDLE PinHandle; + PSHORT SoundBuffer; + UINT i = 0; + BOOL Result; + NTSTATUS Status; + + // + // Get a handle to KS Audio Interfaces + // + DeviceHandle = SetupDiGetClassDevs(&CategoryGuid, + NULL, + NULL, + DIGCF_DEVICEINTERFACE); //DIGCF_PRESENT + + printf("DeviceHandle %p\n", DeviceHandle); + + // + // Enumerate the first interface + // + InterfaceData.cbSize = sizeof(InterfaceData); + InterfaceData.Reserved = 0; + Result = SetupDiEnumDeviceInterfaces(DeviceHandle, + NULL, + &CategoryGuid, + 1, + &InterfaceData); + + printf("SetupDiEnumDeviceInterfaces %u Error %ld\n", Result, GetLastError()); + + // + // Get the interface details (namely the device path) + // + Length = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + MAX_PATH * sizeof(WCHAR); + DetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)HeapAlloc(GetProcessHeap(), + 0, + Length); + DetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); + DeviceData.cbSize = sizeof(DeviceData); + DeviceData.Reserved = 0; + Result = SetupDiGetDeviceInterfaceDetail(DeviceHandle, + &InterfaceData, + DetailData, + Length, + NULL, + &DeviceData); + + wprintf(L"SetupDiGetDeviceInterfaceDetail %u Path DetailData %s\n", Result, (LPWSTR)&DetailData->DevicePath[0]); + + // + // Open a handle to the device + // + FilterHandle = CreateFile(DetailData->DevicePath, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + + printf("Handle %p\n", FilterHandle); + + // + // Close the interface handle and clean up + // + SetupDiDestroyDeviceInfoList(DeviceHandle); + + // + // Allocate a KS Pin Connection Request Structure + // + Length = sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT_WAVEFORMATEX); + printf("Length %ld KSPIN %u DATAFORAMT %u\n", Length, sizeof(KSPIN_CONNECT), sizeof(KSDATAFORMAT_WAVEFORMATEX)); + PinConnect = (PKSPIN_CONNECT)HeapAlloc(GetProcessHeap(), 0, Length); + DataFormat = (PKSDATAFORMAT_WAVEFORMATEX)(PinConnect + 1); + + // + // Setup the KS Pin Data + // + PinConnect->Interface.Set = KSINTERFACESETID_Standard; + PinConnect->Interface.Id = KSINTERFACE_STANDARD_STREAMING; + PinConnect->Interface.Flags = 0; + PinConnect->Medium.Set = KSMEDIUMSETID_Standard; + PinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE; + PinConnect->Medium.Flags = 0; + PinConnect->PinId = 0; + PinConnect->PinToHandle = NULL; + PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL; + PinConnect->Priority.PrioritySubClass = 1; + + // + // Setup the KS Data Format Information + // + DataFormat->WaveFormatEx.wFormatTag = WAVE_FORMAT_PCM; + DataFormat->WaveFormatEx.nChannels = 2; + DataFormat->WaveFormatEx.nSamplesPerSec = 48000; + DataFormat->WaveFormatEx.nBlockAlign = 4; + DataFormat->WaveFormatEx.nAvgBytesPerSec = 48000 * 4; + DataFormat->WaveFormatEx.wBitsPerSample = 16; + DataFormat->WaveFormatEx.cbSize = 0; + DataFormat->DataFormat.FormatSize = sizeof(KSDATAFORMAT) + + sizeof(WAVEFORMATEX); + DataFormat->DataFormat.Flags = KSDATAFORMAT_ATTRIBUTES; + DataFormat->DataFormat.Reserved = 0; + DataFormat->DataFormat.MajorFormat = KSDATAFORMAT_TYPE_AUDIO; + DataFormat->DataFormat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; + DataFormat->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX; + DataFormat->DataFormat.SampleSize = 4; + + // + // Create the pin + // + Status = KsCreatePin(FilterHandle, PinConnect, GENERIC_WRITE, &PinHandle); + + printf("PinHandle %p Status %lx\n", PinHandle, Status); + + // + // Allocate a buffer for 1 second + // + Length = 48000 * 4; + SoundBuffer = (PSHORT)HeapAlloc(GetProcessHeap(), 0, Length); + + // + // Fill the buffer with a 500 Hz sine tone + // + while (i < Length / 2) + { + // + // Generate the wave for each channel: + // Amplitude * sin( Sample * Frequency * 2PI / SamplesPerSecond ) + // + SoundBuffer[i] = 0x7FFF * sin(0.5 * (i - 1) * 500 * _2pi / 48000); + i++; + SoundBuffer[i] = 0x7FFF * sin((0.5 * i - 2) * 500 * _2pi / 48000); + i++; + } + + // + // Create and fill out the KS Stream Packet + // + Packet = (PKSSTREAM_HEADER)HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + sizeof(KSSTREAM_HEADER)); + Packet->Data = SoundBuffer; + Packet->FrameExtent = Length; + Packet->DataUsed = Length; + Packet->Size = sizeof(KSSTREAM_HEADER); + Packet->PresentationTime.Numerator = 1; + Packet->PresentationTime.Denominator = 1; + + // + // Setup a KS Property to change the state + // + Property = (PKSPROPERTY)HeapAlloc(GetProcessHeap(), 0, sizeof(KSPROPERTY)); + Property->Set = KSPROPSETID_Connection; + Property->Id = KSPROPERTY_CONNECTION_STATE; + Property->Flags = KSPROPERTY_TYPE_SET; + + // + // Change the state to run + // + State = KSSTATE_RUN; + DeviceIoControl(PinHandle, + IOCTL_KS_PROPERTY, + Property, + sizeof(KSPROPERTY), + &State, + sizeof(State), + &Length, + NULL); + + // + // Play our 1-second buffer + // + DeviceIoControl(PinHandle, + IOCTL_KS_WRITE_STREAM, + NULL, + 0, + Packet, + Packet->Size, + &Length, + NULL); + + // + // Change the state to stop + // + State = KSSTATE_STOP; + DeviceIoControl(PinHandle, + IOCTL_KS_PROPERTY, + Property, + sizeof(KSPROPERTY), + &State, + sizeof(State), + &Length, + NULL); + + CloseHandle(PinHandle); + CloseHandle(FilterHandle); +} + int __cdecl main(int argc, char* argv[]) @@ -24,6 +260,8 @@ main(int argc, char* argv[]) HANDLE hWdmAud; WDMAUD_DEVICE_INFO DeviceInfo; + TestKs(); + return 0; hWdmAud = CreateFileW(L"\\\\.\\wdmaud", GENERIC_READ | GENERIC_WRITE, @@ -139,8 +377,8 @@ main(int argc, char* argv[]) // // Play our 1-second buffer // - DeviceInfo.Buffer = (PUCHAR)SoundBuffer; - DeviceInfo.BufferSize = Length; + DeviceInfo.Header.Data = (PUCHAR)SoundBuffer; + DeviceInfo.Header.DataUsed = DeviceInfo.Header.FrameExtent = Length; Status = DeviceIoControl(hWdmAud, IOCTL_WRITEDATA, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped); if (!Status) { diff --git a/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.rbuild b/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.rbuild index 7c88d3fdba5..aac33b56743 100644 --- a/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.rbuild +++ b/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.rbuild @@ -4,8 +4,11 @@ include/reactos/libs/sound . + . kernel32 - + setupapi + libsamplerate + ksuser audio_test.c diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c index 7d4756f765f..1324462d03b 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c @@ -327,8 +327,9 @@ WdmAudControlDeviceType( if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE) { - DPRINT1("FIXME: Unsupported device type %x\n", DeviceInfo->DeviceType); - return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); + DPRINT("FIXME: Unsupported device type %x\n", DeviceInfo->DeviceType); + DeviceInfo->DeviceCount = 0; + return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); } Pin.Property.Set = KSPROPSETID_Sysaudio; @@ -393,7 +394,7 @@ WdmAudControlDeviceType( /* store result count */ DeviceInfo->DeviceCount = Result; - DPRINT1("WdmAudControlDeviceType Status %x Devices %u\n", Status, DeviceInfo->DeviceCount); + DPRINT("WdmAudControlDeviceType Status %x Devices %u\n", Status, DeviceInfo->DeviceCount); return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); } @@ -415,7 +416,7 @@ WdmAudControlDeviceState( Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); if (!NT_SUCCESS(Status)) { - DPRINT1("Error: invalid device handle provided %p\n", DeviceInfo->hDevice); + DPRINT1("Error: invalid device handle provided %p Type %x\n", DeviceInfo->hDevice, DeviceInfo->DeviceType); return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); } @@ -1037,14 +1038,14 @@ WdmAudWrite( return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); } - Packet->Header.FrameExtent = DeviceInfo->BufferSize; - Packet->Header.DataUsed = DeviceInfo->BufferSize; + Packet->Header.FrameExtent = DeviceInfo->Header.FrameExtent; + Packet->Header.DataUsed = DeviceInfo->Header.DataUsed; Packet->Header.Size = sizeof(KSSTREAM_HEADER); Packet->Header.PresentationTime.Numerator = 1; Packet->Header.PresentationTime.Denominator = 1; Packet->Irp = Irp; - Buffer = ExAllocatePool(NonPagedPool, DeviceInfo->BufferSize); + Buffer = ExAllocatePool(NonPagedPool, DeviceInfo->Header.DataUsed); if (!Buffer) { /* no memory */ @@ -1054,7 +1055,7 @@ WdmAudWrite( } Packet->Header.Data = Buffer; - Mdl = IoAllocateMdl(DeviceInfo->Buffer, DeviceInfo->BufferSize, FALSE, FALSE, FALSE); + Mdl = IoAllocateMdl(DeviceInfo->Header.Data, DeviceInfo->Header.DataUsed, FALSE, FALSE, FALSE); if (!Mdl) { /* no memory */ @@ -1096,7 +1097,7 @@ WdmAudWrite( return SetIrpIoStatus(Irp, STATUS_INSUFFICIENT_RESOURCES, 0); } - RtlMoveMemory(Buffer, SystemBuffer, DeviceInfo->BufferSize); + RtlMoveMemory(Buffer, SystemBuffer, DeviceInfo->Header.DataUsed); MmUnlockPages(Mdl); IoFreeMdl(Mdl); diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h b/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h index d3f5286b66e..0b31c7f1a5d 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h @@ -25,17 +25,18 @@ typedef enum typedef struct { + KSSTREAM_HEADER Header; SOUND_DEVICE_TYPE DeviceType; ULONG DeviceIndex; HANDLE hDevice; ULONG DeviceCount; - ULONG BufferSize; - PUCHAR Buffer; - union { + MIXERCONTROLDETAILS MixDetails; + MIXERLINECONTROLSW MixControls; + MIXERLINEW MixLine; WAVEFORMATEX WaveFormatEx; WAVEOUTCAPSW WaveOutCaps; AUXCAPSW AuxCaps; diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c b/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c index c8c239f817d..483de834659 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c @@ -238,6 +238,8 @@ WdmAudControlOpenMixer( ULONG Index; PWDMAUD_HANDLE Handels; + DPRINT("WdmAudControlOpenMixer\n"); + if (DeviceInfo->DeviceIndex >= GetNumOfMixerDevices(DeviceObject)) { /* mixer index doesnt exist */ diff --git a/reactos/lib/drivers/sound/mmebuddy/deviceinstance.c b/reactos/lib/drivers/sound/mmebuddy/deviceinstance.c index 8646e55e81a..790429ef524 100644 --- a/reactos/lib/drivers/sound/mmebuddy/deviceinstance.c +++ b/reactos/lib/drivers/sound/mmebuddy/deviceinstance.c @@ -273,12 +273,15 @@ DestroySoundDeviceInstance( return MMSYSERR_NOTSUPPORTED; } - /* Stop the streaming thread (TODO - is this for wave only?) */ - Result = DestroySoundThread(SoundDeviceInstance->Thread); - SND_ASSERT( MMSUCCESS(Result) ); /* It should succeed! */ - if ( ! MMSUCCESS(Result ) ) + /* Stop the streaming thread */ + if ( SoundDeviceInstance->Thread ) { - return TranslateInternalMmResult(Result); + Result = DestroySoundThread(SoundDeviceInstance->Thread); + SND_ASSERT( MMSUCCESS(Result) ); /* It should succeed! */ + if ( ! MMSUCCESS(Result ) ) + { + return TranslateInternalMmResult(Result); + } } /* Blank this out here */ diff --git a/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c b/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c index f4596912b05..2050dd4c1a2 100644 --- a/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c +++ b/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c @@ -15,9 +15,103 @@ #include #include - +#undef NDEBUG #include + +MMRESULT +MmeCloseMixerDevice( + IN DWORD PrivateHandle) +{ + MMRESULT Result; + PSOUND_DEVICE_INSTANCE SoundDeviceInstance; + PSOUND_DEVICE SoundDevice; + + SND_TRACE(L"Closing mixer device \n"); + + VALIDATE_MMSYS_PARAMETER( PrivateHandle ); + SoundDeviceInstance = (PSOUND_DEVICE_INSTANCE) PrivateHandle; + + if ( ! IsValidSoundDeviceInstance(SoundDeviceInstance) ) + return MMSYSERR_INVALHANDLE; + + Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice); + if ( ! MMSUCCESS(Result) ) + return TranslateInternalMmResult(Result); + + + Result = DestroySoundDeviceInstance(SoundDeviceInstance); + + return Result; +} + +MMRESULT +MmeOpenMixerDevice( + IN MMDEVICE_TYPE DeviceType, + IN DWORD DeviceId, + IN LPMIXEROPENDESC OpenParameters, + IN DWORD Flags, + OUT DWORD* PrivateHandle) +{ + MMRESULT Result; + PMMFUNCTION_TABLE FunctionTable; + PSOUND_DEVICE SoundDevice; + PSOUND_DEVICE_INSTANCE SoundDeviceInstance; + + SND_TRACE(L"Opening mixer device"); + + VALIDATE_MMSYS_PARAMETER( OpenParameters ); + + Result = GetSoundDevice(DeviceType, DeviceId, &SoundDevice); + if ( ! MMSUCCESS(Result) ) + return TranslateInternalMmResult(Result); + + /* Check that winmm gave us a private handle to fill */ + VALIDATE_MMSYS_PARAMETER( PrivateHandle ); + + /* Create a sound device instance and open the sound device */ + Result = CreateSoundDeviceInstance(SoundDevice, &SoundDeviceInstance); + if ( ! MMSUCCESS(Result) ) + return TranslateInternalMmResult(Result); + + Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable); + if ( ! MMSUCCESS(Result) ) + return TranslateInternalMmResult(Result); + + if ( ! FunctionTable->SetWaveFormat ) + return MMSYSERR_NOTSUPPORTED; + + Result = FunctionTable->SetWaveFormat(SoundDeviceInstance, DeviceId, NULL, 0); + if ( ! MMSUCCESS(Result) ) + { + /* TODO: Destroy sound instance */ + return TranslateInternalMmResult(Result); + } + + /* Store the device instance pointer in the private handle - is DWORD safe here? */ + *PrivateHandle = (DWORD) SoundDeviceInstance; + + /* Store the additional information we were given - FIXME: Need flags! */ + SetSoundDeviceInstanceMmeData(SoundDeviceInstance, + (HDRVR)OpenParameters->hmx, + OpenParameters->dwCallback, + OpenParameters->dwInstance, + Flags); + + /* Let the application know the device is open */ + ReleaseEntrypointMutex(DeviceType); +#if 0 + NotifyMmeClient(SoundDeviceInstance, + DeviceType == WAVE_OUT_DEVICE_TYPE ? WOM_OPEN : WIM_OPEN, + 0); +#endif + AcquireEntrypointMutex(DeviceType); + + SND_TRACE(L"Mixer device now open\n"); + + return MMSYSERR_NOERROR; +} + /* Standard MME driver entry-point for messages relating to mixers. */ @@ -60,11 +154,19 @@ mxdMessage( case MXDM_OPEN : { + Result = MmeOpenMixerDevice(MIXER_DEVICE_TYPE, + DeviceId, + (LPMIXEROPENDESC) Parameter1, + Parameter2, + (DWORD*) PrivateHandle); + break; } case MXDM_CLOSE : { + Result = MmeCloseMixerDevice(PrivateHandle); + break; }