From c06e43d7ff5eff33af416a35ef4ca962a0cc0a2e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 17 Jan 2009 02:03:35 +0100 Subject: actually create pa_card object in module-alsa-card --- src/modules/alsa/module-alsa-card.c | 154 ++++++++++++++++++++++++++++++++++-- 1 file changed, 147 insertions(+), 7 deletions(-) (limited to 'src/modules/alsa/module-alsa-card.c') diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c index 64559c4f..2cc8a151 100644 --- a/src/modules/alsa/module-alsa-card.c +++ b/src/modules/alsa/module-alsa-card.c @@ -23,6 +23,10 @@ #include #endif +#include +#include +#include + #include "alsa-util.h" #include "module-alsa-card-symdef.h" @@ -30,27 +34,163 @@ PA_MODULE_AUTHOR("Lennart Poettering"); PA_MODULE_DESCRIPTION("ALSA Card"); PA_MODULE_VERSION(PACKAGE_VERSION); PA_MODULE_LOAD_ONCE(FALSE); +PA_MODULE_USAGE( + "name= " + "device_id= " + "format= " + "rate= " + "fragments= " + "fragment_size= " + "mmap= " + "tsched= " + "tsched_buffer_size= " + "tsched_buffer_watermark= " + "profile="); + +static const char* const valid_modargs[] = { + "sink_name", + "device", + "device_id", + "format", + "rate", + "channels", + "channel_map", + "fragments", + "fragment_size", + "mmap", + "tsched", + "tsched_buffer_size", + "tsched_buffer_watermark", + NULL +}; + +#define DEFAULT_DEVICE_ID "0" + +struct userdata { + pa_core *core; + pa_module *module; + + char *device_id; + + pa_card *card; +}; + +struct profile_data { + const pa_alsa_profile_info *sink, *source; +}; static void enumerate_cb( const pa_alsa_profile_info *sink, const pa_alsa_profile_info *source, void *userdata) { - if (sink && source) - pa_log("Found Output %s + Input %s", sink->description, source->description); - else if (sink) - pa_log("Found Output %s", sink->description); - else if (source) - pa_log("Found Input %s", source->description); + pa_hashmap *profiles = (pa_hashmap *) userdata; + char *t, *n; + pa_card_profile *p; + struct profile_data *d; + + if (sink && source) { + n = pa_sprintf_malloc("%s+%s", sink->name, source->name); + t = pa_sprintf_malloc("Output %s + Input %s", sink->description, source->description); + } else if (sink) { + n = pa_xstrdup(sink->name); + t = pa_sprintf_malloc("Output %s", sink->description); + } else { + pa_assert(source); + n = pa_xstrdup(source->name); + t = pa_sprintf_malloc("Input %s", source->description); + } + pa_log_info("Found output profile '%s'", t); + + p = pa_card_profile_new(n, t, sizeof(struct profile_data)); + + pa_xfree(t); + pa_xfree(n); + + p->n_sinks = !!sink; + p->n_sources = !!source; + + if (sink) + p->max_sink_channels = sink->map.channels; + if (source) + p->max_source_channels = source->map.channels; + + d = PA_CARD_PROFILE_DATA(p); + + d->sink = sink; + d->source = source; + + pa_hashmap_put(profiles, p->name, p); } int pa__init(pa_module*m) { + pa_card_new_data data; + pa_modargs *ma; + int alsa_card_index; + struct userdata *u; + pa_alsa_redirect_errors_inc(); - pa_alsa_probe_profiles("1", &m->core->default_sample_spec, enumerate_cb, m); + + pa_assert(m); + + if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { + pa_log("Failed to parse module arguments"); + goto fail; + } + + m->userdata = u = pa_xnew0(struct userdata, 1); + u->core = m->core; + u->module = m; + u->device_id = pa_xstrdup(pa_modargs_get_value(ma, "device_id", DEFAULT_DEVICE_ID)); + + if ((alsa_card_index = snd_card_get_index(u->device_id)) < 0) { + pa_log("Card '%s' doesn't exist: %s", u->device_id, snd_strerror(alsa_card_index)); + goto fail; + } + + pa_card_new_data_init(&data); + data.driver = __FILE__; + data.module = m; + pa_alsa_init_proplist_card(data.proplist, alsa_card_index); + pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, u->device_id); + pa_card_new_data_set_name(&data, pa_modargs_get_value(ma, "name", u->device_id)); + + data.profiles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); + if (pa_alsa_probe_profiles(u->device_id, &m->core->default_sample_spec, enumerate_cb, data.profiles) < 0) { + pa_card_new_data_done(&data); + goto fail; + } + + u->card = pa_card_new(m->core, &data); + pa_card_new_data_done(&data); + return 0; + +fail: + + if (ma) + pa_modargs_free(ma); + + pa__done(m); + return -1; } void pa__done(pa_module*m) { + struct userdata *u; + + pa_assert(m); + + if (!(u = m->userdata)) + goto finish; + + if (u->card) + pa_card_free(u->card); + + pa_xfree(u->device_id); + pa_xfree(u); + +finish: + snd_config_update_free_global(); pa_alsa_redirect_errors_dec(); } -- cgit