summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-07-25 15:36:16 +0200
committerTakashi Iwai <tiwai@suse.de>2012-09-11 11:34:50 +0200
commit3fb013065fee01ba7ac7c64fa48149f0e124fe26 (patch)
tree2ec05b4e55f476be7e9efdfc8ccf3742a345c1b6
parent3c4a22ea49a881cdbfe2d50eef94b17e38104734 (diff)
downloadalsa-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.c60
-rw-r--r--src/pcm/pcm_plug.c3
-rw-r--r--src/pcm/pcm_route.c30
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,