[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
This commit is contained in:
Johannes Anderwald 2009-09-24 18:11:22 +00:00
parent bea4561694
commit c17e7adfbd
9 changed files with 468 additions and 38 deletions

View file

@ -520,8 +520,12 @@ WriteFileEx_Remixer(
ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
DeviceInfo.hDevice = Handle; DeviceInfo.hDevice = Handle;
DeviceInfo.DeviceType = WAVE_OUT_DEVICE_TYPE; //FIXME DeviceInfo.DeviceType = WAVE_OUT_DEVICE_TYPE; //FIXME
DeviceInfo.Buffer = BufferOut; DeviceInfo.Header.FrameExtent = BufferLength;
DeviceInfo.BufferSize = 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->OriginalBufferSize = Length;
Overlap->OriginalCompletionRoutine = CompletionRoutine; Overlap->OriginalCompletionRoutine = CompletionRoutine;

View file

@ -216,14 +216,17 @@ CloseWdmSoundDevice(
DeviceInfo.hDevice = SoundDeviceInstance->Handle; DeviceInfo.hDevice = SoundDeviceInstance->Handle;
/* First stop the stream */ /* First stop the stream */
DeviceInfo.u.State = KSSTATE_STOP; if (DeviceType != MIXER_DEVICE_TYPE)
SyncOverlappedDeviceIoControl(KernelHandle, {
IOCTL_SETDEVICE_STATE, DeviceInfo.u.State = KSSTATE_STOP;
(LPVOID) &DeviceInfo, SyncOverlappedDeviceIoControl(KernelHandle,
sizeof(WDMAUD_DEVICE_INFO), IOCTL_SETDEVICE_STATE,
(LPVOID) &DeviceInfo, (LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO), sizeof(WDMAUD_DEVICE_INFO),
NULL); (LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
NULL);
}
SyncOverlappedDeviceIoControl(KernelHandle, SyncOverlappedDeviceIoControl(KernelHandle,
IOCTL_CLOSE_WDMAUD, IOCTL_CLOSE_WDMAUD,
@ -256,6 +259,67 @@ QueryWdmWaveDeviceFormatSupport(
return MMSYSERR_NOERROR; 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 MMRESULT
SetWdmWaveDeviceFormat( SetWdmWaveDeviceFormat(
IN PSOUND_DEVICE_INSTANCE Instance, IN PSOUND_DEVICE_INSTANCE Instance,
@ -350,7 +414,7 @@ SetWdmWaveDeviceFormat(
{ {
if (DeviceInfo.u.FrameSize) if (DeviceInfo.u.FrameSize)
{ {
Instance->FrameSize = DeviceInfo.u.FrameSize; //Instance->FrameSize = DeviceInfo.u.FrameSize;
Instance->BufferCount = WaveFormat->nAvgBytesPerSec / Instance->FrameSize; Instance->BufferCount = WaveFormat->nAvgBytesPerSec / Instance->FrameSize;
SND_TRACE(L"FrameSize %u BufferCount %u\n", Instance->FrameSize, Instance->BufferCount); SND_TRACE(L"FrameSize %u BufferCount %u\n", Instance->FrameSize, Instance->BufferCount);
} }
@ -391,10 +455,14 @@ WriteFileEx_Committer2(
SND_ASSERT(Handle); SND_ASSERT(Handle);
ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); 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.hDevice = Handle;
DeviceInfo.DeviceType = WAVE_OUT_DEVICE_TYPE; //FIXME DeviceInfo.DeviceType = WAVE_OUT_DEVICE_TYPE; //FIXME
DeviceInfo.Buffer = OffsetPtr;
DeviceInfo.BufferSize = Length;
Overlap->Standard.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL); Overlap->Standard.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
@ -498,7 +566,15 @@ PopulateWdmDeviceList(
ZeroMemory(&FuncTable, sizeof(MMFUNCTION_TABLE)); ZeroMemory(&FuncTable, sizeof(MMFUNCTION_TABLE));
FuncTable.GetCapabilities = GetWdmDeviceCapabilities; FuncTable.GetCapabilities = GetWdmDeviceCapabilities;
FuncTable.QueryWaveFormatSupport = QueryWdmWaveDeviceFormatSupport; FuncTable.QueryWaveFormatSupport = QueryWdmWaveDeviceFormatSupport;
FuncTable.SetWaveFormat = SetWdmWaveDeviceFormat; if (DeviceType == MIXER_DEVICE_TYPE)
{
FuncTable.SetWaveFormat = SetWdmMixerDeviceFormat;
}
else
{
FuncTable.SetWaveFormat = SetWdmWaveDeviceFormat;
}
FuncTable.Open = OpenWdmSoundDevice; FuncTable.Open = OpenWdmSoundDevice;
FuncTable.Close = CloseWdmSoundDevice; FuncTable.Close = CloseWdmSoundDevice;
#ifndef USERMODE_MIXER #ifndef USERMODE_MIXER

View file

@ -1,16 +1,252 @@
#define _UNICODE #define _UNICODE
#define UNICODE #define UNICODE
#define WIN32_NO_STATUS
#define _KSDDK_
#include <windows.h> #include <windows.h>
#include <mmsystem.h> #include <mmsystem.h>
#include <stdio.h> #include <stdio.h>
#include <math.h> #include <math.h>
#include <setupapi.h>
#define _2pi 6.283185307179586476925286766559 #include <ndk/ntndk.h>
#include <ks.h> #include <ks.h>
#include <ksmedia.h> #include <ksmedia.h>
#include "interface.h" #include "interface.h"
#define _2pi 6.283185307179586476925286766559
#include <ks.h>
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 int
__cdecl __cdecl
main(int argc, char* argv[]) main(int argc, char* argv[])
@ -24,6 +260,8 @@ main(int argc, char* argv[])
HANDLE hWdmAud; HANDLE hWdmAud;
WDMAUD_DEVICE_INFO DeviceInfo; WDMAUD_DEVICE_INFO DeviceInfo;
TestKs();
return 0;
hWdmAud = CreateFileW(L"\\\\.\\wdmaud", hWdmAud = CreateFileW(L"\\\\.\\wdmaud",
GENERIC_READ | GENERIC_WRITE, GENERIC_READ | GENERIC_WRITE,
@ -139,8 +377,8 @@ main(int argc, char* argv[])
// //
// Play our 1-second buffer // Play our 1-second buffer
// //
DeviceInfo.Buffer = (PUCHAR)SoundBuffer; DeviceInfo.Header.Data = (PUCHAR)SoundBuffer;
DeviceInfo.BufferSize = Length; 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); Status = DeviceIoControl(hWdmAud, IOCTL_WRITEDATA, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped);
if (!Status) if (!Status)
{ {

View file

@ -4,8 +4,11 @@
<define name="PC_NO_IMPORTS" /> <define name="PC_NO_IMPORTS" />
<include base="ReactOS">include/reactos/libs/sound</include> <include base="ReactOS">include/reactos/libs/sound</include>
<include base="wdmaud_kernel">.</include> <include base="wdmaud_kernel">.</include>
<include base="libsamplerate">.</include>
<library>kernel32</library> <library>kernel32</library>
<library>setupapi</library>
<library>libsamplerate</library>
<library>ksuser</library>
<file>audio_test.c</file> <file>audio_test.c</file>
</module> </module>

View file

@ -327,8 +327,9 @@ WdmAudControlDeviceType(
if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE) if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE)
{ {
DPRINT1("FIXME: Unsupported device type %x\n", DeviceInfo->DeviceType); DPRINT("FIXME: Unsupported device type %x\n", DeviceInfo->DeviceType);
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); DeviceInfo->DeviceCount = 0;
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
} }
Pin.Property.Set = KSPROPSETID_Sysaudio; Pin.Property.Set = KSPROPSETID_Sysaudio;
@ -393,7 +394,7 @@ WdmAudControlDeviceType(
/* store result count */ /* store result count */
DeviceInfo->DeviceCount = Result; 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)); 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); Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
if (!NT_SUCCESS(Status)) 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); return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
} }
@ -1037,14 +1038,14 @@ WdmAudWrite(
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
} }
Packet->Header.FrameExtent = DeviceInfo->BufferSize; Packet->Header.FrameExtent = DeviceInfo->Header.FrameExtent;
Packet->Header.DataUsed = DeviceInfo->BufferSize; Packet->Header.DataUsed = DeviceInfo->Header.DataUsed;
Packet->Header.Size = sizeof(KSSTREAM_HEADER); Packet->Header.Size = sizeof(KSSTREAM_HEADER);
Packet->Header.PresentationTime.Numerator = 1; Packet->Header.PresentationTime.Numerator = 1;
Packet->Header.PresentationTime.Denominator = 1; Packet->Header.PresentationTime.Denominator = 1;
Packet->Irp = Irp; Packet->Irp = Irp;
Buffer = ExAllocatePool(NonPagedPool, DeviceInfo->BufferSize); Buffer = ExAllocatePool(NonPagedPool, DeviceInfo->Header.DataUsed);
if (!Buffer) if (!Buffer)
{ {
/* no memory */ /* no memory */
@ -1054,7 +1055,7 @@ WdmAudWrite(
} }
Packet->Header.Data = Buffer; 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) if (!Mdl)
{ {
/* no memory */ /* no memory */
@ -1096,7 +1097,7 @@ WdmAudWrite(
return SetIrpIoStatus(Irp, STATUS_INSUFFICIENT_RESOURCES, 0); return SetIrpIoStatus(Irp, STATUS_INSUFFICIENT_RESOURCES, 0);
} }
RtlMoveMemory(Buffer, SystemBuffer, DeviceInfo->BufferSize); RtlMoveMemory(Buffer, SystemBuffer, DeviceInfo->Header.DataUsed);
MmUnlockPages(Mdl); MmUnlockPages(Mdl);
IoFreeMdl(Mdl); IoFreeMdl(Mdl);

View file

@ -25,17 +25,18 @@ typedef enum
typedef struct typedef struct
{ {
KSSTREAM_HEADER Header;
SOUND_DEVICE_TYPE DeviceType; SOUND_DEVICE_TYPE DeviceType;
ULONG DeviceIndex; ULONG DeviceIndex;
HANDLE hDevice; HANDLE hDevice;
ULONG DeviceCount; ULONG DeviceCount;
ULONG BufferSize;
PUCHAR Buffer;
union union
{ {
MIXERCONTROLDETAILS MixDetails;
MIXERLINECONTROLSW MixControls;
MIXERLINEW MixLine;
WAVEFORMATEX WaveFormatEx; WAVEFORMATEX WaveFormatEx;
WAVEOUTCAPSW WaveOutCaps; WAVEOUTCAPSW WaveOutCaps;
AUXCAPSW AuxCaps; AUXCAPSW AuxCaps;

View file

@ -238,6 +238,8 @@ WdmAudControlOpenMixer(
ULONG Index; ULONG Index;
PWDMAUD_HANDLE Handels; PWDMAUD_HANDLE Handels;
DPRINT("WdmAudControlOpenMixer\n");
if (DeviceInfo->DeviceIndex >= GetNumOfMixerDevices(DeviceObject)) if (DeviceInfo->DeviceIndex >= GetNumOfMixerDevices(DeviceObject))
{ {
/* mixer index doesnt exist */ /* mixer index doesnt exist */

View file

@ -273,12 +273,15 @@ DestroySoundDeviceInstance(
return MMSYSERR_NOTSUPPORTED; return MMSYSERR_NOTSUPPORTED;
} }
/* Stop the streaming thread (TODO - is this for wave only?) */ /* Stop the streaming thread */
Result = DestroySoundThread(SoundDeviceInstance->Thread); if ( SoundDeviceInstance->Thread )
SND_ASSERT( MMSUCCESS(Result) ); /* It should succeed! */
if ( ! MMSUCCESS(Result ) )
{ {
return TranslateInternalMmResult(Result); Result = DestroySoundThread(SoundDeviceInstance->Thread);
SND_ASSERT( MMSUCCESS(Result) ); /* It should succeed! */
if ( ! MMSUCCESS(Result ) )
{
return TranslateInternalMmResult(Result);
}
} }
/* Blank this out here */ /* Blank this out here */

View file

@ -15,9 +15,103 @@
#include <ntddsnd.h> #include <ntddsnd.h>
#include <sndtypes.h> #include <sndtypes.h>
#undef NDEBUG
#include <mmebuddy.h> #include <mmebuddy.h>
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. Standard MME driver entry-point for messages relating to mixers.
*/ */
@ -60,11 +154,19 @@ mxdMessage(
case MXDM_OPEN : case MXDM_OPEN :
{ {
Result = MmeOpenMixerDevice(MIXER_DEVICE_TYPE,
DeviceId,
(LPMIXEROPENDESC) Parameter1,
Parameter2,
(DWORD*) PrivateHandle);
break; break;
} }
case MXDM_CLOSE : case MXDM_CLOSE :
{ {
Result = MmeCloseMixerDevice(PrivateHandle);
break; break;
} }