[Spice-devel] [PATCH] audio: use GstVolume to have volume control.
Victor Toso
victortoso at redhat.com
Wed Feb 4 07:20:24 PST 2015
Using GstVolume in the pipeline to have volume control instead of
changing sink and src elements directly.
---
gtk/spice-gstaudio.c | 119 +++++++++++++++++++++++----------------------------
1 file changed, 53 insertions(+), 66 deletions(-)
diff --git a/gtk/spice-gstaudio.c b/gtk/spice-gstaudio.c
index 892028c..8ac6aac 100644
--- a/gtk/spice-gstaudio.c
+++ b/gtk/spice-gstaudio.c
@@ -30,12 +30,15 @@
#define SPICE_GSTAUDIO_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE((obj), SPICE_TYPE_GSTAUDIO, SpiceGstaudioPrivate))
+#define MUTE_STR(mute) ((mute) ? "muted" : "not muted")
+
G_DEFINE_TYPE(SpiceGstaudio, spice_gstaudio, SPICE_TYPE_AUDIO)
struct stream {
GstElement *pipe;
GstElement *src;
GstElement *sink;
+ GstElement *vol;
guint rate;
guint channels;
};
@@ -73,6 +76,11 @@ void stream_dispose(struct stream *s)
gst_object_unref(s->sink);
s->sink = NULL;
}
+
+ if (s->vol) {
+ gst_object_unref(s->vol);
+ s->vol = NULL;
+ }
}
static void spice_gstaudio_dispose(GObject *obj)
@@ -207,8 +215,9 @@ static void record_start(SpiceRecordChannel *channel, gint format, gint channels
g_strdup_printf("audio/x-raw,format=\"S16LE\",channels=%d,rate=%d,"
"layout=interleaved", channels, frequency);
gchar *pipeline =
- g_strdup_printf("autoaudiosrc name=audiosrc ! queue ! audioconvert ! audioresample ! "
- "appsink caps=\"%s\" name=appsink", audio_caps);
+ g_strdup_printf("autoaudiosrc name=audiosrc ! volume name=appvol ! queue ! "
+ "audioconvert ! audioresample ! appsink caps=\"%s\" name=appsink",
+ audio_caps);
p->record.pipe = gst_parse_launch(pipeline, &error);
if (error != NULL) {
@@ -222,6 +231,7 @@ static void record_start(SpiceRecordChannel *channel, gint format, gint channels
p->record.src = gst_bin_get_by_name(GST_BIN(p->record.pipe), "audiosrc");
p->record.sink = gst_bin_get_by_name(GST_BIN(p->record.pipe), "appsink");
+ p->record.vol = gst_bin_get_by_name(GST_BIN(p->record.pipe), "appvol");
p->record.rate = frequency;
p->record.channels = channels;
@@ -301,8 +311,10 @@ static void playback_start(SpicePlaybackChannel *channel, gint format, gint chan
"layout=interleaved", channels, frequency);
gchar *pipeline = g_strdup (g_getenv("SPICE_GST_AUDIOSINK"));
if (pipeline == NULL)
- pipeline = g_strdup_printf("appsrc is-live=1 do-timestamp=0 caps=\"%s\" name=\"appsrc\" ! queue ! "
- "audioconvert ! audioresample ! autoaudiosink name=\"audiosink\"", audio_caps);
+ pipeline =
+ g_strdup_printf("appsrc is-live=1 do-timestamp=0 caps=\"%s\" name=\"appsrc\" ! "
+ "volume name=appvol ! queue ! audioconvert ! audioresample ! "
+ "autoaudiosink name=\"audiosink\"", audio_caps);
SPICE_DEBUG("audio pipeline: %s", pipeline);
p->playback.pipe = gst_parse_launch(pipeline, &error);
if (error != NULL) {
@@ -311,6 +323,7 @@ static void playback_start(SpicePlaybackChannel *channel, gint format, gint chan
}
p->playback.src = gst_bin_get_by_name(GST_BIN(p->playback.pipe), "appsrc");
p->playback.sink = gst_bin_get_by_name(GST_BIN(p->playback.pipe), "audiosink");
+ p->playback.vol = gst_bin_get_by_name(GST_BIN(p->playback.pipe), "appvol");
p->playback.rate = frequency;
p->playback.channels = channels;
@@ -353,13 +366,12 @@ static void playback_data(SpicePlaybackChannel *channel,
static void playback_volume_changed(GObject *object, GParamSpec *pspec, gpointer data)
{
SpiceGstaudio *gstaudio = data;
- GstElement *e;
guint16 *volume;
guint nchannels;
SpiceGstaudioPrivate *p = gstaudio->priv;
- gdouble vol;
+ gdouble old_vol, vol;
- if (!p->playback.sink)
+ if (!p->playback.sink || !p->playback.vol)
return;
g_object_get(object,
@@ -370,54 +382,44 @@ static void playback_volume_changed(GObject *object, GParamSpec *pspec, gpointer
g_return_if_fail(nchannels > 0);
vol = 1.0 * volume[0] / VOLUME_NORMAL;
-
- if (GST_IS_BIN(p->playback.sink))
- e = gst_bin_get_by_interface(GST_BIN(p->playback.sink), GST_TYPE_STREAM_VOLUME);
- else
- e = g_object_ref(p->playback.sink);
-
- if (GST_IS_STREAM_VOLUME(e))
- gst_stream_volume_set_volume(GST_STREAM_VOLUME(e), GST_STREAM_VOLUME_FORMAT_CUBIC, vol);
- else
- g_object_set(e, "volume", vol, NULL);
-
- g_object_unref(e);
+ old_vol = gst_stream_volume_get_volume(GST_STREAM_VOLUME(p->playback.vol),
+ GST_STREAM_VOLUME_FORMAT_CUBIC);
+ if (old_vol != vol) {
+ SPICE_DEBUG("playback: volume changed from %f to %f [%u]",
+ old_vol, vol, volume[0]);
+ gst_stream_volume_set_volume(GST_STREAM_VOLUME(p->playback.vol),
+ GST_STREAM_VOLUME_FORMAT_CUBIC,
+ vol);
+ }
}
static void playback_mute_changed(GObject *object, GParamSpec *pspec, gpointer data)
{
SpiceGstaudio *gstaudio = data;
SpiceGstaudioPrivate *p = gstaudio->priv;
- GstElement *e;
- gboolean mute;
+ gboolean old_mute, mute;
- if (!p->playback.sink)
+ if (!p->playback.sink || !p->playback.vol)
return;
g_object_get(object, "mute", &mute, NULL);
- SPICE_DEBUG("playback mute changed %u", mute);
-
- if (GST_IS_BIN(p->playback.sink))
- e = gst_bin_get_by_interface(GST_BIN(p->playback.sink), GST_TYPE_STREAM_VOLUME);
- else
- e = g_object_ref(p->playback.sink);
-
- if (GST_IS_STREAM_VOLUME(e))
- gst_stream_volume_set_mute(GST_STREAM_VOLUME(e), mute);
-
- g_object_unref(e);
+ old_mute = gst_stream_volume_get_mute(GST_STREAM_VOLUME(p->playback.vol));
+ if (old_mute != mute) {
+ SPICE_DEBUG("playback: mute changed from %s to %s",
+ MUTE_STR(old_mute), MUTE_STR(mute));
+ gst_stream_volume_set_mute(GST_STREAM_VOLUME(p->playback.vol), mute);
+ }
}
static void record_volume_changed(GObject *object, GParamSpec *pspec, gpointer data)
{
SpiceGstaudio *gstaudio = data;
SpiceGstaudioPrivate *p = gstaudio->priv;
- GstElement *e;
guint16 *volume;
guint nchannels;
- gdouble vol;
+ gdouble old_vol, vol;
- if (!p->record.src)
+ if (!p->record.src || !p->record.vol)
return;
g_object_get(object,
@@ -428,46 +430,31 @@ static void record_volume_changed(GObject *object, GParamSpec *pspec, gpointer d
g_return_if_fail(nchannels > 0);
vol = 1.0 * volume[0] / VOLUME_NORMAL;
-
- /* TODO directsoundsrc doesn't support IDirectSoundBuffer_SetVolume */
- /* TODO pulsesrc doesn't support volume property, it's all coming! */
-
- if (GST_IS_BIN(p->record.src))
- e = gst_bin_get_by_interface(GST_BIN(p->record.src), GST_TYPE_STREAM_VOLUME);
- else
- e = g_object_ref(p->record.src);
-
- if (GST_IS_STREAM_VOLUME(e))
- gst_stream_volume_set_volume(GST_STREAM_VOLUME(e), GST_STREAM_VOLUME_FORMAT_CUBIC, vol);
- else
- g_warning("gst lacks volume capabilities on src (TODO)");
-
- g_object_unref(e);
+ old_vol = gst_stream_volume_get_volume(GST_STREAM_VOLUME(p->record.vol), GST_STREAM_VOLUME_FORMAT_CUBIC);
+ if (old_vol != vol) {
+ SPICE_DEBUG("record: volume changed from %f to %f [%u]", old_vol, vol, volume[0]);
+ gst_stream_volume_set_volume(GST_STREAM_VOLUME(p->record.vol),
+ GST_STREAM_VOLUME_FORMAT_CUBIC,
+ vol);
+ }
}
static void record_mute_changed(GObject *object, GParamSpec *pspec, gpointer data)
{
SpiceGstaudio *gstaudio = data;
SpiceGstaudioPrivate *p = gstaudio->priv;
- GstElement *e;
- gboolean mute;
+ gboolean old_mute, mute;
- if (!p->record.src)
+ if (!p->record.src || !p->record.vol)
return;
g_object_get(object, "mute", &mute, NULL);
-
- if (GST_IS_BIN(p->record.src))
- e = gst_bin_get_by_interface(GST_BIN(p->record.src), GST_TYPE_STREAM_VOLUME);
- else
- e = g_object_ref(p->record.src);
-
- if (GST_IS_STREAM_VOLUME (e))
- gst_stream_volume_set_mute(GST_STREAM_VOLUME(e), mute);
- else
- g_warning("gst lacks mute capabilities on src: %d (TODO)", mute);
-
- g_object_unref(e);
+ old_mute = gst_stream_volume_get_mute(GST_STREAM_VOLUME(p->record.vol));
+ if (old_mute != mute) {
+ SPICE_DEBUG("record: mute changed from %s to %s",
+ MUTE_STR(old_mute), MUTE_STR(mute));
+ gst_stream_volume_set_mute(GST_STREAM_VOLUME(p->record.vol), mute);
+ }
}
static void
--
2.1.0
More information about the Spice-devel
mailing list