From e8f93b125e0e0776024ae78a2bdd33daf4442326 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 21 Jan 2009 02:02:30 +0100 Subject: make implementation of module-alsa-card complete --- src/modules/alsa/module-alsa-card.c | 106 ++++++++++++++++++++++++++++++++---- 1 file changed, 94 insertions(+), 12 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 6c947c06..f2506024 100644 --- a/src/modules/alsa/module-alsa-card.c +++ b/src/modules/alsa/module-alsa-card.c @@ -28,6 +28,8 @@ #include #include "alsa-util.h" +#include "alsa-sink.h" +#include "alsa-source.h" #include "module-alsa-card-symdef.h" PA_MODULE_AUTHOR("Lennart Poettering"); @@ -48,19 +50,17 @@ PA_MODULE_USAGE( "profile="); static const char* const valid_modargs[] = { - "sink_name", - "device", + "name", "device_id", "format", "rate", - "channels", - "channel_map", "fragments", "fragment_size", "mmap", "tsched", "tsched_buffer_size", "tsched_buffer_watermark", + "profile", NULL }; @@ -73,10 +73,14 @@ struct userdata { char *device_id; pa_card *card; + pa_sink *sink; + pa_source *source; + + pa_modargs *modargs; }; struct profile_data { - const pa_alsa_profile_info *sink, *source; + const pa_alsa_profile_info *sink_profile, *source_profile; }; static void enumerate_cb( @@ -119,8 +123,8 @@ static void enumerate_cb( d = PA_CARD_PROFILE_DATA(p); - d->sink = sink; - d->source = source; + d->sink_profile = sink; + d->source_profile = source; pa_hashmap_put(profiles, p->name, p); } @@ -132,11 +136,59 @@ static void add_disabled_profile(pa_hashmap *profiles) { p = pa_card_profile_new("off", "Off", sizeof(struct profile_data)); d = PA_CARD_PROFILE_DATA(p); - d->sink = d->source = NULL; + d->sink_profile = d->source_profile = NULL; pa_hashmap_put(profiles, p->name, p); } +static int card_set_profile(pa_card *c, pa_card_profile *new_profile) { + struct userdata *u; + struct profile_data *nd, *od; + + pa_assert(c); + pa_assert(new_profile); + pa_assert_se(u = c->userdata); + + nd = PA_CARD_PROFILE_DATA(new_profile); + od = PA_CARD_PROFILE_DATA(c->active_profile); + + if (od->sink_profile != nd->sink_profile) { + if (u->sink) { + pa_alsa_sink_free(u->sink); + u->sink = NULL; + } + + if (nd->sink_profile) + u->sink = pa_alsa_sink_new(c->module, u->modargs, __FILE__, c, nd->sink_profile); + } + + if (od->source_profile != nd->source_profile) { + if (u->source) { + pa_alsa_source_free(u->source); + u->source = NULL; + } + + if (nd->source_profile) + u->source = pa_alsa_source_new(c->module, u->modargs, __FILE__, c, nd->source_profile); + } + + return 0; +} + +static void init_profile(struct userdata *u) { + struct profile_data *d; + + pa_assert(u); + + d = PA_CARD_PROFILE_DATA(u->card->active_profile); + + if (d->sink_profile) + u->sink = pa_alsa_sink_new(u->module, u->modargs, __FILE__, u->card, d->sink_profile); + + if (d->source_profile) + u->source = pa_alsa_source_new(u->module, u->modargs, __FILE__, u->card, d->source_profile); +} + int pa__init(pa_module*m) { pa_card_new_data data; pa_modargs *ma; @@ -144,6 +196,7 @@ int pa__init(pa_module*m) { struct userdata *u; pa_alsa_redirect_errors_inc(); + snd_config_update_free_global(); pa_assert(m); @@ -152,10 +205,14 @@ int pa__init(pa_module*m) { goto fail; } - m->userdata = u = pa_xnew0(struct userdata, 1); + m->userdata = u = pa_xnew(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)); + u->card = NULL; + u->sink = NULL; + u->source = NULL; + u->modargs = ma; 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)); @@ -186,17 +243,33 @@ int pa__init(pa_module*m) { u->card = pa_card_new(m->core, &data); pa_card_new_data_done(&data); + if (!u->card) + goto fail; + + u->card->userdata = u; + u->card->set_profile = card_set_profile; + + init_profile(u); + return 0; fail: - if (ma) - pa_modargs_free(ma); - pa__done(m); return -1; } +int pa__get_n_used(pa_module *m) { + struct userdata *u; + + pa_assert(m); + pa_assert_se(u = m->userdata); + + return + (u->sink ? pa_sink_linked_by(u->sink) : 0) + + (u->source ? pa_source_linked_by(u->source) : 0); +} + void pa__done(pa_module*m) { struct userdata *u; @@ -205,9 +278,18 @@ void pa__done(pa_module*m) { if (!(u = m->userdata)) goto finish; + if (u->sink) + pa_alsa_sink_free(u->sink); + + if (u->source) + pa_alsa_source_free(u->source); + if (u->card) pa_card_free(u->card); + if (u->modargs) + pa_modargs_free(u->modargs); + pa_xfree(u->device_id); pa_xfree(u); -- cgit