[alsa-devel] Cannot combine audio devices with more than 64 channels

Clemens Ladisch clemens at ladisch.de
Thu Jan 26 17:13:50 CET 2017


Jörg Müller wrote:
> I created an .asoundrc with 194 inputs for each card.
>
> pcm_multi.c:1060: snd_pcm_multi_open: Assertion `!slave_map[sidxs[i]][schannels[i]]' failed.
>
> To me, this looks like a bug.

--8<---------------------------------------------------------------->8--
pcm: multi: allocate slave_map dynamically

Using a fixed-size buffer for an arbitrarily-sized list is not a good idea.

Signed-off-by: Clemens Ladisch <clemens at ladisch.de>
---
 src/pcm/pcm_multi.c |   20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

untested

diff --git a/src/pcm/pcm_multi.c b/src/pcm/pcm_multi.c
index c4b1fba3..f8efca97 100644
--- a/src/pcm/pcm_multi.c
+++ b/src/pcm/pcm_multi.c
@@ -1015,7 +1015,7 @@ int snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
 	snd_pcm_multi_t *multi;
 	unsigned int i;
 	snd_pcm_stream_t stream;
-	char slave_map[64][64] = { { 0 } };
+	char **slave_map;
 	int err;

 	assert(pcmp);
@@ -1044,12 +1044,27 @@ int snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
 		free(multi);
 		return -ENOMEM;
 	}
+	slave_map = calloc(slaves_count, sizeof(*slave_map));
+	if (!slave_map) {
+		free(multi->slaves);
+		free(multi);
+		return -ENOMEM;
+	}
 	for (i = 0; i < slaves_count; ++i) {
 		snd_pcm_multi_slave_t *slave = &multi->slaves[i];
 		assert(slaves_pcm[i]->stream == stream);
 		slave->pcm = slaves_pcm[i];
 		slave->channels_count = schannels_count[i];
 		slave->close_slave = close_slaves;
+		slave_map[i] = calloc(schannels_count[i], sizeof(*slave_map[i]));
+		if (!slave_map[i]) {
+			while (i--)
+				free(slave_map[i]);
+			free(slave_map);
+			free(multi->slaves);
+			free(multi);
+			return -ENOMEM;
+		}
 	}
 	for (i = 0; i < channels_count; ++i) {
 		snd_pcm_multi_channel_t *bind = &multi->channels[i];
@@ -1062,6 +1077,9 @@ int snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
 		assert(!slave_map[sidxs[i]][schannels[i]]);
 		slave_map[sidxs[i]][schannels[i]] = 1;
 	}
+	for (i = 0; i < slaves_count; ++i)
+		free(slave_map[i]);
+	free(slave_map);
 	multi->channels_count = channels_count;

 	err = snd_pcm_new(&pcm, SND_PCM_TYPE_MULTI, name, stream,




More information about the Alsa-devel mailing list