From: Takashi Iwai <tiwai@suse.de>
To: David Henningsson <david.henningsson@canonical.com>
Cc: alsa-devel@alsa-project.org
Subject: Re: [PATCH 2/3] route: Select slave chmap based on ttable information
Date: Fri, 21 Feb 2014 16:49:21 +0100 [thread overview]
Message-ID: <s5hvbw8tqim.wl%tiwai@suse.de> (raw)
In-Reply-To: <1392996262-27970-3-git-send-email-david.henningsson@canonical.com>
At Fri, 21 Feb 2014 16:24:21 +0100,
David Henningsson wrote:
>
> It means we need to initialize this order:
>
> 1) Read the ttable to figure out which channels are present
> 2) Open slave pcm and find a matching chmap
> 3) Determine size of ttable (this can now depend on the chmap)
> 4) Read ttable coefficients
> 5) At prepare time, select the matching chmap
>
> Signed-off-by: David Henningsson <david.henningsson@canonical.com>
> ---
> src/pcm/pcm_route.c | 300 ++++++++++++++++++++++++++++++++++++++++++++--------
> 1 file changed, 257 insertions(+), 43 deletions(-)
>
> diff --git a/src/pcm/pcm_route.c b/src/pcm/pcm_route.c
> index ffc283f..355da1e 100644
> --- a/src/pcm/pcm_route.c
> +++ b/src/pcm/pcm_route.c
> @@ -103,6 +103,7 @@ typedef struct {
> snd_pcm_format_t sformat;
> int schannels;
> snd_pcm_route_params_t params;
> + snd_pcm_chmap_t *chmap;
> } snd_pcm_route_t;
>
> #endif /* DOC_HIDDEN */
> @@ -518,6 +519,7 @@ static int snd_pcm_route_close(snd_pcm_t *pcm)
> }
> free(params->dsts);
> }
> + free(route->chmap);
> return snd_pcm_generic_close(pcm);
> }
>
> @@ -789,21 +791,168 @@ static void snd_pcm_route_dump(snd_pcm_t *pcm, snd_output_t *out)
> snd_pcm_dump(route->plug.gen.slave, out);
> }
>
> -static int safe_chmapchannel(const char *id, long *channel)
> +static int safe_chmapchannel(const char *id, snd_pcm_chmap_t *chmap,
> + long *channel, int channel_size)
A brief description of the function would be helpful, as the code
becomes no longer trivial by this patch.
> {
> - int err;
> int ch;
> - err = safe_strtol(id, channel);
> - if (err >= 0)
> - return err;
> + if (safe_strtol(id, channel) >= 0)
> + return 1;
>
> ch = (int) snd_pcm_chmap_from_string(id);
> if (ch == -1)
> return -EINVAL;
>
> - /* For now, assume standard channel mapping */
> - *channel = ch - SND_CHMAP_FL;
> + if (chmap) {
> + int i, r = 0;
> + /* Start with highest channel to simplify implementation of
> + determine ttable size */
> + for (i = chmap->channels - 1; i >= 0; i--) {
> + if ((int) chmap->pos[i] != ch)
> + continue;
> + if (r >= channel_size)
> + continue;
> + channel[r++] = i;
> + }
> + return r;
> + }
> + else {
> + /* Assume ALSA standard channel mapping */
> + *channel = ch - SND_CHMAP_FL;
> + return 1;
> + }
> +}
> +
> +#define MAX_CHMAP_CHANNELS 256
> +
> +static int determine_chmap(snd_config_t *tt, snd_pcm_chmap_t **tt_chmap)
> +{
> + snd_config_iterator_t i, inext;
> + snd_pcm_chmap_t *chmap;
> +
> + assert(tt && tt_chmap);
> + chmap = malloc(sizeof(snd_pcm_chmap_t) +
> + MAX_CHMAP_CHANNELS * sizeof(unsigned int));
> +
> + chmap->channels = 0;
> + snd_config_for_each(i, inext, tt) {
> + const char *id;
> + snd_config_iterator_t j, jnext;
> + snd_config_t *in = snd_config_iterator_entry(i);
> +
> + if (!snd_config_get_id(in, &id) < 0)
> + continue;
> + if (snd_config_get_type(in) != SND_CONFIG_TYPE_COMPOUND)
> + goto err;
> + snd_config_for_each(j, jnext, in) {
> + int ch, k, found;
> + long schannel;
> + snd_config_t *jnode = snd_config_iterator_entry(j);
> + if (snd_config_get_id(jnode, &id) < 0)
> + continue;
> + if (safe_strtol(id, &schannel) >= 0)
> + continue;
> + ch = (int) snd_pcm_chmap_from_string(id);
> + if (ch == -1)
> + goto err;
> +
> + found = 0;
> + for (k = 0; k < (int) chmap->channels; k++)
> + if (ch == (int) chmap->pos[k]) {
> + found = 1;
> + break;
> + }
> + if (found)
> + continue;
> +
> + if (chmap->channels >= MAX_CHMAP_CHANNELS) {
> + SNDERR("Too many channels in ttable chmap");
> + goto err;
> + }
> + chmap->pos[chmap->channels++] = ch;
> + }
> + }
> +
> +
> + *tt_chmap = chmap;
> return 0;
> +
> +err:
> + *tt_chmap = NULL;
> + free(chmap);
> + return -EINVAL;
> +}
> +
> +static int find_matching_chmap(snd_pcm_t *spcm, snd_pcm_chmap_t *tt_chmap,
> + snd_pcm_chmap_t **found_chmap, int *schannels)
> +{
> + snd_pcm_chmap_query_t** chmaps = snd_pcm_query_chmaps(spcm);
> + int i;
> +
> + *found_chmap = NULL;
> +
> + if (chmaps == NULL)
> + return 0; /* chmap API not supported for this slave */
> +
> + for (i = 0; chmaps[i]; i++) {
> + unsigned int j, k;
> + int match = 1;
> + snd_pcm_chmap_t *c = &chmaps[i]->map;
> + if (*schannels >= 0 && (int) c->channels != *schannels)
> + continue;
> +
> + for (j = 0; j < tt_chmap->channels; j++) {
> + int found = 0;
> + unsigned int ch = tt_chmap->pos[j];
> + for (k = 0; k < c->channels; k++)
> + if (c->pos[k] == ch) {
> + found = 1;
> + break;
> + }
> + if (!found) {
> + match = 0;
> + break;
> + }
> + }
> +
> + if (match) {
> + int size = sizeof(snd_pcm_chmap_t) + c->channels * sizeof(unsigned int);
> + *found_chmap = malloc(size);
NULL check is missing here.
> + memcpy(*found_chmap, c, size);
> + *schannels = c->channels;
> + break;
> + }
> + }
> +
> + snd_pcm_free_chmaps(chmaps);
> +
> + if (*found_chmap == NULL) {
> + SNDERR("Found no matching channel map");
> + return -EINVAL;
> + }
> + return 0;
> +}
> +
> +static int route_chmap_init(snd_pcm_t *pcm)
> +{
> + int set_map = 0;
> + snd_pcm_chmap_t *current;
> + snd_pcm_route_t *route = pcm->private_data;
> + if (!route->chmap)
> + return 0;
> + if (snd_pcm_state(pcm) != SND_PCM_STATE_PREPARED)
> + return 0;
> +
> + current = snd_pcm_get_chmap(route->plug.gen.slave);
> + if (!current)
> + return -ENOSYS;
> + if (current->channels != route->chmap->channels)
> + set_map = 1;
> + else set_map = memcmp(current->pos, route->chmap->pos, current->channels);
Please fix the indentation.
Takashi
next prev parent reply other threads:[~2014-02-21 15:49 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-02-21 15:24 [PATCH 0/3] alsa-lib - improve surround 2.1 support David Henningsson
2014-02-21 15:24 ` [PATCH 1/3] route: Allow chmap syntax for slave channels in ttable David Henningsson
2014-02-21 15:42 ` Takashi Iwai
2014-02-21 15:24 ` [PATCH 2/3] route: Select slave chmap based on ttable information David Henningsson
2014-02-21 15:49 ` Takashi Iwai [this message]
2014-02-21 15:24 ` [PATCH 3/3] conf: Allow 2.1 surround to use different number of channels David Henningsson
2014-02-21 15:50 ` [PATCH 0/3] alsa-lib - improve surround 2.1 support Takashi Iwai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=s5hvbw8tqim.wl%tiwai@suse.de \
--to=tiwai@suse.de \
--cc=alsa-devel@alsa-project.org \
--cc=david.henningsson@canonical.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox