9a2739e299244a8e9026d1040981c07ebabe3e95
[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 /* sanity check */
61 ASSERT(BytesReturned);
62
63 /* allocate an result buffer */
64 MultipleItem = (PKSMULTIPLE_ITEM)MixerContext->Alloc(BytesReturned);
65
66 if (!MultipleItem)
67 {
68 /* not enough memory */
69 return MM_STATUS_NO_MEMORY;
70 }
71
72 /* query again with allocated buffer */
73 Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)MultipleItem, BytesReturned, &BytesReturned);
74
75 if (Status != MM_STATUS_SUCCESS)
76 {
77 /* failed */
78 MixerContext->Free((PVOID)MultipleItem);
79 return Status;
80 }
81
82 /* store result */
83 *OutMultipleItem = MultipleItem;
84
85 /* done */
86 return Status;
87 }
88
89 MIXER_STATUS
90 MMixerGetPhysicalConnection(
91 IN PMIXER_CONTEXT MixerContext,
92 IN HANDLE hMixer,
93 IN ULONG PinId,
94 OUT PKSPIN_PHYSICALCONNECTION *OutConnection)
95 {
96 KSP_PIN Pin;
97 MIXER_STATUS Status;
98 ULONG BytesReturned;
99 PKSPIN_PHYSICALCONNECTION Connection;
100
101 /* setup the request */
102 Pin.Property.Flags = KSPROPERTY_TYPE_GET;
103 Pin.Property.Id = KSPROPERTY_PIN_PHYSICALCONNECTION;
104 Pin.Property.Set = KSPROPSETID_Pin;
105 Pin.PinId = PinId;
106
107 /* query the pin for the physical connection */
108 Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), NULL, 0, &BytesReturned);
109
110 if (Status == MM_STATUS_UNSUCCESSFUL)
111 {
112 /* pin does not have a physical connection */
113 return Status;
114 }
115 DPRINT("Status %u BytesReturned %lu\n", Status, BytesReturned);
116 Connection = (PKSPIN_PHYSICALCONNECTION)MixerContext->Alloc(BytesReturned);
117 if (!Connection)
118 {
119 /* not enough memory */
120 return MM_STATUS_NO_MEMORY;
121 }
122
123 /* query the pin for the physical connection */
124 Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)Connection, BytesReturned, &BytesReturned);
125 if (Status != MM_STATUS_SUCCESS)
126 {
127 /* failed to query the physical connection */
128 MixerContext->Free(Connection);
129 return Status;
130 }
131
132 // store connection
133 *OutConnection = Connection;
134 return Status;
135 }
136
137 ULONG
138 MMixerGetControlTypeFromTopologyNode(
139 IN LPGUID NodeType)
140 {
141 if (IsEqualGUIDAligned(NodeType, (LPGUID)&KSNODETYPE_AGC))
142 {
143 /* automatic gain control */
144 return MIXERCONTROL_CONTROLTYPE_ONOFF;
145 }
146 else if (IsEqualGUIDAligned(NodeType, (LPGUID)&KSNODETYPE_LOUDNESS))
147 {
148 /* loudness control */
149 return MIXERCONTROL_CONTROLTYPE_LOUDNESS;
150 }
151 else if (IsEqualGUIDAligned(NodeType, (LPGUID)&KSNODETYPE_MUTE))
152 {
153 /* mute control */
154 return MIXERCONTROL_CONTROLTYPE_MUTE;
155 }
156 else if (IsEqualGUIDAligned(NodeType, (LPGUID)&KSNODETYPE_TONE))
157 {
158 /* tone control
159 * FIXME
160 * MIXERCONTROL_CONTROLTYPE_ONOFF if KSPROPERTY_AUDIO_BASS_BOOST is supported
161 * MIXERCONTROL_CONTROLTYPE_BASS if KSPROPERTY_AUDIO_BASS is supported
162 * MIXERCONTROL_CONTROLTYPE_TREBLE if KSPROPERTY_AUDIO_TREBLE is supported
163 */
164 UNIMPLEMENTED;
165 return MIXERCONTROL_CONTROLTYPE_ONOFF;
166 }
167 else if (IsEqualGUIDAligned(NodeType, (LPGUID)&KSNODETYPE_VOLUME))
168 {
169 /* volume control */
170 return MIXERCONTROL_CONTROLTYPE_VOLUME;
171 }
172 else if (IsEqualGUIDAligned(NodeType, (LPGUID)&KSNODETYPE_PEAKMETER))
173 {
174 /* peakmeter control */
175 return MIXERCONTROL_CONTROLTYPE_PEAKMETER;
176 }
177 else if (IsEqualGUIDAligned(NodeType, (LPGUID)&KSNODETYPE_MUX))
178 {
179 /* mux control */
180 return MIXERCONTROL_CONTROLTYPE_MUX;
181 }
182 else if (IsEqualGUIDAligned(NodeType, (LPGUID)&KSNODETYPE_MUX))
183 {
184 /* mux control */
185 return MIXERCONTROL_CONTROLTYPE_MUX;
186 }
187 else if (IsEqualGUIDAligned(NodeType, (LPGUID)&KSNODETYPE_STEREO_WIDE))
188 {
189 /* stero wide control */
190 return MIXERCONTROL_CONTROLTYPE_FADER;
191 }
192 else if (IsEqualGUIDAligned(NodeType, (LPGUID)&KSNODETYPE_CHORUS))
193 {
194 /* chorus control */
195 return MIXERCONTROL_CONTROLTYPE_FADER;
196 }
197 else if (IsEqualGUIDAligned(NodeType, (LPGUID)&KSNODETYPE_REVERB))
198 {
199 /* reverb control */
200 return MIXERCONTROL_CONTROLTYPE_FADER;
201 }
202 else if (IsEqualGUIDAligned(NodeType, (LPGUID)&KSNODETYPE_SUPERMIX))
203 {
204 /* supermix control
205 * MIXERCONTROL_CONTROLTYPE_MUTE if KSPROPERTY_AUDIO_MUTE is supported
206 */
207 UNIMPLEMENTED;
208 return MIXERCONTROL_CONTROLTYPE_VOLUME;
209 }
210 /* TODO
211 * check for other supported node types
212 */
213 //UNIMPLEMENTED
214 return 0;
215 }
216
217 MIXER_STATUS
218 MMixerSetGetControlDetails(
219 IN PMIXER_CONTEXT MixerContext,
220 IN HANDLE hMixer,
221 IN ULONG NodeId,
222 IN ULONG bSet,
223 IN ULONG PropertyId,
224 IN ULONG Channel,
225 IN PLONG InputValue)
226 {
227 KSNODEPROPERTY_AUDIO_CHANNEL Property;
228 MIXER_STATUS Status;
229 LONG Value;
230 ULONG BytesReturned;
231
232 if (bSet)
233 Value = *InputValue;
234
235 /* setup the request */
236 RtlZeroMemory(&Property, sizeof(KSNODEPROPERTY_AUDIO_CHANNEL));
237
238 Property.NodeProperty.NodeId = NodeId;
239 Property.NodeProperty.Property.Id = PropertyId;
240 Property.NodeProperty.Property.Flags = KSPROPERTY_TYPE_TOPOLOGY;
241 Property.NodeProperty.Property.Set = KSPROPSETID_Audio;
242 Property.Channel = Channel;
243 Property.Reserved = 0;
244
245 if (bSet)
246 Property.NodeProperty.Property.Flags |= KSPROPERTY_TYPE_SET;
247 else
248 Property.NodeProperty.Property.Flags |= KSPROPERTY_TYPE_GET;
249
250 /* send the request */
251 Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSNODEPROPERTY_AUDIO_CHANNEL), (PVOID)&Value, sizeof(LONG), &BytesReturned);
252
253 if (!bSet && Status == MM_STATUS_SUCCESS)
254 {
255 *InputValue = Value;
256 }
257
258 DPRINT("Status %x bSet %u NodeId %u Value %d PropertyId %u\n", Status, bSet, NodeId, Value, PropertyId);
259 return Status;
260 }
261
262 ULONG
263 MMixerGetPinInstanceCount(
264 PMIXER_CONTEXT MixerContext,
265 HANDLE hFilter,
266 ULONG PinId)
267 {
268 KSP_PIN PinRequest;
269 KSPIN_CINSTANCES PinInstances;
270 ULONG BytesReturned;
271 MIXER_STATUS Status;
272
273 /* query the instance count */
274 PinRequest.Reserved = 0;
275 PinRequest.PinId = PinId;
276 PinRequest.Property.Set = KSPROPSETID_Pin;
277 PinRequest.Property.Flags = KSPROPERTY_TYPE_GET;
278 PinRequest.Property.Id = KSPROPERTY_PIN_CINSTANCES;
279
280 Status = MixerContext->Control(hFilter, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)&PinInstances, sizeof(KSPIN_CINSTANCES), &BytesReturned);
281 ASSERT(Status == MM_STATUS_SUCCESS);
282 return PinInstances.CurrentCount;
283 }