|
1 /* GStreamer Mixer |
|
2 * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net> |
|
3 * |
|
4 * mixer.c: mixer design virtual class function wrappers |
|
5 * |
|
6 * This library is free software; you can redistribute it and/or |
|
7 * modify it under the terms of the GNU Library General Public |
|
8 * License as published by the Free Software Foundation; either |
|
9 * version 2 of the License, or (at your option) any later version. |
|
10 * |
|
11 * This library is distributed in the hope that it will be useful, |
|
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
14 * Library General Public License for more details. |
|
15 * |
|
16 * You should have received a copy of the GNU Library General Public |
|
17 * License along with this library; if not, write to the |
|
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
|
19 * Boston, MA 02111-1307, USA. |
|
20 */ |
|
21 |
|
22 #ifdef HAVE_CONFIG_H |
|
23 #include "config.h" |
|
24 #endif |
|
25 |
|
26 #include "mixer.h" |
|
27 #include "interfaces-marshal.h" |
|
28 |
|
29 #define GST_MIXER_MESSAGE_NAME "gst-mixer-message" |
|
30 |
|
31 /** |
|
32 * SECTION:gstmixer |
|
33 * @short_description: Interface for elements that provide mixer operations |
|
34 */ |
|
35 |
|
36 #ifndef GST_DISABLE_DEPRECATED |
|
37 enum |
|
38 { |
|
39 SIGNAL_MUTE_TOGGLED, |
|
40 SIGNAL_RECORD_TOGGLED, |
|
41 SIGNAL_VOLUME_CHANGED, |
|
42 SIGNAL_OPTION_CHANGED, |
|
43 LAST_SIGNAL |
|
44 }; |
|
45 |
|
46 static guint gst_mixer_signals[LAST_SIGNAL] = { 0 }; |
|
47 |
|
48 #endif |
|
49 |
|
50 static void gst_mixer_class_init (GstMixerClass * klass); |
|
51 #ifdef __SYMBIAN32__ |
|
52 EXPORT_C |
|
53 #endif |
|
54 |
|
55 |
|
56 GType |
|
57 gst_mixer_get_type (void) |
|
58 { |
|
59 static GType gst_mixer_type = 0; |
|
60 |
|
61 if (!gst_mixer_type) { |
|
62 static const GTypeInfo gst_mixer_info = { |
|
63 sizeof (GstMixerClass), |
|
64 (GBaseInitFunc) gst_mixer_class_init, |
|
65 NULL, |
|
66 NULL, |
|
67 NULL, |
|
68 NULL, |
|
69 0, |
|
70 0, |
|
71 NULL, |
|
72 }; |
|
73 |
|
74 gst_mixer_type = g_type_register_static (G_TYPE_INTERFACE, |
|
75 "GstMixer", &gst_mixer_info, 0); |
|
76 g_type_interface_add_prerequisite (gst_mixer_type, |
|
77 GST_TYPE_IMPLEMENTS_INTERFACE); |
|
78 } |
|
79 |
|
80 return gst_mixer_type; |
|
81 } |
|
82 |
|
83 static void |
|
84 gst_mixer_class_init (GstMixerClass * klass) |
|
85 { |
|
86 #ifndef GST_DISABLE_DEPRECATED |
|
87 static gboolean initialized = FALSE; |
|
88 |
|
89 /* signals (deprecated) */ |
|
90 if (!initialized) { |
|
91 gst_mixer_signals[SIGNAL_RECORD_TOGGLED] = |
|
92 g_signal_new ("record-toggled", |
|
93 GST_TYPE_MIXER, G_SIGNAL_RUN_LAST, |
|
94 G_STRUCT_OFFSET (GstMixerClass, record_toggled), |
|
95 NULL, NULL, |
|
96 gst_interfaces_marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 2, |
|
97 GST_TYPE_MIXER_TRACK, G_TYPE_BOOLEAN); |
|
98 gst_mixer_signals[SIGNAL_MUTE_TOGGLED] = |
|
99 g_signal_new ("mute-toggled", |
|
100 GST_TYPE_MIXER, G_SIGNAL_RUN_LAST, |
|
101 G_STRUCT_OFFSET (GstMixerClass, mute_toggled), |
|
102 NULL, NULL, |
|
103 gst_interfaces_marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 2, |
|
104 GST_TYPE_MIXER_TRACK, G_TYPE_BOOLEAN); |
|
105 gst_mixer_signals[SIGNAL_VOLUME_CHANGED] = |
|
106 g_signal_new ("volume-changed", |
|
107 GST_TYPE_MIXER, G_SIGNAL_RUN_LAST, |
|
108 G_STRUCT_OFFSET (GstMixerClass, volume_changed), |
|
109 NULL, NULL, |
|
110 gst_interfaces_marshal_VOID__OBJECT_POINTER, G_TYPE_NONE, 2, |
|
111 GST_TYPE_MIXER_TRACK, G_TYPE_POINTER); |
|
112 gst_mixer_signals[SIGNAL_OPTION_CHANGED] = |
|
113 g_signal_new ("option-changed", |
|
114 GST_TYPE_MIXER, G_SIGNAL_RUN_LAST, |
|
115 G_STRUCT_OFFSET (GstMixerClass, option_changed), |
|
116 NULL, NULL, |
|
117 gst_interfaces_marshal_VOID__OBJECT_STRING, G_TYPE_NONE, 2, |
|
118 GST_TYPE_MIXER_OPTIONS, G_TYPE_STRING); |
|
119 |
|
120 initialized = TRUE; |
|
121 } |
|
122 #endif |
|
123 |
|
124 klass->mixer_type = GST_MIXER_SOFTWARE; |
|
125 |
|
126 /* default virtual functions */ |
|
127 klass->list_tracks = NULL; |
|
128 klass->set_volume = NULL; |
|
129 klass->get_volume = NULL; |
|
130 klass->set_mute = NULL; |
|
131 klass->set_record = NULL; |
|
132 klass->set_option = NULL; |
|
133 klass->get_option = NULL; |
|
134 } |
|
135 |
|
136 /** |
|
137 * gst_mixer_list_tracks: |
|
138 * @mixer: the #GstMixer (a #GstElement) to get the tracks from. |
|
139 * |
|
140 * Returns a list of available tracks for this mixer/element. Note |
|
141 * that it is allowed for sink (output) elements to only provide |
|
142 * the output tracks in this list. Likewise, for sources (inputs), |
|
143 * it is allowed to only provide input elements in this list. |
|
144 * |
|
145 * Returns: A #GList consisting of zero or more #GstMixerTracks. |
|
146 */ |
|
147 #ifdef __SYMBIAN32__ |
|
148 EXPORT_C |
|
149 #endif |
|
150 |
|
151 |
|
152 const GList * |
|
153 gst_mixer_list_tracks (GstMixer * mixer) |
|
154 { |
|
155 GstMixerClass *klass; |
|
156 |
|
157 g_return_val_if_fail (mixer != NULL, NULL); |
|
158 |
|
159 klass = GST_MIXER_GET_CLASS (mixer); |
|
160 |
|
161 if (klass->list_tracks) { |
|
162 return klass->list_tracks (mixer); |
|
163 } |
|
164 |
|
165 return NULL; |
|
166 } |
|
167 |
|
168 /** |
|
169 * gst_mixer_set_volume: |
|
170 * @mixer: The #GstMixer (a #GstElement) that owns the track. |
|
171 * @track: The #GstMixerTrack to set the volume on. |
|
172 * @volumes: an array of integers (of size track->num_channels) |
|
173 * that gives the wanted volume for each channel in |
|
174 * this track. |
|
175 * |
|
176 * Sets the volume on each channel in a track. Short note about |
|
177 * naming: a track is defined as one separate stream owned by |
|
178 * the mixer/element, such as 'Line-in' or 'Microphone'. A |
|
179 * channel is said to be a mono-stream inside this track. A |
|
180 * stereo track thus contains two channels. |
|
181 */ |
|
182 #ifdef __SYMBIAN32__ |
|
183 EXPORT_C |
|
184 #endif |
|
185 |
|
186 |
|
187 void |
|
188 gst_mixer_set_volume (GstMixer * mixer, GstMixerTrack * track, gint * volumes) |
|
189 { |
|
190 GstMixerClass *klass; |
|
191 |
|
192 g_return_if_fail (mixer != NULL); |
|
193 g_return_if_fail (track != NULL); |
|
194 g_return_if_fail (volumes != NULL); |
|
195 |
|
196 klass = GST_MIXER_GET_CLASS (mixer); |
|
197 |
|
198 if (klass->set_volume) { |
|
199 klass->set_volume (mixer, track, volumes); |
|
200 } |
|
201 } |
|
202 |
|
203 /** |
|
204 * gst_mixer_get_volume: |
|
205 * @mixer: the #GstMixer (a #GstElement) that owns the track |
|
206 * @track: the GstMixerTrack to get the volume from. |
|
207 * @volumes: a pre-allocated array of integers (of size |
|
208 * track->num_channels) to store the current volume |
|
209 * of each channel in the given track in. |
|
210 * |
|
211 * Get the current volume(s) on the given track. |
|
212 */ |
|
213 #ifdef __SYMBIAN32__ |
|
214 EXPORT_C |
|
215 #endif |
|
216 |
|
217 |
|
218 void |
|
219 gst_mixer_get_volume (GstMixer * mixer, GstMixerTrack * track, gint * volumes) |
|
220 { |
|
221 GstMixerClass *klass; |
|
222 |
|
223 g_return_if_fail (mixer != NULL); |
|
224 g_return_if_fail (track != NULL); |
|
225 g_return_if_fail (volumes != NULL); |
|
226 |
|
227 klass = GST_MIXER_GET_CLASS (mixer); |
|
228 |
|
229 if (klass->get_volume) { |
|
230 klass->get_volume (mixer, track, volumes); |
|
231 } else { |
|
232 gint i; |
|
233 |
|
234 for (i = 0; i < track->num_channels; i++) { |
|
235 volumes[i] = 0; |
|
236 } |
|
237 } |
|
238 } |
|
239 |
|
240 /** |
|
241 * gst_mixer_set_mute: |
|
242 * @mixer: the #GstMixer (a #GstElement) that owns the track. |
|
243 * @track: the #GstMixerTrack to operate on. |
|
244 * @mute: a boolean value indicating whether to turn on or off |
|
245 * muting. |
|
246 * |
|
247 * Mutes or unmutes the given channel. To find out whether a |
|
248 * track is currently muted, use GST_MIXER_TRACK_HAS_FLAG (). |
|
249 */ |
|
250 #ifdef __SYMBIAN32__ |
|
251 EXPORT_C |
|
252 #endif |
|
253 |
|
254 |
|
255 void |
|
256 gst_mixer_set_mute (GstMixer * mixer, GstMixerTrack * track, gboolean mute) |
|
257 { |
|
258 GstMixerClass *klass; |
|
259 |
|
260 g_return_if_fail (mixer != NULL); |
|
261 g_return_if_fail (track != NULL); |
|
262 |
|
263 klass = GST_MIXER_GET_CLASS (mixer); |
|
264 |
|
265 if (klass->set_mute) { |
|
266 klass->set_mute (mixer, track, mute); |
|
267 } |
|
268 } |
|
269 |
|
270 /** |
|
271 * gst_mixer_set_record: |
|
272 * @mixer: The #GstMixer (a #GstElement) that owns the track. |
|
273 * @track: the #GstMixerTrack to operate on. |
|
274 * @record: a boolean value that indicates whether to turn on |
|
275 * or off recording. |
|
276 * |
|
277 * Enables or disables recording on the given track. Note that |
|
278 * this is only possible on input tracks, not on output tracks |
|
279 * (see GST_MIXER_TRACK_HAS_FLAG () and the GST_MIXER_TRACK_INPUT |
|
280 * flag). |
|
281 */ |
|
282 #ifdef __SYMBIAN32__ |
|
283 EXPORT_C |
|
284 #endif |
|
285 |
|
286 |
|
287 void |
|
288 gst_mixer_set_record (GstMixer * mixer, GstMixerTrack * track, gboolean record) |
|
289 { |
|
290 GstMixerClass *klass = GST_MIXER_GET_CLASS (mixer); |
|
291 |
|
292 if (klass->set_record) { |
|
293 klass->set_record (mixer, track, record); |
|
294 } |
|
295 } |
|
296 |
|
297 /** |
|
298 * gst_mixer_set_option: |
|
299 * @mixer: The #GstMixer (a #GstElement) that owns the optionlist. |
|
300 * @opts: The #GstMixerOptions that we operate on. |
|
301 * @value: The requested new option value. |
|
302 * |
|
303 * Sets a name/value option in the mixer to the requested value. |
|
304 */ |
|
305 #ifdef __SYMBIAN32__ |
|
306 EXPORT_C |
|
307 #endif |
|
308 |
|
309 |
|
310 void |
|
311 gst_mixer_set_option (GstMixer * mixer, GstMixerOptions * opts, gchar * value) |
|
312 { |
|
313 GstMixerClass *klass; |
|
314 |
|
315 g_return_if_fail (mixer != NULL); |
|
316 g_return_if_fail (opts != NULL); |
|
317 |
|
318 klass = GST_MIXER_GET_CLASS (mixer); |
|
319 |
|
320 if (klass->set_option) { |
|
321 klass->set_option (mixer, opts, value); |
|
322 } |
|
323 } |
|
324 |
|
325 /** |
|
326 * gst_mixer_get_option: |
|
327 * @mixer: The #GstMixer (a #GstElement) that owns the optionlist. |
|
328 * @opts: The #GstMixerOptions that we operate on. |
|
329 * |
|
330 * Get the current value of a name/value option in the mixer. |
|
331 * |
|
332 * Returns: current value of the name/value option. |
|
333 */ |
|
334 #ifdef __SYMBIAN32__ |
|
335 EXPORT_C |
|
336 #endif |
|
337 |
|
338 |
|
339 const gchar * |
|
340 gst_mixer_get_option (GstMixer * mixer, GstMixerOptions * opts) |
|
341 { |
|
342 GstMixerClass *klass; |
|
343 |
|
344 g_return_val_if_fail (mixer != NULL, NULL); |
|
345 g_return_val_if_fail (opts != NULL, NULL); |
|
346 |
|
347 klass = GST_MIXER_GET_CLASS (mixer); |
|
348 |
|
349 if (klass->get_option) { |
|
350 return klass->get_option (mixer, opts); |
|
351 } |
|
352 |
|
353 return NULL; |
|
354 } |
|
355 |
|
356 /** |
|
357 * gst_mixer_get_mixer_flags: |
|
358 * @mixer: The #GstMixer implementation |
|
359 * |
|
360 * Get the set of supported flags for this mixer implementation. |
|
361 * |
|
362 * Returns: A set of or-ed GstMixerFlags for supported features. |
|
363 */ |
|
364 #ifdef __SYMBIAN32__ |
|
365 EXPORT_C |
|
366 #endif |
|
367 |
|
368 GstMixerFlags |
|
369 gst_mixer_get_mixer_flags (GstMixer * mixer) |
|
370 { |
|
371 GstMixerClass *klass; |
|
372 |
|
373 g_return_val_if_fail (mixer != NULL, FALSE); |
|
374 klass = GST_MIXER_GET_CLASS (mixer); |
|
375 |
|
376 if (klass->get_mixer_flags) { |
|
377 return klass->get_mixer_flags (mixer); |
|
378 } |
|
379 return GST_MIXER_FLAG_NONE; |
|
380 } |
|
381 |
|
382 /** |
|
383 * gst_mixer_mute_toggled: |
|
384 * @mixer: the #GstMixer (a #GstElement) that owns the track |
|
385 * @track: the GstMixerTrack that has change mute state. |
|
386 * @mute: the new state of the mute flag on the track |
|
387 * |
|
388 * This function is called by the mixer implementation to produce |
|
389 * a notification message on the bus indicating that the given track |
|
390 * has changed mute state. |
|
391 * |
|
392 * This function only works for GstElements that are implementing the |
|
393 * GstMixer interface, and the element needs to have been provided a bus. |
|
394 */ |
|
395 #ifdef __SYMBIAN32__ |
|
396 EXPORT_C |
|
397 #endif |
|
398 |
|
399 void |
|
400 gst_mixer_mute_toggled (GstMixer * mixer, GstMixerTrack * track, gboolean mute) |
|
401 { |
|
402 GstStructure *s; |
|
403 GstMessage *m; |
|
404 |
|
405 g_return_if_fail (mixer != NULL); |
|
406 g_return_if_fail (GST_IS_ELEMENT (mixer)); |
|
407 g_return_if_fail (track != NULL); |
|
408 |
|
409 s = gst_structure_new (GST_MIXER_MESSAGE_NAME, |
|
410 "type", G_TYPE_STRING, "mute-toggled", |
|
411 "track", GST_TYPE_MIXER_TRACK, track, "mute", G_TYPE_BOOLEAN, mute, NULL); |
|
412 |
|
413 m = gst_message_new_element (GST_OBJECT (mixer), s); |
|
414 if (gst_element_post_message (GST_ELEMENT (mixer), m) == FALSE) { |
|
415 GST_WARNING ("This element has no bus, therefore no message sent!"); |
|
416 } |
|
417 } |
|
418 |
|
419 /** |
|
420 * gst_mixer_record_toggled: |
|
421 * @mixer: the #GstMixer (a #GstElement) that owns the track |
|
422 * @track: the GstMixerTrack that has changed recording state. |
|
423 * @record: the new state of the record flag on the track |
|
424 * |
|
425 * This function is called by the mixer implementation to produce |
|
426 * a notification message on the bus indicating that the given track |
|
427 * has changed recording state. |
|
428 * |
|
429 * This function only works for GstElements that are implementing the |
|
430 * GstMixer interface, and the element needs to have been provided a bus. |
|
431 */ |
|
432 #ifdef __SYMBIAN32__ |
|
433 EXPORT_C |
|
434 #endif |
|
435 |
|
436 void |
|
437 gst_mixer_record_toggled (GstMixer * mixer, |
|
438 GstMixerTrack * track, gboolean record) |
|
439 { |
|
440 GstStructure *s; |
|
441 GstMessage *m; |
|
442 |
|
443 g_return_if_fail (mixer != NULL); |
|
444 g_return_if_fail (GST_IS_ELEMENT (mixer)); |
|
445 g_return_if_fail (track != NULL); |
|
446 |
|
447 s = gst_structure_new (GST_MIXER_MESSAGE_NAME, |
|
448 "type", G_TYPE_STRING, "record-toggled", |
|
449 "track", GST_TYPE_MIXER_TRACK, track, |
|
450 "record", G_TYPE_BOOLEAN, record, NULL); |
|
451 |
|
452 m = gst_message_new_element (GST_OBJECT (mixer), s); |
|
453 if (gst_element_post_message (GST_ELEMENT (mixer), m) == FALSE) { |
|
454 GST_WARNING ("This element has no bus, therefore no message sent!"); |
|
455 } |
|
456 } |
|
457 |
|
458 /** |
|
459 * gst_mixer_volume_changed: |
|
460 * @mixer: the #GstMixer (a #GstElement) that owns the track |
|
461 * @track: the GstMixerTrack that has changed. |
|
462 * @volumes: Array of volume values, one per channel on the mixer track. |
|
463 * |
|
464 * This function is called by the mixer implementation to produce |
|
465 * a notification message on the bus indicating that the volume(s) for the |
|
466 * given track have changed. |
|
467 * |
|
468 * This function only works for GstElements that are implementing the |
|
469 * GstMixer interface, and the element needs to have been provided a bus. |
|
470 */ |
|
471 #ifdef __SYMBIAN32__ |
|
472 EXPORT_C |
|
473 #endif |
|
474 |
|
475 void |
|
476 gst_mixer_volume_changed (GstMixer * mixer, |
|
477 GstMixerTrack * track, gint * volumes) |
|
478 { |
|
479 GstStructure *s; |
|
480 GstMessage *m; |
|
481 GValue l = { 0, }; |
|
482 GValue v = { 0, }; |
|
483 gint i; |
|
484 |
|
485 g_return_if_fail (mixer != NULL); |
|
486 g_return_if_fail (GST_IS_ELEMENT (mixer)); |
|
487 g_return_if_fail (track != NULL); |
|
488 |
|
489 s = gst_structure_new (GST_MIXER_MESSAGE_NAME, |
|
490 "type", G_TYPE_STRING, "volume-changed", |
|
491 "track", GST_TYPE_MIXER_TRACK, track, NULL); |
|
492 |
|
493 g_value_init (&l, GST_TYPE_ARRAY); |
|
494 |
|
495 g_value_init (&v, G_TYPE_INT); |
|
496 |
|
497 /* FIXME 0.11: pass track->num_channels to the function */ |
|
498 for (i = 0; i < track->num_channels; ++i) { |
|
499 g_value_set_int (&v, volumes[i]); |
|
500 gst_value_array_append_value (&l, &v); |
|
501 } |
|
502 g_value_unset (&v); |
|
503 |
|
504 gst_structure_set_value (s, "volumes", &l); |
|
505 g_value_unset (&l); |
|
506 |
|
507 m = gst_message_new_element (GST_OBJECT (mixer), s); |
|
508 if (gst_element_post_message (GST_ELEMENT (mixer), m) == FALSE) { |
|
509 GST_WARNING ("This element has no bus, therefore no message sent!"); |
|
510 } |
|
511 } |
|
512 |
|
513 /** |
|
514 * gst_mixer_option_changed: |
|
515 * @mixer: the #GstMixer (a #GstElement) that owns the options |
|
516 * @opts: the GstMixerOptions that has changed value. |
|
517 * @value: the new value of the GstMixerOptions. |
|
518 * |
|
519 * This function is called by the mixer implementation to produce |
|
520 * a notification message on the bus indicating that the given options |
|
521 * object has changed state. |
|
522 * |
|
523 * This function only works for GstElements that are implementing the |
|
524 * GstMixer interface, and the element needs to have been provided a bus. |
|
525 */ |
|
526 #ifdef __SYMBIAN32__ |
|
527 EXPORT_C |
|
528 #endif |
|
529 |
|
530 void |
|
531 gst_mixer_option_changed (GstMixer * mixer, |
|
532 GstMixerOptions * opts, gchar * value) |
|
533 { |
|
534 GstStructure *s; |
|
535 GstMessage *m; |
|
536 |
|
537 g_return_if_fail (mixer != NULL); |
|
538 g_return_if_fail (GST_IS_ELEMENT (mixer)); |
|
539 g_return_if_fail (opts != NULL); |
|
540 |
|
541 s = gst_structure_new (GST_MIXER_MESSAGE_NAME, |
|
542 "type", G_TYPE_STRING, "option-changed", |
|
543 "options", GST_TYPE_MIXER_OPTIONS, opts, |
|
544 "value", G_TYPE_STRING, value, NULL); |
|
545 |
|
546 m = gst_message_new_element (GST_OBJECT (mixer), s); |
|
547 if (gst_element_post_message (GST_ELEMENT (mixer), m) == FALSE) { |
|
548 GST_WARNING ("This element has no bus, therefore no message sent!"); |
|
549 } |
|
550 } |
|
551 |
|
552 /** |
|
553 * gst_mixer_options_list_changed: |
|
554 * @mixer: the #GstMixer (a #GstElement) that owns the options |
|
555 * @opts: the GstMixerOptions whose list of values has changed |
|
556 * |
|
557 * This function is called by the mixer implementation to produce |
|
558 * a notification message on the bus indicating that the list of possible |
|
559 * options of a given options object has changed. |
|
560 * |
|
561 * The new options are not contained in the message on purpose. Applications |
|
562 * should call gst_mixer_option_get_values() on @opts to make @opts update |
|
563 * its internal state and obtain the new list of values. |
|
564 * |
|
565 * This function only works for GstElements that are implementing the |
|
566 * GstMixer interface, and the element needs to have been provided a bus |
|
567 * for this to work. |
|
568 * |
|
569 * Since: 0.10.18 |
|
570 */ |
|
571 #ifdef __SYMBIAN32__ |
|
572 EXPORT_C |
|
573 #endif |
|
574 |
|
575 void |
|
576 gst_mixer_options_list_changed (GstMixer * mixer, GstMixerOptions * opts) |
|
577 { |
|
578 GstStructure *s; |
|
579 GstMessage *m; |
|
580 |
|
581 g_return_if_fail (mixer != NULL); |
|
582 g_return_if_fail (GST_IS_ELEMENT (mixer)); |
|
583 g_return_if_fail (opts != NULL); |
|
584 g_return_if_fail (GST_IS_MIXER_OPTIONS (opts)); |
|
585 |
|
586 /* we do not include the new list here on purpose, so that the application |
|
587 * has to use gst_mixer_options_get_values() to get the new list, which then |
|
588 * allows the mixer options object to update the internal GList in a somewhat |
|
589 * thread-safe way at least */ |
|
590 s = gst_structure_new (GST_MIXER_MESSAGE_NAME, |
|
591 "type", G_TYPE_STRING, "options-list-changed", |
|
592 "options", GST_TYPE_MIXER_OPTIONS, opts, NULL); |
|
593 |
|
594 m = gst_message_new_element (GST_OBJECT (mixer), s); |
|
595 if (gst_element_post_message (GST_ELEMENT (mixer), m) == FALSE) { |
|
596 GST_WARNING ("This element has no bus, therefore no message sent!"); |
|
597 } |
|
598 } |
|
599 |
|
600 /** |
|
601 * gst_mixer_mixer_changed: |
|
602 * @mixer: the #GstMixer (a #GstElement) which has changed |
|
603 * |
|
604 * This function is called by the mixer implementation to produce |
|
605 * a notification message on the bus indicating that the list of available |
|
606 * mixer tracks for a given mixer object has changed. Applications should |
|
607 * rebuild their interface when they receive this message. |
|
608 * |
|
609 * This function only works for GstElements that are implementing the |
|
610 * GstMixer interface, and the element needs to have been provided a bus. |
|
611 * |
|
612 * Since: 0.10.18 |
|
613 */ |
|
614 #ifdef __SYMBIAN32__ |
|
615 EXPORT_C |
|
616 #endif |
|
617 |
|
618 void |
|
619 gst_mixer_mixer_changed (GstMixer * mixer) |
|
620 { |
|
621 GstStructure *s; |
|
622 GstMessage *m; |
|
623 |
|
624 g_return_if_fail (mixer != NULL); |
|
625 g_return_if_fail (GST_IS_ELEMENT (mixer)); |
|
626 |
|
627 s = gst_structure_new (GST_MIXER_MESSAGE_NAME, |
|
628 "type", G_TYPE_STRING, "mixer-changed", NULL); |
|
629 |
|
630 m = gst_message_new_element (GST_OBJECT (mixer), s); |
|
631 if (gst_element_post_message (GST_ELEMENT (mixer), m) == FALSE) { |
|
632 GST_WARNING ("This element has no bus, therefore no message sent!"); |
|
633 } |
|
634 } |
|
635 |
|
636 static gboolean |
|
637 gst_mixer_message_is_mixer_message (GstMessage * message) |
|
638 { |
|
639 const GstStructure *s; |
|
640 |
|
641 if (message == NULL) |
|
642 return FALSE; |
|
643 if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT) |
|
644 return FALSE; |
|
645 |
|
646 s = gst_message_get_structure (message); |
|
647 return gst_structure_has_name (s, GST_MIXER_MESSAGE_NAME); |
|
648 } |
|
649 |
|
650 /** |
|
651 * gst_mixer_message_get_type: |
|
652 * @message: A GstMessage to inspect. |
|
653 * |
|
654 * Check a bus message to see if it is a GstMixer notification |
|
655 * message and return the GstMixerMessageType identifying which |
|
656 * type of notification it is. |
|
657 * |
|
658 * Returns: The type of the GstMixerMessage, or GST_MIXER_MESSAGE_NONE |
|
659 * if the message is not a GstMixer notification. |
|
660 * |
|
661 * Since: 0.10.14 |
|
662 */ |
|
663 #ifdef __SYMBIAN32__ |
|
664 EXPORT_C |
|
665 #endif |
|
666 |
|
667 GstMixerMessageType |
|
668 gst_mixer_message_get_type (GstMessage * message) |
|
669 { |
|
670 const GstStructure *s; |
|
671 const gchar *m_type; |
|
672 |
|
673 if (!gst_mixer_message_is_mixer_message (message)) |
|
674 return GST_MIXER_MESSAGE_INVALID; |
|
675 |
|
676 s = gst_message_get_structure (message); |
|
677 m_type = gst_structure_get_string (s, "type"); |
|
678 g_return_val_if_fail (m_type != NULL, GST_MIXER_MESSAGE_INVALID); |
|
679 |
|
680 if (g_str_equal (m_type, "mute-toggled")) |
|
681 return GST_MIXER_MESSAGE_MUTE_TOGGLED; |
|
682 else if (g_str_equal (m_type, "record-toggled")) |
|
683 return GST_MIXER_MESSAGE_RECORD_TOGGLED; |
|
684 else if (g_str_equal (m_type, "volume-changed")) |
|
685 return GST_MIXER_MESSAGE_VOLUME_CHANGED; |
|
686 else if (g_str_equal (m_type, "option-changed")) |
|
687 return GST_MIXER_MESSAGE_OPTION_CHANGED; |
|
688 else if (g_str_equal (m_type, "options-list-changed")) |
|
689 return GST_MIXER_MESSAGE_OPTIONS_LIST_CHANGED; |
|
690 else if (g_str_equal (m_type, "mixer-changed")) |
|
691 return GST_MIXER_MESSAGE_MIXER_CHANGED; |
|
692 |
|
693 return GST_MIXER_MESSAGE_INVALID; |
|
694 } |
|
695 |
|
696 #define GST_MIXER_MESSAGE_HAS_TYPE(msg,msg_type) \ |
|
697 (gst_mixer_message_get_type (msg) == GST_MIXER_MESSAGE_ ## msg_type) |
|
698 |
|
699 /** |
|
700 * gst_mixer_message_parse_mute_toggled: |
|
701 * @message: A mute-toggled change notification message. |
|
702 * @track: Pointer to hold a GstMixerTrack object, or NULL. |
|
703 * @mute: A pointer to a gboolean variable, or NULL. |
|
704 * |
|
705 * Extracts the contents of a mute-toggled bus message. Reads |
|
706 * the GstMixerTrack that has changed, and the new value of the mute |
|
707 * flag. |
|
708 * |
|
709 * The GstMixerTrack remains valid until the message is freed. |
|
710 * |
|
711 * Since: 0.10.14 |
|
712 */ |
|
713 #ifdef __SYMBIAN32__ |
|
714 EXPORT_C |
|
715 #endif |
|
716 |
|
717 void |
|
718 gst_mixer_message_parse_mute_toggled (GstMessage * message, |
|
719 GstMixerTrack ** track, gboolean * mute) |
|
720 { |
|
721 const GstStructure *s; |
|
722 |
|
723 g_return_if_fail (gst_mixer_message_is_mixer_message (message)); |
|
724 g_return_if_fail (GST_MIXER_MESSAGE_HAS_TYPE (message, MUTE_TOGGLED)); |
|
725 |
|
726 s = gst_message_get_structure (message); |
|
727 |
|
728 if (track) { |
|
729 const GValue *v = gst_structure_get_value (s, "track"); |
|
730 |
|
731 g_return_if_fail (v != NULL); |
|
732 *track = (GstMixerTrack *) g_value_get_object (v); |
|
733 g_return_if_fail (GST_IS_MIXER_TRACK (*track)); |
|
734 } |
|
735 |
|
736 if (mute) |
|
737 g_return_if_fail (gst_structure_get_boolean (s, "mute", mute)); |
|
738 } |
|
739 |
|
740 /** |
|
741 * gst_mixer_message_parse_record_toggled: |
|
742 * @message: A record-toggled change notification message. |
|
743 * @track: Pointer to hold a GstMixerTrack object, or NULL. |
|
744 * @record: A pointer to a gboolean variable, or NULL. |
|
745 * |
|
746 * Extracts the contents of a record-toggled bus message. Reads |
|
747 * the GstMixerTrack that has changed, and the new value of the |
|
748 * recording flag. |
|
749 * |
|
750 * The GstMixerTrack remains valid until the message is freed. |
|
751 * |
|
752 * Since: 0.10.14 |
|
753 */ |
|
754 #ifdef __SYMBIAN32__ |
|
755 EXPORT_C |
|
756 #endif |
|
757 |
|
758 void |
|
759 gst_mixer_message_parse_record_toggled (GstMessage * message, |
|
760 GstMixerTrack ** track, gboolean * record) |
|
761 { |
|
762 const GstStructure *s; |
|
763 |
|
764 g_return_if_fail (gst_mixer_message_is_mixer_message (message)); |
|
765 g_return_if_fail (GST_MIXER_MESSAGE_HAS_TYPE (message, RECORD_TOGGLED)); |
|
766 |
|
767 s = gst_message_get_structure (message); |
|
768 |
|
769 if (track) { |
|
770 const GValue *v = gst_structure_get_value (s, "track"); |
|
771 |
|
772 g_return_if_fail (v != NULL); |
|
773 *track = (GstMixerTrack *) g_value_get_object (v); |
|
774 g_return_if_fail (GST_IS_MIXER_TRACK (*track)); |
|
775 } |
|
776 |
|
777 if (record) |
|
778 g_return_if_fail (gst_structure_get_boolean (s, "record", record)); |
|
779 } |
|
780 |
|
781 /** |
|
782 * gst_mixer_message_parse_volume_changed: |
|
783 * @message: A volume-changed change notification message. |
|
784 * @track: Pointer to hold a GstMixerTrack object, or NULL. |
|
785 * @volumes: A pointer to receive an array of gint values, or NULL. |
|
786 * @num_channels: Result location to receive the number of channels, or NULL. |
|
787 * |
|
788 * Parses a volume-changed notification message and extracts the track object |
|
789 * it refers to, as well as an array of volumes and the size of the volumes array. |
|
790 * |
|
791 * The track object remains valid until the message is freed. |
|
792 * |
|
793 * The caller must free the array returned in the volumes parameter using g_free |
|
794 * when they are done with it. |
|
795 * |
|
796 * Since: 0.10.14 |
|
797 */ |
|
798 #ifdef __SYMBIAN32__ |
|
799 EXPORT_C |
|
800 #endif |
|
801 |
|
802 void |
|
803 gst_mixer_message_parse_volume_changed (GstMessage * message, |
|
804 GstMixerTrack ** track, gint ** volumes, gint * num_channels) |
|
805 { |
|
806 const GstStructure *s; |
|
807 |
|
808 g_return_if_fail (gst_mixer_message_is_mixer_message (message)); |
|
809 g_return_if_fail (GST_MIXER_MESSAGE_HAS_TYPE (message, VOLUME_CHANGED)); |
|
810 |
|
811 s = gst_message_get_structure (message); |
|
812 |
|
813 if (track) { |
|
814 const GValue *v = gst_structure_get_value (s, "track"); |
|
815 |
|
816 g_return_if_fail (v != NULL); |
|
817 *track = (GstMixerTrack *) g_value_get_object (v); |
|
818 g_return_if_fail (GST_IS_MIXER_TRACK (*track)); |
|
819 } |
|
820 |
|
821 if (volumes || num_channels) { |
|
822 gint n_chans, i; |
|
823 const GValue *v = gst_structure_get_value (s, "volumes"); |
|
824 |
|
825 g_return_if_fail (v != NULL); |
|
826 g_return_if_fail (GST_VALUE_HOLDS_ARRAY (v)); |
|
827 |
|
828 n_chans = gst_value_array_get_size (v); |
|
829 if (num_channels) |
|
830 *num_channels = n_chans; |
|
831 |
|
832 if (volumes) { |
|
833 *volumes = g_new (gint, n_chans); |
|
834 for (i = 0; i < n_chans; i++) { |
|
835 const GValue *e = gst_value_array_get_value (v, i); |
|
836 |
|
837 g_return_if_fail (e != NULL && G_VALUE_HOLDS_INT (e)); |
|
838 (*volumes)[i] = g_value_get_int (e); |
|
839 } |
|
840 } |
|
841 } |
|
842 } |
|
843 |
|
844 /** |
|
845 * gst_mixer_message_parse_option_changed: |
|
846 * @message: A volume-changed change notification message. |
|
847 * @options: Pointer to hold a GstMixerOptions object, or NULL. |
|
848 * @value: Result location to receive the new options value, or NULL. |
|
849 * |
|
850 * Extracts the GstMixerOptions and new value from a option-changed bus notification |
|
851 * message. |
|
852 * |
|
853 * The options and value returned remain valid until the message is freed. |
|
854 * |
|
855 * Since: 0.10.14 |
|
856 */ |
|
857 #ifdef __SYMBIAN32__ |
|
858 EXPORT_C |
|
859 #endif |
|
860 |
|
861 void |
|
862 gst_mixer_message_parse_option_changed (GstMessage * message, |
|
863 GstMixerOptions ** options, const gchar ** value) |
|
864 { |
|
865 const GstStructure *s; |
|
866 |
|
867 g_return_if_fail (gst_mixer_message_is_mixer_message (message)); |
|
868 g_return_if_fail (GST_MIXER_MESSAGE_HAS_TYPE (message, OPTION_CHANGED)); |
|
869 |
|
870 s = gst_message_get_structure (message); |
|
871 |
|
872 if (options) { |
|
873 const GValue *v = gst_structure_get_value (s, "options"); |
|
874 |
|
875 g_return_if_fail (v != NULL); |
|
876 *options = (GstMixerOptions *) g_value_get_object (v); |
|
877 g_return_if_fail (GST_IS_MIXER_OPTIONS (*options)); |
|
878 } |
|
879 |
|
880 if (value) |
|
881 *value = gst_structure_get_string (s, "value"); |
|
882 } |
|
883 |
|
884 /** |
|
885 * gst_mixer_message_parse_options_list_changed: |
|
886 * @message: A volume-changed change notification message. |
|
887 * @options: Pointer to hold a GstMixerOptions object, or NULL. |
|
888 * |
|
889 * Extracts the GstMixerOptions whose value list has changed from an |
|
890 * options-list-changed bus notification message. |
|
891 * |
|
892 * The options object returned remains valid until the message is freed. You |
|
893 * do not need to unref it. |
|
894 * |
|
895 * Since: 0.10.18 |
|
896 */ |
|
897 #ifdef __SYMBIAN32__ |
|
898 EXPORT_C |
|
899 #endif |
|
900 |
|
901 void |
|
902 gst_mixer_message_parse_options_list_changed (GstMessage * message, |
|
903 GstMixerOptions ** options) |
|
904 { |
|
905 const GstStructure *s; |
|
906 |
|
907 g_return_if_fail (gst_mixer_message_is_mixer_message (message)); |
|
908 g_return_if_fail (GST_MIXER_MESSAGE_HAS_TYPE (message, OPTIONS_LIST_CHANGED)); |
|
909 |
|
910 s = gst_message_get_structure (message); |
|
911 |
|
912 if (options) { |
|
913 const GValue *v = gst_structure_get_value (s, "options"); |
|
914 |
|
915 g_return_if_fail (v != NULL); |
|
916 *options = (GstMixerOptions *) g_value_get_object (v); |
|
917 g_return_if_fail (GST_IS_MIXER_OPTIONS (*options)); |
|
918 } |
|
919 } |