diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-07-25 15:36:16 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-09-11 11:34:50 +0200 |
commit | 3fb013065fee01ba7ac7c64fa48149f0e124fe26 (patch) | |
tree | 2ec05b4e55f476be7e9efdfc8ccf3742a345c1b6 | |
parent | 3c4a22ea49a881cdbfe2d50eef94b17e38104734 (diff) | |
download | alsa-lib-3fb013065fee01ba7ac7c64fa48149f0e124fe26.tar.gz |
Implement get_chmap/set_chmap for PCM plug, route and multi plugins
Still incomplete implementations. The query and set ops are missing
for route and multi plugins.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | src/pcm/pcm_multi.c | 60 | ||||
-rw-r--r-- | src/pcm/pcm_plug.c | 3 | ||||
-rw-r--r-- | src/pcm/pcm_route.c | 30 |
3 files changed, 93 insertions, 0 deletions
diff --git a/src/pcm/pcm_multi.c b/src/pcm/pcm_multi.c index 6b39c7a1..693752cd 100644 --- a/src/pcm/pcm_multi.c +++ b/src/pcm/pcm_multi.c @@ -739,6 +739,63 @@ static int snd_pcm_multi_mmap(snd_pcm_t *pcm) return 0; } +static int *snd_pcm_multi_get_chmap(snd_pcm_t *pcm) +{ + snd_pcm_multi_t *multi = pcm->private_data; + int *map; + unsigned int i, idx; + + map = malloc(pcm->channels + 4); + if (!map) + return NULL; + idx = 0; + for (i = 0; i < multi->slaves_count; ++i) { + int c, *slave_map; + slave_map = snd_pcm_get_chmap(multi->slaves[i].pcm); + if (!slave_map) { + free(map); + return NULL; + } + for (c = 0; c < *slave_map; c++) { + if (idx >= pcm->channels) + break; + map[idx++] = slave_map[c + 1]; + } + free(slave_map); + } + return map; +} + +static int snd_pcm_multi_set_chmap(snd_pcm_t *pcm, const int *map) +{ + snd_pcm_multi_t *multi = pcm->private_data; + unsigned int i, idx, chs; + int err; + + chs = *map; + if (chs != pcm->channels) + return -EINVAL; + map++; + for (i = 0; i < multi->slaves_count; ++i) { + int *slave_map; + unsigned int slave_chs; + slave_chs = multi->slaves[i].channels_count; + if (idx + slave_chs > chs) + break; + slave_map = malloc(slave_chs * 4 + 4); + if (!slave_map) + return -ENOMEM; + *slave_map = slave_chs; + memcpy(slave_map, map + idx, slave_chs * 4); + err = snd_pcm_set_chmap(multi->slaves[i].pcm, slave_map); + free(slave_map); + if (err < 0) + return err; + idx += slave_chs; + } + return 0; +} + static void snd_pcm_multi_dump(snd_pcm_t *pcm, snd_output_t *out) { snd_pcm_multi_t *multi = pcm->private_data; @@ -775,6 +832,9 @@ static const snd_pcm_ops_t snd_pcm_multi_ops = { .async = snd_pcm_multi_async, .mmap = snd_pcm_multi_mmap, .munmap = snd_pcm_multi_munmap, + .query_chmaps = NULL, /* NYI */ + .get_chmap = snd_pcm_multi_get_chmap, + .set_chmap = snd_pcm_multi_set_chmap, }; static const snd_pcm_fast_ops_t snd_pcm_multi_fast_ops = { diff --git a/src/pcm/pcm_plug.c b/src/pcm/pcm_plug.c index 72456d5a..0bd88504 100644 --- a/src/pcm/pcm_plug.c +++ b/src/pcm/pcm_plug.c @@ -1084,6 +1084,9 @@ static const snd_pcm_ops_t snd_pcm_plug_ops = { .async = snd_pcm_generic_async, .mmap = snd_pcm_generic_mmap, .munmap = snd_pcm_generic_munmap, + .query_chmaps = snd_pcm_generic_query_chmaps, + .get_chmap = snd_pcm_generic_get_chmap, + .set_chmap = snd_pcm_generic_set_chmap, }; /** diff --git a/src/pcm/pcm_route.c b/src/pcm/pcm_route.c index 4da623f8..b81fb600 100644 --- a/src/pcm/pcm_route.c +++ b/src/pcm/pcm_route.c @@ -703,6 +703,33 @@ snd_pcm_route_read_areas(snd_pcm_t *pcm, return size; } +static int *snd_pcm_route_get_chmap(snd_pcm_t *pcm) +{ + snd_pcm_route_t *route = pcm->private_data; + int *map, *slave_map; + unsigned int src, dst; + + slave_map = snd_pcm_generic_get_chmap(pcm); + if (!slave_map) + return NULL; + map = calloc(4, route->schannels + 1); + if (!map) { + free(slave_map); + return NULL; + } + *map = route->schannels; + for (dst = 0; dst < route->params.ndsts; dst++) { + snd_pcm_route_ttable_dst_t *d = &route->params.dsts[dst]; + for (src = 0; src < d->nsrcs; src++) { + int c = d->srcs[src].channel; + if (c < route->schannels && !map[c + 1]) + map[c + 1] = slave_map[dst + 1]; + } + } + free(slave_map); + return map; +} + static void snd_pcm_route_dump(snd_pcm_t *pcm, snd_output_t *out) { snd_pcm_route_t *route = pcm->private_data; @@ -760,6 +787,9 @@ static const snd_pcm_ops_t snd_pcm_route_ops = { .async = snd_pcm_generic_async, .mmap = snd_pcm_generic_mmap, .munmap = snd_pcm_generic_munmap, + .query_chmaps = NULL, /* NYI */ + .get_chmap = snd_pcm_route_get_chmap, + .set_chmap = NULL, /* NYI */ }; static int route_load_ttable(snd_pcm_route_params_t *params, snd_pcm_stream_t stream, |