diff options
Diffstat (limited to 'src/audio.c')
-rw-r--r-- | src/audio.c | 86 |
1 files changed, 41 insertions, 45 deletions
diff --git a/src/audio.c b/src/audio.c index e0bb6b0..37e746b 100644 --- a/src/audio.c +++ b/src/audio.c @@ -15,42 +15,6 @@ G_STRINGIFY(CHANNELS) ",rate=" G_STRINGIFY(SAMPLERATE) static void -set_pulse_states(const GValue *item, gpointer user_data) -{ - GstElement *elm = g_value_get_object(item); - struct cmumble_user *user = user_data; - GstStructure *props; - gchar *name; - - if (g_strcmp0(G_OBJECT_TYPE_NAME(elm), "GstPulseSink") != 0 || - g_object_class_find_property(G_OBJECT_GET_CLASS(elm), - "stream-properties") == NULL) - goto out; - - /* FIXME: Move this into a man-page or so: - * Dear User: Add the following to the pulseaudio configuration: - * load-module module-device-manager "do_routing=1" - * This is to let new join users default to e.g. a headset output. - * Also consider setting device.intended_roles = "phone" for your - * output to be marked as headset (if you dont have a usb headset dev). */ - - name = g_strdup_printf("cmumble [%s]", user->name); - - props = gst_structure_new("props", - "application.name", G_TYPE_STRING, name, - "media.role", G_TYPE_STRING, "phone", - NULL); - - g_object_set(elm, "stream-properties", props, NULL); - gst_structure_free(props); - g_free(name); - -out: - g_object_unref(G_OBJECT(elm)); -} - - -static void add_celt_streamheader(struct cmumble *cm, GstAppSrc *src) { GValue streamheader = { 0, }, val = { 0, }; @@ -89,6 +53,44 @@ add_celt_streamheader(struct cmumble *cm, GstAppSrc *src) gst_caps_unref(caps); } +static void +set_pulse_sink_states(GstElement *el, struct cmumble_user *user) +{ + GstStructure *props; + gchar *name; + + /* FIXME: Move this into a man-page or so: + * Dear User: Add the following to the pulseaudio configuration: + * load-module module-device-manager "do_routing=1" + * This is to let new join users default to e.g. a headset output. + * Also consider setting device.intended_roles = "phone" for your + * output to be marked as headset (if you dont have a usb headset dev). */ + + name = g_strdup_printf("cmumble [%s]", user->name); + + props = gst_structure_new("props", + "application.name", G_TYPE_STRING, name, + "media.role", G_TYPE_STRING, "phone", + NULL); + + g_object_set(el, "stream-properties", props, NULL); + gst_structure_free(props); + g_free(name); +} + +static void +on_sink_bin_element_added (GstBin *bin, GstElement *el, gpointer user_data) +{ + struct cmumble_user *user = user_data; + + if (g_strcmp0(G_OBJECT_TYPE_NAME(el), "GstPulseSink") == 0 && + g_object_class_find_property(G_OBJECT_GET_CLASS(el), + "stream-properties") != NULL) { + set_pulse_sink_states(el, user); + } +} + + int cmumble_audio_create_playback_pipeline(struct cmumble *cm, struct cmumble_user *user) @@ -98,7 +100,6 @@ cmumble_audio_create_playback_pipeline(struct cmumble *cm, char *desc = "appsrc name=src format=GST_FORMAT_TIME caps="CELT_CAPS" " "! celtdec name=dec " "! audioresample ! audioconvert ! autoaudiosink name=sink"; - GstIterator *it; pipeline = gst_parse_launch(desc, &error); if (error) { @@ -109,16 +110,11 @@ cmumble_audio_create_playback_pipeline(struct cmumble *cm, user->pipeline = pipeline; user->src = GST_APP_SRC(gst_bin_get_by_name(GST_BIN(pipeline), "src")); add_celt_streamheader(cm, user->src); - - gst_element_set_state(pipeline, GST_STATE_PLAYING); - - /* FIXME: Use a recursive name for sink-actual-sink-pluse instead? like: - * gst_bin_get_by_name(GST_BIN(pipeline), "sink-actual-sink-pulse"); */ sink_bin = gst_bin_get_by_name(GST_BIN(pipeline), "sink"); - it = gst_bin_iterate_sinks(GST_BIN(sink_bin)); - gst_iterator_foreach(it, set_pulse_states, user); - gst_iterator_free(it); + g_signal_connect(G_OBJECT(sink_bin), "element-added", + G_CALLBACK(on_sink_bin_element_added), user); + gst_element_set_state(pipeline, GST_STATE_PLAYING); user->last_sequence = -1; return 0; |