File 0002-Implement-get_chmap-set_chmap-for-PCM-plug-route-and.patch of Package alsa

From 3fb013065fee01ba7ac7c64fa48149f0e124fe26 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Wed, 25 Jul 2012 15:36:16 +0200
Subject: [PATCH 02/30] 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>
---
 src/pcm/pcm_multi.c |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/pcm/pcm_plug.c  |    3 ++
 src/pcm/pcm_route.c |   30 ++++++++++++++++++++++++++
 3 files changed, 93 insertions(+)

--- 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
 	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
 	.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 = {
--- 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_
 	.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,
 };
 
 /**
--- 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
 	.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,
openSUSE Build Service is sponsored by