mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 09:25:10 +00:00
[MMIXER]
- Enumerate MIDI devices and provide all necessary functions to deal with them [WDMAUD_KERNEL] - Implement support functions which call the provided functions of mmixer library - Fix a bug in device interface request ioctl handler - Midi devices should now be visible, capabilities be retrieved and opened / close - Writing data is not yet supported svn path=/trunk/; revision=49376
This commit is contained in:
parent
5dd7b0178c
commit
bafe662783
16 changed files with 905 additions and 159 deletions
|
@ -171,7 +171,7 @@ WdmAudGetCapabilitiesByLegacy(
|
||||||
{
|
{
|
||||||
case MIXER_DEVICE_TYPE:
|
case MIXER_DEVICE_TYPE:
|
||||||
{
|
{
|
||||||
LPMIXERCAPS MixerCaps = (LPMIXERCAPS) Capabilities;
|
LPMIXERCAPSW MixerCaps = (LPMIXERCAPSW) Capabilities;
|
||||||
|
|
||||||
DeviceInfo.u.MixCaps.szPname[MAXPNAMELEN-1] = L'\0';
|
DeviceInfo.u.MixCaps.szPname[MAXPNAMELEN-1] = L'\0';
|
||||||
CopyWideString(MixerCaps->szPname, DeviceInfo.u.MixCaps.szPname);
|
CopyWideString(MixerCaps->szPname, DeviceInfo.u.MixCaps.szPname);
|
||||||
|
@ -185,13 +185,13 @@ WdmAudGetCapabilitiesByLegacy(
|
||||||
}
|
}
|
||||||
case WAVE_OUT_DEVICE_TYPE :
|
case WAVE_OUT_DEVICE_TYPE :
|
||||||
{
|
{
|
||||||
LPWAVEOUTCAPS WaveOutCaps = (LPWAVEOUTCAPS) Capabilities;
|
LPWAVEOUTCAPSW WaveOutCaps = (LPWAVEOUTCAPSW) Capabilities;
|
||||||
|
|
||||||
DeviceInfo.u.WaveOutCaps.szPname[MAXPNAMELEN-1] = L'\0';
|
DeviceInfo.u.WaveOutCaps.szPname[MAXPNAMELEN-1] = L'\0';
|
||||||
WaveOutCaps->wMid = DeviceInfo.u.WaveOutCaps.wMid;
|
WaveOutCaps->wMid = DeviceInfo.u.WaveOutCaps.wMid;
|
||||||
WaveOutCaps->wPid = DeviceInfo.u.WaveOutCaps.wPid;
|
WaveOutCaps->wPid = DeviceInfo.u.WaveOutCaps.wPid;
|
||||||
|
|
||||||
WaveOutCaps->vDriverVersion = 0x0001;
|
WaveOutCaps->vDriverVersion = DeviceInfo.u.WaveOutCaps.vDriverVersion;
|
||||||
CopyWideString(WaveOutCaps->szPname, DeviceInfo.u.WaveOutCaps.szPname);
|
CopyWideString(WaveOutCaps->szPname, DeviceInfo.u.WaveOutCaps.szPname);
|
||||||
|
|
||||||
WaveOutCaps->dwFormats = DeviceInfo.u.WaveOutCaps.dwFormats;
|
WaveOutCaps->dwFormats = DeviceInfo.u.WaveOutCaps.dwFormats;
|
||||||
|
@ -208,7 +208,7 @@ WdmAudGetCapabilitiesByLegacy(
|
||||||
WaveInCaps->wMid = DeviceInfo.u.WaveInCaps.wMid;
|
WaveInCaps->wMid = DeviceInfo.u.WaveInCaps.wMid;
|
||||||
WaveInCaps->wPid = DeviceInfo.u.WaveInCaps.wPid;
|
WaveInCaps->wPid = DeviceInfo.u.WaveInCaps.wPid;
|
||||||
|
|
||||||
WaveInCaps->vDriverVersion = 0x0001;
|
WaveInCaps->vDriverVersion = DeviceInfo.u.WaveInCaps.vDriverVersion;
|
||||||
CopyWideString(WaveInCaps->szPname, DeviceInfo.u.WaveInCaps.szPname);
|
CopyWideString(WaveInCaps->szPname, DeviceInfo.u.WaveInCaps.szPname);
|
||||||
|
|
||||||
WaveInCaps->dwFormats = DeviceInfo.u.WaveInCaps.dwFormats;
|
WaveInCaps->dwFormats = DeviceInfo.u.WaveInCaps.dwFormats;
|
||||||
|
@ -216,6 +216,34 @@ WdmAudGetCapabilitiesByLegacy(
|
||||||
WaveInCaps->wReserved1 = 0;
|
WaveInCaps->wReserved1 = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MIDI_IN_DEVICE_TYPE :
|
||||||
|
{
|
||||||
|
LPMIDIINCAPSW MidiInCaps = (LPMIDIINCAPSW)Capabilities;
|
||||||
|
|
||||||
|
DeviceInfo.u.MidiInCaps.szPname[MAXPNAMELEN-1] = L'\0';
|
||||||
|
|
||||||
|
MidiInCaps->vDriverVersion = DeviceInfo.u.MidiInCaps.vDriverVersion;
|
||||||
|
MidiInCaps->wMid = DeviceInfo.u.MidiInCaps.wMid;
|
||||||
|
MidiInCaps->wPid = DeviceInfo.u.MidiInCaps.wPid;
|
||||||
|
MidiInCaps->dwSupport = DeviceInfo.u.MidiInCaps.dwSupport;
|
||||||
|
|
||||||
|
CopyWideString(MidiInCaps->szPname, DeviceInfo.u.MidiInCaps.szPname);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MIDI_OUT_DEVICE_TYPE :
|
||||||
|
{
|
||||||
|
LPMIDIOUTCAPSW MidiOutCaps = (LPMIDIOUTCAPSW)Capabilities;
|
||||||
|
|
||||||
|
DeviceInfo.u.MidiOutCaps.szPname[MAXPNAMELEN-1] = L'\0';
|
||||||
|
|
||||||
|
MidiOutCaps->vDriverVersion = DeviceInfo.u.MidiOutCaps.vDriverVersion;
|
||||||
|
MidiOutCaps->wMid = DeviceInfo.u.MidiOutCaps.wMid;
|
||||||
|
MidiOutCaps->wPid = DeviceInfo.u.MidiOutCaps.wPid;
|
||||||
|
MidiOutCaps->dwSupport = DeviceInfo.u.MidiOutCaps.dwSupport;
|
||||||
|
|
||||||
|
CopyWideString(MidiOutCaps->szPname, DeviceInfo.u.MidiOutCaps.szPname);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return MMSYSERR_NOERROR;
|
return MMSYSERR_NOERROR;
|
||||||
|
|
|
@ -654,6 +654,19 @@ MMRESULT
|
||||||
WdmAudSetWaveStateByMMixer(
|
WdmAudSetWaveStateByMMixer(
|
||||||
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
|
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
|
||||||
IN BOOL bStart)
|
IN BOOL bStart)
|
||||||
|
{
|
||||||
|
MMDEVICE_TYPE DeviceType;
|
||||||
|
PSOUND_DEVICE SoundDevice;
|
||||||
|
MMRESULT Result;
|
||||||
|
|
||||||
|
Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
|
||||||
|
SND_ASSERT( Result == MMSYSERR_NOERROR );
|
||||||
|
|
||||||
|
|
||||||
|
Result = GetSoundDeviceType(SoundDevice, &DeviceType);
|
||||||
|
SND_ASSERT( Result == MMSYSERR_NOERROR );
|
||||||
|
|
||||||
|
if (DeviceType == WAVE_IN_DEVICE_TYPE || DeviceType == WAVE_OUT_DEVICE_TYPE)
|
||||||
{
|
{
|
||||||
if (bStart)
|
if (bStart)
|
||||||
{
|
{
|
||||||
|
@ -667,6 +680,22 @@ WdmAudSetWaveStateByMMixer(
|
||||||
MMixerSetWaveStatus(&MixerContext, SoundDeviceInstance->Handle, KSSTATE_ACQUIRE);
|
MMixerSetWaveStatus(&MixerContext, SoundDeviceInstance->Handle, KSSTATE_ACQUIRE);
|
||||||
MMixerSetWaveStatus(&MixerContext, SoundDeviceInstance->Handle, KSSTATE_STOP);
|
MMixerSetWaveStatus(&MixerContext, SoundDeviceInstance->Handle, KSSTATE_STOP);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (DeviceType == MIDI_IN_DEVICE_TYPE || DeviceType == MIDI_OUT_DEVICE_TYPE)
|
||||||
|
{
|
||||||
|
if (bStart)
|
||||||
|
{
|
||||||
|
MMixerSetMidiStatus(&MixerContext, SoundDeviceInstance->Handle, KSSTATE_ACQUIRE);
|
||||||
|
MMixerSetMidiStatus(&MixerContext, SoundDeviceInstance->Handle, KSSTATE_PAUSE);
|
||||||
|
MMixerSetMidiStatus(&MixerContext, SoundDeviceInstance->Handle, KSSTATE_RUN);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MMixerSetMidiStatus(&MixerContext, SoundDeviceInstance->Handle, KSSTATE_PAUSE);
|
||||||
|
MMixerSetMidiStatus(&MixerContext, SoundDeviceInstance->Handle, KSSTATE_ACQUIRE);
|
||||||
|
MMixerSetMidiStatus(&MixerContext, SoundDeviceInstance->Handle, KSSTATE_STOP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return MMSYSERR_NOERROR;
|
return MMSYSERR_NOERROR;
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,6 +90,12 @@ PopulateWdmDeviceList(
|
||||||
FuncTable.CommitWaveBuffer = WriteFileEx_Remixer;
|
FuncTable.CommitWaveBuffer = WriteFileEx_Remixer;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
else if (DeviceType == MIDI_IN_DEVICE_TYPE || DeviceType == MIDI_OUT_DEVICE_TYPE)
|
||||||
|
{
|
||||||
|
FuncTable.SetWaveFormat = FUNC_NAME(WdmAudSetMixerDeviceFormat);
|
||||||
|
FuncTable.SetState = FUNC_NAME(WdmAudSetWaveState);
|
||||||
|
FuncTable.GetPos = FUNC_NAME(WdmAudGetWavePosition);
|
||||||
|
}
|
||||||
|
|
||||||
SetSoundDeviceFunctionTable(SoundDevice, &FuncTable);
|
SetSoundDeviceFunctionTable(SoundDevice, &FuncTable);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,12 @@ WdmAudControlOpen(
|
||||||
return WdmAudControlOpenWave(DeviceObject, Irp, DeviceInfo, ClientInfo);
|
return WdmAudControlOpenWave(DeviceObject, Irp, DeviceInfo, ClientInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DeviceInfo->DeviceType == MIDI_OUT_DEVICE_TYPE || DeviceInfo->DeviceType == MIDI_IN_DEVICE_TYPE)
|
||||||
|
{
|
||||||
|
return WdmAudControlOpenMidi(DeviceObject, Irp, DeviceInfo, ClientInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return SetIrpIoStatus(Irp, STATUS_NOT_SUPPORTED, sizeof(WDMAUD_DEVICE_INFO));
|
return SetIrpIoStatus(Irp, STATUS_NOT_SUPPORTED, sizeof(WDMAUD_DEVICE_INFO));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,6 +61,15 @@ WdmAudControlDeviceType(
|
||||||
{
|
{
|
||||||
Result = WdmAudGetWaveOutDeviceCount();
|
Result = WdmAudGetWaveOutDeviceCount();
|
||||||
}
|
}
|
||||||
|
else if (DeviceInfo->DeviceType == MIDI_IN_DEVICE_TYPE)
|
||||||
|
{
|
||||||
|
Result = WdmAudGetMidiInDeviceCount();
|
||||||
|
}
|
||||||
|
else if (DeviceInfo->DeviceType == MIDI_OUT_DEVICE_TYPE)
|
||||||
|
{
|
||||||
|
Result = WdmAudGetMidiOutDeviceCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* store result count */
|
/* store result count */
|
||||||
DeviceInfo->DeviceCount = Result;
|
DeviceInfo->DeviceCount = Result;
|
||||||
|
@ -121,6 +136,10 @@ WdmAudCapabilities(
|
||||||
{
|
{
|
||||||
Status = WdmAudWaveCapabilities(DeviceObject, DeviceInfo, ClientInfo, DeviceExtension);
|
Status = WdmAudWaveCapabilities(DeviceObject, DeviceInfo, ClientInfo, DeviceExtension);
|
||||||
}
|
}
|
||||||
|
else if (DeviceInfo->DeviceType == MIDI_IN_DEVICE_TYPE || DeviceInfo->DeviceType == MIDI_OUT_DEVICE_TYPE)
|
||||||
|
{
|
||||||
|
Status = WdmAudMidiCapabilities(DeviceObject, DeviceInfo, ClientInfo, DeviceExtension);
|
||||||
|
}
|
||||||
|
|
||||||
return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
|
return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
|
||||||
}
|
}
|
||||||
|
@ -219,9 +238,7 @@ WdmAudGetDeviceInterface(
|
||||||
/* get device interface string input length */
|
/* get device interface string input length */
|
||||||
Size = DeviceInfo->u.Interface.DeviceInterfaceStringSize;
|
Size = DeviceInfo->u.Interface.DeviceInterfaceStringSize;
|
||||||
|
|
||||||
if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE || DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
|
/* get mixer info */
|
||||||
{
|
|
||||||
/* get wave info */
|
|
||||||
Status = WdmAudGetPnpNameByIndexAndType(DeviceInfo->DeviceIndex, DeviceInfo->DeviceType, &Device);
|
Status = WdmAudGetPnpNameByIndexAndType(DeviceInfo->DeviceIndex, DeviceInfo->DeviceType, &Device);
|
||||||
|
|
||||||
/* check for success */
|
/* check for success */
|
||||||
|
@ -254,46 +271,6 @@ WdmAudGetDeviceInterface(
|
||||||
FreeItem(Device);
|
FreeItem(Device);
|
||||||
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
|
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
|
||||||
}
|
}
|
||||||
else if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
|
|
||||||
{
|
|
||||||
if (DeviceInfo->DeviceIndex >= WdmAudGetMixerDeviceCount())
|
|
||||||
{
|
|
||||||
/* invalid device id */
|
|
||||||
return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, sizeof(WDMAUD_DEVICE_INFO));
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = WdmAudGetMixerPnpNameByIndex(DeviceInfo->DeviceIndex, &Device);
|
|
||||||
/* check for success */
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
/* invalid device id */
|
|
||||||
return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* calculate length */
|
|
||||||
Length = (wcslen(Device)+1) * sizeof(WCHAR);
|
|
||||||
|
|
||||||
if (!Size)
|
|
||||||
{
|
|
||||||
/* store device interface size */
|
|
||||||
DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length;
|
|
||||||
}
|
|
||||||
else if (Size < Length)
|
|
||||||
{
|
|
||||||
/* buffer too small */
|
|
||||||
DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length;
|
|
||||||
return SetIrpIoStatus(Irp, STATUS_BUFFER_OVERFLOW, sizeof(WDMAUD_DEVICE_INFO));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//FIXME SEH
|
|
||||||
RtlMoveMemory(DeviceInfo->u.Interface.DeviceInterfaceString, Device, Length);
|
|
||||||
}
|
|
||||||
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
|
|
||||||
}
|
|
||||||
|
|
||||||
return SetIrpIoStatus(Irp, STATUS_INVALID_DEVICE_REQUEST, sizeof(WDMAUD_DEVICE_INFO));
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
|
|
|
@ -42,6 +42,8 @@ typedef struct
|
||||||
WAVEOUTCAPSW WaveOutCaps;
|
WAVEOUTCAPSW WaveOutCaps;
|
||||||
AUXCAPSW AuxCaps;
|
AUXCAPSW AuxCaps;
|
||||||
WAVEINCAPSW WaveInCaps;
|
WAVEINCAPSW WaveInCaps;
|
||||||
|
MIDIINCAPSW MidiInCaps;
|
||||||
|
MIDIOUTCAPSW MidiOutCaps;
|
||||||
ULONGLONG Position;
|
ULONGLONG Position;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
|
|
@ -612,13 +612,16 @@ WdmAudGetWaveOutDeviceCount()
|
||||||
return MMixerGetWaveOutCount(&MixerContext);
|
return MMixerGetWaveOutCount(&MixerContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
ULONG
|
||||||
WdmAudGetMixerPnpNameByIndex(
|
WdmAudGetMidiInDeviceCount()
|
||||||
IN ULONG DeviceIndex,
|
|
||||||
OUT LPWSTR * Device)
|
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED
|
return MMixerGetMidiInCount(&MixerContext);
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
}
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
WdmAudGetMidiOutDeviceCount()
|
||||||
|
{
|
||||||
|
return MMixerGetWaveOutCount(&MixerContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -626,12 +629,28 @@ WdmAudGetPnpNameByIndexAndType(
|
||||||
IN ULONG DeviceIndex,
|
IN ULONG DeviceIndex,
|
||||||
IN SOUND_DEVICE_TYPE DeviceType,
|
IN SOUND_DEVICE_TYPE DeviceType,
|
||||||
OUT LPWSTR *DevicePath)
|
OUT LPWSTR *DevicePath)
|
||||||
|
{
|
||||||
|
if (DeviceType == WAVE_IN_DEVICE_TYPE || DeviceType == WAVE_OUT_DEVICE_TYPE)
|
||||||
{
|
{
|
||||||
if (MMixerGetWaveDevicePath(&MixerContext, DeviceType == WAVE_IN_DEVICE_TYPE, DeviceIndex, DevicePath) == MM_STATUS_SUCCESS)
|
if (MMixerGetWaveDevicePath(&MixerContext, DeviceType == WAVE_IN_DEVICE_TYPE, DeviceIndex, DevicePath) == MM_STATUS_SUCCESS)
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
else
|
else
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
else if (DeviceType == MIDI_IN_DEVICE_TYPE || DeviceType == MIDI_OUT_DEVICE_TYPE)
|
||||||
|
{
|
||||||
|
if (MMixerGetMidiDevicePath(&MixerContext, DeviceType == MIDI_IN_DEVICE_TYPE, DeviceIndex, DevicePath) == MM_STATUS_SUCCESS)
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
else
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
else if (DeviceType == MIXER_DEVICE_TYPE)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
WdmAudWaveCapabilities(
|
WdmAudWaveCapabilities(
|
||||||
|
@ -640,7 +659,7 @@ WdmAudWaveCapabilities(
|
||||||
IN PWDMAUD_CLIENT ClientInfo,
|
IN PWDMAUD_CLIENT ClientInfo,
|
||||||
IN PWDMAUD_DEVICE_EXTENSION DeviceExtension)
|
IN PWDMAUD_DEVICE_EXTENSION DeviceExtension)
|
||||||
{
|
{
|
||||||
MIXER_STATUS Status;
|
MIXER_STATUS Status = MM_STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
|
if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
|
||||||
{
|
{
|
||||||
|
@ -652,10 +671,31 @@ WdmAudWaveCapabilities(
|
||||||
/* get capabilities */
|
/* get capabilities */
|
||||||
Status = MMixerWaveOutCapabilities(&MixerContext, DeviceInfo->DeviceIndex, &DeviceInfo->u.WaveOutCaps);
|
Status = MMixerWaveOutCapabilities(&MixerContext, DeviceInfo->DeviceIndex, &DeviceInfo->u.WaveOutCaps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Status == MM_STATUS_SUCCESS)
|
||||||
|
return STATUS_SUCCESS;
|
||||||
else
|
else
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
WdmAudMidiCapabilities(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PWDMAUD_DEVICE_INFO DeviceInfo,
|
||||||
|
IN PWDMAUD_CLIENT ClientInfo,
|
||||||
|
IN PWDMAUD_DEVICE_EXTENSION DeviceExtension)
|
||||||
{
|
{
|
||||||
ASSERT(0);
|
MIXER_STATUS Status = MM_STATUS_UNSUCCESSFUL;
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
|
if (DeviceInfo->DeviceType == MIDI_IN_DEVICE_TYPE)
|
||||||
|
{
|
||||||
|
/* get capabilities */
|
||||||
|
Status = MMixerMidiInCapabilities(&MixerContext, DeviceInfo->DeviceIndex, &DeviceInfo->u.MidiInCaps);
|
||||||
|
}
|
||||||
|
else if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
|
||||||
|
{
|
||||||
|
/* get capabilities */
|
||||||
|
Status = MMixerMidiOutCapabilities(&MixerContext, DeviceInfo->DeviceIndex, &DeviceInfo->u.MidiOutCaps);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Status == MM_STATUS_SUCCESS)
|
if (Status == MM_STATUS_SUCCESS)
|
||||||
|
@ -737,3 +777,26 @@ WdmAudControlOpenWave(
|
||||||
else
|
else
|
||||||
return SetIrpIoStatus(Irp, STATUS_NOT_SUPPORTED, sizeof(WDMAUD_DEVICE_INFO));
|
return SetIrpIoStatus(Irp, STATUS_NOT_SUPPORTED, sizeof(WDMAUD_DEVICE_INFO));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
WdmAudControlOpenMidi(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PWDMAUD_DEVICE_INFO DeviceInfo,
|
||||||
|
IN PWDMAUD_CLIENT ClientInfo)
|
||||||
|
{
|
||||||
|
MIXER_STATUS Status;
|
||||||
|
PIN_CREATE_CONTEXT Context;
|
||||||
|
|
||||||
|
Context.ClientInfo = ClientInfo;
|
||||||
|
Context.DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
Context.DeviceType = DeviceInfo->DeviceType;
|
||||||
|
|
||||||
|
Status = MMixerOpenMidi(&MixerContext, DeviceInfo->DeviceIndex, DeviceInfo->DeviceType == MIDI_IN_DEVICE_TYPE, CreatePinCallback, &Context, &DeviceInfo->hDevice);
|
||||||
|
|
||||||
|
if (Status == MM_STATUS_SUCCESS)
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
|
||||||
|
else
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_NOT_SUPPORTED, sizeof(WDMAUD_DEVICE_INFO));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -130,6 +130,12 @@ WdmAudControlOpenWave(
|
||||||
IN PWDMAUD_DEVICE_INFO DeviceInfo,
|
IN PWDMAUD_DEVICE_INFO DeviceInfo,
|
||||||
IN PWDMAUD_CLIENT ClientInfo);
|
IN PWDMAUD_CLIENT ClientInfo);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
WdmAudControlOpenMidi(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PWDMAUD_DEVICE_INFO DeviceInfo,
|
||||||
|
IN PWDMAUD_CLIENT ClientInfo);
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
GetNumOfMixerDevices(
|
GetNumOfMixerDevices(
|
||||||
|
@ -166,6 +172,13 @@ WdmAudWaveCapabilities(
|
||||||
IN PWDMAUD_CLIENT ClientInfo,
|
IN PWDMAUD_CLIENT ClientInfo,
|
||||||
IN PWDMAUD_DEVICE_EXTENSION DeviceExtension);
|
IN PWDMAUD_DEVICE_EXTENSION DeviceExtension);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
WdmAudMidiCapabilities(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PWDMAUD_DEVICE_INFO DeviceInfo,
|
||||||
|
IN PWDMAUD_CLIENT ClientInfo,
|
||||||
|
IN PWDMAUD_DEVICE_EXTENSION DeviceExtension);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
WdmAudFrameSize(
|
WdmAudFrameSize(
|
||||||
|
@ -267,10 +280,11 @@ WdmAudGetWaveInDeviceCount();
|
||||||
ULONG
|
ULONG
|
||||||
WdmAudGetWaveOutDeviceCount();
|
WdmAudGetWaveOutDeviceCount();
|
||||||
|
|
||||||
NTSTATUS
|
ULONG
|
||||||
WdmAudGetMixerPnpNameByIndex(
|
WdmAudGetMidiInDeviceCount();
|
||||||
IN ULONG DeviceIndex,
|
|
||||||
OUT LPWSTR * Device);
|
ULONG
|
||||||
|
WdmAudGetMidiOutDeviceCount();
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
WdmAudGetPnpNameByIndexAndType(
|
WdmAudGetPnpNameByIndexAndType(
|
||||||
|
|
|
@ -955,7 +955,7 @@ MMixerInitializeFilter(
|
||||||
MixerInfo->hMixer = MixerData->hDevice;
|
MixerInfo->hMixer = MixerData->hDevice;
|
||||||
|
|
||||||
/* get mixer name */
|
/* get mixer name */
|
||||||
MMixerGetDeviceName(MixerContext, MixerInfo, MixerData->hDeviceInterfaceKey);
|
MMixerGetDeviceName(MixerContext, MixerInfo->MixCaps.szPname, MixerData->hDeviceInterfaceKey);
|
||||||
|
|
||||||
/* initialize line list */
|
/* initialize line list */
|
||||||
InitializeListHead(&MixerInfo->LineList);
|
InitializeListHead(&MixerInfo->LineList);
|
||||||
|
@ -1128,6 +1128,9 @@ MMixerSetupFilter(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* activate midi devices */
|
||||||
|
MMixerInitializeMidiForFilter(MixerContext, MixerList, MixerData, Topology);
|
||||||
|
|
||||||
/* done */
|
/* done */
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
541
reactos/lib/drivers/sound/mmixer/midi.c
Normal file
541
reactos/lib/drivers/sound/mmixer/midi.c
Normal file
|
@ -0,0 +1,541 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS Kernel Streaming
|
||||||
|
* FILE: lib/drivers/sound/mmixer/midi.c
|
||||||
|
* PURPOSE: Midi Support Functions
|
||||||
|
* PROGRAMMER: Johannes Anderwald
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "priv.h"
|
||||||
|
|
||||||
|
MIXER_STATUS
|
||||||
|
MMixerGetPinDataFlowAndCommunication(
|
||||||
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN LPMIXER_DATA MixerData,
|
||||||
|
IN ULONG PinId,
|
||||||
|
OUT PKSPIN_DATAFLOW DataFlow,
|
||||||
|
OUT PKSPIN_COMMUNICATION Communication)
|
||||||
|
{
|
||||||
|
KSP_PIN Pin;
|
||||||
|
ULONG BytesReturned;
|
||||||
|
MIXER_STATUS Status;
|
||||||
|
|
||||||
|
/* setup request */
|
||||||
|
Pin.PinId = PinId;
|
||||||
|
Pin.Reserved = 0;
|
||||||
|
Pin.Property.Flags = KSPROPERTY_TYPE_GET;
|
||||||
|
Pin.Property.Id = KSPROPERTY_PIN_DATAFLOW;
|
||||||
|
Pin.Property.Set = KSPROPSETID_Pin;
|
||||||
|
|
||||||
|
/* get pin dataflow */
|
||||||
|
Status = MixerContext->Control(MixerData->hDevice, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)DataFlow, sizeof(KSPIN_DATAFLOW), &BytesReturned);
|
||||||
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
/* failed to retrieve dataflow */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* setup communication request */
|
||||||
|
Pin.Property.Id = KSPROPERTY_PIN_COMMUNICATION;
|
||||||
|
|
||||||
|
/* get pin communication */
|
||||||
|
Status = MixerContext->Control(MixerData->hDevice, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
MIXER_STATUS
|
||||||
|
MMixerAddMidiPin(
|
||||||
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN PMIXER_LIST MixerList,
|
||||||
|
IN ULONG DeviceId,
|
||||||
|
IN ULONG PinId,
|
||||||
|
IN ULONG bInput,
|
||||||
|
IN LPWSTR DeviceName)
|
||||||
|
{
|
||||||
|
LPMIDI_INFO MidiInfo;
|
||||||
|
|
||||||
|
/* allocate midi info */
|
||||||
|
MidiInfo = MixerContext->Alloc(sizeof(MIDI_INFO));
|
||||||
|
|
||||||
|
if (!MidiInfo)
|
||||||
|
{
|
||||||
|
/* no memory */
|
||||||
|
return MM_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialize midi info */
|
||||||
|
MidiInfo->DeviceId = DeviceId;
|
||||||
|
MidiInfo->PinId = PinId;
|
||||||
|
|
||||||
|
/* sanity check */
|
||||||
|
ASSERT(wcslen(DeviceName) + 1 < MAXPNAMELEN);
|
||||||
|
|
||||||
|
/* copy device name */
|
||||||
|
if (bInput && DeviceName)
|
||||||
|
{
|
||||||
|
wcscpy(MidiInfo->u.InCaps.szPname, DeviceName);
|
||||||
|
}
|
||||||
|
else if (!bInput && DeviceName)
|
||||||
|
{
|
||||||
|
wcscpy(MidiInfo->u.OutCaps.szPname, DeviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME determine manufacturer / product id */
|
||||||
|
if (bInput)
|
||||||
|
{
|
||||||
|
MidiInfo->u.InCaps.dwSupport = 0;
|
||||||
|
MidiInfo->u.InCaps.wMid = MM_MICROSOFT;
|
||||||
|
MidiInfo->u.InCaps.wPid = MM_PID_UNMAPPED;
|
||||||
|
MidiInfo->u.InCaps.vDriverVersion = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MidiInfo->u.OutCaps.dwSupport = 0;
|
||||||
|
MidiInfo->u.OutCaps.wMid = MM_MICROSOFT;
|
||||||
|
MidiInfo->u.OutCaps.wPid = MM_PID_UNMAPPED;
|
||||||
|
MidiInfo->u.OutCaps.vDriverVersion = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bInput)
|
||||||
|
{
|
||||||
|
/* insert into list */
|
||||||
|
InsertTailList(&MixerList->MidiInList, &MidiInfo->Entry);
|
||||||
|
MixerList->MidiInListCount++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* insert into list */
|
||||||
|
InsertTailList(&MixerList->MidiOutList, &MidiInfo->Entry);
|
||||||
|
MixerList->MidiOutListCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MM_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MMixerCheckFilterPinMidiSupport(
|
||||||
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN PMIXER_LIST MixerList,
|
||||||
|
IN LPMIXER_DATA MixerData,
|
||||||
|
IN ULONG PinId,
|
||||||
|
IN PKSMULTIPLE_ITEM MultipleItem,
|
||||||
|
IN LPWSTR szPname)
|
||||||
|
{
|
||||||
|
ULONG Index;
|
||||||
|
PKSDATARANGE DataRange;
|
||||||
|
KSPIN_COMMUNICATION Communication;
|
||||||
|
KSPIN_DATAFLOW DataFlow;
|
||||||
|
MIXER_STATUS Status;
|
||||||
|
|
||||||
|
/* get first datarange */
|
||||||
|
DataRange = (PKSDATARANGE)(MultipleItem + 1);
|
||||||
|
|
||||||
|
/* alignment assert */
|
||||||
|
ASSERT(((ULONG_PTR)DataRange & 0x7) == 0);
|
||||||
|
|
||||||
|
/* iterate through all data ranges */
|
||||||
|
for(Index = 0; Index < MultipleItem->Count; Index++)
|
||||||
|
{
|
||||||
|
if (IsEqualGUIDAligned(&DataRange->MajorFormat, &KSDATAFORMAT_TYPE_MUSIC) &&
|
||||||
|
IsEqualGUIDAligned(&DataRange->SubFormat, &KSDATAFORMAT_SUBTYPE_MIDI) &&
|
||||||
|
IsEqualGUIDAligned(&DataRange->Specifier, &KSDATAFORMAT_SPECIFIER_NONE))
|
||||||
|
{
|
||||||
|
/* pin supports midi datarange */
|
||||||
|
if (MMixerGetPinDataFlowAndCommunication(MixerContext, MixerData, PinId, &DataFlow, &Communication) == MM_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
if (DataFlow == KSPIN_DATAFLOW_IN && Communication == KSPIN_COMMUNICATION_SINK)
|
||||||
|
{
|
||||||
|
Status = MMixerAddMidiPin(MixerContext, MixerList, MixerData->DeviceId, PinId, FALSE, szPname);
|
||||||
|
}
|
||||||
|
else if (DataFlow == KSPIN_DATAFLOW_OUT && Communication == KSPIN_COMMUNICATION_SOURCE)
|
||||||
|
{
|
||||||
|
Status = MMixerAddMidiPin(MixerContext, MixerList, MixerData->DeviceId, PinId, TRUE, szPname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* move to next datarange */
|
||||||
|
DataRange = (PKSDATARANGE)((ULONG_PTR)DataRange + DataRange->FormatSize);
|
||||||
|
|
||||||
|
/* alignment assert */
|
||||||
|
ASSERT(((ULONG_PTR)DataRange & 0x7) == 0);
|
||||||
|
|
||||||
|
/* data ranges are 64-bit aligned */
|
||||||
|
DataRange = (PVOID)(((ULONG_PTR)DataRange + 0x7) & ~0x7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MMixerInitializeMidiForFilter(
|
||||||
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN PMIXER_LIST MixerList,
|
||||||
|
IN LPMIXER_DATA MixerData,
|
||||||
|
IN PTOPOLOGY Topology)
|
||||||
|
{
|
||||||
|
ULONG PinCount, Index;
|
||||||
|
MIXER_STATUS Status;
|
||||||
|
PKSMULTIPLE_ITEM MultipleItem;
|
||||||
|
WCHAR szPname[MAXPNAMELEN];
|
||||||
|
|
||||||
|
/* get filter pin count */
|
||||||
|
MMixerGetTopologyPinCount(Topology, &PinCount);
|
||||||
|
|
||||||
|
/* get mixer name */
|
||||||
|
if (MMixerGetDeviceName(MixerContext, szPname, MixerData->hDeviceInterfaceKey) != MM_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
/* clear name */
|
||||||
|
szPname[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* iterate all pins and check for KSDATARANGE_MUSIC support */
|
||||||
|
for(Index = 0; Index < PinCount; Index++)
|
||||||
|
{
|
||||||
|
/* get audio pin data ranges */
|
||||||
|
Status = MMixerGetAudioPinDataRanges(MixerContext, MixerData->hDevice, Index, &MultipleItem);
|
||||||
|
|
||||||
|
/* check for success */
|
||||||
|
if (Status == MM_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
/* check if there is support KSDATARANGE_MUSIC */
|
||||||
|
MMixerCheckFilterPinMidiSupport(MixerContext, MixerList, MixerData, Index, MultipleItem, szPname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MIXER_STATUS
|
||||||
|
MMixerOpenMidiPin(
|
||||||
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN PMIXER_LIST MixerList,
|
||||||
|
IN ULONG DeviceId,
|
||||||
|
IN ULONG PinId,
|
||||||
|
IN ACCESS_MASK DesiredAccess,
|
||||||
|
IN PIN_CREATE_CALLBACK CreateCallback,
|
||||||
|
IN PVOID Context,
|
||||||
|
OUT PHANDLE PinHandle)
|
||||||
|
{
|
||||||
|
PKSPIN_CONNECT PinConnect;
|
||||||
|
PKSDATAFORMAT DataFormat;
|
||||||
|
LPMIXER_DATA MixerData;
|
||||||
|
NTSTATUS Status;
|
||||||
|
MIXER_STATUS MixerStatus;
|
||||||
|
|
||||||
|
MixerData = MMixerGetDataByDeviceId(MixerList, DeviceId);
|
||||||
|
if (!MixerData)
|
||||||
|
return MM_STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
/* allocate pin connect */
|
||||||
|
PinConnect = MMixerAllocatePinConnect(MixerContext, sizeof(KSDATAFORMAT));
|
||||||
|
if (!PinConnect)
|
||||||
|
{
|
||||||
|
/* no memory */
|
||||||
|
return MM_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialize pin connect struct */
|
||||||
|
MMixerInitializePinConnect(PinConnect, PinId);
|
||||||
|
|
||||||
|
/* get offset to dataformat */
|
||||||
|
DataFormat = (PKSDATAFORMAT) (PinConnect + 1);
|
||||||
|
|
||||||
|
/* initialize data format */
|
||||||
|
RtlMoveMemory(&DataFormat->MajorFormat, &KSDATAFORMAT_TYPE_MUSIC, sizeof(GUID));
|
||||||
|
RtlMoveMemory(&DataFormat->SubFormat, &KSDATAFORMAT_SUBTYPE_MIDI, sizeof(GUID));
|
||||||
|
RtlMoveMemory(&DataFormat->Specifier, &KSDATAFORMAT_SPECIFIER_NONE, sizeof(GUID));
|
||||||
|
|
||||||
|
if (CreateCallback)
|
||||||
|
{
|
||||||
|
/* let the callback handle the creation */
|
||||||
|
MixerStatus = CreateCallback(Context, DeviceId, PinId, MixerData->hDevice, PinConnect, DesiredAccess, PinHandle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* now create the pin */
|
||||||
|
Status = KsCreatePin(MixerData->hDevice, PinConnect, DesiredAccess, PinHandle);
|
||||||
|
|
||||||
|
/* normalize status */
|
||||||
|
if (Status == STATUS_SUCCESS)
|
||||||
|
MixerStatus = MM_STATUS_SUCCESS;
|
||||||
|
else
|
||||||
|
MixerStatus = MM_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free create info */
|
||||||
|
MixerContext->Free(PinConnect);
|
||||||
|
|
||||||
|
/* done */
|
||||||
|
return MixerStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
MIXER_STATUS
|
||||||
|
MMixerGetMidiInfoByIndexAndType(
|
||||||
|
IN PMIXER_LIST MixerList,
|
||||||
|
IN ULONG DeviceIndex,
|
||||||
|
IN ULONG bMidiInputType,
|
||||||
|
OUT LPMIDI_INFO *OutMidiInfo)
|
||||||
|
{
|
||||||
|
ULONG Index = 0;
|
||||||
|
PLIST_ENTRY Entry, ListHead;
|
||||||
|
LPMIDI_INFO MidiInfo;
|
||||||
|
|
||||||
|
if (bMidiInputType)
|
||||||
|
ListHead = &MixerList->MidiInList;
|
||||||
|
else
|
||||||
|
ListHead = &MixerList->MidiOutList;
|
||||||
|
|
||||||
|
/* get first entry */
|
||||||
|
Entry = ListHead->Flink;
|
||||||
|
|
||||||
|
while(Entry != ListHead)
|
||||||
|
{
|
||||||
|
MidiInfo = (LPMIDI_INFO)CONTAINING_RECORD(Entry, MIDI_INFO, Entry);
|
||||||
|
|
||||||
|
if (Index == DeviceIndex)
|
||||||
|
{
|
||||||
|
*OutMidiInfo = MidiInfo;
|
||||||
|
return MM_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
Index++;
|
||||||
|
Entry = Entry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MM_STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
MIXER_STATUS
|
||||||
|
MMixerMidiOutCapabilities(
|
||||||
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN ULONG DeviceIndex,
|
||||||
|
OUT LPMIDIOUTCAPSW Caps)
|
||||||
|
{
|
||||||
|
PMIXER_LIST MixerList;
|
||||||
|
MIXER_STATUS Status;
|
||||||
|
LPMIDI_INFO MidiInfo;
|
||||||
|
|
||||||
|
/* verify mixer context */
|
||||||
|
Status = MMixerVerifyContext(MixerContext);
|
||||||
|
|
||||||
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
/* invalid context passed */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* grab mixer list */
|
||||||
|
MixerList = (PMIXER_LIST)MixerContext->MixerContext;
|
||||||
|
|
||||||
|
/* find destination midi */
|
||||||
|
Status = MMixerGetMidiInfoByIndexAndType(MixerList, DeviceIndex, FALSE, &MidiInfo);
|
||||||
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
/* failed to find midi info */
|
||||||
|
return MM_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy capabilities */
|
||||||
|
MixerContext->Copy(Caps, &MidiInfo->u.OutCaps, sizeof(MIDIOUTCAPSW));
|
||||||
|
|
||||||
|
return MM_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
MIXER_STATUS
|
||||||
|
MMixerMidiInCapabilities(
|
||||||
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN ULONG DeviceIndex,
|
||||||
|
OUT LPMIDIINCAPSW Caps)
|
||||||
|
{
|
||||||
|
PMIXER_LIST MixerList;
|
||||||
|
MIXER_STATUS Status;
|
||||||
|
LPMIDI_INFO MidiInfo;
|
||||||
|
|
||||||
|
/* verify mixer context */
|
||||||
|
Status = MMixerVerifyContext(MixerContext);
|
||||||
|
|
||||||
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
/* invalid context passed */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* grab mixer list */
|
||||||
|
MixerList = (PMIXER_LIST)MixerContext->MixerContext;
|
||||||
|
|
||||||
|
/* find destination midi */
|
||||||
|
Status = MMixerGetMidiInfoByIndexAndType(MixerList, DeviceIndex, TRUE, &MidiInfo);
|
||||||
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
/* failed to find midi info */
|
||||||
|
return MM_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy capabilities */
|
||||||
|
MixerContext->Copy(Caps, &MidiInfo->u.InCaps, sizeof(MIDIINCAPSW));
|
||||||
|
|
||||||
|
return MM_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
MIXER_STATUS
|
||||||
|
MMixerGetMidiDevicePath(
|
||||||
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN ULONG bMidiIn,
|
||||||
|
IN ULONG DeviceId,
|
||||||
|
OUT LPWSTR * DevicePath)
|
||||||
|
{
|
||||||
|
PMIXER_LIST MixerList;
|
||||||
|
LPMIXER_DATA MixerData;
|
||||||
|
LPMIDI_INFO MidiInfo;
|
||||||
|
ULONG Length;
|
||||||
|
MIXER_STATUS Status;
|
||||||
|
|
||||||
|
/* verify mixer context */
|
||||||
|
Status = MMixerVerifyContext(MixerContext);
|
||||||
|
|
||||||
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
/* invalid context passed */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* grab mixer list */
|
||||||
|
MixerList = (PMIXER_LIST)MixerContext->MixerContext;
|
||||||
|
|
||||||
|
/* find destination midi */
|
||||||
|
Status = MMixerGetMidiInfoByIndexAndType(MixerList, DeviceId, bMidiIn, &MidiInfo);
|
||||||
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
/* failed to find midi info */
|
||||||
|
return MM_STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get associated device id */
|
||||||
|
MixerData = MMixerGetDataByDeviceId(MixerList, MidiInfo->DeviceId);
|
||||||
|
if (!MixerData)
|
||||||
|
return MM_STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
/* calculate length */
|
||||||
|
Length = wcslen(MixerData->DeviceName)+1;
|
||||||
|
|
||||||
|
/* allocate destination buffer */
|
||||||
|
*DevicePath = MixerContext->Alloc(Length * sizeof(WCHAR));
|
||||||
|
|
||||||
|
if (!*DevicePath)
|
||||||
|
{
|
||||||
|
/* no memory */
|
||||||
|
return MM_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy device path */
|
||||||
|
MixerContext->Copy(*DevicePath, MixerData->DeviceName, Length * sizeof(WCHAR));
|
||||||
|
|
||||||
|
/* done */
|
||||||
|
return MM_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
MIXER_STATUS
|
||||||
|
MMixerSetMidiStatus(
|
||||||
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN HANDLE PinHandle,
|
||||||
|
IN KSSTATE State)
|
||||||
|
{
|
||||||
|
KSPROPERTY Property;
|
||||||
|
ULONG Length;
|
||||||
|
|
||||||
|
/* setup property request */
|
||||||
|
Property.Set = KSPROPSETID_Connection;
|
||||||
|
Property.Id = KSPROPERTY_CONNECTION_STATE;
|
||||||
|
Property.Flags = KSPROPERTY_TYPE_SET;
|
||||||
|
|
||||||
|
return MixerContext->Control(PinHandle, IOCTL_KS_PROPERTY, &Property, sizeof(KSPROPERTY), &State, sizeof(KSSTATE), &Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
MIXER_STATUS
|
||||||
|
MMixerOpenMidi(
|
||||||
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN ULONG DeviceIndex,
|
||||||
|
IN ULONG bMidiIn,
|
||||||
|
IN PIN_CREATE_CALLBACK CreateCallback,
|
||||||
|
IN PVOID Context,
|
||||||
|
OUT PHANDLE PinHandle)
|
||||||
|
{
|
||||||
|
PMIXER_LIST MixerList;
|
||||||
|
MIXER_STATUS Status;
|
||||||
|
LPMIDI_INFO MidiInfo;
|
||||||
|
ACCESS_MASK DesiredAccess = 0;
|
||||||
|
|
||||||
|
/* verify mixer context */
|
||||||
|
Status = MMixerVerifyContext(MixerContext);
|
||||||
|
|
||||||
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
/* invalid context passed */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* grab mixer list */
|
||||||
|
MixerList = (PMIXER_LIST)MixerContext->MixerContext;
|
||||||
|
|
||||||
|
/* find destination midi */
|
||||||
|
Status = MMixerGetMidiInfoByIndexAndType(MixerList, DeviceIndex, bMidiIn, &MidiInfo);
|
||||||
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
/* failed to find midi info */
|
||||||
|
return MM_STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get desired access */
|
||||||
|
if (bMidiIn)
|
||||||
|
{
|
||||||
|
DesiredAccess |= GENERIC_READ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DesiredAccess |= GENERIC_WRITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now try open the pin */
|
||||||
|
return MMixerOpenMidiPin(MixerContext, MixerList, MidiInfo->DeviceId, MidiInfo->PinId, DesiredAccess, CreateCallback, Context, PinHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
MMixerGetMidiInCount(
|
||||||
|
IN PMIXER_CONTEXT MixerContext)
|
||||||
|
{
|
||||||
|
PMIXER_LIST MixerList;
|
||||||
|
MIXER_STATUS Status;
|
||||||
|
|
||||||
|
/* verify mixer context */
|
||||||
|
Status = MMixerVerifyContext(MixerContext);
|
||||||
|
|
||||||
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
/* invalid context passed */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* grab mixer list */
|
||||||
|
MixerList = (PMIXER_LIST)MixerContext->MixerContext;
|
||||||
|
|
||||||
|
return MixerList->MidiInListCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
MMixerGetMidiOutCount(
|
||||||
|
IN PMIXER_CONTEXT MixerContext)
|
||||||
|
{
|
||||||
|
PMIXER_LIST MixerList;
|
||||||
|
MIXER_STATUS Status;
|
||||||
|
|
||||||
|
/* verify mixer context */
|
||||||
|
Status = MMixerVerifyContext(MixerContext);
|
||||||
|
|
||||||
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
/* invalid context passed */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* grab mixer list */
|
||||||
|
MixerList = (PMIXER_LIST)MixerContext->MixerContext;
|
||||||
|
|
||||||
|
return MixerList->MidiOutListCount;
|
||||||
|
}
|
|
@ -447,11 +447,14 @@ MMixerInitialize(
|
||||||
MixerList->MixerDataCount = 0;
|
MixerList->MixerDataCount = 0;
|
||||||
MixerList->WaveInListCount = 0;
|
MixerList->WaveInListCount = 0;
|
||||||
MixerList->WaveOutListCount = 0;
|
MixerList->WaveOutListCount = 0;
|
||||||
|
MixerList->MidiInListCount = 0;
|
||||||
|
MixerList->MidiOutListCount = 0;
|
||||||
InitializeListHead(&MixerList->MixerList);
|
InitializeListHead(&MixerList->MixerList);
|
||||||
InitializeListHead(&MixerList->MixerData);
|
InitializeListHead(&MixerList->MixerData);
|
||||||
InitializeListHead(&MixerList->WaveInList);
|
InitializeListHead(&MixerList->WaveInList);
|
||||||
InitializeListHead(&MixerList->WaveOutList);
|
InitializeListHead(&MixerList->WaveOutList);
|
||||||
|
InitializeListHead(&MixerList->MidiInList);
|
||||||
|
InitializeListHead(&MixerList->MidiOutList);
|
||||||
|
|
||||||
/* store mixer list */
|
/* store mixer list */
|
||||||
MixerContext->MixerContext = (PVOID)MixerList;
|
MixerContext->MixerContext = (PVOID)MixerList;
|
||||||
|
|
|
@ -122,6 +122,15 @@ ULONG
|
||||||
MMixerGetWaveOutCount(
|
MMixerGetWaveOutCount(
|
||||||
IN PMIXER_CONTEXT MixerContext);
|
IN PMIXER_CONTEXT MixerContext);
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
MMixerGetMidiInCount(
|
||||||
|
IN PMIXER_CONTEXT MixerContext);
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
MMixerGetMidiOutCount(
|
||||||
|
IN PMIXER_CONTEXT MixerContext);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
MIXER_STATUS
|
MIXER_STATUS
|
||||||
MMixerGetCapabilities(
|
MMixerGetCapabilities(
|
||||||
|
@ -199,3 +208,37 @@ MMixerGetWaveDevicePath(
|
||||||
IN ULONG bWaveIn,
|
IN ULONG bWaveIn,
|
||||||
IN ULONG DeviceId,
|
IN ULONG DeviceId,
|
||||||
OUT LPWSTR * DevicePath);
|
OUT LPWSTR * DevicePath);
|
||||||
|
|
||||||
|
MIXER_STATUS
|
||||||
|
MMixerMidiOutCapabilities(
|
||||||
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN ULONG DeviceIndex,
|
||||||
|
OUT LPMIDIOUTCAPSW Caps);
|
||||||
|
|
||||||
|
MIXER_STATUS
|
||||||
|
MMixerMidiInCapabilities(
|
||||||
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN ULONG DeviceIndex,
|
||||||
|
OUT LPMIDIINCAPSW Caps);
|
||||||
|
|
||||||
|
MIXER_STATUS
|
||||||
|
MMixerGetMidiDevicePath(
|
||||||
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN ULONG bMidiIn,
|
||||||
|
IN ULONG DeviceId,
|
||||||
|
OUT LPWSTR * DevicePath);
|
||||||
|
|
||||||
|
MIXER_STATUS
|
||||||
|
MMixerSetMidiStatus(
|
||||||
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN HANDLE PinHandle,
|
||||||
|
IN KSSTATE State);
|
||||||
|
|
||||||
|
MIXER_STATUS
|
||||||
|
MMixerOpenMidi(
|
||||||
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN ULONG DeviceIndex,
|
||||||
|
IN ULONG bMidiIn,
|
||||||
|
IN PIN_CREATE_CALLBACK CreateCallback,
|
||||||
|
IN PVOID Context,
|
||||||
|
OUT PHANDLE PinHandle);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
<define name="NDEBUG">1</define>
|
<define name="NDEBUG">1</define>
|
||||||
<file>controls.c</file>
|
<file>controls.c</file>
|
||||||
<file>filter.c</file>
|
<file>filter.c</file>
|
||||||
|
<file>midi.c</file>
|
||||||
<file>mixer.c</file>
|
<file>mixer.c</file>
|
||||||
<file>sup.c</file>
|
<file>sup.c</file>
|
||||||
<file>wave.c</file>
|
<file>wave.c</file>
|
||||||
|
|
|
@ -128,16 +128,38 @@ typedef struct
|
||||||
}u;
|
}u;
|
||||||
}WAVE_INFO, *LPWAVE_INFO;
|
}WAVE_INFO, *LPWAVE_INFO;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
LIST_ENTRY Entry;
|
||||||
|
ULONG DeviceId;
|
||||||
|
ULONG PinId;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
MIDIOUTCAPSW OutCaps;
|
||||||
|
MIDIINCAPSW InCaps;
|
||||||
|
}u;
|
||||||
|
|
||||||
|
}MIDI_INFO, *LPMIDI_INFO;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ULONG MixerListCount;
|
ULONG MixerListCount;
|
||||||
LIST_ENTRY MixerList;
|
LIST_ENTRY MixerList;
|
||||||
|
|
||||||
ULONG MixerDataCount;
|
ULONG MixerDataCount;
|
||||||
LIST_ENTRY MixerData;
|
LIST_ENTRY MixerData;
|
||||||
|
|
||||||
ULONG WaveInListCount;
|
ULONG WaveInListCount;
|
||||||
LIST_ENTRY WaveInList;
|
LIST_ENTRY WaveInList;
|
||||||
|
|
||||||
ULONG WaveOutListCount;
|
ULONG WaveOutListCount;
|
||||||
LIST_ENTRY WaveOutList;
|
LIST_ENTRY WaveOutList;
|
||||||
|
|
||||||
|
ULONG MidiInListCount;
|
||||||
|
LIST_ENTRY MidiInList;
|
||||||
|
|
||||||
|
ULONG MidiOutListCount;
|
||||||
|
LIST_ENTRY MidiOutList;
|
||||||
}MIXER_LIST, *PMIXER_LIST;
|
}MIXER_LIST, *PMIXER_LIST;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -196,16 +218,6 @@ MMixerFreeMixerInfo(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
IN LPMIXER_INFO MixerInfo);
|
IN LPMIXER_INFO MixerInfo);
|
||||||
|
|
||||||
MIXER_STATUS
|
|
||||||
MMixerGetTargetPins(
|
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
|
||||||
IN PKSMULTIPLE_ITEM NodeTypes,
|
|
||||||
IN PKSMULTIPLE_ITEM NodeConnections,
|
|
||||||
IN ULONG NodeIndex,
|
|
||||||
IN ULONG bUpDirection,
|
|
||||||
OUT PULONG Pins,
|
|
||||||
IN ULONG PinCount);
|
|
||||||
|
|
||||||
MIXER_STATUS
|
MIXER_STATUS
|
||||||
MMixerGetPhysicalConnection(
|
MMixerGetPhysicalConnection(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
@ -213,11 +225,6 @@ MMixerGetPhysicalConnection(
|
||||||
IN ULONG PinId,
|
IN ULONG PinId,
|
||||||
OUT PKSPIN_PHYSICALCONNECTION *OutConnection);
|
OUT PKSPIN_PHYSICALCONNECTION *OutConnection);
|
||||||
|
|
||||||
ULONG
|
|
||||||
MMixerGetIndexOfGuid(
|
|
||||||
PKSMULTIPLE_ITEM MultipleItem,
|
|
||||||
LPCGUID NodeType);
|
|
||||||
|
|
||||||
MIXER_STATUS
|
MIXER_STATUS
|
||||||
MMixerSetupFilter(
|
MMixerSetupFilter(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
@ -225,24 +232,24 @@ MMixerSetupFilter(
|
||||||
IN LPMIXER_DATA MixerData,
|
IN LPMIXER_DATA MixerData,
|
||||||
IN PULONG DeviceCount);
|
IN PULONG DeviceCount);
|
||||||
|
|
||||||
MIXER_STATUS
|
PKSPIN_CONNECT
|
||||||
MMixerGetTargetPinsByNodeConnectionIndex(
|
MMixerAllocatePinConnect(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
IN PKSMULTIPLE_ITEM NodeConnections,
|
ULONG DataFormatSize);
|
||||||
IN PKSMULTIPLE_ITEM NodeTypes,
|
|
||||||
IN ULONG bUpDirection,
|
|
||||||
IN ULONG NodeConnectionIndex,
|
|
||||||
IN ULONG PinCount,
|
|
||||||
OUT PULONG Pins);
|
|
||||||
|
|
||||||
MIXER_STATUS
|
MIXER_STATUS
|
||||||
MMixerGetControlsFromPin(
|
MMixerGetAudioPinDataRanges(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
IN PKSMULTIPLE_ITEM NodeConnections,
|
IN HANDLE hDevice,
|
||||||
IN PKSMULTIPLE_ITEM NodeTypes,
|
|
||||||
IN ULONG PinId,
|
IN ULONG PinId,
|
||||||
IN ULONG bUpDirection,
|
IN OUT PKSMULTIPLE_ITEM * OutMultipleItem);
|
||||||
OUT PULONG Nodes);
|
|
||||||
|
VOID
|
||||||
|
MMixerInitializeMidiForFilter(
|
||||||
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
IN PMIXER_LIST MixerList,
|
||||||
|
IN LPMIXER_DATA MixerData,
|
||||||
|
IN PTOPOLOGY Topology);
|
||||||
|
|
||||||
MIXER_STATUS
|
MIXER_STATUS
|
||||||
MMixerVerifyContext(
|
MMixerVerifyContext(
|
||||||
|
@ -314,12 +321,6 @@ MMixerCreateMixerData(
|
||||||
IN HANDLE hDevice,
|
IN HANDLE hDevice,
|
||||||
IN HANDLE hKey);
|
IN HANDLE hKey);
|
||||||
|
|
||||||
MIXER_STATUS
|
|
||||||
MMixerGetDeviceName(
|
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
|
||||||
IN LPMIXER_INFO MixerInfo,
|
|
||||||
IN HANDLE hKey);
|
|
||||||
|
|
||||||
MIXER_STATUS
|
MIXER_STATUS
|
||||||
MMixerInitializeWaveInfo(
|
MMixerInitializeWaveInfo(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
@ -337,6 +338,18 @@ MMixerAddEvent(
|
||||||
IN PVOID MixerEvent,
|
IN PVOID MixerEvent,
|
||||||
IN PMIXER_EVENT MixerEventRoutine);
|
IN PMIXER_EVENT MixerEventRoutine);
|
||||||
|
|
||||||
|
MIXER_STATUS
|
||||||
|
MMixerGetDeviceName(
|
||||||
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
OUT LPWSTR DeviceName,
|
||||||
|
IN HANDLE hKey);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MMixerInitializePinConnect(
|
||||||
|
IN OUT PKSPIN_CONNECT PinConnect,
|
||||||
|
IN ULONG PinId);
|
||||||
|
|
||||||
|
|
||||||
/* topology.c */
|
/* topology.c */
|
||||||
|
|
||||||
MIXER_STATUS
|
MIXER_STATUS
|
||||||
|
@ -448,3 +461,9 @@ MMixerIsTopologyNodeReserved(
|
||||||
IN PTOPOLOGY Topology,
|
IN PTOPOLOGY Topology,
|
||||||
IN ULONG NodeIndex,
|
IN ULONG NodeIndex,
|
||||||
OUT PULONG bReserved);
|
OUT PULONG bReserved);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MMixerGetTopologyPinCount(
|
||||||
|
IN PTOPOLOGY Topology,
|
||||||
|
OUT PULONG PinCount);
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,11 @@ const GUID KSPROPSETID_General = {0x1464EDA5L, 0x6A8F, 0x11D1,
|
||||||
const GUID KSPROPSETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
|
const GUID KSPROPSETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
|
||||||
const GUID KSEVENTSETID_AudioControlChange = {0xE85E9698L, 0xFA2F, 0x11D1, {0x95, 0xBD, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}};
|
const GUID KSEVENTSETID_AudioControlChange = {0xE85E9698L, 0xFA2F, 0x11D1, {0x95, 0xBD, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}};
|
||||||
|
|
||||||
|
const GUID KSDATAFORMAT_TYPE_MUSIC = {0xE725D360L, 0x62CC, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
|
||||||
|
const GUID KSDATAFORMAT_SUBTYPE_MIDI = {0x1D262760L, 0xE957, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
|
||||||
|
const GUID KSDATAFORMAT_SPECIFIER_NONE = {0x0F6417D6L, 0xC318, 0x11D0, {0xA4, 0x3F, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
|
||||||
|
|
||||||
|
|
||||||
MIXER_STATUS
|
MIXER_STATUS
|
||||||
MMixerVerifyContext(
|
MMixerVerifyContext(
|
||||||
IN PMIXER_CONTEXT MixerContext)
|
IN PMIXER_CONTEXT MixerContext)
|
||||||
|
@ -444,7 +449,7 @@ MMixerCreateMixerData(
|
||||||
MIXER_STATUS
|
MIXER_STATUS
|
||||||
MMixerGetDeviceName(
|
MMixerGetDeviceName(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
IN LPMIXER_INFO MixerInfo,
|
OUT LPWSTR DeviceName,
|
||||||
IN HANDLE hKey)
|
IN HANDLE hKey)
|
||||||
{
|
{
|
||||||
LPWSTR Name;
|
LPWSTR Name;
|
||||||
|
@ -457,10 +462,10 @@ MMixerGetDeviceName(
|
||||||
if (Status == MM_STATUS_SUCCESS)
|
if (Status == MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
/* copy device name */
|
/* copy device name */
|
||||||
MixerContext->Copy(MixerInfo->MixCaps.szPname, Name, min(wcslen(Name), MAXPNAMELEN-1) * sizeof(WCHAR));
|
MixerContext->Copy(DeviceName, Name, min(wcslen(Name), MAXPNAMELEN-1) * sizeof(WCHAR));
|
||||||
|
|
||||||
/* make sure its null terminated */
|
/* make sure its null terminated */
|
||||||
MixerInfo->MixCaps.szPname[MAXPNAMELEN-1] = L'\0';
|
DeviceName[MAXPNAMELEN-1] = L'\0';
|
||||||
|
|
||||||
/* free device name */
|
/* free device name */
|
||||||
MixerContext->Free(Name);
|
MixerContext->Free(Name);
|
||||||
|
@ -473,14 +478,14 @@ MMixerGetDeviceName(
|
||||||
if (Status != MM_STATUS_SUCCESS)
|
if (Status != MM_STATUS_SUCCESS)
|
||||||
return Status;
|
return Status;
|
||||||
|
|
||||||
Status = MixerContext->QueryKeyValue(hKey, L"FriendlyName", (PVOID*)&Name, &Length, &Type);
|
Status = MixerContext->QueryKeyValue(hTemp, L"FriendlyName", (PVOID*)&Name, &Length, &Type);
|
||||||
if (Status == MM_STATUS_SUCCESS)
|
if (Status == MM_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
/* copy device name */
|
/* copy device name */
|
||||||
MixerContext->Copy(MixerInfo->MixCaps.szPname, Name, min(wcslen(Name), MAXPNAMELEN-1) * sizeof(WCHAR));
|
MixerContext->Copy(DeviceName, Name, min(wcslen(Name), MAXPNAMELEN-1) * sizeof(WCHAR));
|
||||||
|
|
||||||
/* make sure its null terminated */
|
/* make sure its null terminated */
|
||||||
MixerInfo->MixCaps.szPname[MAXPNAMELEN-1] = L'\0';
|
DeviceName[MAXPNAMELEN-1] = L'\0';
|
||||||
|
|
||||||
/* free device name */
|
/* free device name */
|
||||||
MixerContext->Free(Name);
|
MixerContext->Free(Name);
|
||||||
|
@ -489,3 +494,21 @@ MMixerGetDeviceName(
|
||||||
MixerContext->CloseKey(hTemp);
|
MixerContext->CloseKey(hTemp);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MMixerInitializePinConnect(
|
||||||
|
IN OUT PKSPIN_CONNECT PinConnect,
|
||||||
|
IN ULONG PinId)
|
||||||
|
{
|
||||||
|
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->PinToHandle = NULL;
|
||||||
|
PinConnect->PinId = PinId;
|
||||||
|
PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL;
|
||||||
|
PinConnect->Priority.PrioritySubClass = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -983,6 +983,15 @@ MMixerGetNextNodesFromNodeIndex(
|
||||||
*OutNodesCount = TopologyNodesCount;
|
*OutNodesCount = TopologyNodesCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MMixerGetTopologyPinCount(
|
||||||
|
IN PTOPOLOGY Topology,
|
||||||
|
OUT PULONG PinCount)
|
||||||
|
{
|
||||||
|
/* store pin count */
|
||||||
|
*PinCount = Topology->TopologyPinsCount;
|
||||||
|
}
|
||||||
|
|
||||||
MIXER_STATUS
|
MIXER_STATUS
|
||||||
MMixerAllocateTopologyPinArray(
|
MMixerAllocateTopologyPinArray(
|
||||||
IN PMIXER_CONTEXT MixerContext,
|
IN PMIXER_CONTEXT MixerContext,
|
||||||
|
|
|
@ -109,22 +109,7 @@ MMixerGetWaveInfoByIndexAndType(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID
|
|
||||||
MMixerInitializePinConnect(
|
|
||||||
IN OUT PKSPIN_CONNECT PinConnect,
|
|
||||||
IN ULONG PinId)
|
|
||||||
{
|
|
||||||
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->PinToHandle = NULL;
|
|
||||||
PinConnect->PinId = PinId;
|
|
||||||
PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL;
|
|
||||||
PinConnect->Priority.PrioritySubClass = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MMixerInitializeDataFormat(
|
MMixerInitializeDataFormat(
|
||||||
|
@ -369,7 +354,7 @@ MMixerInitializeWaveInfo(
|
||||||
WaveInfo->PinId = Pins[0];
|
WaveInfo->PinId = Pins[0];
|
||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
ASSERT(wcslen(DeviceName) < MAXPNAMELEN);
|
ASSERT(wcslen(DeviceName) + 1 < MAXPNAMELEN);
|
||||||
|
|
||||||
/* copy device name */
|
/* copy device name */
|
||||||
if (bWaveIn)
|
if (bWaveIn)
|
||||||
|
|
Loading…
Reference in a new issue