Author: silverblade Date: Sat Jul 5 19:15:43 2008 New Revision: 34316
URL: http://svn.reactos.org/svn/reactos?rev=34316&view=rev Log: Implemented routines for querying if a particular wave format is supported by an audio device. This is done by sending IOCTL_WAVE_QUERY_FORMAT to the driver. This has been tested with the NT4 Sound Blaster driver, which return success for 22050Hz/16bit/Mono, and returns MMSYSERR_NOTSUPPORTED if the same request is then sent with a request for an abnormally high number of channels.
Modified: branches/silverblade-audio/include/reactos/libs/sound/mmebuddy.h branches/silverblade-audio/lib/drivers/sound/mmebuddy/devices.c branches/silverblade-audio/lib/drivers/sound/mmebuddy/instances.c branches/silverblade-audio/lib/drivers/sound/mmebuddy/nt4.c branches/silverblade-audio/lib/drivers/sound/mmebuddy/testing.c
Modified: branches/silverblade-audio/include/reactos/libs/sound/mmebuddy.h URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/include/reacto... ============================================================================== --- branches/silverblade-audio/include/reactos/libs/sound/mmebuddy.h [iso-8859-1] (original) +++ branches/silverblade-audio/include/reactos/libs/sound/mmebuddy.h [iso-8859-1] Sat Jul 5 19:15:43 2008 @@ -115,11 +115,17 @@ IN struct _SOUND_DEVICE* SoundDevice, OUT PUNIVERSAL_CAPS Capabilities);
+typedef MMRESULT (*MMQUERYWAVEFORMAT_FUNC)( + IN struct _SOUND_DEVICE* SoundDevice, + IN PWAVEFORMATEX WaveFormat, + IN DWORD WaveFormatSize); + typedef struct _MMFUNCTION_TABLE { - MMOPEN_FUNC Open; - MMCLOSE_FUNC Close; - MMGETCAPS_FUNC GetCapabilities; + MMOPEN_FUNC Open; + MMCLOSE_FUNC Close; + MMGETCAPS_FUNC GetCapabilities; + MMQUERYWAVEFORMAT_FUNC QueryWaveFormat; } MMFUNCTION_TABLE, *PMMFUNCTION_TABLE;
@@ -322,6 +328,18 @@ IN PSOUND_DEVICE Device, OUT PUNIVERSAL_CAPS Capabilities);
+MMRESULT +QueryWaveDeviceFormatSupport( + IN PSOUND_DEVICE Device, + IN PWAVEFORMATEX WaveFormat, + IN DWORD WaveFormatSize); + +MMRESULT +DefaultQueryWaveDeviceFormatSupport( + IN PSOUND_DEVICE Device, + IN PWAVEFORMATEX WaveFormat, + IN DWORD WaveFormatSize); +
/* thread.c
Modified: branches/silverblade-audio/lib/drivers/sound/mmebuddy/devices.c URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/so... ============================================================================== --- branches/silverblade-audio/lib/drivers/sound/mmebuddy/devices.c [iso-8859-1] (original) +++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/devices.c [iso-8859-1] Sat Jul 5 19:15:43 2008 @@ -149,6 +149,7 @@ IN PSOUND_DEVICE Device) { Device->Functions.GetCapabilities = DefaultGetSoundDeviceCapabilities; + Device->Functions.QueryWaveFormat = DefaultQueryWaveDeviceFormatSupport; }
@@ -306,28 +307,142 @@ }
- -/* Should this go somewhere else? */ +#include <ntddk.h> /* How do I avoid this? */ + +/* Should these go somewhere else? */
MMRESULT GetSoundDeviceCapabilities( - PSOUND_DEVICE SoundDevice, + PSOUND_DEVICE Device, PUNIVERSAL_CAPS Capabilities) { - if ( ! SoundDevice ) + if ( ! Device ) return MMSYSERR_INVALPARAM;
if ( ! Capabilities ) return MMSYSERR_INVALPARAM;
- return SoundDevice->Functions.GetCapabilities(SoundDevice, Capabilities); -} - -MMRESULT -IsSoundDeviceFormatSupported( - IN PSOUND_DEVICE SoundDevice /* what else? */) -{ - /* TODO */ - return MMSYSERR_NOTSUPPORTED; -} - + return Device->Functions.GetCapabilities(Device, Capabilities); +} + +MMRESULT +DefaultGetSoundDeviceCapabilities( + IN PSOUND_DEVICE Device, + OUT PUNIVERSAL_CAPS Capabilities) +{ + PVOID RawCapsPtr = NULL; + ULONG CapsSize = 0; + DWORD Ioctl; + MMRESULT Result; + DWORD BytesReturned; + + ZeroMemory(Capabilities, sizeof(UNIVERSAL_CAPS)); + + if ( ! Device ) + return MMSYSERR_INVALPARAM; + + if ( ! Capabilities ) + return MMSYSERR_INVALPARAM; + + /* Select appropriate IOCTL and capabilities structure */ + switch ( Device->DeviceType ) + { + case WAVE_OUT_DEVICE_TYPE : + Ioctl = IOCTL_WAVE_GET_CAPABILITIES; + RawCapsPtr = (PVOID) &Capabilities->WaveOut; + CapsSize = sizeof(WAVEOUTCAPS); + break; + + case WAVE_IN_DEVICE_TYPE : + Ioctl = IOCTL_WAVE_GET_CAPABILITIES; + RawCapsPtr = (PVOID) &Capabilities->WaveIn; + CapsSize = sizeof(WAVEINCAPS); + break; + + case MIDI_OUT_DEVICE_TYPE : + Ioctl = IOCTL_MIDI_GET_CAPABILITIES; + RawCapsPtr = (PVOID) &Capabilities->MidiOut; + CapsSize = sizeof(MIDIOUTCAPS); + break; + + case MIDI_IN_DEVICE_TYPE : + Ioctl = IOCTL_MIDI_GET_CAPABILITIES; + RawCapsPtr = (PVOID) &Capabilities->MidiIn; + CapsSize = sizeof(MIDIINCAPS); + break; + + case MIXER_DEVICE_TYPE : + /* TODO */ + /*Ioctl = IOCTL_MIX_GET_CAPABILITIES;*/ + return MMSYSERR_NOTSUPPORTED; + + case AUX_DEVICE_TYPE : + /* TODO */ + Ioctl = IOCTL_AUX_GET_CAPABILITIES; + return MMSYSERR_NOTSUPPORTED; + + default : + return MMSYSERR_NOTSUPPORTED; + } + + /* Call the driver */ + Result = ReadSoundDevice( + Device, + Ioctl, + (LPVOID) RawCapsPtr, + CapsSize, + &BytesReturned, + NULL); + + return Result; +} + +MMRESULT +QueryWaveDeviceFormatSupport( + IN PSOUND_DEVICE Device, + IN PWAVEFORMATEX WaveFormat, + IN DWORD WaveFormatSize) +{ + if ( ! Device ) + return MMSYSERR_INVALPARAM; + + if ( ! WaveFormat ) + return MMSYSERR_INVALPARAM; + + /* TODO: Should we check the size? */ + + return Device->Functions.QueryWaveFormat(Device, WaveFormat, WaveFormatSize); +} + +MMRESULT +DefaultQueryWaveDeviceFormatSupport( + IN PSOUND_DEVICE Device, + IN PWAVEFORMATEX WaveFormat, + IN DWORD WaveFormatSize) +{ + MMRESULT Result; + DWORD BytesReturned = 0; + + if ( ! Device ) + return MMSYSERR_INVALPARAM; + + if ( ! WaveFormat ) + return MMSYSERR_INVALPARAM; + + /* Make sure we have a wave device */ + if ( ( Device->DeviceType != WAVE_OUT_DEVICE_TYPE ) && + ( Device->DeviceType != WAVE_IN_DEVICE_TYPE ) ) + { + return MMSYSERR_INVALPARAM; + } + + Result = WriteSoundDevice(Device, + IOCTL_WAVE_QUERY_FORMAT, + (LPVOID) WaveFormat, + WaveFormatSize, + &BytesReturned, + NULL); + + return Result; +} +
Modified: branches/silverblade-audio/lib/drivers/sound/mmebuddy/instances.c URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/so... ============================================================================== --- branches/silverblade-audio/lib/drivers/sound/mmebuddy/instances.c [iso-8859-1] (original) +++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/instances.c [iso-8859-1] Sat Jul 5 19:15:43 2008 @@ -50,6 +50,7 @@ /* Initialise */ NewInstance->Next = NULL; NewInstance->Device = SoundDevice; + NewInstance->Thread = NULL;
/* Search for an appropriate place in the list to put this instance */ CurrentInstance = SoundDevice->FirstInstance;
Modified: branches/silverblade-audio/lib/drivers/sound/mmebuddy/nt4.c URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/so... ============================================================================== --- branches/silverblade-audio/lib/drivers/sound/mmebuddy/nt4.c [iso-8859-1] (original) +++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/nt4.c [iso-8859-1] Sat Jul 5 19:15:43 2008 @@ -361,78 +361,3 @@
return MMSYSERR_NOERROR; } - - -#include <ntddk.h> /* How do I avoid this? */ - -MMRESULT -DefaultGetSoundDeviceCapabilities( - IN PSOUND_DEVICE Device, - OUT PUNIVERSAL_CAPS Capabilities) -{ - PVOID RawCapsPtr = NULL; - ULONG CapsSize = 0; - DWORD Ioctl; - MMRESULT Result; - DWORD BytesReturned; - - ZeroMemory(Capabilities, sizeof(UNIVERSAL_CAPS)); - - if ( ! Device ) - return MMSYSERR_INVALPARAM; - - if ( ! Capabilities ) - return MMSYSERR_INVALPARAM; - - /* Select appropriate IOCTL and capabilities structure */ - switch ( Device->DeviceType ) - { - case WAVE_OUT_DEVICE_TYPE : - Ioctl = IOCTL_WAVE_GET_CAPABILITIES; - RawCapsPtr = (PVOID) &Capabilities->WaveOut; - CapsSize = sizeof(WAVEOUTCAPS); - break; - - case WAVE_IN_DEVICE_TYPE : - Ioctl = IOCTL_WAVE_GET_CAPABILITIES; - RawCapsPtr = (PVOID) &Capabilities->WaveIn; - CapsSize = sizeof(WAVEINCAPS); - break; - - case MIDI_OUT_DEVICE_TYPE : - Ioctl = IOCTL_MIDI_GET_CAPABILITIES; - RawCapsPtr = (PVOID) &Capabilities->MidiOut; - CapsSize = sizeof(MIDIOUTCAPS); - break; - - case MIDI_IN_DEVICE_TYPE : - Ioctl = IOCTL_MIDI_GET_CAPABILITIES; - RawCapsPtr = (PVOID) &Capabilities->MidiIn; - CapsSize = sizeof(MIDIINCAPS); - break; - - case MIXER_DEVICE_TYPE : - /* TODO */ - /*Ioctl = IOCTL_MIX_GET_CAPABILITIES;*/ - return MMSYSERR_NOTSUPPORTED; - - case AUX_DEVICE_TYPE : - /* TODO */ - Ioctl = IOCTL_AUX_GET_CAPABILITIES; - return MMSYSERR_NOTSUPPORTED; - - default : - return MMSYSERR_NOTSUPPORTED; - } - - /* Call the driver */ - Result = ReadSoundDevice( - Device, - Ioctl, - (LPVOID) RawCapsPtr, - CapsSize, - &BytesReturned, - NULL); - - return Result; -}
Modified: branches/silverblade-audio/lib/drivers/sound/mmebuddy/testing.c URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/so... ============================================================================== --- branches/silverblade-audio/lib/drivers/sound/mmebuddy/testing.c [iso-8859-1] (original) +++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/testing.c [iso-8859-1] Sat Jul 5 19:15:43 2008 @@ -114,54 +114,49 @@
wsprintf(DevInfo, L"Device name: %hS\nManufacturer ID: %d\nProduct ID: %d\nDriver version: %x\nChannels: %d", Caps.WaveOut.szPname, Caps.WaveOut.wMid, Caps.WaveOut.wPid, Caps.WaveOut.vDriverVersion, Caps.WaveOut.wChannels);
- MessageBox(0, DevInfo, L"Result", MB_OK | MB_TASKMODAL); - -#if 0 - HANDLE Handle; + MessageBox(0, DevInfo, L"Device caps", MB_OK | MB_TASKMODAL); +} + + +VOID +TestFormatQuery() +{ + WCHAR msg[1024]; + PSOUND_DEVICE Device; MMRESULT Result; - WAVEOUTCAPS Caps; - DWORD BytesReturned = 0; - WCHAR DevInfo[1024]; - - Result = OpenKernelSoundDevice( - L"\\.\SBWaveOut0", - GENERIC_READ, - &Handle); - - if ( Result != MMSYSERR_NOERROR ) - { - MessageBox(0, L"Fail open", L"Fail open", MB_OK | MB_TASKMODAL); - return; - } - - ZeroMemory(&Caps, sizeof(WAVEOUTCAPS)); - - if ( ! - DeviceIoControl(Handle, - IOCTL_WAVE_GET_CAPABILITIES, - NULL, - 0, - (LPVOID) &Caps, - sizeof(WAVEOUTCAPS), - &BytesReturned, - NULL) ) - { - MessageBox(0, L"Fail", L"Fail", MB_OK | MB_TASKMODAL); - } - else - { - wsprintf(DevInfo, L"%02x %02x %02x %02x %02x %02x", Caps.szPname[0], Caps.szPname[1], Caps.szPname[2], Caps.szPname[3], Caps.szPname[4], Caps.szPname[5]); -/* - wsprintf(DevInfo, L"Device name: %hS\nManufacturer ID: %d\nProduct ID: %d\nDriver version: %x\nChannels: %d", Caps.szPname, Caps.wMid, Caps.wPid, Caps.vDriverVersion, Caps.wChannels); -*/ - - MessageBox(0, DevInfo, L"Result", MB_OK | MB_TASKMODAL); - } - - CloseHandle(Handle); -#endif -} - + WAVEFORMATEX fmt; + + CreateSoundDevice(WAVE_OUT_DEVICE_TYPE, L"\\.\SBWaveOut0"); + Result = GetSoundDevice(WAVE_OUT_DEVICE_TYPE, 0, &Device); + + if ( Result != MMSYSERR_NOERROR ) + { + MessageBox(0, L"Fail 1", L"Fail", MB_OK | MB_TASKMODAL); + return; + } + + /* Request a valid format */ + fmt.wFormatTag = WAVE_FORMAT_PCM; + fmt.nChannels = 1; + fmt.nSamplesPerSec = 22050; + fmt.wBitsPerSample = 16; + fmt.nBlockAlign = fmt.nChannels * (fmt.wBitsPerSample / 8); + fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; + fmt.cbSize = 0; + + Result = QueryWaveDeviceFormatSupport(Device, &fmt, sizeof(WAVEFORMATEX)); + + wsprintf(msg, L"Format support query result: %d", Result); + MessageBox(0, msg, L"Result", MB_OK | MB_TASKMODAL); + + /* Send it some garbage */ + fmt.nChannels = 6969; + + Result = QueryWaveDeviceFormatSupport(Device, &fmt, sizeof(WAVEFORMATEX)); + + wsprintf(msg, L"Format support query result: %d", Result); + MessageBox(0, msg, L"Result", MB_OK | MB_TASKMODAL); +}
APIENTRY VOID @@ -238,7 +233,8 @@ LPWSTR lpCmdLine, int nCmdShow) { - TestDevEnum(); + TestFormatQuery(); +// TestDevEnum(); /* TestThreading(); */