summaryrefslogtreecommitdiff
path: root/src/audio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio.c')
-rw-r--r--src/audio.c86
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;