]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Implement get_chmap/set_chmap for PCM plug, route and multi plugins
authorTakashi Iwai <tiwai@suse.de>
Wed, 25 Jul 2012 13:36:16 +0000 (15:36 +0200)
committerTakashi Iwai <tiwai@suse.de>
Tue, 11 Sep 2012 09:34:50 +0000 (11:34 +0200)
Still incomplete implementations.  The query and set ops are missing
for route and multi plugins.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
src/pcm/pcm_multi.c
src/pcm/pcm_plug.c
src/pcm/pcm_route.c

index 6b39c7a1341f54513e3a7ce07073b45096d52ae6..693752cd540d3df620a29b6d950f1e12ac5b560c 100644 (file)
@@ -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 = {
index 72456d5a1a5fb118dab61534e04e5d00019ff2fb..0bd88504975f511a42cf1a8726e52a45bf6de76b 100644 (file)
@@ -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,
 };
 
 /**
index 4da623f82e79345f4552839ee8faceb868cb319f..b81fb60084e2c2bdf7400cb360713a265b0e82a8 100644 (file)
@@ -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,