[alsa-devel] [Alsa-Devel] Cannot combine audio devices with more than 64 channels
I need to combine two HDSPe MADI FX cards to one virtual device. I have a working driver, which is alsa-compatible. I can select each single card in any alsa-compatible application and all channels work flawless. For combining the MADI FX cards to one virtual device, I created an .asoundrc with 194 inputs for each card. When I start that virtual device via jackd -R -d alsa -C madifx_record_all -P madifx_playback_all
I get this error:
creating alsa driver ... madifx_playback_all|madifx_record_all|1024|2|48000|0|0|nomon|swmeter|-|32bit jackd: pcm_multi.c:1060: snd_pcm_multi_open: Assertion `!slave_map[sidxs[i]][schannels[i]]' failed.
However, it works when I reduce the amount from 194 to 64 channels per card. I tried to use 128 channels per card, but that fails the same way. See my alsa-info here http://pastebin.com/4hq1B3wZ , which also includes the .asoundrc content.
I also found this, which might be related: https://ccrma.stanford.edu/mirrors/lalists/lad/2005/06/0202.html
To me, this looks like a bug. What do you think?
For reference, I posted the same question on http://lists.jackaudio.org/private.cgi/jack-devel-jackaudio.org/2017-January..., however, they recommended to ask here for help.
On Thu, 26 Jan 2017 15:14:41 +0100, Jörg Müller wrote:
I need to combine two HDSPe MADI FX cards to one virtual device. I have a working driver, which is alsa-compatible. I can select each single card in any alsa-compatible application and all channels work flawless. For combining the MADI FX cards to one virtual device, I created an .asoundrc with 194 inputs for each card. When I start that virtual device via jackd -R -d alsa -C madifx_record_all -P madifx_playback_all
I get this error:
creating alsa driver ... madifx_playback_all|madifx_record_all|1024|2|48000|0|0|nomon|swmeter|-|32bit jackd: pcm_multi.c:1060: snd_pcm_multi_open: Assertion `!slave_map[sidxs[i]][schannels[i]]' failed.
However, it works when I reduce the amount from 194 to 64 channels per card. I tried to use 128 channels per card, but that fails the same way. See my alsa-info here http://pastebin.com/4hq1B3wZ , which also includes the .asoundrc content.
I also found this, which might be related: https://ccrma.stanford.edu/mirrors/lalists/lad/2005/06/0202.html
To me, this looks like a bug. What do you think?
Yes, it's a bug, the multi plugin has some weird check with a static table in the fixed size 64x64, and it overflowed. It looks nothing more like a sanity check, so we can get rid of it, I suppose.
Could you try the patch below?
thanks,
Takashi
--- diff --git a/src/pcm/pcm_multi.c b/src/pcm/pcm_multi.c index c4b1fba32cac..991f8540b62e 100644 --- a/src/pcm/pcm_multi.c +++ b/src/pcm/pcm_multi.c @@ -1015,7 +1015,6 @@ 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 } }; int err;
assert(pcmp); @@ -1051,17 +1050,7 @@ int snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name, slave->channels_count = schannels_count[i]; slave->close_slave = close_slaves; } - for (i = 0; i < channels_count; ++i) { - snd_pcm_multi_channel_t *bind = &multi->channels[i]; - assert(sidxs[i] < (int)slaves_count); - assert(schannels[i] < schannels_count[sidxs[i]]); - bind->slave_idx = sidxs[i]; - bind->slave_channel = schannels[i]; - if (sidxs[i] < 0) - continue; - assert(!slave_map[sidxs[i]][schannels[i]]); - slave_map[sidxs[i]][schannels[i]] = 1; - } + multi->channels_count = channels_count;
err = snd_pcm_new(&pcm, SND_PCM_TYPE_MULTI, name, stream,
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@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,
On Thu, 26 Jan 2017 17:13:50 +0100, Clemens Ladisch wrote:
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@ladisch.de
It turned out that we don't need the array at all. I'll apply the following cleanup (and fix) patch. My previous one was buggy.
thanks,
Takashi
-- 8< -- From: Takashi Iwai tiwai@suse.de Subject: [PATCH] pcm: multi: Drop the fixed slave_map[] in snd_pcm_multi_open()
slave_map[] in snd_pcm_multi_open() is a fixed size array and obviously we have no overflow check, and eventually the program gets an error when more than 64 channels are used.
Although we can modify the code to allocate the array dynamically, it turned out that we can drop the whole slave_map[] thingy in this function when looking at the code closely. In the past, it was used to identify the one-to-many mapping. But the check was dropped, and now it's nothing more than a sanity check.
Reported-by: Jörg Müller joerg.mueller7744@gmail.com Signed-off-by: Takashi Iwai tiwai@suse.de --- src/pcm/pcm_multi.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/src/pcm/pcm_multi.c b/src/pcm/pcm_multi.c index c4b1fba32cac..9e4be7122c0f 100644 --- a/src/pcm/pcm_multi.c +++ b/src/pcm/pcm_multi.c @@ -1015,7 +1015,6 @@ 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 } }; int err;
assert(pcmp); @@ -1059,8 +1058,6 @@ int snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name, bind->slave_channel = schannels[i]; if (sidxs[i] < 0) continue; - assert(!slave_map[sidxs[i]][schannels[i]]); - slave_map[sidxs[i]][schannels[i]] = 1; } multi->channels_count = channels_count;
Thanks for the patch, that was fast!
So I want to apply that patch to my system (Ubuntu Studio 14.04). How do I proceed? I guess, the patch wont be available via apt-get soon, right? So I'd have to compile from source. 1. What source code packages do I need to download? 2. I'm familiar with the usual "/.configure", "make" and "sudo make install" but in the case of this specific alsa-module, is there anything more I'd need to do?
On Fri, 27 Jan 2017 14:03:16 +0100, Jörg Müller wrote:
Thanks for the patch, that was fast!
So I want to apply that patch to my system (Ubuntu Studio 14.04). How do I proceed? I guess, the patch wont be available via apt-get soon, right?
I have no idea about Ubuntu. Ask Ubuntu people.
So I'd have to compile from source.
- What source code packages do I need to download?
See alsa-lib git repo listed in: https://www.alsa-project.org/main/index.php/GIT_Server
- I'm familiar with the usual "/.configure", "make" and "sudo make
install" but in the case of this specific alsa-module, is there anything more I'd need to do?
No, it's only the usual stuff, autoreconf, configure, etc.
Takashi
On Jan 27 2017 22:16, Takashi Iwai wrote:
On Fri, 27 Jan 2017 14:03:16 +0100, Jörg Müller wrote:
Thanks for the patch, that was fast!
So I want to apply that patch to my system (Ubuntu Studio 14.04). How do I proceed? I guess, the patch wont be available via apt-get soon, right?
I have no idea about Ubuntu. Ask Ubuntu people.
Ubuntu 14.04 is one of LTSs, while development for this release already finished three years ago. Basically, packages for the release are not updated unless some exceptions.
In your case, you can generate alsa-lib related packages with the patch by your own. But no one can care of your packages and you need to do everything to be required.; e.g. even if you encounter issues from the generated packages, no one can help you.
$ sudo apt-get install build-essentials devscripts $ sudo apt-get build-dep alsa-lib $ cd /tmp $ apt-get source alsa-lib $ cd alsa-lib-* (apply the patch) $ dpkg-buildpackage -rfakeroot -uc -b (packages are generated in higher directory by one level)
Perhaps, the above command lines are not enough. Some packages are still missing for packaging.
Regards
Takashi Sakamoto
Thanks, that worked! However, in Ubuntu, the package is called "libasound2" instead of "alsa-lib".
2017-01-28 0:14 GMT+01:00 Takashi Sakamoto o-takashi@sakamocchi.jp:
On Jan 27 2017 22:16, Takashi Iwai wrote:
On Fri, 27 Jan 2017 14:03:16 +0100, Jörg Müller wrote:
Thanks for the patch, that was fast!
So I want to apply that patch to my system (Ubuntu Studio 14.04). How do I proceed? I guess, the patch wont be available via apt-get soon, right?
I have no idea about Ubuntu. Ask Ubuntu people.
Ubuntu 14.04 is one of LTSs, while development for this release already finished three years ago. Basically, packages for the release are not updated unless some exceptions.
In your case, you can generate alsa-lib related packages with the patch by your own. But no one can care of your packages and you need to do everything to be required.; e.g. even if you encounter issues from the generated packages, no one can help you.
$ sudo apt-get install build-essentials devscripts $ sudo apt-get build-dep alsa-lib $ cd /tmp $ apt-get source alsa-lib $ cd alsa-lib-* (apply the patch) $ dpkg-buildpackage -rfakeroot -uc -b (packages are generated in higher directory by one level)
Perhaps, the above command lines are not enough. Some packages are still missing for packaging.
Regards
Takashi Sakamoto
On Fri, Jan 27, 2017 at 02:03:16PM +0100, Jörg Müller wrote:
So I want to apply that patch to my system (Ubuntu Studio 14.04). How do I proceed? I guess, the patch wont be available via apt-get soon, right? So I'd have to compile from source.
- What source code packages do I need to download?
- I'm familiar with the usual "/.configure", "make" and "sudo make
install" but in the case of this specific alsa-module, is there anything more I'd need to do?
One method is to download alsa-lib source, apply the patch, compile and install over the top of the existing Ubuntu libasound2 files.
Another method is to build your own patched libasound2 .deb package to replace the standard Ubuntu one.
I'll be applying the patch here on Debian using the first method. If you need instructions on how to do that, feel free to email me off list at 'john.rigg.audio at gmail.com' (gmail doesn't like my own mail server so I need to use that address to send mail to gmail users).
John
I applied the patch to my system and it fixed the error!
However, I get the following error which seems to be caused by a code not being able to handle more than 256 channels:
wfs@wfs16:~$ jackd -R -d alsa -C madifx_record_all -P madifx_playback_all jackdmp 1.9.10 Copyright 2001-2005 Paul Davis and others. Copyright 2004-2014 Grame. jackdmp comes with ABSOLUTELY NO WARRANTY This is free software, and you are welcome to redistribute it under certain conditions; see the file COPYING for details no message buffer overruns no message buffer overruns no message buffer overruns JACK server starting in realtime mode with priority 10 self-connect-mode is "Don't restrict self connect requests" audio_reservation_init Acquire audio card Audio0 creating alsa driver ... madifx_playback_all|madifx_record_all|1024|2|48000|0|0|nomon|swmeter|-|32bit configuring for 48000Hz, period = 1024 frames (21.3 ms), buffer = 2 periods ALSA: final selected sample format for capture: 32bit float little-endian ALSA: use 8 periods for capture ALSA: final selected sample format for playback: 32bit float little-endian ALSA: use 8 periods for playback jackd: ../linux/alsa/JackAlsaDriver.cpp:122: virtual int Jack::JackAlsaDriver::Attach(): Assertion `fCaptureChannels < 256' failed. Aborted (core dumped)
What could be the problem here?
2017-01-27 12:08 GMT+01:00 Takashi Iwai tiwai@suse.de:
On Thu, 26 Jan 2017 17:13:50 +0100, Clemens Ladisch wrote:
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@ladisch.de
It turned out that we don't need the array at all. I'll apply the following cleanup (and fix) patch. My previous one was buggy.
thanks,
Takashi
-- 8< -- From: Takashi Iwai tiwai@suse.de Subject: [PATCH] pcm: multi: Drop the fixed slave_map[] in snd_pcm_multi_open()
slave_map[] in snd_pcm_multi_open() is a fixed size array and obviously we have no overflow check, and eventually the program gets an error when more than 64 channels are used.
Although we can modify the code to allocate the array dynamically, it turned out that we can drop the whole slave_map[] thingy in this function when looking at the code closely. In the past, it was used to identify the one-to-many mapping. But the check was dropped, and now it's nothing more than a sanity check.
Reported-by: Jörg Müller joerg.mueller7744@gmail.com Signed-off-by: Takashi Iwai tiwai@suse.de
src/pcm/pcm_multi.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/src/pcm/pcm_multi.c b/src/pcm/pcm_multi.c index c4b1fba32cac..9e4be7122c0f 100644 --- a/src/pcm/pcm_multi.c +++ b/src/pcm/pcm_multi.c @@ -1015,7 +1015,6 @@ 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 } }; int err; assert(pcmp);
@@ -1059,8 +1058,6 @@ int snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name, bind->slave_channel = schannels[i]; if (sidxs[i] < 0) continue;
assert(!slave_map[sidxs[i]][schannels[i]]);
slave_map[sidxs[i]][schannels[i]] = 1; } multi->channels_count = channels_count;
-- 2.11.0
On Tue, Jan 31, 2017 at 06:18:48PM +0100, Jörg Müller wrote:
I applied the patch to my system and it fixed the error!
However, I get the following error which seems to be caused by a code not being able to handle more than 256 channels:
wfs@wfs16:~$ jackd -R -d alsa -C madifx_record_all -P madifx_playback_all jackdmp 1.9.10 Copyright 2001-2005 Paul Davis and others. Copyright 2004-2014 Grame. jackdmp comes with ABSOLUTELY NO WARRANTY This is free software, and you are welcome to redistribute it under certain conditions; see the file COPYING for details no message buffer overruns no message buffer overruns no message buffer overruns JACK server starting in realtime mode with priority 10 self-connect-mode is "Don't restrict self connect requests" audio_reservation_init Acquire audio card Audio0 creating alsa driver ... madifx_playback_all|madifx_record_all|1024|2|48000|0|0|nomon|swmeter|-|32bit configuring for 48000Hz, period = 1024 frames (21.3 ms), buffer = 2 periods ALSA: final selected sample format for capture: 32bit float little-endian ALSA: use 8 periods for capture ALSA: final selected sample format for playback: 32bit float little-endian ALSA: use 8 periods for playback jackd: ../linux/alsa/JackAlsaDriver.cpp:122: virtual int Jack::JackAlsaDriver::Attach(): Assertion `fCaptureChannels < 256' failed. Aborted (core dumped)
What could be the problem here?
jackd only allows 256 ports maximum by default. Try using -p option to increase it, eg. to 512:
jackd -R -p512 -d alsa....etc
BTW you don't need to specify -R on recent jackd versions as it's realtime by default (use -r if you don't want realtime).
John
On Tue, 31 Jan 2017 18:18:48 +0100, Jörg Müller wrote:
I applied the patch to my system and it fixed the error!
However, I get the following error which seems to be caused by a code not being able to handle more than 256 channels:
wfs@wfs16:~$ jackd -R -d alsa -C madifx_record_all -P madifx_playback_all jackdmp 1.9.10 Copyright 2001-2005 Paul Davis and others. Copyright 2004-2014 Grame. jackdmp comes with ABSOLUTELY NO WARRANTY This is free software, and you are welcome to redistribute it under certain conditions; see the file COPYING for details no message buffer overruns no message buffer overruns no message buffer overruns JACK server starting in realtime mode with priority 10 self-connect-mode is "Don't restrict self connect requests" audio_reservation_init Acquire audio card Audio0 creating alsa driver ... madifx_playback_all|madifx_record_all|1024|2|48000|0|0|nomon|swmeter|-|32bit configuring for 48000Hz, period = 1024 frames (21.3 ms), buffer = 2 periods ALSA: final selected sample format for capture: 32bit float little-endian ALSA: use 8 periods for capture ALSA: final selected sample format for playback: 32bit float little-endian ALSA: use 8 periods for playback jackd: ../linux/alsa/JackAlsaDriver.cpp:122: virtual int Jack::JackAlsaDriver::Attach(): Assertion `fCaptureChannels < 256' failed. Aborted (core dumped)
What could be the problem here?
It looks rather like a problem / limitation of jack itself.
Takashi
participants (5)
-
Clemens Ladisch
-
John Rigg
-
Jörg Müller
-
Takashi Iwai
-
Takashi Sakamoto