diff options
author | Michal Ratajsky <[email protected]> | 2014-06-20 00:12:40 +0200 |
---|---|---|
committer | Michal Ratajsky <[email protected]> | 2014-06-20 00:12:40 +0200 |
commit | 6be9a89195e0d3bf8408cea661f22cb97b638f24 (patch) | |
tree | 745cfec763facc62b6c3bc51cd246e5cad4d9f68 /backends/pulse/pulse-sink.c | |
parent | a2290d5e13ccee88fd9ae66a3895eb4da646f81f (diff) | |
download | libmatemixer-6be9a89195e0d3bf8408cea661f22cb97b638f24.tar.bz2 libmatemixer-6be9a89195e0d3bf8408cea661f22cb97b638f24.tar.xz |
Pulse and API updates, fixes
Diffstat (limited to 'backends/pulse/pulse-sink.c')
-rw-r--r-- | backends/pulse/pulse-sink.c | 246 |
1 files changed, 161 insertions, 85 deletions
diff --git a/backends/pulse/pulse-sink.c b/backends/pulse/pulse-sink.c index 53ed64f..b7a440b 100644 --- a/backends/pulse/pulse-sink.c +++ b/backends/pulse/pulse-sink.c @@ -19,11 +19,11 @@ #include <glib-object.h> #include <libmatemixer/matemixer-stream.h> -#include <libmatemixer/matemixer-port.h> #include <pulse/pulseaudio.h> #include "pulse-connection.h" +#include "pulse-monitor.h" #include "pulse-stream.h" #include "pulse-sink.h" @@ -32,27 +32,20 @@ struct _PulseSinkPrivate guint32 index_monitor; }; -enum { - PROP_0, - N_PROPERTIES -}; - -static gboolean sink_set_mute (MateMixerStream *stream, - gboolean mute); -static gboolean sink_set_volume (MateMixerStream *stream, - pa_cvolume *volume); -static gboolean sink_set_active_port (MateMixerStream *stream, - const gchar *port_name); +static void pulse_sink_class_init (PulseSinkClass *klass); +static void pulse_sink_init (PulseSink *sink); G_DEFINE_TYPE (PulseSink, pulse_sink, PULSE_TYPE_STREAM); -static void -pulse_sink_init (PulseSink *sink) -{ - sink->priv = G_TYPE_INSTANCE_GET_PRIVATE (sink, - PULSE_TYPE_SINK, - PulseSinkPrivate); -} +static gboolean sink_set_mute (MateMixerStream *stream, + gboolean mute); +static gboolean sink_set_volume (MateMixerStream *stream, + pa_cvolume *volume); +static gboolean sink_set_active_port (MateMixerStream *stream, + const gchar *port); +static gboolean sink_suspend (MateMixerStream *stream); +static gboolean sink_resume (MateMixerStream *stream); +static PulseMonitor *sink_create_monitor (MateMixerStream *stream); static void pulse_sink_class_init (PulseSinkClass *klass) @@ -64,43 +57,30 @@ pulse_sink_class_init (PulseSinkClass *klass) stream_class->set_mute = sink_set_mute; stream_class->set_volume = sink_set_volume; stream_class->set_active_port = sink_set_active_port; + stream_class->suspend = sink_suspend; + stream_class->resume = sink_resume; + stream_class->create_monitor = sink_create_monitor; g_type_class_add_private (klass, sizeof (PulseSinkPrivate)); } +static void +pulse_sink_init (PulseSink *sink) +{ + sink->priv = G_TYPE_INSTANCE_GET_PRIVATE (sink, + PULSE_TYPE_SINK, + PulseSinkPrivate); + + sink->priv->index_monitor = PA_INVALID_INDEX; +} + PulseStream * pulse_sink_new (PulseConnection *connection, const pa_sink_info *info) { PulseSink *sink; - GList *ports = NULL; - int i; - - /* Convert the list of sink ports to a GList of MateMixerPorts */ - for (i = 0; i < info->n_ports; i++) { - MateMixerPort *port; - MateMixerPortStatus status = MATE_MIXER_PORT_UNKNOWN_STATUS; - pa_sink_port_info *p_info = info->ports[i]; - -#if PA_CHECK_VERSION(2, 0, 0) - switch (p_info->available) { - case PA_PORT_AVAILABLE_YES: - status = MATE_MIXER_PORT_AVAILABLE; - break; - case PA_PORT_AVAILABLE_NO: - status = MATE_MIXER_PORT_UNAVAILABLE; - break; - default: - break; - } -#endif - port = mate_mixer_port_new (p_info->name, - p_info->description, - NULL, - p_info->priority, - status); - ports = g_list_prepend (ports, port); - } + g_return_val_if_fail (PULSE_IS_CONNECTION (connection), NULL); + g_return_val_if_fail (info != NULL, NULL); /* Consider the sink index as unchanging parameter */ sink = g_object_new (PULSE_TYPE_SINK, @@ -108,58 +88,78 @@ pulse_sink_new (PulseConnection *connection, const pa_sink_info *info) "index", info->index, NULL); - /* According to the PulseAudio code, the list of sink port never changes with - * updates. - * This may be not future-proof, but checking and validating the list of ports on - * each update would be an expensive operation, so let's set the list only during - * the construction */ - pulse_stream_update_ports (PULSE_STREAM (sink), g_list_reverse (ports)); - /* Other data may change at any time, so let's make a use of our update function */ pulse_sink_update (PULSE_STREAM (sink), info); return PULSE_STREAM (sink); } +guint32 +pulse_sink_get_monitor_index (PulseStream *stream) +{ + g_return_val_if_fail (PULSE_IS_SINK (stream), PA_INVALID_INDEX); + + return PULSE_SINK (stream)->priv->index_monitor; +} + gboolean pulse_sink_update (PulseStream *stream, const pa_sink_info *info) { - PulseSink *sink; - MateMixerStreamFlags flags = MATE_MIXER_STREAM_OUTPUT | - MATE_MIXER_STREAM_HAS_MUTE | - MATE_MIXER_STREAM_HAS_VOLUME | - MATE_MIXER_STREAM_CAN_SET_VOLUME; + MateMixerStreamFlags flags = MATE_MIXER_STREAM_OUTPUT | + MATE_MIXER_STREAM_HAS_MUTE | + MATE_MIXER_STREAM_HAS_VOLUME | + MATE_MIXER_STREAM_HAS_MONITOR | + MATE_MIXER_STREAM_CAN_SET_VOLUME | + MATE_MIXER_STREAM_CAN_SUSPEND; + PulseSink *sink; + GList *ports = NULL; + guint32 i; g_return_val_if_fail (PULSE_IS_SINK (stream), FALSE); - sink = PULSE_SINK (stream); - /* Let all the information update before emitting notify signals */ g_object_freeze_notify (G_OBJECT (stream)); pulse_stream_update_name (stream, info->name); pulse_stream_update_description (stream, info->description); pulse_stream_update_mute (stream, info->mute ? TRUE : FALSE); - pulse_stream_update_channel_map (stream, &info->channel_map); - pulse_stream_update_volume_extended (stream, - &info->volume, - info->base_volume, - info->n_volume_steps); + + /* List of ports */ + for (i = 0; i < info->n_ports; i++) { + MateMixerPortFlags flags = MATE_MIXER_PORT_NO_FLAGS; + +#if PA_CHECK_VERSION(2, 0, 0) + if (info->ports[i]->available == PA_PORT_AVAILABLE_YES) + flags |= MATE_MIXER_PORT_AVAILABLE; +#endif + ports = g_list_prepend (ports, + mate_mixer_port_new (info->ports[i]->name, + info->ports[i]->description, + NULL, + info->ports[i]->priority, + flags)); + } + pulse_stream_update_ports (stream, ports); + + /* Active port */ if (info->active_port) pulse_stream_update_active_port (stream, info->active_port->name); + else + pulse_stream_update_active_port (stream, NULL); + /* Stream state */ switch (info->state) { case PA_SINK_RUNNING: - pulse_stream_update_status (stream, MATE_MIXER_STREAM_RUNNING); + pulse_stream_update_state (stream, MATE_MIXER_STREAM_RUNNING); break; case PA_SINK_IDLE: - pulse_stream_update_status (stream, MATE_MIXER_STREAM_IDLE); + pulse_stream_update_state (stream, MATE_MIXER_STREAM_IDLE); break; case PA_SINK_SUSPENDED: - pulse_stream_update_status (stream, MATE_MIXER_STREAM_SUSPENDED); + pulse_stream_update_state (stream, MATE_MIXER_STREAM_SUSPENDED); break; default: - pulse_stream_update_status (stream, MATE_MIXER_STREAM_UNKNOWN_STATUS); + pulse_stream_update_state (stream, MATE_MIXER_STREAM_UNKNOWN_STATE); break; } @@ -169,21 +169,35 @@ pulse_sink_update (PulseStream *stream, const pa_sink_info *info) if (info->flags & PA_SINK_FLAT_VOLUME) flags |= MATE_MIXER_STREAM_HAS_FLAT_VOLUME; - if (info->monitor_source_name) - flags |= MATE_MIXER_STREAM_OUTPUT_MONITOR; - if (pa_channel_map_can_balance (&info->channel_map)) flags |= MATE_MIXER_STREAM_CAN_BALANCE; if (pa_channel_map_can_fade (&info->channel_map)) flags |= MATE_MIXER_STREAM_CAN_FADE; + /* Flags must be updated before volume */ pulse_stream_update_flags (stream, flags); + pulse_stream_update_volume_extended (stream, + &info->volume, + &info->channel_map, + info->base_volume, + info->n_volume_steps); + + sink = PULSE_SINK (stream); + + /* Handle change of monitoring source index */ + // XXX probably call this each time to validate if (sink->priv->index_monitor != info->monitor_source) { - sink->priv->index_monitor = info->monitor_source; + PulseMonitor *monitor; + + monitor = pulse_stream_get_monitor (PULSE_STREAM (stream)); - // TODO: provide a property - // g_object_notify (G_OBJECT (stream), "monitor"); + if (monitor) + pulse_monitor_update_index (monitor, + info->monitor_source, + PA_INVALID_INDEX); + + sink->priv->index_monitor = info->monitor_source; } g_object_thaw_notify (G_OBJECT (stream)); @@ -193,31 +207,93 @@ pulse_sink_update (PulseStream *stream, const pa_sink_info *info) static gboolean sink_set_mute (MateMixerStream *stream, gboolean mute) { + PulseStream *pulse; + g_return_val_if_fail (PULSE_IS_SINK (stream), FALSE); - return pulse_connection_set_sink_mute (pulse_stream_get_connection (PULSE_STREAM (stream)), - pulse_stream_get_index (PULSE_STREAM (stream)), + pulse = PULSE_STREAM (stream); + + return pulse_connection_set_sink_mute (pulse_stream_get_connection (pulse), + pulse_stream_get_index (pulse), mute); } static gboolean sink_set_volume (MateMixerStream *stream, pa_cvolume *volume) { + PulseStream *pulse; + g_return_val_if_fail (PULSE_IS_SINK (stream), FALSE); g_return_val_if_fail (volume != NULL, FALSE); - return pulse_connection_set_sink_volume (pulse_stream_get_connection (PULSE_STREAM (stream)), - pulse_stream_get_index (PULSE_STREAM (stream)), + pulse = PULSE_STREAM (stream); + + return pulse_connection_set_sink_volume (pulse_stream_get_connection (pulse), + pulse_stream_get_index (pulse), volume); } static gboolean -sink_set_active_port (MateMixerStream *stream, const gchar *port_name) +sink_set_active_port (MateMixerStream *stream, const gchar *port) { + PulseStream *pulse; + g_return_val_if_fail (PULSE_IS_SINK (stream), FALSE); - g_return_val_if_fail (port_name != NULL, FALSE); + g_return_val_if_fail (port != NULL, FALSE); + + pulse = PULSE_STREAM (stream); + + return pulse_connection_set_sink_port (pulse_stream_get_connection (pulse), + pulse_stream_get_index (pulse), + port); +} + +static gboolean +sink_suspend (MateMixerStream *stream) +{ + PulseStream *pulse; + + g_return_val_if_fail (PULSE_IS_SINK (stream), FALSE); + + pulse = PULSE_STREAM (stream); + + return pulse_connection_suspend_sink (pulse_stream_get_connection (pulse), + pulse_stream_get_index (pulse), + TRUE); +} + +static gboolean +sink_resume (MateMixerStream *stream) +{ + PulseStream *pulse; + + g_return_val_if_fail (PULSE_IS_SINK (stream), FALSE); + + pulse = PULSE_STREAM (stream); + + return pulse_connection_suspend_sink (pulse_stream_get_connection (pulse), + pulse_stream_get_index (pulse), + FALSE); +} + +static PulseMonitor * +sink_create_monitor (MateMixerStream *stream) +{ + PulseStream *pulse; + guint32 index; + + g_return_val_if_fail (PULSE_IS_SINK (stream), NULL); + + pulse = PULSE_STREAM (stream); + index = pulse_sink_get_monitor_index (pulse); + + if (G_UNLIKELY (index == PA_INVALID_INDEX)) { + g_debug ("Not creating monitor for stream %s as it is not available", + mate_mixer_stream_get_name (stream)); + return NULL; + } - return pulse_connection_set_sink_port (pulse_stream_get_connection (PULSE_STREAM (stream)), - pulse_stream_get_index (PULSE_STREAM (stream)), - port_name); + return pulse_connection_create_monitor (pulse_stream_get_connection (pulse), + index, + PA_INVALID_INDEX); } |