fix(pulseaudio): listen for default sink changes, and use @DEFAULT_SINK@

Using @DEFAULT_SINK@ macro avoids having to retrieve default sink name
This commit is contained in:
NBonaparte 2018-04-14 17:04:48 -07:00 committed by Patrick Ziegler
parent 45b39b0fbd
commit 4bf73ddd81
2 changed files with 20 additions and 32 deletions

View file

@ -22,7 +22,7 @@ DEFINE_ERROR(pulseaudio_error);
class pulseaudio {
// events to add to our queue
enum class evtype { NEW = 0, CHANGE, REMOVE };
enum class evtype { NEW = 0, CHANGE, REMOVE, SERVER };
using queue = std::queue<evtype>;
public:
@ -50,7 +50,6 @@ class pulseaudio {
static void get_sink_volume_callback(pa_context *context, const pa_sink_info *info, int is_last, void *userdata);
static void subscribe_callback(pa_context* context, pa_subscription_event_type_t t, uint32_t idx, void* userdata);
static void simple_callback(pa_context *context, int success, void *userdata);
static void get_default_sink_callback(pa_context *context, const pa_server_info *info, void *userdata);
static void sink_info_callback(pa_context *context, const pa_sink_info *info, int eol, void *userdata);
static void context_state_callback(pa_context *context, void *userdata);
@ -63,7 +62,7 @@ class pulseaudio {
pa_cvolume cv;
bool muted{false};
// default sink name
string def_s_name;
static constexpr auto DEFAULT_SINK{"@DEFAULT_SINK@"};
pa_context* m_context{nullptr};
pa_threaded_mainloop* m_mainloop{nullptr};

View file

@ -56,15 +56,8 @@ pulseaudio::pulseaudio(const logger& logger, string&& sink_name, bool m_max_volu
wait_loop(op, m_mainloop);
}
if (s_name.empty()) {
op = pa_context_get_server_info(m_context, get_default_sink_callback, this);
if (!op) {
throw pulseaudio_error("Failed to get pulseaudio server info.");
}
wait_loop(op, m_mainloop);
if (def_s_name.empty())
throw pulseaudio_error("Failed to get default sink.");
// get the sink index
op = pa_context_get_sink_info_by_name(m_context, def_s_name.c_str(), sink_info_callback, this);
op = pa_context_get_sink_info_by_name(m_context, DEFAULT_SINK, sink_info_callback, this);
wait_loop(op, m_mainloop);
m_log.warn("pulseaudio: using default sink %s", s_name);
} else {
@ -73,10 +66,11 @@ pulseaudio::pulseaudio(const logger& logger, string&& sink_name, bool m_max_volu
max_volume = m_max_volume ? PA_VOLUME_UI_MAX : PA_VOLUME_NORM;
op = pa_context_subscribe(m_context, PA_SUBSCRIPTION_MASK_SINK, simple_callback, this);
auto event_types = static_cast<pa_subscription_mask_t>(PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SERVER);
op = pa_context_subscribe(m_context, event_types, simple_callback, this);
wait_loop(op, m_mainloop);
if (!success)
throw pulseaudio_error("Failed to subscribe to server.");
throw pulseaudio_error("Failed to subscribe to sink.");
pa_context_set_subscribe_callback(m_context, subscribe_callback, this);
update_volume(op);
@ -129,13 +123,15 @@ int pulseaudio::process_events() {
break;
}
// FALLTHRU
case evtype::SERVER:
// don't fallthrough only if always using default sink
if (!spec_s_name.empty()) {
break;
}
// FALLTHRU
// get default sink
case evtype::REMOVE:
o = pa_context_get_server_info(m_context, get_default_sink_callback, this);
wait_loop(o, m_mainloop);
if (def_s_name.empty())
throw pulseaudio_error("Failed to get default sink.");
o = pa_context_get_sink_info_by_name(m_context, def_s_name.c_str(), sink_info_callback, this);
o = pa_context_get_sink_info_by_name(m_context, DEFAULT_SINK, sink_info_callback, this);
wait_loop(o, m_mainloop);
if (spec_s_name != s_name)
m_log.warn("pulseaudio: using default sink %s", s_name);
@ -244,9 +240,14 @@ void pulseaudio::get_sink_volume_callback(pa_context *, const pa_sink_info *info
*/
void pulseaudio::subscribe_callback(pa_context *, pa_subscription_event_type_t t, uint32_t idx, void* userdata) {
pulseaudio *This = static_cast<pulseaudio *>(userdata);
if (idx == PA_INVALID_INDEX)
return;
switch(t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) {
case PA_SUBSCRIPTION_EVENT_SERVER:
switch(t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) {
case PA_SUBSCRIPTION_EVENT_CHANGE:
This->m_events.emplace(evtype::SERVER);
break;
}
break;
case PA_SUBSCRIPTION_EVENT_SINK:
switch(t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) {
case PA_SUBSCRIPTION_EVENT_NEW:
@ -275,18 +276,6 @@ void pulseaudio::simple_callback(pa_context *, int success, void *userdata) {
pa_threaded_mainloop_signal(This->m_mainloop, 0);
}
/**
* Callback when getting default sink name
*/
void pulseaudio::get_default_sink_callback(pa_context *, const pa_server_info *info, void *userdata) {
pulseaudio *This = static_cast<pulseaudio *>(userdata);
if (info->default_sink_name) {
This->def_s_name = info->default_sink_name;
This->s_name = info->default_sink_name;
} else
This->def_s_name = ""s;
pa_threaded_mainloop_signal(This->m_mainloop, 0);
}
/**
* Callback when getting sink info & existence