From 183b45c7eaa0781acaf701b720eab90239009b35 Mon Sep 17 00:00:00 2001 From: Julian Schuler <31921487+julianschuler@users.noreply.github.com> Date: Thu, 9 Dec 2021 22:34:35 +0100 Subject: [PATCH] Add basic pulse audio source support Added conky objects $if_pa_source_running and $if_pa_source_muted to query the status of the default pulse audio source. --- doc/variables.yaml | 9 +++++++++ src/core.cc | 6 ++++++ src/pulseaudio.cc | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/pulseaudio.h | 11 ++++++++++- 4 files changed, 70 insertions(+), 1 deletion(-) diff --git a/doc/variables.yaml b/doc/variables.yaml index fb991ac3..efdb7241 100644 --- a/doc/variables.yaml +++ b/doc/variables.yaml @@ -951,6 +951,15 @@ values: desc: |- If Pulseaudio's default sink is muted, display everything between $if_pa_sink_muted and the corresponding $else or $endif. + - name: if_pa_source_running + desc: |- + If Pulseaudio's default source is running (e.g. a program is accessing + your microphone), display everything between $if_pa_source_running and + the corresponding $else or $endif. + - name: if_pa_source_muted + desc: |- + If Pulseaudio's default source (e.g. your microphone) is muted, display + everything between $if_pa_source_muted and the corresponding $else or $endif. - name: if_running desc: "If PROCESS is running, display everything between\n$if_running and the corresponding\ diff --git a/src/core.cc b/src/core.cc index aecce44a..9424d77b 100644 --- a/src/core.cc +++ b/src/core.cc @@ -2013,6 +2013,12 @@ struct text_object *construct_text_object(char *s, const char *arg, long line, END OBJ(pa_card_name, 0) obj->callbacks.print = &print_puau_card_name; obj->callbacks.free = &free_pulseaudio; init_pulseaudio(obj); + END OBJ_IF(if_pa_source_running, 0) obj->callbacks.iftest = &puau_source_running; + obj->callbacks.free = &free_pulseaudio; + init_pulseaudio(obj); + END OBJ_IF(if_pa_source_muted, 0) obj->callbacks.iftest = &puau_source_muted; + obj->callbacks.free = &free_pulseaudio; + init_pulseaudio(obj); #endif /* BUILD_PULSEAUDIO */ #ifdef BUILD_INTEL_BACKLIGHT END OBJ(intel_backlight, 0) obj->callbacks.print = &print_intel_backlight; diff --git a/src/pulseaudio.cc b/src/pulseaudio.cc index 020b977b..457e0ec3 100644 --- a/src/pulseaudio.cc +++ b/src/pulseaudio.cc @@ -49,6 +49,9 @@ const struct pulseaudio_default_results pulseaudio_result0 = {std::string(), 0, 0, std::string(), + PA_SOURCE_SUSPENDED, + 0, + std::string(), std::string(), 0}; pulseaudio_c *pulseaudio = nullptr; @@ -77,12 +80,27 @@ void pa_sink_info_callback(pa_context *c, const pa_sink_info *i, int eol, ++eol; } + +void pa_source_info_callback(pa_context *c, const pa_source_info *i, int eol, + void *data) { + if (i != nullptr && data) { + struct pulseaudio_default_results *pdr = + (struct pulseaudio_default_results *)data; + pdr->source_state = i->state; + pdr->source_mute = i->mute; + pa_threaded_mainloop_signal(pulseaudio->mainloop, 0); + } + (void)c; + ++eol; +} + void pa_server_info_callback(pa_context *c, const pa_server_info *i, void *userdata) { if (i != nullptr) { struct pulseaudio_default_results *pdr = (struct pulseaudio_default_results *)userdata; pdr->sink_name.assign(i->default_sink_name); + pdr->source_name.assign(i->default_source_name); pa_threaded_mainloop_signal(pulseaudio->mainloop, 0); } (void)c; @@ -165,6 +183,14 @@ void subscribe_cb(pa_context *c, pa_subscription_event_type_t t, uint32_t index, "pa_context_get_sink_info_by_name failed"); } break; + case PA_SUBSCRIPTION_EVENT_SOURCE: { + if (res->source_name.empty()) return; + pa_operation *op; + PULSEAUDIO_OP(pa_context_get_source_info_by_name( + c, res->source_name.c_str(), pa_source_info_callback, res), + "pa_context_get_source_info_by_name failed"); + } break; + case PA_SUBSCRIPTION_EVENT_CARD: if (index == res->card_index && res->card_index != (uint32_t)-1) { pa_operation *op; @@ -252,6 +278,16 @@ void init_pulseaudio(struct text_object *obj) { return; } + if (pulseaudio->result.source_name.empty()) return; + + PULSEAUDIO_WAIT(pa_context_get_source_info_by_name( + pulseaudio->context, pulseaudio->result.source_name.c_str(), + pa_source_info_callback, &pulseaudio->result)); + + if (pulseaudio->result.source_name.empty()) { + NORM_ERR("Incorrect pulseaudio source information."); + return; + } if (pulseaudio->result.sink_card != (uint32_t)-1) PULSEAUDIO_WAIT(pa_context_get_card_info_by_index( pulseaudio->context, pulseaudio->result.sink_card, @@ -264,6 +300,7 @@ void init_pulseaudio(struct text_object *obj) { if (!(op = pa_context_subscribe( pulseaudio->context, (pa_subscription_mask_t)(PA_SUBSCRIPTION_MASK_SINK | + PA_SUBSCRIPTION_MASK_SOURCE | PA_SUBSCRIPTION_MASK_SERVER | PA_SUBSCRIPTION_MASK_CARD), nullptr, NULL))) { @@ -313,6 +350,14 @@ int puau_muted(struct text_object *obj) { return get_pulseaudio(obj).sink_mute; } +int puau_source_running(struct text_object *obj) { + return get_pulseaudio(obj).source_state == PA_SOURCE_RUNNING; +} + +int puau_source_muted(struct text_object *obj) { + return get_pulseaudio(obj).source_mute; +} + void print_puau_sink_description(struct text_object *obj, char *p, unsigned int p_max_size) { snprintf(p, p_max_size, "%s", get_pulseaudio(obj).sink_description.c_str()); diff --git a/src/pulseaudio.h b/src/pulseaudio.h index 4a7e20b7..9df07ae0 100644 --- a/src/pulseaudio.h +++ b/src/pulseaudio.h @@ -31,6 +31,7 @@ #define _PULSEAUDIO_H #include +#include #include "text_object.h" void init_pulseaudio(struct text_object *obj); @@ -48,6 +49,8 @@ void print_puau_card_active_profile(struct text_object *obj, char *p, unsigned int p_max_size); double puau_volumebarval(struct text_object *obj); int puau_muted(struct text_object *obj); +int puau_source_running(struct text_object *obj); +int puau_source_muted(struct text_object *obj); struct pulseaudio_default_results { // default sink @@ -60,6 +63,11 @@ struct pulseaudio_default_results { uint32_t sink_index; unsigned int sink_volume; // percentage + // default source + std::string source_name; + pa_source_state source_state; + int source_mute; + // default card std::string card_active_profile_description; std::string card_name; @@ -87,7 +95,8 @@ class pulseaudio_c { cstate(PULSE_CONTEXT_INITIALIZING), ninits(0), result({std::string(), std::string(), std::string(), std::string(), 0, - 0, 0, 0, std::string(), std::string(), 0}){}; + 0, 0, 0, std::string(), PA_SOURCE_SUSPENDED, 0, std::string(), + std::string(), 0}){}; }; #endif /* _PULSEAUDIO_H */