mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
[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:
parent
bea4561694
commit
c17e7adfbd
9 changed files with 468 additions and 38 deletions
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,16 +1,252 @@
|
|||
#define _UNICODE
|
||||
#define UNICODE
|
||||
#define WIN32_NO_STATUS
|
||||
#define _KSDDK_
|
||||
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#define _2pi 6.283185307179586476925286766559
|
||||
|
||||
#include <setupapi.h>
|
||||
#include <ndk/ntndk.h>
|
||||
#include <ks.h>
|
||||
#include <ksmedia.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
|
||||
__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)
|
||||
{
|
||||
|
|
|
@ -4,8 +4,11 @@
|
|||
<define name="PC_NO_IMPORTS" />
|
||||
<include base="ReactOS">include/reactos/libs/sound</include>
|
||||
<include base="wdmaud_kernel">.</include>
|
||||
<include base="libsamplerate">.</include>
|
||||
<library>kernel32</library>
|
||||
|
||||
<library>setupapi</library>
|
||||
<library>libsamplerate</library>
|
||||
<library>ksuser</library>
|
||||
<file>audio_test.c</file>
|
||||
|
||||
</module>
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -238,6 +238,8 @@ WdmAudControlOpenMixer(
|
|||
ULONG Index;
|
||||
PWDMAUD_HANDLE Handels;
|
||||
|
||||
DPRINT("WdmAudControlOpenMixer\n");
|
||||
|
||||
if (DeviceInfo->DeviceIndex >= GetNumOfMixerDevices(DeviceObject))
|
||||
{
|
||||
/* mixer index doesnt exist */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -15,9 +15,103 @@
|
|||
|
||||
#include <ntddsnd.h>
|
||||
#include <sndtypes.h>
|
||||
|
||||
#undef NDEBUG
|
||||
#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.
|
||||
*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue