From e0d66cf4ad299b7158ac7254d6abf4b7a0cdd38a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juho=20H=C3=A4m=C3=A4l=C3=A4inen?= Date: Wed, 23 Feb 2022 11:41:13 +0200 Subject: [PATCH] card: Update card with new common. --- src/droid/module-droid-card.c | 132 ++++++++++++++++++++-------------- 1 file changed, 80 insertions(+), 52 deletions(-) diff --git a/src/droid/module-droid-card.c b/src/droid/module-droid-card.c index e6a39e7..40c2802 100644 --- a/src/droid/module-droid-card.c +++ b/src/droid/module-droid-card.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2018 Jolla Ltd. + * Copyright (C) 2013-2022 Jolla Ltd. * * Contact: Juho Hämäläinen * @@ -61,6 +61,7 @@ #include #include +#include #include "droid-sink.h" #include "droid-source.h" @@ -73,16 +74,13 @@ PA_MODULE_USAGE( "source_name= " "namereg_fail= " "rate= " - "output_flags= " "module_id= " "voice_source_routing= " "deferred_volume= " "config= " "voice_property_key= " "voice_property_value= " - "default_profile= " - "merge_inputs= " - "quirks=" + "options=" ); static const char* const valid_modargs[] = { @@ -97,26 +95,18 @@ static const char* const valid_modargs[] = { "sink_rate", "sink_format", "sink_channel_map", - "sink_mix_route", "source_rate", "source_format", "source_channel_map", - "output_flags", "module_id", "voice_source_routing", "sink_buffer", "source_buffer", "deferred_volume", - "mute_routing_before", - "mute_routing_after", - "prewrite_on_resume", "config", "voice_property_key", "voice_property_value", - "default_profile", - "combine", - "merge_inputs", - "quirks", + /* DM_OPTIONS */ NULL, }; @@ -289,16 +279,57 @@ static void set_card_name(pa_modargs *ma, pa_card_new_data *data, const char *mo } static bool output_enabled(struct userdata *u, pa_droid_mapping *am) { + bool enabled = false; + pa_assert(u); pa_assert(am); - if (!pa_droid_quirk(u->hw_module, QUIRK_OUTPUT_FAST) && am->output->flags & AUDIO_OUTPUT_FLAG_FAST) - return false; - if (!pa_droid_quirk(u->hw_module, QUIRK_OUTPUT_DEEP_BUFFER) && am->output->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) - return false; + if (am->mix_port->flags & AUDIO_OUTPUT_FLAG_PRIMARY) + enabled = true; - return true; + else if (am->mix_port->flags & AUDIO_OUTPUT_FLAG_RAW) + enabled = false; + + else if (pa_droid_option(u->hw_module, DM_OPTION_OUTPUT_FAST) && am->mix_port->flags & AUDIO_OUTPUT_FLAG_FAST) + enabled = true; + + else if (pa_droid_option(u->hw_module, DM_OPTION_OUTPUT_DEEP_BUFFER) && am->mix_port->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) + enabled = true; + + pa_log_debug("Output mix port \"%s\" %s", am->name, enabled ? "enabled" : "disabled"); + + return enabled; +} + +static bool input_enabled(struct userdata *u, pa_droid_mapping *am) { + bool enabled = false; + + pa_assert(u); + pa_assert(am); + + /* Look for primary mix port as the one used for creating droid-source. */ + if (dm_strcasestr(am->name, "primary")) + enabled = true; + + pa_log_debug("Input mix port \"%s\" %s", am->name, enabled ? "enabled" : "disabled"); + + return enabled; +} + +static uint32_t max_channels_for_mix_port(dm_config_port *mix_port, uint32_t previous_max_channels) { + uint32_t max_channels = 0; + dm_config_profile *profile; + void *state; + + DM_LIST_FOREACH_DATA(profile, mix_port->profiles, state) { + for (int i = 0; profile->channel_masks[i]; i++) { + max_channels = audio_channel_count_from_out_mask(profile->channel_masks[i]) > max_channels + ? audio_channel_count_from_out_mask(profile->channel_masks[i]) : max_channels; + } + } + + return max_channels > previous_max_channels ? max_channels : previous_max_channels; } static void add_profile(struct userdata *u, pa_hashmap *h, pa_hashmap *ports, pa_droid_profile *ap) { @@ -319,26 +350,23 @@ static void add_profile(struct userdata *u, pa_hashmap *h, pa_hashmap *ports, pa cp->available = PA_AVAILABLE_YES; cp->priority = ap->priority; + /* Output mappings */ + max_channels = 0; PA_IDXSET_FOREACH(am, ap->output_mappings, idx) { - if (!output_enabled(u, am)) - continue; - cp->n_sinks++; pa_droid_add_card_ports(cp, ports, am, u->core); - max_channels = popcount(am->output->channel_masks) > max_channels - ? popcount(am->output->channel_masks) : max_channels; + max_channels = max_channels_for_mix_port(am->mix_port, max_channels); } cp->max_sink_channels = max_channels; + /* Input mappings */ + max_channels = 0; - if ((am = ap->input_mapping)) { - const pa_droid_config_device *input; + PA_IDXSET_FOREACH(am, ap->input_mappings, idx) { cp->n_sources++; pa_droid_add_card_ports(cp, ports, am, u->core); - SLLIST_FOREACH(input, am->inputs) - max_channels = popcount(input->channel_masks) > max_channels - ? popcount(input->channel_masks) : max_channels; + max_channels = max_channels_for_mix_port(am->mix_port, max_channels); } cp->max_source_channels = max_channels; @@ -384,8 +412,13 @@ static void init_profile(struct userdata *u) { } } - if (d->droid_profile && (am = d->droid_profile->input_mapping)) { - am->source = pa_droid_source_new(u->module, u->modargs, __FILE__, (audio_devices_t) 0, &u->card_data, am, u->card); + if (d->droid_profile && pa_idxset_size(d->droid_profile->input_mappings) > 0) { + PA_IDXSET_FOREACH(am, d->droid_profile->input_mappings, idx) { + if (!input_enabled(u, am)) + continue; + + am->source = pa_droid_source_new(u->module, u->modargs, __FILE__, &u->card_data, am, u->card); + } } } @@ -437,12 +470,12 @@ static bool voicecall_profile_event_cb(struct userdata *u, pa_droid_profile *p, if (enabling) { pa_droid_sink_set_voice_control(am_output->sink, true); - if (pa_droid_quirk(u->hw_module, QUIRK_REALCALL)) + if (pa_droid_option(u->hw_module, DM_OPTION_REALCALL)) pa_droid_set_parameters(u->hw_module, VENDOR_EXT_REALCALL_ON); } else { pa_droid_sink_set_voice_control(am_output->sink, false); - if (pa_droid_quirk(u->hw_module, QUIRK_REALCALL)) + if (pa_droid_option(u->hw_module, DM_OPTION_REALCALL)) pa_droid_set_parameters(u->hw_module, VENDOR_EXT_REALCALL_OFF); } @@ -681,13 +714,18 @@ static int card_set_profile(pa_card *c, pa_card_profile *new_profile) { } } - if (next->droid_profile && (am = next->droid_profile->input_mapping)) { - if (!am->source) - am->source = pa_droid_source_new(u->module, u->modargs, __FILE__, (audio_devices_t) 0, &u->card_data, am, u->card); + if (next->droid_profile && pa_idxset_size(next->droid_profile->input_mappings) > 0) { + PA_IDXSET_FOREACH(am, next->droid_profile->input_mappings, idx) { + if (!input_enabled(u, am)) + continue; - if (source_outputs && am->source) { - pa_source_move_all_finish(am->source, source_outputs, false); - source_outputs = NULL; + if (!am->source) + am->source = pa_droid_source_new(u->module, u->modargs, __FILE__, &u->card_data, am, u->card); + + if (source_outputs && am->source) { + pa_source_move_all_finish(am->source, source_outputs, false); + source_outputs = NULL; + } } } @@ -714,23 +752,17 @@ int pa__init(pa_module *m) { pa_card_new_data data; const char *module_id; bool namereg_fail = false; - bool default_profile = true; pa_card_profile *voicecall = NULL; pa_assert(m); pa_log_info("Create new droid-card"); - if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { + if (!(ma = pa_droid_modargs_new(m->argument, valid_modargs))) { pa_log("Failed to parse module arguments."); goto fail; } - if (pa_modargs_get_value_boolean(ma, "default_profile", &default_profile) < 0) { - pa_log("Failed to parse default_profile argument. Expects boolean value"); - goto fail; - } - u = pa_xnew0(struct userdata, 1); u->core = m->core; m->userdata = u; @@ -740,15 +772,12 @@ int pa__init(pa_module *m) { if (!(u->hw_module = pa_droid_hw_module_get2(u->core, ma, module_id))) goto fail; - pa_droid_quirk_log(u->hw_module); + pa_droid_options_log(u->hw_module); u->card_data.module_id = pa_xstrdup(module_id); u->card_data.userdata = u; - if (default_profile) - u->profile_set = pa_droid_profile_set_default_new(u->hw_module->enabled_module); - else - u->profile_set = pa_droid_profile_set_new(u->hw_module->enabled_module); + u->profile_set = pa_droid_profile_set_default_new(u->hw_module->enabled_module); pa_card_new_data_init(&data); data.driver = __FILE__; @@ -859,7 +888,6 @@ void pa__done(pa_module *m) { if (u->card && u->card->sources) pa_idxset_remove_all(u->card->sources, (pa_free_cb_t) pa_droid_source_free); - if (u->card) pa_card_free(u->card);