[vlc-commits] pulse: allow setting volume while not connected
Rémi Denis-Courmont
git at videolan.org
Wed Oct 23 21:38:21 CEST 2013
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Wed Oct 23 22:36:52 2013 +0300| [8d88c98034958358d58b7d27ce4819597b8837d9] | committer: Rémi Denis-Courmont
pulse: allow setting volume while not connected
(Unfortunately, this will clobber the balance and requires that the base
volume be known.)
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=8d88c98034958358d58b7d27ce4819597b8837d9
---
modules/audio_output/pulse.c | 45 ++++++++++++++++++++++++++++++++----------
1 file changed, 35 insertions(+), 10 deletions(-)
diff --git a/modules/audio_output/pulse.c b/modules/audio_output/pulse.c
index cb5d7aa..f3734a9 100644
--- a/modules/audio_output/pulse.c
+++ b/modules/audio_output/pulse.c
@@ -74,6 +74,7 @@ struct aout_sys_t
pa_cvolume cvolume; /**< actual sink input volume */
mtime_t first_pts; /**< Play time of buffer start */
+ pa_volume_t volume_force; /**< Forced volume (stream must be NULL) */
pa_stream_flags_t flags_force; /**< Forced flags (stream must be NULL) */
char *sink_force; /**< Forced sink name (stream must be NULL) */
@@ -98,6 +99,14 @@ static struct sink *sink_find(aout_sys_t *sys, uint32_t index)
return NULL;
}
+static struct sink *sink_find_by_name(aout_sys_t *sys, const char *name)
+{
+ for (struct sink *sink = sys->sinks; sink != NULL; sink = sink->next)
+ if (!strcmp(sink->name, name))
+ return sink;
+ return NULL;
+}
+
static void sink_add_cb(pa_context *ctx, const pa_sink_info *i, int eol,
void *userdata)
{
@@ -611,12 +620,6 @@ static int VolumeSet(audio_output_t *aout, float vol)
pa_operation *op;
int ret = -1;
- if (s == NULL)
- {
- msg_Err (aout, "cannot change volume while not playing");
- return -1;
- }
-
/* VLC provides the software volume so convert directly to PulseAudio
* software volume, pa_volume_t. This is not a linear amplification factor
* so do not use PulseAudio linear amplification! */
@@ -631,6 +634,16 @@ static int VolumeSet(audio_output_t *aout, float vol)
msg_Err(aout, "cannot change volume without base");
goto out;
}
+
+ pa_volume_t volume = pa_sw_volume_multiply(lroundf(vol), sys->base_volume);
+
+ if (s == NULL)
+ {
+ sys->volume_force = volume;
+ ret = 0;
+ goto out;
+ }
+
if (!pa_cvolume_valid(&sys->cvolume))
{
const pa_sample_spec *ss = pa_stream_get_sample_spec(s);
@@ -639,7 +652,6 @@ static int VolumeSet(audio_output_t *aout, float vol)
pa_cvolume_set(&sys->cvolume, ss->channels, PA_VOLUME_NORM);
}
- pa_volume_t volume = pa_sw_volume_multiply(lroundf(vol), sys->base_volume);
/* Preserve the balance (VLC does not support it). */
pa_cvolume cvolume = sys->cvolume;
pa_cvolume_scale(&cvolume, PA_VOLUME_NORM);
@@ -688,6 +700,10 @@ static int StreamMove(audio_output_t *aout, const char *name)
if (sys->stream == NULL)
{
+ struct sink *sink = sink_find_by_name(sys, name);
+
+ sys->base_volume = likely(sink != NULL) ? sink->base_volume
+ : PA_VOLUME_INVALID;
msg_Dbg(aout, "will connect to sink %s", name);
free(sys->sink_force);
sys->sink_force = strdup(name);
@@ -843,8 +859,14 @@ static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
attr.minreq = pa_usec_to_bytes(AOUT_MIN_PREPARE_TIME, &ss);
attr.fragsize = 0; /* not used for output */
+ pa_cvolume *cvolume = NULL, cvolumebuf;
+ if (PA_VOLUME_IS_VALID(sys->volume_force))
+ {
+ cvolume = &cvolumebuf;
+ pa_cvolume_set(cvolume, ss.channels, sys->volume_force);
+ }
+
sys->trigger = NULL;
- sys->base_volume = PA_VOLUME_INVALID;
pa_cvolume_init(&sys->cvolume);
sys->first_pts = VLC_TS_INVALID;
@@ -913,12 +935,13 @@ static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
pa_stream_set_suspended_callback(s, stream_suspended_cb, aout);
pa_stream_set_underflow_callback(s, stream_underflow_cb, aout);
- if (pa_stream_connect_playback(s, sys->sink_force, &attr, flags, NULL,
- NULL) < 0
+ if (pa_stream_connect_playback(s, sys->sink_force, &attr, flags,
+ cvolume, NULL) < 0
|| stream_wait(s, sys->mainloop)) {
vlc_pa_error(aout, "stream connection failure", sys->context);
goto fail;
}
+ sys->volume_force = PA_VOLUME_INVALID;
sys->flags_force = PA_STREAM_NOFLAGS;
free(sys->sink_force);
sys->sink_force = NULL;
@@ -979,6 +1002,7 @@ static void Stop(audio_output_t *aout)
pa_stream_unref(s);
sys->stream = NULL;
+ sys->base_volume = PA_VOLUME_INVALID;
pa_threaded_mainloop_unlock(sys->mainloop);
}
@@ -1004,6 +1028,7 @@ static int Open(vlc_object_t *obj)
}
sys->stream = NULL;
sys->context = ctx;
+ sys->volume_force = PA_VOLUME_INVALID;
sys->flags_force = PA_STREAM_NOFLAGS;
sys->sink_force = NULL;
sys->sinks = NULL;
More information about the vlc-commits
mailing list