| /* GStreamer Mixer |
| * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net> |
| * |
| * mixer.c: mixer design virtual class function wrappers |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Library General Public |
| * License as published by the Free Software Foundation; either |
| * version 2 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Library General Public License for more details. |
| * |
| * You should have received a copy of the GNU Library General Public |
| * License along with this library; if not, write to the |
| * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
| * Boston, MA 02111-1307, USA. |
| */ |
| |
| #ifdef HAVE_CONFIG_H |
| #include "config.h" |
| #endif |
| |
| #include "mixer.h" |
| #include "audio-marshal.h" |
| |
| #define GST_MIXER_MESSAGE_NAME "gst-mixer-message" |
| |
| /** |
| * SECTION:gstmixer |
| * @short_description: Interface for elements that provide mixer operations |
| * @see_also: alsamixer, oss4mixer, sunaudiomixer |
| * |
| * Basic interface for hardware mixer controls. |
| * |
| * Applications rarely need to use this interface, it is provided mainly |
| * for system-level mixer applets and the like. Volume control in playback |
| * applications should be done using a <classname>volume</classname> |
| * element or, if available, using the <quote>volume</quote> property of |
| * the audio sink element used (as provided by <classname>pulsesink</classname> |
| * for example), or even better: just use the <classname>playbin2</classname> |
| * element's <quote>volume</quote> property. |
| * |
| * Usage: In order to use the <classname>GstMixer</classname> interface, the |
| * element needs to be at least in READY state (so that the element has opened |
| * the mixer device). Once the element has been set to READY state or higher, |
| * it can be cast to a <classname>GstMixer</classname> using the GST_MIXER |
| * macro (in C) and the mixer API can be used. |
| */ |
| |
| /* FIXME 0.11: check if we need to add API for sometimes-supportedness |
| * (aka making up for GstImplementsInterface removal) */ |
| |
| static void gst_mixer_class_init (GstMixerInterface * iface); |
| |
| GType |
| gst_mixer_get_type (void) |
| { |
| static GType gst_mixer_type = 0; |
| |
| if (!gst_mixer_type) { |
| static const GTypeInfo gst_mixer_info = { |
| sizeof (GstMixerInterface), |
| (GBaseInitFunc) gst_mixer_class_init, |
| NULL, |
| NULL, |
| NULL, |
| NULL, |
| 0, |
| 0, |
| NULL, |
| }; |
| |
| gst_mixer_type = g_type_register_static (G_TYPE_INTERFACE, |
| "GstMixer", &gst_mixer_info, 0); |
| } |
| |
| return gst_mixer_type; |
| } |
| |
| static void |
| gst_mixer_class_init (GstMixerInterface * iface) |
| { |
| /* default virtual functions */ |
| iface->get_mixer_type = NULL; |
| iface->list_tracks = NULL; |
| iface->set_volume = NULL; |
| iface->get_volume = NULL; |
| iface->set_mute = NULL; |
| iface->set_record = NULL; |
| iface->set_option = NULL; |
| iface->get_option = NULL; |
| } |
| |
| /** |
| * gst_mixer_list_tracks: |
| * @mixer: the #GstMixer (a #GstElement) to get the tracks from. |
| * |
| * Returns a list of available tracks for this mixer/element. Note |
| * that it is allowed for sink (output) elements to only provide |
| * the output tracks in this list. Likewise, for sources (inputs), |
| * it is allowed to only provide input elements in this list. |
| * |
| * Returns: A #GList consisting of zero or more #GstMixerTracks. |
| * The list is owned by the #GstMixer instance and must not be freed |
| * or modified. |
| */ |
| |
| const GList * |
| gst_mixer_list_tracks (GstMixer * mixer) |
| { |
| GstMixerInterface *iface; |
| |
| g_return_val_if_fail (mixer != NULL, NULL); |
| |
| iface = GST_MIXER_GET_INTERFACE (mixer); |
| |
| if (iface->list_tracks) { |
| return iface->list_tracks (mixer); |
| } |
| |
| return NULL; |
| } |
| |
| /** |
| * gst_mixer_set_volume: |
| * @mixer: The #GstMixer (a #GstElement) that owns the track. |
| * @track: The #GstMixerTrack to set the volume on. |
| * @volumes: an array of integers (of size track->num_channels) |
| * that gives the wanted volume for each channel in |
| * this track. |
| * |
| * Sets the volume on each channel in a track. Short note about |
| * naming: a track is defined as one separate stream owned by |
| * the mixer/element, such as 'Line-in' or 'Microphone'. A |
| * channel is said to be a mono-stream inside this track. A |
| * stereo track thus contains two channels. |
| */ |
| |
| void |
| gst_mixer_set_volume (GstMixer * mixer, GstMixerTrack * track, gint * volumes) |
| { |
| GstMixerInterface *iface; |
| |
| g_return_if_fail (mixer != NULL); |
| g_return_if_fail (track != NULL); |
| g_return_if_fail (volumes != NULL); |
| |
| iface = GST_MIXER_GET_INTERFACE (mixer); |
| |
| if (iface->set_volume) { |
| iface->set_volume (mixer, track, volumes); |
| } |
| } |
| |
| /** |
| * gst_mixer_get_volume: |
| * @mixer: the #GstMixer (a #GstElement) that owns the track |
| * @track: the GstMixerTrack to get the volume from. |
| * @volumes: a pre-allocated array of integers (of size |
| * track->num_channels) to store the current volume |
| * of each channel in the given track in. |
| * |
| * Get the current volume(s) on the given track. |
| */ |
| |
| void |
| gst_mixer_get_volume (GstMixer * mixer, GstMixerTrack * track, gint * volumes) |
| { |
| GstMixerInterface *iface; |
| |
| g_return_if_fail (mixer != NULL); |
| g_return_if_fail (track != NULL); |
| g_return_if_fail (volumes != NULL); |
| |
| iface = GST_MIXER_GET_INTERFACE (mixer); |
| |
| if (iface->get_volume) { |
| iface->get_volume (mixer, track, volumes); |
| } else { |
| gint i; |
| |
| for (i = 0; i < track->num_channels; i++) { |
| volumes[i] = 0; |
| } |
| } |
| } |
| |
| /** |
| * gst_mixer_set_mute: |
| * @mixer: the #GstMixer (a #GstElement) that owns the track. |
| * @track: the #GstMixerTrack to operate on. |
| * @mute: a boolean value indicating whether to turn on or off |
| * muting. |
| * |
| * Mutes or unmutes the given channel. To find out whether a |
| * track is currently muted, use GST_MIXER_TRACK_HAS_FLAG (). |
| */ |
| |
| void |
| gst_mixer_set_mute (GstMixer * mixer, GstMixerTrack * track, gboolean mute) |
| { |
| GstMixerInterface *iface; |
| |
| g_return_if_fail (mixer != NULL); |
| g_return_if_fail (track != NULL); |
| |
| iface = GST_MIXER_GET_INTERFACE (mixer); |
| |
| if (iface->set_mute) { |
| iface->set_mute (mixer, track, mute); |
| } |
| } |
| |
| /** |
| * gst_mixer_set_record: |
| * @mixer: The #GstMixer (a #GstElement) that owns the track. |
| * @track: the #GstMixerTrack to operate on. |
| * @record: a boolean value that indicates whether to turn on |
| * or off recording. |
| * |
| * Enables or disables recording on the given track. Note that |
| * this is only possible on input tracks, not on output tracks |
| * (see GST_MIXER_TRACK_HAS_FLAG () and the GST_MIXER_TRACK_INPUT |
| * flag). |
| */ |
| |
| void |
| gst_mixer_set_record (GstMixer * mixer, GstMixerTrack * track, gboolean record) |
| { |
| GstMixerInterface *iface = GST_MIXER_GET_INTERFACE (mixer); |
| |
| if (iface->set_record) { |
| iface->set_record (mixer, track, record); |
| } |
| } |
| |
| /** |
| * gst_mixer_set_option: |
| * @mixer: The #GstMixer (a #GstElement) that owns the optionlist. |
| * @opts: The #GstMixerOptions that we operate on. |
| * @value: The requested new option value. |
| * |
| * Sets a name/value option in the mixer to the requested value. |
| */ |
| |
| void |
| gst_mixer_set_option (GstMixer * mixer, GstMixerOptions * opts, gchar * value) |
| { |
| GstMixerInterface *iface; |
| |
| g_return_if_fail (mixer != NULL); |
| g_return_if_fail (opts != NULL); |
| |
| iface = GST_MIXER_GET_INTERFACE (mixer); |
| |
| if (iface->set_option) { |
| iface->set_option (mixer, opts, value); |
| } |
| } |
| |
| /** |
| * gst_mixer_get_option: |
| * @mixer: The #GstMixer (a #GstElement) that owns the optionlist. |
| * @opts: The #GstMixerOptions that we operate on. |
| * |
| * Get the current value of a name/value option in the mixer. |
| * |
| * Returns: current value of the name/value option. |
| */ |
| |
| const gchar * |
| gst_mixer_get_option (GstMixer * mixer, GstMixerOptions * opts) |
| { |
| GstMixerInterface *iface; |
| |
| g_return_val_if_fail (mixer != NULL, NULL); |
| g_return_val_if_fail (opts != NULL, NULL); |
| |
| iface = GST_MIXER_GET_INTERFACE (mixer); |
| |
| if (iface->get_option) { |
| return iface->get_option (mixer, opts); |
| } |
| |
| return NULL; |
| } |
| |
| /** |
| * gst_mixer_get_mixer_type: |
| * @mixer: The #GstMixer implementation |
| * |
| * Get the #GstMixerType of this mixer implementation. |
| * |
| * Returns: A the #GstMixerType. |
| * |
| * Since: 0.10.24 |
| */ |
| GstMixerType |
| gst_mixer_get_mixer_type (GstMixer * mixer) |
| { |
| GstMixerInterface *iface = GST_MIXER_GET_INTERFACE (mixer); |
| |
| g_return_val_if_fail (iface->get_mixer_type != NULL, GST_MIXER_SOFTWARE); |
| return iface->get_mixer_type (mixer); |
| } |
| |
| /** |
| * gst_mixer_get_mixer_flags: |
| * @mixer: The #GstMixer implementation |
| * |
| * Get the set of supported flags for this mixer implementation. |
| * |
| * Returns: A set of or-ed GstMixerFlags for supported features. |
| */ |
| GstMixerFlags |
| gst_mixer_get_mixer_flags (GstMixer * mixer) |
| { |
| GstMixerInterface *iface; |
| |
| g_return_val_if_fail (mixer != NULL, FALSE); |
| iface = GST_MIXER_GET_INTERFACE (mixer); |
| |
| if (iface->get_mixer_flags) { |
| return iface->get_mixer_flags (mixer); |
| } |
| return GST_MIXER_FLAG_NONE; |
| } |
| |
| /** |
| * gst_mixer_mute_toggled: |
| * @mixer: the #GstMixer (a #GstElement) that owns the track |
| * @track: the GstMixerTrack that has change mute state. |
| * @mute: the new state of the mute flag on the track |
| * |
| * This function is called by the mixer implementation to produce |
| * a notification message on the bus indicating that the given track |
| * has changed mute state. |
| * |
| * This function only works for GstElements that are implementing the |
| * GstMixer interface, and the element needs to have been provided a bus. |
| */ |
| void |
| gst_mixer_mute_toggled (GstMixer * mixer, GstMixerTrack * track, gboolean mute) |
| { |
| GstStructure *s; |
| GstMessage *m; |
| |
| g_return_if_fail (mixer != NULL); |
| g_return_if_fail (GST_IS_ELEMENT (mixer)); |
| g_return_if_fail (track != NULL); |
| |
| s = gst_structure_new (GST_MIXER_MESSAGE_NAME, |
| "type", G_TYPE_STRING, "mute-toggled", |
| "track", GST_TYPE_MIXER_TRACK, track, "mute", G_TYPE_BOOLEAN, mute, NULL); |
| |
| m = gst_message_new_element (GST_OBJECT (mixer), s); |
| if (gst_element_post_message (GST_ELEMENT (mixer), m) == FALSE) { |
| GST_WARNING ("This element has no bus, therefore no message sent!"); |
| } |
| } |
| |
| /** |
| * gst_mixer_record_toggled: |
| * @mixer: the #GstMixer (a #GstElement) that owns the track |
| * @track: the GstMixerTrack that has changed recording state. |
| * @record: the new state of the record flag on the track |
| * |
| * This function is called by the mixer implementation to produce |
| * a notification message on the bus indicating that the given track |
| * has changed recording state. |
| * |
| * This function only works for GstElements that are implementing the |
| * GstMixer interface, and the element needs to have been provided a bus. |
| */ |
| void |
| gst_mixer_record_toggled (GstMixer * mixer, |
| GstMixerTrack * track, gboolean record) |
| { |
| GstStructure *s; |
| GstMessage *m; |
| |
| g_return_if_fail (mixer != NULL); |
| g_return_if_fail (GST_IS_ELEMENT (mixer)); |
| g_return_if_fail (track != NULL); |
| |
| s = gst_structure_new (GST_MIXER_MESSAGE_NAME, |
| "type", G_TYPE_STRING, "record-toggled", |
| "track", GST_TYPE_MIXER_TRACK, track, |
| "record", G_TYPE_BOOLEAN, record, NULL); |
| |
| m = gst_message_new_element (GST_OBJECT (mixer), s); |
| if (gst_element_post_message (GST_ELEMENT (mixer), m) == FALSE) { |
| GST_WARNING ("This element has no bus, therefore no message sent!"); |
| } |
| } |
| |
| /** |
| * gst_mixer_volume_changed: |
| * @mixer: the #GstMixer (a #GstElement) that owns the track |
| * @track: the GstMixerTrack that has changed. |
| * @volumes: Array of volume values, one per channel on the mixer track. |
| * |
| * This function is called by the mixer implementation to produce |
| * a notification message on the bus indicating that the volume(s) for the |
| * given track have changed. |
| * |
| * This function only works for GstElements that are implementing the |
| * GstMixer interface, and the element needs to have been provided a bus. |
| */ |
| void |
| gst_mixer_volume_changed (GstMixer * mixer, |
| GstMixerTrack * track, gint * volumes) |
| { |
| GstStructure *s; |
| GstMessage *m; |
| GValue l = { 0, }; |
| GValue v = { 0, }; |
| gint i; |
| |
| g_return_if_fail (mixer != NULL); |
| g_return_if_fail (GST_IS_ELEMENT (mixer)); |
| g_return_if_fail (track != NULL); |
| |
| s = gst_structure_new (GST_MIXER_MESSAGE_NAME, |
| "type", G_TYPE_STRING, "volume-changed", |
| "track", GST_TYPE_MIXER_TRACK, track, NULL); |
| |
| g_value_init (&l, GST_TYPE_ARRAY); |
| |
| g_value_init (&v, G_TYPE_INT); |
| |
| /* FIXME 0.11: pass track->num_channels to the function */ |
| for (i = 0; i < track->num_channels; ++i) { |
| g_value_set_int (&v, volumes[i]); |
| gst_value_array_append_value (&l, &v); |
| } |
| g_value_unset (&v); |
| |
| gst_structure_set_value (s, "volumes", &l); |
| g_value_unset (&l); |
| |
| m = gst_message_new_element (GST_OBJECT (mixer), s); |
| if (gst_element_post_message (GST_ELEMENT (mixer), m) == FALSE) { |
| GST_WARNING ("This element has no bus, therefore no message sent!"); |
| } |
| } |
| |
| /** |
| * gst_mixer_option_changed: |
| * @mixer: the #GstMixer (a #GstElement) that owns the options |
| * @opts: the GstMixerOptions that has changed value. |
| * @value: the new value of the GstMixerOptions. |
| * |
| * This function is called by the mixer implementation to produce |
| * a notification message on the bus indicating that the given options |
| * object has changed state. |
| * |
| * This function only works for GstElements that are implementing the |
| * GstMixer interface, and the element needs to have been provided a bus. |
| */ |
| void |
| gst_mixer_option_changed (GstMixer * mixer, |
| GstMixerOptions * opts, const gchar * value) |
| { |
| GstStructure *s; |
| GstMessage *m; |
| |
| g_return_if_fail (mixer != NULL); |
| g_return_if_fail (GST_IS_ELEMENT (mixer)); |
| g_return_if_fail (opts != NULL); |
| |
| s = gst_structure_new (GST_MIXER_MESSAGE_NAME, |
| "type", G_TYPE_STRING, "option-changed", |
| "options", GST_TYPE_MIXER_OPTIONS, opts, |
| "value", G_TYPE_STRING, value, NULL); |
| |
| m = gst_message_new_element (GST_OBJECT (mixer), s); |
| if (gst_element_post_message (GST_ELEMENT (mixer), m) == FALSE) { |
| GST_WARNING ("This element has no bus, therefore no message sent!"); |
| } |
| } |
| |
| /** |
| * gst_mixer_options_list_changed: |
| * @mixer: the #GstMixer (a #GstElement) that owns the options |
| * @opts: the GstMixerOptions whose list of values has changed |
| * |
| * This function is called by the mixer implementation to produce |
| * a notification message on the bus indicating that the list of possible |
| * options of a given options object has changed. |
| * |
| * The new options are not contained in the message on purpose. Applications |
| * should call gst_mixer_options_get_values() on @opts to make @opts update |
| * its internal state and obtain the new list of values. |
| * |
| * This function only works for GstElements that are implementing the |
| * GstMixer interface, and the element needs to have been provided a bus |
| * for this to work. |
| * |
| * Since: 0.10.18 |
| */ |
| void |
| gst_mixer_options_list_changed (GstMixer * mixer, GstMixerOptions * opts) |
| { |
| GstStructure *s; |
| GstMessage *m; |
| |
| g_return_if_fail (mixer != NULL); |
| g_return_if_fail (GST_IS_ELEMENT (mixer)); |
| g_return_if_fail (opts != NULL); |
| g_return_if_fail (GST_IS_MIXER_OPTIONS (opts)); |
| |
| /* we do not include the new list here on purpose, so that the application |
| * has to use gst_mixer_options_get_values() to get the new list, which then |
| * allows the mixer options object to update the internal GList in a somewhat |
| * thread-safe way at least */ |
| s = gst_structure_new (GST_MIXER_MESSAGE_NAME, |
| "type", G_TYPE_STRING, "options-list-changed", |
| "options", GST_TYPE_MIXER_OPTIONS, opts, NULL); |
| |
| m = gst_message_new_element (GST_OBJECT (mixer), s); |
| if (gst_element_post_message (GST_ELEMENT (mixer), m) == FALSE) { |
| GST_WARNING ("This element has no bus, therefore no message sent!"); |
| } |
| } |
| |
| /** |
| * gst_mixer_mixer_changed: |
| * @mixer: the #GstMixer (a #GstElement) which has changed |
| * |
| * This function is called by the mixer implementation to produce |
| * a notification message on the bus indicating that the list of available |
| * mixer tracks for a given mixer object has changed. Applications should |
| * rebuild their interface when they receive this message. |
| * |
| * This function only works for GstElements that are implementing the |
| * GstMixer interface, and the element needs to have been provided a bus. |
| * |
| * Since: 0.10.18 |
| */ |
| void |
| gst_mixer_mixer_changed (GstMixer * mixer) |
| { |
| GstStructure *s; |
| GstMessage *m; |
| |
| g_return_if_fail (mixer != NULL); |
| g_return_if_fail (GST_IS_ELEMENT (mixer)); |
| |
| s = gst_structure_new (GST_MIXER_MESSAGE_NAME, |
| "type", G_TYPE_STRING, "mixer-changed", NULL); |
| |
| m = gst_message_new_element (GST_OBJECT (mixer), s); |
| if (gst_element_post_message (GST_ELEMENT (mixer), m) == FALSE) { |
| GST_WARNING ("This element has no bus, therefore no message sent!"); |
| } |
| } |
| |
| static gboolean |
| gst_mixer_message_is_mixer_message (GstMessage * message) |
| { |
| const GstStructure *s; |
| |
| if (message == NULL) |
| return FALSE; |
| if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT) |
| return FALSE; |
| |
| s = gst_message_get_structure (message); |
| return gst_structure_has_name (s, GST_MIXER_MESSAGE_NAME); |
| } |
| |
| /** |
| * gst_mixer_message_get_type: |
| * @message: A GstMessage to inspect. |
| * |
| * Check a bus message to see if it is a GstMixer notification |
| * message and return the GstMixerMessageType identifying which |
| * type of notification it is. |
| * |
| * Returns: The type of the GstMixerMessage, or GST_MIXER_MESSAGE_INVALID |
| * if the message is not a GstMixer notification. |
| * |
| * Since: 0.10.14 |
| */ |
| GstMixerMessageType |
| gst_mixer_message_get_type (GstMessage * message) |
| { |
| const GstStructure *s; |
| const gchar *m_type; |
| |
| if (!gst_mixer_message_is_mixer_message (message)) |
| return GST_MIXER_MESSAGE_INVALID; |
| |
| s = gst_message_get_structure (message); |
| m_type = gst_structure_get_string (s, "type"); |
| g_return_val_if_fail (m_type != NULL, GST_MIXER_MESSAGE_INVALID); |
| |
| if (g_str_equal (m_type, "mute-toggled")) |
| return GST_MIXER_MESSAGE_MUTE_TOGGLED; |
| else if (g_str_equal (m_type, "record-toggled")) |
| return GST_MIXER_MESSAGE_RECORD_TOGGLED; |
| else if (g_str_equal (m_type, "volume-changed")) |
| return GST_MIXER_MESSAGE_VOLUME_CHANGED; |
| else if (g_str_equal (m_type, "option-changed")) |
| return GST_MIXER_MESSAGE_OPTION_CHANGED; |
| else if (g_str_equal (m_type, "options-list-changed")) |
| return GST_MIXER_MESSAGE_OPTIONS_LIST_CHANGED; |
| else if (g_str_equal (m_type, "mixer-changed")) |
| return GST_MIXER_MESSAGE_MIXER_CHANGED; |
| |
| return GST_MIXER_MESSAGE_INVALID; |
| } |
| |
| #define GST_MIXER_MESSAGE_HAS_TYPE(msg,msg_type) \ |
| (gst_mixer_message_get_type (msg) == GST_MIXER_MESSAGE_ ## msg_type) |
| |
| /** |
| * gst_mixer_message_parse_mute_toggled: |
| * @message: A mute-toggled change notification message. |
| * @track: Pointer to hold a GstMixerTrack object, or NULL. |
| * @mute: A pointer to a gboolean variable, or NULL. |
| * |
| * Extracts the contents of a mute-toggled bus message. Reads |
| * the GstMixerTrack that has changed, and the new value of the mute |
| * flag. |
| * |
| * The GstMixerTrack remains valid until the message is freed. |
| * |
| * Since: 0.10.14 |
| */ |
| void |
| gst_mixer_message_parse_mute_toggled (GstMessage * message, |
| GstMixerTrack ** track, gboolean * mute) |
| { |
| const GstStructure *s; |
| |
| g_return_if_fail (gst_mixer_message_is_mixer_message (message)); |
| g_return_if_fail (GST_MIXER_MESSAGE_HAS_TYPE (message, MUTE_TOGGLED)); |
| |
| s = gst_message_get_structure (message); |
| |
| if (track) { |
| const GValue *v = gst_structure_get_value (s, "track"); |
| |
| g_return_if_fail (v != NULL); |
| *track = (GstMixerTrack *) g_value_get_object (v); |
| g_return_if_fail (GST_IS_MIXER_TRACK (*track)); |
| } |
| |
| if (mute) |
| g_return_if_fail (gst_structure_get_boolean (s, "mute", mute)); |
| } |
| |
| /** |
| * gst_mixer_message_parse_record_toggled: |
| * @message: A record-toggled change notification message. |
| * @track: Pointer to hold a GstMixerTrack object, or NULL. |
| * @record: A pointer to a gboolean variable, or NULL. |
| * |
| * Extracts the contents of a record-toggled bus message. Reads |
| * the GstMixerTrack that has changed, and the new value of the |
| * recording flag. |
| * |
| * The GstMixerTrack remains valid until the message is freed. |
| * |
| * Since: 0.10.14 |
| */ |
| void |
| gst_mixer_message_parse_record_toggled (GstMessage * message, |
| GstMixerTrack ** track, gboolean * record) |
| { |
| const GstStructure *s; |
| |
| g_return_if_fail (gst_mixer_message_is_mixer_message (message)); |
| g_return_if_fail (GST_MIXER_MESSAGE_HAS_TYPE (message, RECORD_TOGGLED)); |
| |
| s = gst_message_get_structure (message); |
| |
| if (track) { |
| const GValue *v = gst_structure_get_value (s, "track"); |
| |
| g_return_if_fail (v != NULL); |
| *track = (GstMixerTrack *) g_value_get_object (v); |
| g_return_if_fail (GST_IS_MIXER_TRACK (*track)); |
| } |
| |
| if (record) |
| g_return_if_fail (gst_structure_get_boolean (s, "record", record)); |
| } |
| |
| /** |
| * gst_mixer_message_parse_volume_changed: |
| * @message: A volume-changed change notification message. |
| * @track: Pointer to hold a GstMixerTrack object, or NULL. |
| * @volumes: A pointer to receive an array of gint values, or NULL. |
| * @num_channels: Result location to receive the number of channels, or NULL. |
| * |
| * Parses a volume-changed notification message and extracts the track object |
| * it refers to, as well as an array of volumes and the size of the volumes array. |
| * |
| * The track object remains valid until the message is freed. |
| * |
| * The caller must free the array returned in the volumes parameter using g_free |
| * when they are done with it. |
| * |
| * Since: 0.10.14 |
| */ |
| void |
| gst_mixer_message_parse_volume_changed (GstMessage * message, |
| GstMixerTrack ** track, gint ** volumes, gint * num_channels) |
| { |
| const GstStructure *s; |
| |
| g_return_if_fail (gst_mixer_message_is_mixer_message (message)); |
| g_return_if_fail (GST_MIXER_MESSAGE_HAS_TYPE (message, VOLUME_CHANGED)); |
| |
| s = gst_message_get_structure (message); |
| |
| if (track) { |
| const GValue *v = gst_structure_get_value (s, "track"); |
| |
| g_return_if_fail (v != NULL); |
| *track = (GstMixerTrack *) g_value_get_object (v); |
| g_return_if_fail (GST_IS_MIXER_TRACK (*track)); |
| } |
| |
| if (volumes || num_channels) { |
| gint n_chans, i; |
| const GValue *v = gst_structure_get_value (s, "volumes"); |
| |
| g_return_if_fail (v != NULL); |
| g_return_if_fail (GST_VALUE_HOLDS_ARRAY (v)); |
| |
| n_chans = gst_value_array_get_size (v); |
| if (num_channels) |
| *num_channels = n_chans; |
| |
| if (volumes) { |
| *volumes = g_new (gint, n_chans); |
| for (i = 0; i < n_chans; i++) { |
| const GValue *e = gst_value_array_get_value (v, i); |
| |
| g_return_if_fail (e != NULL && G_VALUE_HOLDS_INT (e)); |
| (*volumes)[i] = g_value_get_int (e); |
| } |
| } |
| } |
| } |
| |
| /** |
| * gst_mixer_message_parse_option_changed: |
| * @message: A volume-changed change notification message. |
| * @options: Pointer to hold a GstMixerOptions object, or NULL. |
| * @value: Result location to receive the new options value, or NULL. |
| * |
| * Extracts the GstMixerOptions and new value from a option-changed bus notification |
| * message. |
| * |
| * The options and value returned remain valid until the message is freed. |
| * |
| * Since: 0.10.14 |
| */ |
| void |
| gst_mixer_message_parse_option_changed (GstMessage * message, |
| GstMixerOptions ** options, const gchar ** value) |
| { |
| const GstStructure *s; |
| |
| g_return_if_fail (gst_mixer_message_is_mixer_message (message)); |
| g_return_if_fail (GST_MIXER_MESSAGE_HAS_TYPE (message, OPTION_CHANGED)); |
| |
| s = gst_message_get_structure (message); |
| |
| if (options) { |
| const GValue *v = gst_structure_get_value (s, "options"); |
| |
| g_return_if_fail (v != NULL); |
| *options = (GstMixerOptions *) g_value_get_object (v); |
| g_return_if_fail (GST_IS_MIXER_OPTIONS (*options)); |
| } |
| |
| if (value) |
| *value = gst_structure_get_string (s, "value"); |
| } |
| |
| /** |
| * gst_mixer_message_parse_options_list_changed: |
| * @message: A volume-changed change notification message. |
| * @options: Pointer to hold a GstMixerOptions object, or NULL. |
| * |
| * Extracts the GstMixerOptions whose value list has changed from an |
| * options-list-changed bus notification message. |
| * |
| * The options object returned remains valid until the message is freed. You |
| * do not need to unref it. |
| * |
| * Since: 0.10.18 |
| */ |
| void |
| gst_mixer_message_parse_options_list_changed (GstMessage * message, |
| GstMixerOptions ** options) |
| { |
| const GstStructure *s; |
| |
| g_return_if_fail (gst_mixer_message_is_mixer_message (message)); |
| g_return_if_fail (GST_MIXER_MESSAGE_HAS_TYPE (message, OPTIONS_LIST_CHANGED)); |
| |
| s = gst_message_get_structure (message); |
| |
| if (options) { |
| const GValue *v = gst_structure_get_value (s, "options"); |
| |
| g_return_if_fail (v != NULL); |
| *options = (GstMixerOptions *) g_value_get_object (v); |
| g_return_if_fail (GST_IS_MIXER_OPTIONS (*options)); |
| } |
| } |