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/alsa-sink.c | 11 ++-- src/modules/alsa/alsa-sink.h | 2 +- src/modules/alsa/alsa-source.c | 16 +++-- src/modules/alsa/alsa-source.h | 2 +- src/modules/alsa/module-alsa-card.c | 106 ++++++++++++++++++++++++++++++---- src/modules/alsa/module-alsa-sink.c | 2 +- src/modules/alsa/module-alsa-source.c | 2 +- 7 files changed, 114 insertions(+), 27 deletions(-) (limited to 'src/modules/alsa') diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index e890ef76..e6b3e0e5 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -1201,7 +1201,7 @@ finish: pa_log_debug("Thread shutting down"); } -pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const pa_alsa_profile_info *profile) { +pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_card *card, const pa_alsa_profile_info *profile) { struct userdata *u = NULL; const char *dev_id = NULL; @@ -1372,11 +1372,11 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const pa_alsa_profile_in if (snd_pcm_info(u->pcm_handle, info) >= 0) { char *md; - int card; + int card_idx; - if ((card = snd_pcm_info_get_card(info)) >= 0) { + if ((card_idx = snd_pcm_info_get_card(info)) >= 0) { - md = pa_sprintf_malloc("hw:%i", card); + md = pa_sprintf_malloc("hw:%i", card_idx); if (strcmp(u->device_name, md)) if (pa_alsa_prepare_mixer(u->mixer_handle, md) >= 0) @@ -1407,8 +1407,9 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const pa_alsa_profile_in } pa_sink_new_data_init(&data); - data.driver = __FILE__; + data.driver = driver; data.module = m; + data.card = card; pa_sink_new_data_set_name(&data, name); data.namereg_fail = namereg_fail; pa_sink_new_data_set_sample_spec(&data, &ss); diff --git a/src/modules/alsa/alsa-sink.h b/src/modules/alsa/alsa-sink.h index e5032018..47ece9e0 100644 --- a/src/modules/alsa/alsa-sink.h +++ b/src/modules/alsa/alsa-sink.h @@ -29,7 +29,7 @@ #include "alsa-util.h" -pa_sink* pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const pa_alsa_profile_info *profile); +pa_sink* pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_card *card, const pa_alsa_profile_info *profile); void pa_alsa_sink_free(pa_sink *s); diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c index f4d97386..29145f6a 100644 --- a/src/modules/alsa/alsa-source.c +++ b/src/modules/alsa/alsa-source.c @@ -1036,7 +1036,7 @@ finish: pa_log_debug("Thread shutting down"); } -pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const pa_alsa_profile_info *profile) { +pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, pa_card *card, const pa_alsa_profile_info *profile) { struct userdata *u = NULL; const char *dev_id = NULL; @@ -1197,11 +1197,11 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const pa_alsa_profil if (snd_pcm_info(u->pcm_handle, info) >= 0) { char *md; - int card; + int card_idx; - if ((card = snd_pcm_info_get_card(info)) >= 0) { + if ((card_idx = snd_pcm_info_get_card(info)) >= 0) { - md = pa_sprintf_malloc("hw:%i", card); + md = pa_sprintf_malloc("hw:%i", card_idx); if (strcmp(u->device_name, md)) if (pa_alsa_prepare_mixer(u->mixer_handle, md) >= 0) @@ -1223,14 +1223,18 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const pa_alsa_profil if ((name = pa_modargs_get_value(ma, "source_name", NULL))) namereg_fail = TRUE; - else { + else if ((name = pa_modargs_get_value(ma, "name", NULL))) { + name = name_buf = pa_sprintf_malloc("alsa_input.%s", name); + namereg_fail = TRUE; + } else { name = name_buf = pa_sprintf_malloc("alsa_input.%s", u->device_name); namereg_fail = FALSE; } pa_source_new_data_init(&data); - data.driver = __FILE__; + data.driver = driver; data.module = m; + data.card = card; pa_source_new_data_set_name(&data, name); data.namereg_fail = namereg_fail; pa_source_new_data_set_sample_spec(&data, &ss); diff --git a/src/modules/alsa/alsa-source.h b/src/modules/alsa/alsa-source.h index bdb24d10..5fed6cc8 100644 --- a/src/modules/alsa/alsa-source.h +++ b/src/modules/alsa/alsa-source.h @@ -29,7 +29,7 @@ #include "alsa-util.h" -pa_source* pa_alsa_source_new(pa_module *m, pa_modargs *ma, const pa_alsa_profile_info *profile); +pa_source* pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, pa_card *card, const pa_alsa_profile_info *profile); void pa_alsa_source_free(pa_source *s); 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); diff --git a/src/modules/alsa/module-alsa-sink.c b/src/modules/alsa/module-alsa-sink.c index f8303a5e..6a66ad32 100644 --- a/src/modules/alsa/module-alsa-sink.c +++ b/src/modules/alsa/module-alsa-sink.c @@ -82,7 +82,7 @@ int pa__init(pa_module*m) { goto fail; } - if (!(m->userdata = pa_alsa_sink_new(m, ma, NULL))) + if (!(m->userdata = pa_alsa_sink_new(m, ma, __FILE__, NULL, NULL))) goto fail; pa_modargs_free(ma); diff --git a/src/modules/alsa/module-alsa-source.c b/src/modules/alsa/module-alsa-source.c index 468a1262..7dc22fea 100644 --- a/src/modules/alsa/module-alsa-source.c +++ b/src/modules/alsa/module-alsa-source.c @@ -106,7 +106,7 @@ int pa__init(pa_module*m) { goto fail; } - if (!(m->userdata = pa_alsa_source_new(m, ma, NULL))) + if (!(m->userdata = pa_alsa_source_new(m, ma, __FILE__, NULL, NULL))) goto fail; pa_modargs_free(ma); -- cgit