[MMIXER]
[reactos.git] / reactos / lib / drivers / sound / mmixer / filter.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: lib/drivers/sound/mmixer/filter.c
5 * PURPOSE: Mixer Filter Functions
6 * PROGRAMMER: Johannes Anderwald
7 */
8
9
10
11 #include "priv.h"
12
13 ULONG
14 MMixerGetFilterPinCount(
15 IN PMIXER_CONTEXT MixerContext,
16 IN HANDLE hMixer)
17 {
18 KSPROPERTY Pin;
19 MIXER_STATUS Status;
20 ULONG NumPins, BytesReturned;
21
22 // setup property request
23 Pin.Flags = KSPROPERTY_TYPE_GET;
24 Pin.Set = KSPROPSETID_Pin;
25 Pin.Id = KSPROPERTY_PIN_CTYPES;
26
27 // query pin count
28 Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&NumPins, sizeof(ULONG), (PULONG)&BytesReturned);
29
30 // check for success
31 if (Status != MM_STATUS_SUCCESS)
32 return 0;
33
34 return NumPins;
35 }
36
37 MIXER_STATUS
38 MMixerGetFilterTopologyProperty(
39 IN PMIXER_CONTEXT MixerContext,
40 IN HANDLE hMixer,
41 IN ULONG PropertyId,
42 OUT PKSMULTIPLE_ITEM * OutMultipleItem)
43 {
44 KSPROPERTY Property;
45 PKSMULTIPLE_ITEM MultipleItem;
46 MIXER_STATUS Status;
47 ULONG BytesReturned;
48
49 // setup property request
50 Property.Id = PropertyId;
51 Property.Flags = KSPROPERTY_TYPE_GET;
52 Property.Set = KSPROPSETID_Topology;
53
54 // query for the size
55 Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), NULL, 0, &BytesReturned);
56
57 if (Status != MM_STATUS_MORE_ENTRIES)
58 return Status;
59
60 // allocate an result buffer
61 MultipleItem = (PKSMULTIPLE_ITEM)MixerContext->Alloc(BytesReturned);
62
63 if (!MultipleItem)
64 {
65 // not enough memory
66 return MM_STATUS_NO_MEMORY;
67 }
68
69 // query again with allocated buffer
70 Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)MultipleItem, BytesReturned, &BytesReturned);
71
72 if (Status != MM_STATUS_SUCCESS)
73 {
74 // failed
75 MixerContext->Free((PVOID)MultipleItem);
76 return Status;
77 }
78
79 // store result
80 *OutMultipleItem = MultipleItem;
81
82 // done
83 return Status;
84 }
85
86 MIXER_STATUS
87 MMixerGetPhysicalConnection(
88 IN PMIXER_CONTEXT MixerContext,
89 IN HANDLE hMixer,
90 IN ULONG PinId,
91 OUT PKSPIN_PHYSICALCONNECTION *OutConnection)
92 {
93 KSP_PIN Pin;
94 MIXER_STATUS Status;
95 ULONG BytesReturned;
96 PKSPIN_PHYSICALCONNECTION Connection;
97
98 /* setup the request */
99 Pin.Property.Flags = KSPROPERTY_TYPE_GET;
100 Pin.Property.Id = KSPROPERTY_PIN_PHYSICALCONNECTION;
101 Pin.Property.Set = KSPROPSETID_Pin;
102 Pin.PinId = PinId;
103
104 /* query the pin for the physical connection */
105 Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), NULL, 0, &BytesReturned);
106
107 if (Status == MM_STATUS_UNSUCCESSFUL)
108 {
109 // pin does not have a physical connection
110 return Status;
111 }
112
113 Connection = (PKSPIN_PHYSICALCONNECTION)MixerContext->Alloc(BytesReturned);
114 if (!Connection)
115 {
116 // not enough memory
117 return MM_STATUS_NO_MEMORY;
118 }
119
120 // query the pin for the physical connection
121 Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)Connection, BytesReturned, &BytesReturned);
122 if (Status != MM_STATUS_SUCCESS)
123 {
124 // failed to query the physical connection
125 MixerContext->Free(Connection);
126 return Status;
127 }
128
129 // store connection
130 *OutConnection = Connection;
131 return Status;
132 }
133
134 ULONG
135 MMixerGetControlTypeFromTopologyNode(
136 IN LPGUID NodeType)
137 {
138 if (IsEqualGUIDAligned(NodeType, (LPGUID)&KSNODETYPE_AGC))
139 {
140 // automatic gain control
141 return MIXERCONTROL_CONTROLTYPE_ONOFF;
142 }
143 else if (IsEqualGUIDAligned(NodeType, (LPGUID)&KSNODETYPE_LOUDNESS))
144 {
145 // loudness control
146 return MIXERCONTROL_CONTROLTYPE_LOUDNESS;
147 }
148 else if (IsEqualGUIDAligned(NodeType, (LPGUID)&KSNODETYPE_MUTE ))
149 {
150 // mute control
151 return MIXERCONTROL_CONTROLTYPE_MUTE;
152 }
153 else if (IsEqualGUIDAligned(NodeType, (LPGUID)&KSNODETYPE_TONE))
154 {
155 // tpne control
156 //FIXME
157 // MIXERCONTROL_CONTROLTYPE_ONOFF if KSPROPERTY_AUDIO_BASS_BOOST is supported
158 // MIXERCONTROL_CONTROLTYPE_BASS if KSPROPERTY_AUDIO_BASS is supported
159 // MIXERCONTROL_CONTROLTYPE_TREBLE if KSPROPERTY_AUDIO_TREBLE is supported
160 UNIMPLEMENTED;
161 return MIXERCONTROL_CONTROLTYPE_ONOFF;
162 }
163 else if (IsEqualGUIDAligned(NodeType, (LPGUID)&KSNODETYPE_VOLUME))
164 {
165 // volume control
166 return MIXERCONTROL_CONTROLTYPE_VOLUME;
167 }
168 else if (IsEqualGUIDAligned(NodeType, (LPGUID)&KSNODETYPE_PEAKMETER))
169 {
170 // peakmeter control
171 return MIXERCONTROL_CONTROLTYPE_PEAKMETER;
172 }
173 else if (IsEqualGUIDAligned(NodeType, (LPGUID)&KSNODETYPE_MUX))
174 {
175 // mux control
176 return MIXERCONTROL_CONTROLTYPE_MUX;
177 }
178 else if (IsEqualGUIDAligned(NodeType, (LPGUID)&KSNODETYPE_MUX))
179 {
180 // mux control
181 return MIXERCONTROL_CONTROLTYPE_MUX;
182 }
183 else if (IsEqualGUIDAligned(NodeType, (LPGUID)&KSNODETYPE_STEREO_WIDE))
184 {
185 // stero wide control
186 return MIXERCONTROL_CONTROLTYPE_FADER;
187 }
188 else if (IsEqualGUIDAligned(NodeType, (LPGUID)&KSNODETYPE_CHORUS))
189 {
190 // chorus control
191 return MIXERCONTROL_CONTROLTYPE_FADER;
192 }
193 else if (IsEqualGUIDAligned(NodeType, (LPGUID)&KSNODETYPE_REVERB))
194 {
195 // reverb control
196 return MIXERCONTROL_CONTROLTYPE_FADER;
197 }
198 else if (IsEqualGUIDAligned(NodeType, (LPGUID)&KSNODETYPE_SUPERMIX))
199 {
200 // supermix control
201 // MIXERCONTROL_CONTROLTYPE_MUTE if KSPROPERTY_AUDIO_MUTE is supported
202 UNIMPLEMENTED;
203 return MIXERCONTROL_CONTROLTYPE_VOLUME;
204 }
205 UNIMPLEMENTED
206 return 0;
207 }