static void sink_subscribe_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) { struct userdata *u = (struct userdata *)userdata; if (t == PA_SUBSCRIPTION_EVENT_CHANGE) { pa_sink *sink = PA_SINK(pa_idxset_get_by_index(c->sinks, idx)); if (sink) { if (u->master_sink == sink) { const pa_cvolume *vol = pa_sink_get_volume(sink, 0, 0); int aep_step; u->linear_q15_master_volume_L = lrint(pa_sw_volume_to_linear(vol->values[0]) * 32767.0); if (vol->channels == 1) u->linear_q15_master_volume_R = lrint(pa_sw_volume_to_linear(vol->values[0]) * 32767.0); else u->linear_q15_master_volume_R = lrint(pa_sw_volume_to_linear(vol->values[1]) * 32767.0); aep_step = voice_pa_vol_to_aep_step(u, vol->values[0]); if (voice_cmt_ul_is_active_iothread(u) || (u->voip_source && PA_SOURCE_IS_LINKED(u->voip_source->state) && pa_source_used_by(u->voip_source))) { if (aep_step <= 0) { voice_update_aep_volume(0); voice_update_sidetone_gain(0); } else { voice_update_aep_volume(aep_step - 1); voice_update_sidetone_gain(aep_step - 1); } } xprot_change_volume(u->xprot, u->linear_q15_master_volume_L, u->linear_q15_master_volume_R); } } } }
char *pa_source_list_to_string(pa_core *c) { pa_strbuf *s; pa_source *source; uint32_t idx = PA_IDXSET_INVALID; static const char* const state_table[] = { [PA_SOURCE_RUNNING] = "RUNNING", [PA_SOURCE_SUSPENDED] = "SUSPENDED", [PA_SOURCE_IDLE] = "IDLE", [PA_SOURCE_UNLINKED] = "UNLINKED" }; pa_assert(c); s = pa_strbuf_new(); pa_strbuf_printf(s, "%u source(s) available.\n", pa_idxset_size(c->sources)); for (source = pa_idxset_first(c->sources, &idx); source; source = pa_idxset_next(c->sources, &idx)) { char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX]; pa_strbuf_printf( s, " %c index: %u\n" "\tname: <%s>\n" "\tdriver: <%s>\n" "\tflags: %s%s%s%s\n" "\tstate: %s\n" "\tvolume: <%s>\n" "\tmute: <%u>\n" "\tlatency: <%0.0f usec>\n" "\tsample spec: <%s>\n" "\tchannel map: <%s>\n" "\tused by: <%u>\n" "\tlinked by: <%u>\n", c->default_source_name && !strcmp(source->name, c->default_source_name) ? '*' : ' ', source->index, source->name, source->driver, source->flags & PA_SOURCE_HW_VOLUME_CTRL ? "HW_VOLUME_CTRL " : "", source->flags & PA_SOURCE_LATENCY ? "LATENCY " : "", source->flags & PA_SOURCE_HARDWARE ? "HARDWARE " : "", source->flags & PA_SOURCE_NETWORK ? "NETWORK " : "", state_table[pa_source_get_state(source)], pa_cvolume_snprint(cv, sizeof(cv), pa_source_get_volume(source)), !!pa_source_get_mute(source), (double) pa_source_get_latency(source), pa_sample_spec_snprint(ss, sizeof(ss), &source->sample_spec), pa_channel_map_snprint(cm, sizeof(cm), &source->channel_map), pa_source_used_by(source), pa_source_linked_by(source)); if (source->monitor_of) pa_strbuf_printf(s, "\tmonitor_of: <%u>\n", source->monitor_of->index); if (source->module) pa_strbuf_printf(s, "\tmodule: <%u>\n", source->module->index); if (source->description) pa_strbuf_printf(s, "\tdescription: <%s>\n", source->description); } return pa_strbuf_tostring_free(s); }
char *pa_source_list_to_string(pa_core *c) { pa_strbuf *s; pa_source *source; uint32_t idx = PA_IDXSET_INVALID; pa_assert(c); s = pa_strbuf_new(); pa_strbuf_printf(s, "%u source(s) available.\n", pa_idxset_size(c->sources)); for (source = pa_idxset_first(c->sources, &idx); source; source = pa_idxset_next(c->sources, &idx)) { char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cvdb[PA_SW_CVOLUME_SNPRINT_DB_MAX], v[PA_VOLUME_SNPRINT_MAX], vdb[PA_SW_VOLUME_SNPRINT_DB_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX], *t; const char *cmn; cmn = pa_channel_map_to_pretty_name(&source->channel_map); pa_strbuf_printf( s, " %c index: %u\n" "\tname: <%s>\n" "\tdriver: <%s>\n" "\tflags: %s%s%s%s%s%s%s\n" "\tstate: %s\n" "\tsuspend cause: %s%s%s%s\n" "\tpriority: %u\n" "\tvolume: %s%s%s\n" "\t balance %0.2f\n" "\tbase volume: %s%s%s\n" "\tvolume steps: %u\n" "\tmuted: %s\n" "\tcurrent latency: %0.2f ms\n" "\tmax rewind: %lu KiB\n" "\tsample spec: %s\n" "\tchannel map: %s%s%s\n" "\tused by: %u\n" "\tlinked by: %u\n", c->default_source == source ? '*' : ' ', source->index, source->name, source->driver, source->flags & PA_SOURCE_HARDWARE ? "HARDWARE " : "", source->flags & PA_SOURCE_NETWORK ? "NETWORK " : "", source->flags & PA_SOURCE_HW_MUTE_CTRL ? "HW_MUTE_CTRL " : "", source->flags & PA_SOURCE_HW_VOLUME_CTRL ? "HW_VOLUME_CTRL " : "", source->flags & PA_SOURCE_DECIBEL_VOLUME ? "DECIBEL_VOLUME " : "", source->flags & PA_SOURCE_LATENCY ? "LATENCY " : "", source->flags & PA_SOURCE_DYNAMIC_LATENCY ? "DYNAMIC_LATENCY" : "", source_state_to_string(pa_source_get_state(source)), source->suspend_cause & PA_SUSPEND_USER ? "USER " : "", source->suspend_cause & PA_SUSPEND_APPLICATION ? "APPLICATION " : "", source->suspend_cause & PA_SUSPEND_IDLE ? "IDLE " : "", source->suspend_cause & PA_SUSPEND_SESSION ? "SESSION" : "", source->priority, pa_cvolume_snprint(cv, sizeof(cv), pa_source_get_volume(source, FALSE)), source->flags & PA_SOURCE_DECIBEL_VOLUME ? "\n\t " : "", source->flags & PA_SOURCE_DECIBEL_VOLUME ? pa_sw_cvolume_snprint_dB(cvdb, sizeof(cvdb), pa_source_get_volume(source, FALSE)) : "", pa_cvolume_get_balance(pa_source_get_volume(source, FALSE), &source->channel_map), pa_volume_snprint(v, sizeof(v), source->base_volume), source->flags & PA_SOURCE_DECIBEL_VOLUME ? "\n\t " : "", source->flags & PA_SOURCE_DECIBEL_VOLUME ? pa_sw_volume_snprint_dB(vdb, sizeof(vdb), source->base_volume) : "", source->n_volume_steps, pa_yes_no(pa_source_get_mute(source, FALSE)), (double) pa_source_get_latency(source) / PA_USEC_PER_MSEC, (unsigned long) pa_source_get_max_rewind(source) / 1024, pa_sample_spec_snprint(ss, sizeof(ss), &source->sample_spec), pa_channel_map_snprint(cm, sizeof(cm), &source->channel_map), cmn ? "\n\t " : "", cmn ? cmn : "", pa_source_used_by(source), pa_source_linked_by(source)); if (source->flags & PA_SOURCE_DYNAMIC_LATENCY) { pa_usec_t min_latency, max_latency; pa_source_get_latency_range(source, &min_latency, &max_latency); pa_strbuf_printf( s, "\tconfigured latency: %0.2f ms; range is %0.2f .. %0.2f ms\n", (double) pa_source_get_requested_latency(source) / PA_USEC_PER_MSEC, (double) min_latency / PA_USEC_PER_MSEC, (double) max_latency / PA_USEC_PER_MSEC); } else pa_strbuf_printf( s, "\tfixed latency: %0.2f ms\n", (double) pa_source_get_fixed_latency(source) / PA_USEC_PER_MSEC); if (source->monitor_of) pa_strbuf_printf(s, "\tmonitor_of: %u\n", source->monitor_of->index); if (source->card) pa_strbuf_printf(s, "\tcard: %u <%s>\n", source->card->index, source->card->name); if (source->module) pa_strbuf_printf(s, "\tmodule: %u\n", source->module->index); t = pa_proplist_to_string_sep(source->proplist, "\n\t\t"); pa_strbuf_printf(s, "\tproperties:\n\t\t%s\n", t); pa_xfree(t); append_port_list(s, source->ports); if (source->active_port) pa_strbuf_printf( s, "\tactive port: <%s>\n", source->active_port->name); } return pa_strbuf_tostring_free(s); }