diff options
Diffstat (limited to 'src/pulse/pulse_audio.cc')
-rw-r--r-- | src/pulse/pulse_audio.cc | 72 |
1 files changed, 55 insertions, 17 deletions
diff --git a/src/pulse/pulse_audio.cc b/src/pulse/pulse_audio.cc index b732f8d..e741547 100644 --- a/src/pulse/pulse_audio.cc +++ b/src/pulse/pulse_audio.cc @@ -45,6 +45,7 @@ public: constexpr PulseOutput () : OutputPlugin (info, 8) {} bool init (); + void cleanup (); StereoVolume get_volume (); void set_volume (StereoVolume v); @@ -75,6 +76,9 @@ static bool connected, flushed, polling; static pa_cvolume volume; +static StereoVolume saved_volume = {0, 0}; +static bool saved_volume_changed = false; + /* Check whether the connection is still alive. */ static bool alive () { @@ -170,13 +174,8 @@ static void context_success_cb (pa_context *, int success, void * userdata) * (int * ) userdata = success; } -StereoVolume PulseOutput::get_volume () +static void get_volume_locked () { - scoped_lock lock (pulse_mutex); - - if (! connected) - return {0, 0}; - if (! polling) { /* read any pending events to get the lastest volume */ @@ -184,40 +183,61 @@ StereoVolume PulseOutput::get_volume () continue; } - StereoVolume v; if (volume.channels == 2) { - v.left = aud::rescale<int> (volume.values[0], PA_VOLUME_NORM, 100); - v.right = aud::rescale<int> (volume.values[1], PA_VOLUME_NORM, 100); + saved_volume.left = aud::rescale<int> (volume.values[0], PA_VOLUME_NORM, 100); + saved_volume.right = aud::rescale<int> (volume.values[1], PA_VOLUME_NORM, 100); } else - v.left = v.right = aud::rescale<int> (pa_cvolume_avg (& volume), PA_VOLUME_NORM, 100); + { + saved_volume.left = aud::rescale<int> (pa_cvolume_avg (& volume), PA_VOLUME_NORM, 100); + saved_volume.right = saved_volume.left; + } - return v; + saved_volume_changed = false; } -void PulseOutput::set_volume (StereoVolume v) +StereoVolume PulseOutput::get_volume () { scoped_lock lock (pulse_mutex); - if (! connected) - return; + if (connected) + get_volume_locked (); + + return saved_volume; +} +static void set_volume_locked (scoped_lock & lock) +{ if (volume.channels != 1) { - volume.values[0] = aud::rescale<int> (v.left, 100, PA_VOLUME_NORM); - volume.values[1] = aud::rescale<int> (v.right, 100, PA_VOLUME_NORM); + volume.values[0] = aud::rescale<int> (saved_volume.left, 100, PA_VOLUME_NORM); + volume.values[1] = aud::rescale<int> (saved_volume.right, 100, PA_VOLUME_NORM); volume.channels = 2; } else { - volume.values[0] = aud::rescale<int> (aud::max (v.left, v.right), 100, PA_VOLUME_NORM); + int mono = aud::max (saved_volume.left, saved_volume.right); + volume.values[0] = aud::rescale<int> (mono, 100, PA_VOLUME_NORM); volume.channels = 1; } int success = 0; CHECK (pa_context_set_sink_input_volume, context, pa_stream_get_index (stream), & volume, context_success_cb); + + saved_volume_changed = false; +} + +void PulseOutput::set_volume (StereoVolume v) +{ + scoped_lock lock (pulse_mutex); + + saved_volume = v; + saved_volume_changed = true; + + if (connected) + set_volume_locked (lock); } void PulseOutput::pause (bool pause) @@ -477,11 +497,18 @@ bool PulseOutput::open_audio (int fmt, int rate, int nch, String & error) connected = true; flushed = true; + + if (saved_volume_changed) + set_volume_locked (lock); + else + get_volume_locked (); + return true; } bool PulseOutput::init () { + /* check for a running server and get initial volume */ String error; if (! open_audio (FMT_S16_NE, 44100, 2, error)) return false; @@ -490,6 +517,17 @@ bool PulseOutput::init () return true; } +void PulseOutput::cleanup () +{ + if (saved_volume_changed) + { + /* save final volume */ + String error; + if (open_audio (FMT_S16_NE, 44100, 2, error)) + close_audio (); + } +} + const char PulseOutput::about[] = N_("Audacious PulseAudio Output Plugin\n\n" "This program is free software; you can redistribute it and/or modify " |