Author: janderwald
Date: Sun Dec 20 01:55:55 2009
New Revision: 44664
URL:
http://svn.reactos.org/svn/reactos?rev=44664&view=rev
Log:
[MMIXER]
- Add support for enumerating wave in/out devices. Based on the wdmaud driver code
Added:
trunk/reactos/lib/drivers/sound/mmixer/wave.c (with props)
Modified:
trunk/reactos/lib/drivers/sound/mmixer/controls.c
trunk/reactos/lib/drivers/sound/mmixer/filter.c
trunk/reactos/lib/drivers/sound/mmixer/mixer.c
trunk/reactos/lib/drivers/sound/mmixer/mmixer.h
trunk/reactos/lib/drivers/sound/mmixer/mmixer.rbuild
trunk/reactos/lib/drivers/sound/mmixer/priv.h
Modified: trunk/reactos/lib/drivers/sound/mmixer/controls.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/mmixer/c…
==============================================================================
--- trunk/reactos/lib/drivers/sound/mmixer/controls.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/sound/mmixer/controls.c [iso-8859-1] Sun Dec 20 01:55:55
2009
@@ -827,6 +827,7 @@
ULONG BytesReturned;
KSP_PIN Pin;
LPWSTR Buffer = NULL;
+ ULONG PinId;
// allocate a mixer info struct
MixerInfo = (LPMIXER_INFO) MixerContext->Alloc(sizeof(MIXER_INFO));
@@ -864,10 +865,15 @@
// now get the target pins of the ADC / DAC node
Status = MMixerGetTargetPins(MixerContext, NodeTypes, NodeConnections, NodeIndex,
!bInputMixer, Pins, PinCount);
+ // find a target pin with a name
+ PinId = PinCount +1;
for(Index = 0; Index < PinCount; Index++)
{
if (Pins[Index])
{
+ // store index of pin
+ PinId = Index;
+
/* retrieve pin name */
Pin.PinId = Index;
Pin.Reserved = 0;
@@ -900,6 +906,12 @@
}
}
+ if (PinId < PinCount)
+ {
+ // create an wave info struct
+ MMixerInitializeWaveInfo(MixerContext, MixerList, MixerData,
MixerInfo->MixCaps.szPname, bInputMixer, PinId);
+ }
+
Status = MMixerCreateDestinationLine(MixerContext, MixerInfo, bInputMixer, Buffer);
if (Buffer)
Modified: trunk/reactos/lib/drivers/sound/mmixer/filter.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/mmixer/f…
==============================================================================
--- trunk/reactos/lib/drivers/sound/mmixer/filter.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/sound/mmixer/filter.c [iso-8859-1] Sun Dec 20 01:55:55 2009
@@ -251,3 +251,27 @@
DPRINT("Status %x bSet %u NodeId %u Value %d PropertyId %u\n", Status,
bSet, NodeId, Value, PropertyId);
return Status;
}
+
+ULONG
+MMixerGetPinInstanceCount(
+ PMIXER_CONTEXT MixerContext,
+ HANDLE hFilter,
+ ULONG PinId)
+{
+ KSP_PIN PinRequest;
+ KSPIN_CINSTANCES PinInstances;
+ ULONG BytesReturned;
+ MIXER_STATUS Status;
+
+ /* query the instance count */
+ PinRequest.Reserved = 0;
+ PinRequest.PinId = PinId;
+ PinRequest.Property.Set = KSPROPSETID_Pin;
+ PinRequest.Property.Flags = KSPROPERTY_TYPE_GET;
+ PinRequest.Property.Id = KSPROPERTY_PIN_CINSTANCES;
+
+ Status = MixerContext->Control(hFilter, IOCTL_KS_PROPERTY, (PVOID)&PinRequest,
sizeof(KSP_PIN), (PVOID)&PinInstances, sizeof(KSPIN_CINSTANCES), &BytesReturned);
+ ASSERT(Status == MM_STATUS_SUCCESS);
+ return PinInstances.CurrentCount;
+}
+
Modified: trunk/reactos/lib/drivers/sound/mmixer/mixer.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/mmixer/m…
==============================================================================
--- trunk/reactos/lib/drivers/sound/mmixer/mixer.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/sound/mmixer/mixer.c [iso-8859-1] Sun Dec 20 01:55:55 2009
@@ -215,7 +215,7 @@
IN PMIXER_CONTEXT MixerContext,
IN HANDLE MixerHandle,
IN ULONG Flags,
- OUT LPMIXERLINECONTROLS MixerLineControls)
+ OUT LPMIXERLINECONTROLSW MixerLineControls)
{
LPMIXER_INFO MixerInfo;
LPMIXERLINE_EXT MixerLineSrc;
@@ -440,8 +440,13 @@
//initialize mixer list
MixerList->MixerListCount = 0;
MixerList->MixerDataCount = 0;
+ MixerList->WaveInListCount = 0;
+ MixerList->WaveOutListCount = 0;
InitializeListHead(&MixerList->MixerList);
InitializeListHead(&MixerList->MixerData);
+ InitializeListHead(&MixerList->WaveInList);
+ InitializeListHead(&MixerList->WaveOutList);
+
// store mixer list
MixerContext->MixerContext = (PVOID)MixerList;
Modified: trunk/reactos/lib/drivers/sound/mmixer/mmixer.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/mmixer/m…
==============================================================================
--- trunk/reactos/lib/drivers/sound/mmixer/mmixer.h [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/sound/mmixer/mmixer.h [iso-8859-1] Sun Dec 20 01:55:55 2009
@@ -95,6 +95,15 @@
MMixerGetCount(
IN PMIXER_CONTEXT MixerContext);
+ULONG
+MMixerGetWaveInCount(
+ IN PMIXER_CONTEXT MixerContext);
+
+ULONG
+MMixerGetWaveOutCount(
+ IN PMIXER_CONTEXT MixerContext);
+
+
MIXER_STATUS
MMixerGetCapabilities(
IN PMIXER_CONTEXT MixerContext,
@@ -121,7 +130,7 @@
IN PMIXER_CONTEXT MixerContext,
IN HANDLE MixerHandle,
IN ULONG Flags,
- OUT LPMIXERLINECONTROLS MixerLineControls);
+ OUT LPMIXERLINECONTROLSW MixerLineControls);
MIXER_STATUS
MMixerSetControlDetails(
@@ -137,4 +146,24 @@
IN ULONG Flags,
OUT LPMIXERCONTROLDETAILS MixerControlDetails);
+MIXER_STATUS
+MMixerWaveOutCapabilities(
+ IN PMIXER_CONTEXT MixerContext,
+ IN ULONG DeviceIndex,
+ OUT LPWAVEOUTCAPSW Caps);
+
+MIXER_STATUS
+MMixerWaveInCapabilities(
+ IN PMIXER_CONTEXT MixerContext,
+ IN ULONG DeviceIndex,
+ OUT LPWAVEINCAPSW Caps);
+
+MIXER_STATUS
+MMixerOpenWave(
+ IN PMIXER_CONTEXT MixerContext,
+ IN ULONG DeviceIndex,
+ IN ULONG bWaveIn,
+ IN LPWAVEFORMATEX WaveFormat,
+ OUT PHANDLE PinHandle);
+
#endif
Modified: trunk/reactos/lib/drivers/sound/mmixer/mmixer.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/mmixer/m…
==============================================================================
--- trunk/reactos/lib/drivers/sound/mmixer/mmixer.rbuild [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/sound/mmixer/mmixer.rbuild [iso-8859-1] Sun Dec 20 01:55:55
2009
@@ -7,4 +7,5 @@
<file>filter.c</file>
<file>mixer.c</file>
<file>sup.c</file>
+ <file>wave.c</file>
</module>
Modified: trunk/reactos/lib/drivers/sound/mmixer/priv.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/mmixer/p…
==============================================================================
--- trunk/reactos/lib/drivers/sound/mmixer/priv.h [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/sound/mmixer/priv.h [iso-8859-1] Sun Dec 20 01:55:55 2009
@@ -66,10 +66,26 @@
typedef struct
{
+ LIST_ENTRY Entry;
+ ULONG DeviceId;
+ ULONG PinId;
+ union
+ {
+ WAVEOUTCAPSW OutCaps;
+ WAVEINCAPSW InCaps;
+ }u;
+}WAVE_INFO, *LPWAVE_INFO;
+
+typedef struct
+{
ULONG MixerListCount;
LIST_ENTRY MixerList;
ULONG MixerDataCount;
LIST_ENTRY MixerData;
+ ULONG WaveInListCount;
+ LIST_ENTRY WaveInList;
+ ULONG WaveOutListCount;
+ LIST_ENTRY WaveOutList;
}MIXER_LIST, *PMIXER_LIST;
#define DESTINATION_LINE 0xFFFF0000
@@ -243,4 +259,13 @@
IN LPMIXER_INFO MixerInfo,
IN HANDLE hKey);
+MIXER_STATUS
+MMixerInitializeWaveInfo(
+ IN PMIXER_CONTEXT MixerContext,
+ IN PMIXER_LIST MixerList,
+ IN LPMIXER_DATA MixerData,
+ IN LPWSTR DeviceName,
+ IN ULONG bWaveIn,
+ IN ULONG PinId);
+
#endif
Added: trunk/reactos/lib/drivers/sound/mmixer/wave.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/mmixer/w…
==============================================================================
--- trunk/reactos/lib/drivers/sound/mmixer/wave.c (added)
+++ trunk/reactos/lib/drivers/sound/mmixer/wave.c [iso-8859-1] Sun Dec 20 01:55:55 2009
@@ -1,0 +1,578 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel Streaming
+ * FILE: lib/drivers/sound/mmixer/mmixer.c
+ * PURPOSE: Mixer Handling Functions
+ * PROGRAMMER: Johannes Anderwald
+ */
+
+#include "priv.h"
+
+const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX = {0x05589f81L, 0xc356, 0x11ce, {0xbf,
0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}};
+const GUID KSDATAFORMAT_SUBTYPE_PCM = {0x00000001L, 0x0000, 0x0010, {0x80,
0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+const GUID KSDATAFORMAT_TYPE_AUDIO = {0x73647561L, 0x0000, 0x0010, {0x80,
0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+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}};
+
+typedef struct
+{
+ ULONG SampleRate;
+ ULONG Bit8Mono;
+ ULONG Bit8Stereo;
+ ULONG Bit16Mono;
+ ULONG Bit16Stereo;
+}AUDIO_RANGE;
+
+#define AUDIO_TEST_RANGE (5)
+
+static AUDIO_RANGE TestRange[AUDIO_TEST_RANGE] =
+{
+ {
+ 11025,
+ WAVE_FORMAT_1M08,
+ WAVE_FORMAT_1S08,
+ WAVE_FORMAT_1M16,
+ WAVE_FORMAT_1S16
+ },
+ {
+ 22050,
+ WAVE_FORMAT_2M08,
+ WAVE_FORMAT_2S08,
+ WAVE_FORMAT_2M16,
+ WAVE_FORMAT_2S16
+ },
+ {
+ 44100,
+ WAVE_FORMAT_4M08,
+ WAVE_FORMAT_4S08,
+ WAVE_FORMAT_4M16,
+ WAVE_FORMAT_4S16
+ },
+ {
+ 48000,
+ WAVE_FORMAT_48M08,
+ WAVE_FORMAT_48S08,
+ WAVE_FORMAT_48M16,
+ WAVE_FORMAT_48S16
+ },
+ {
+ 96000,
+ WAVE_FORMAT_96M08,
+ WAVE_FORMAT_96S08,
+ WAVE_FORMAT_96M16,
+ WAVE_FORMAT_96S16
+ }
+};
+
+PKSPIN_CONNECT
+MMixerAllocatePinConnect(
+ IN PMIXER_CONTEXT MixerContext,
+ ULONG DataFormatSize)
+{
+ return MixerContext->Alloc(sizeof(KSPIN_CONNECT) + DataFormatSize);
+}
+
+MIXER_STATUS
+MMixerGetWaveInfoByIndexAndType(
+ IN PMIXER_LIST MixerList,
+ IN ULONG DeviceIndex,
+ IN ULONG bWaveInType,
+ OUT LPWAVE_INFO *OutWaveInfo)
+{
+ ULONG Index = 0;
+ PLIST_ENTRY Entry, ListHead;
+ LPWAVE_INFO WaveInfo;
+
+ if (bWaveInType)
+ ListHead = &MixerList->WaveInList;
+ else
+ ListHead = &MixerList->WaveOutList;
+
+ /* get first entry */
+ Entry = ListHead->Flink;
+
+ while(Entry != ListHead)
+ {
+ WaveInfo = (LPWAVE_INFO)CONTAINING_RECORD(Entry, WAVE_INFO, Entry);
+
+ if (Index == DeviceIndex)
+ {
+ *OutWaveInfo = WaveInfo;
+ return MM_STATUS_SUCCESS;
+ }
+ Index++;
+ Entry = Entry->Flink;
+ }
+
+ return MM_STATUS_INVALID_PARAMETER;
+}
+
+
+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
+MMixerInitializeDataFormat(
+ IN PKSDATAFORMAT_WAVEFORMATEX DataFormat,
+ LPWAVEFORMATEX WaveFormatEx)
+{
+
+ DataFormat->WaveFormatEx.wFormatTag = WaveFormatEx->wFormatTag;
+ DataFormat->WaveFormatEx.nChannels = WaveFormatEx->nChannels;
+ DataFormat->WaveFormatEx.nSamplesPerSec = WaveFormatEx->nSamplesPerSec;
+ DataFormat->WaveFormatEx.nBlockAlign = WaveFormatEx->nBlockAlign;
+ DataFormat->WaveFormatEx.nAvgBytesPerSec = WaveFormatEx->nAvgBytesPerSec;
+ DataFormat->WaveFormatEx.wBitsPerSample = WaveFormatEx->wBitsPerSample;
+ DataFormat->WaveFormatEx.cbSize = 0;
+ DataFormat->DataFormat.FormatSize = sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX);
+ DataFormat->DataFormat.Flags = 0;
+ 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;
+}
+
+
+MIXER_STATUS
+MMixerGetAudioPinDataRanges(
+ IN PMIXER_CONTEXT MixerContext,
+ IN HANDLE hDevice,
+ IN ULONG PinId,
+ IN OUT PKSMULTIPLE_ITEM * OutMultipleItem)
+{
+ KSP_PIN PinProperty;
+ ULONG BytesReturned = 0;
+ MIXER_STATUS Status;
+ PKSMULTIPLE_ITEM MultipleItem;
+
+ /* retrieve size of data ranges buffer */
+ PinProperty.Reserved = 0;
+ PinProperty.PinId = PinId;
+ PinProperty.Property.Set = KSPROPSETID_Pin;
+ PinProperty.Property.Id = KSPROPERTY_PIN_DATARANGES;
+ PinProperty.Property.Flags = KSPROPERTY_TYPE_GET;
+
+ Status = MixerContext->Control(hDevice, IOCTL_KS_PROPERTY,
(PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)NULL, 0, &BytesReturned);
+ if (Status != MM_STATUS_MORE_ENTRIES)
+ {
+ return Status;
+ }
+
+ MultipleItem = MixerContext->Alloc(BytesReturned);
+ if (!MultipleItem)
+ {
+ /* not enough memory */
+ return MM_STATUS_NO_MEMORY;
+ }
+
+ Status = MixerContext->Control(hDevice, IOCTL_KS_PROPERTY,
(PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)MultipleItem, BytesReturned,
&BytesReturned);
+ if (Status != MM_STATUS_SUCCESS)
+ {
+ /* failed */
+ MixerContext->Free(MultipleItem);
+ return Status;
+ }
+
+ /* save result */
+ *OutMultipleItem = MultipleItem;
+ return Status;
+}
+
+MIXER_STATUS
+MMixerFindAudioDataRange(
+ PKSMULTIPLE_ITEM MultipleItem,
+ PKSDATARANGE_AUDIO * OutDataRangeAudio)
+{
+ ULONG Index;
+ PKSDATARANGE_AUDIO DataRangeAudio;
+ PKSDATARANGE DataRange;
+
+ DataRange = (PKSDATARANGE) (MultipleItem + 1);
+ for(Index = 0; Index < MultipleItem->Count; Index++)
+ {
+ if (DataRange->FormatSize == sizeof(KSDATARANGE_AUDIO))
+ {
+ DataRangeAudio = (PKSDATARANGE_AUDIO)DataRange;
+ if (IsEqualGUIDAligned(&DataRangeAudio->DataRange.MajorFormat,
&KSDATAFORMAT_TYPE_AUDIO) &&
+ IsEqualGUIDAligned(&DataRangeAudio->DataRange.SubFormat,
&KSDATAFORMAT_SUBTYPE_PCM) &&
+ IsEqualGUIDAligned(&DataRangeAudio->DataRange.Specifier,
&KSDATAFORMAT_SPECIFIER_WAVEFORMATEX))
+ {
+ DPRINT("Min Sample %u Max Sample %u Min Bits %u Max Bits %u Max
Channel %u\n", DataRangeAudio->MinimumSampleFrequency,
DataRangeAudio->MaximumSampleFrequency,
+
DataRangeAudio->MinimumBitsPerSample, DataRangeAudio->MaximumBitsPerSample,
DataRangeAudio->MaximumChannels);
+ *OutDataRangeAudio = DataRangeAudio;
+ return MM_STATUS_SUCCESS;
+ }
+ }
+ DataRange = (PKSDATARANGE)((ULONG_PTR)DataRange + DataRange->FormatSize);
+ }
+ return MM_STATUS_UNSUCCESSFUL;
+}
+
+MIXER_STATUS
+MMixerOpenWavePin(
+ IN PMIXER_CONTEXT MixerContext,
+ IN PMIXER_LIST MixerList,
+ IN ULONG DeviceId,
+ IN ULONG PinId,
+ IN LPWAVEFORMATEX WaveFormatEx,
+ IN ACCESS_MASK DesiredAccess,
+ OUT PHANDLE PinHandle)
+{
+ PKSPIN_CONNECT PinConnect;
+ PKSDATAFORMAT_WAVEFORMATEX DataFormat;
+ LPMIXER_DATA MixerData;
+ NTSTATUS Status;
+
+ MixerData = MMixerGetDataByDeviceId(MixerList, DeviceId);
+ if (!MixerData)
+ return MM_STATUS_INVALID_PARAMETER;
+
+ /* allocate pin connect */
+ PinConnect = MMixerAllocatePinConnect(MixerContext,
sizeof(KSDATAFORMAT_WAVEFORMATEX));
+ if (!PinConnect)
+ {
+ /* no memory */
+ return MM_STATUS_NO_MEMORY;
+ }
+
+ /* initialize pin connect struct */
+ MMixerInitializePinConnect(PinConnect, PinId);
+
+ /* get offset to dataformat */
+ DataFormat = (PKSDATAFORMAT_WAVEFORMATEX) (PinConnect + 1);
+ /* initialize with requested wave format */
+ MMixerInitializeDataFormat(DataFormat, WaveFormatEx);
+
+ /* now create the pin */
+ Status = KsCreatePin(MixerData->hDevice, PinConnect, DesiredAccess, PinHandle);
+
+ /* free create info */
+ MixerContext->Free(PinConnect);
+
+ if (Status == STATUS_SUCCESS)
+ return MM_STATUS_SUCCESS;
+ else
+ return MM_STATUS_UNSUCCESSFUL;
+}
+
+VOID
+MMixerCheckFormat(
+ IN PKSDATARANGE_AUDIO DataRangeAudio,
+ IN LPWAVE_INFO WaveInfo,
+ IN ULONG bInput)
+{
+ ULONG Index, SampleFrequency;
+ ULONG Result = 0;
+
+ for(Index = 0; Index < AUDIO_TEST_RANGE; Index++)
+ {
+ SampleFrequency = TestRange[Index].SampleRate;
+
+ if (DataRangeAudio->MinimumSampleFrequency <= SampleFrequency &&
DataRangeAudio->MaximumSampleFrequency >= SampleFrequency)
+ {
+ /* the audio adapter supports the sample frequency */
+ if (DataRangeAudio->MinimumBitsPerSample <= 8 &&
DataRangeAudio->MaximumBitsPerSample >= 8)
+ {
+ Result |= TestRange[Index].Bit8Mono;
+
+ if (DataRangeAudio->MaximumChannels > 1)
+ {
+ /* check if pin supports the sample rate in 8-Bit Stereo */
+ Result |= TestRange[Index].Bit8Stereo;
+ }
+ }
+
+ if (DataRangeAudio->MinimumBitsPerSample <= 16 &&
DataRangeAudio->MaximumBitsPerSample >= 16)
+ {
+ /* check if pin supports the sample rate in 16-Bit Mono */
+ Result |= TestRange[Index].Bit16Mono;
+
+
+ if (DataRangeAudio->MaximumChannels > 1)
+ {
+ /* check if pin supports the sample rate in 16-Bit Stereo */
+ Result |= TestRange[Index].Bit16Stereo;
+ }
+ }
+ }
+ }
+
+
+ if (bInput)
+ WaveInfo->u.InCaps.dwFormats = Result;
+ else
+ WaveInfo->u.OutCaps.dwFormats = Result;
+
+ DPRINT("Format %lx bInput %u\n", Result, bInput);
+}
+
+MIXER_STATUS
+MMixerInitializeWaveInfo(
+ IN PMIXER_CONTEXT MixerContext,
+ IN PMIXER_LIST MixerList,
+ IN LPMIXER_DATA MixerData,
+ IN LPWSTR DeviceName,
+ IN ULONG bWaveIn,
+ IN ULONG PinId)
+{
+ MIXER_STATUS Status;
+ PKSMULTIPLE_ITEM MultipleItem;
+ PKSDATARANGE_AUDIO DataRangeAudio;
+ LPWAVE_INFO WaveInfo;
+
+ WaveInfo = (LPWAVE_INFO)MixerContext->Alloc(sizeof(WAVE_INFO));
+ if (!WaveInfo)
+ return MM_STATUS_NO_MEMORY;
+
+ /* initialize wave info */
+ WaveInfo->DeviceId = MixerData->DeviceId;
+ WaveInfo->PinId = PinId;
+
+ /* FIXME determine manufacturer / product id */
+ if (bWaveIn)
+ {
+ WaveInfo->u.InCaps.wMid = MM_MICROSOFT;
+ WaveInfo->u.InCaps.wPid = MM_PID_UNMAPPED;
+ WaveInfo->u.InCaps.vDriverVersion = 1;
+ }
+ else
+ {
+ WaveInfo->u.OutCaps.wMid = MM_MICROSOFT;
+ WaveInfo->u.OutCaps.wPid = MM_PID_UNMAPPED;
+ WaveInfo->u.OutCaps.vDriverVersion = 1;
+ }
+
+ /* get audio pin data ranges */
+ Status = MMixerGetAudioPinDataRanges(MixerContext, MixerData->hDevice, PinId,
&MultipleItem);
+ if (Status != MM_STATUS_SUCCESS)
+ {
+ /* failed to get audio pin data ranges */
+ MixerContext->Free(WaveInfo);
+ return MM_STATUS_UNSUCCESSFUL;
+ }
+
+ /* find an KSDATARANGE_AUDIO range */
+ Status = MMixerFindAudioDataRange(MultipleItem, &DataRangeAudio);
+ if (Status != MM_STATUS_SUCCESS)
+ {
+ /* failed to find audio pin data range */
+ MixerContext->Free(MultipleItem);
+ MixerContext->Free(WaveInfo);
+ return MM_STATUS_UNSUCCESSFUL;
+ }
+
+ /* store channel count */
+ if (bWaveIn)
+ {
+ WaveInfo->u.InCaps.wChannels = DataRangeAudio->MaximumChannels;
+ }
+ else
+ {
+ WaveInfo->u.OutCaps.wChannels = DataRangeAudio->MaximumChannels;
+ }
+
+ /* get all supported formats */
+ MMixerCheckFormat(DataRangeAudio, WaveInfo, bWaveIn);
+
+ /* free dataranges buffer */
+ MixerContext->Free(MultipleItem);
+
+
+ if (bWaveIn)
+ {
+ InsertTailList(&MixerList->WaveInList, &WaveInfo->Entry);
+ MixerList->WaveInListCount++;
+ }
+ else
+ {
+ InsertTailList(&MixerList->WaveOutList, &WaveInfo->Entry);
+ MixerList->WaveOutListCount++;
+ }
+
+ return MM_STATUS_SUCCESS;
+}
+
+MIXER_STATUS
+MMixerOpenWave(
+ IN PMIXER_CONTEXT MixerContext,
+ IN ULONG DeviceIndex,
+ IN ULONG bWaveIn,
+ IN LPWAVEFORMATEX WaveFormat,
+ OUT PHANDLE PinHandle)
+{
+ PMIXER_LIST MixerList;
+ MIXER_STATUS Status;
+ LPWAVE_INFO WaveInfo;
+ 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;
+
+ if (WaveFormat->wFormatTag != WAVE_FORMAT_PCM)
+ {
+ // not implemented
+ return MM_STATUS_NOT_IMPLEMENTED;
+ }
+
+ /* find destination wave */
+ Status = MMixerGetWaveInfoByIndexAndType(MixerList, DeviceIndex, bWaveIn,
&WaveInfo);
+ if (Status != MM_STATUS_SUCCESS)
+ {
+ /* failed to find wave info */
+ return MM_STATUS_INVALID_PARAMETER;
+ }
+
+ /* get desired access */
+ if (bWaveIn)
+ {
+ DesiredAccess |= GENERIC_READ;
+ }
+ else
+ {
+ DesiredAccess |= GENERIC_WRITE;
+ }
+
+ /* now try open the pin */
+ return MMixerOpenWavePin(MixerContext, MixerList, WaveInfo->DeviceId,
WaveInfo->PinId, WaveFormat, DesiredAccess, PinHandle);
+}
+
+MIXER_STATUS
+MMixerWaveInCapabilities(
+ IN PMIXER_CONTEXT MixerContext,
+ IN ULONG DeviceIndex,
+ OUT LPWAVEINCAPSW Caps)
+{
+ PMIXER_LIST MixerList;
+ MIXER_STATUS Status;
+ LPWAVE_INFO WaveInfo;
+
+ // 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 wave */
+ Status = MMixerGetWaveInfoByIndexAndType(MixerList, DeviceIndex, TRUE,
&WaveInfo);
+ if (Status != MM_STATUS_SUCCESS)
+ {
+ /* failed to find wave info */
+ return MM_STATUS_UNSUCCESSFUL;
+ }
+
+ //copy capabilities
+ MixerContext->Copy(Caps, &WaveInfo->u.InCaps, sizeof(WAVEINCAPSW));
+
+ return MM_STATUS_SUCCESS;
+}
+
+MIXER_STATUS
+MMixerWaveOutCapabilities(
+ IN PMIXER_CONTEXT MixerContext,
+ IN ULONG DeviceIndex,
+ OUT LPWAVEOUTCAPSW Caps)
+{
+ PMIXER_LIST MixerList;
+ MIXER_STATUS Status;
+ LPWAVE_INFO WaveInfo;
+
+ // 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 wave */
+ Status = MMixerGetWaveInfoByIndexAndType(MixerList, DeviceIndex, FALSE,
&WaveInfo);
+ if (Status != MM_STATUS_SUCCESS)
+ {
+ /* failed to find wave info */
+ return MM_STATUS_UNSUCCESSFUL;
+ }
+
+ //copy capabilities
+ MixerContext->Copy(Caps, &WaveInfo->u.OutCaps, sizeof(WAVEOUTCAPSW));
+
+ return MM_STATUS_SUCCESS;
+}
+
+ULONG
+MMixerGetWaveInCount(
+ 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 0;
+ }
+
+ // grab mixer list
+ MixerList = (PMIXER_LIST)MixerContext->MixerContext;
+
+ return MixerList->WaveInListCount;
+}
+
+ULONG
+MMixerGetWaveOutCount(
+ 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 0;
+ }
+
+ // grab mixer list
+ MixerList = (PMIXER_LIST)MixerContext->MixerContext;
+
+ return MixerList->WaveOutListCount;
+}
Propchange: trunk/reactos/lib/drivers/sound/mmixer/wave.c
------------------------------------------------------------------------------
svn:eol-style = native