How do I make a Linux/ALSA loudspeaker crossover DSP?

I've been noodling around a bit this evening, and have come up with a working .asoundrc

If you want to give the little grey cells a bit more exercise, I seem to recall that the pcm.Route was necessary because I have two physical outputs (two stereo pcm/pwm amps.) For a single physical output ttable can be used. If I've remembered this wrong then someone will correct me.

Regards,

Andy
 
IIUC your setup does just loopback because the PCM crossover device using LADSPA filters is not used. For plain loopback perhaps you might want to look at alsaloop which is designed just for this particular purpose and cares about latency with proper options.

It's entirely possible that I've misunderstood what's going on. I thought with the sox command I was outputting audio to the ALSA filter/crossover configuration that resulted in the 6 outputs in the pcm.Route section.

alsaloop is probably sufficient.

If you want to give the little grey cells a bit more exercise, I seem to recall that the pcm.Route was necessary because I have two physical outputs (two stereo pcm/pwm amps.) For a single physical output ttable can be used. If I've remembered this wrong then someone will correct me.

Regards,

Andy

Ah, I see - yes, I was messing around with this to get it to work for my case - a single audio device outputting 6 channels of audio. I noticed that francolargo's configuration has the ttable output configured instead.

I'm currently getting errors when trying to use the configuration with the SB Audigy (though I was able to route the audio successfully through the card with the chorus effect), so there's more work to do.
 
I clearly don't understand. I just get this message from sox or alsaloop:

Code:
ALSA lib pcm_params.c:2226:(snd1_pcm_hw_refine_slave) Slave PCM not usable

All I'm running is:

Code:
alsaloop -c hw:0,0 -P plug:default -t 50000

Likely a bug in the Crossover pcm device definition. The Plug_Why and Route_2x3 are OK because they worked in your previous posts.

Note1: The capture device param of alsaloop is -C, -c stands for number of channels. Please copy exact commands as in your tests otherwise troubleshooting is next to impossible.

Note2: plug:default is not needed as your default device as defined above already is the plug plugin. Just default will do.
 
The -c switch was incorrectly used by me in a previous test, so I copied an error over :)

I tried to use francolargo's asoundrc from here, but I'm still met with errors:

Code:
$ alsaloop -C hw:0,0 -P default -t 50000
ALSA lib pcm_params.c:2226:(snd1_pcm_hw_refine_slave) Slave PCM not usable
ALSA lib pcm_params.c:2226:(snd1_pcm_hw_refine_slave) Slave PCM not usable
Broken configuration for playback default PCM: no configurations available: Invalid argument
Unable to set parameters for playback default stream: Invalid argument
Loopback start failure.

I can see the ACDf plugin in /usr/lib/ladspa, and the file ownership is correct. The plugin also returns information when I run listplugins and analyseplugin ACDf
 
Well, the plug plugin (plug:hw or shortcut plughw) can be used for any soundcard. The plug interface converts whatever is required to align the upper and lower-layer PCM device (e.g. app requests vs. params allowed by the driver/hardware). If using the plug helped in your case, the plug had to do some conversion, typically in number of channels or sample format.
 
Well, the plug plugin (plug:hw or shortcut plughw) can be used for any soundcard. The plug interface converts whatever is required to align the upper and lower-layer PCM device (e.g. app requests vs. params allowed by the driver/hardware). If using the plug helped in your case, the plug had to do some conversion, typically in number of channels or sample format.

I try to never use plughw because I have always been unsure of what is going on in the background and how any conversions are done. For example, if the sample rate is not supported I believe plughw will convert it, but using what sort of SRC algorithm? This might "work" but you might not realize that the output is of very poor quality. Instead I use hw and if it fails I inspect the source and sink properties and then manually set up any conversions in format or sample rate that are needed so that I can apply dither or use a very high quality sample rate converter, etc.
 
Member
Joined 2007
Paid Member
I try to never use plughw because I have always been unsure of what is going on in the background and how any conversions are done. For example, if the sample rate is not supported I believe plughw will convert it, but using what sort of SRC algorithm? This might "work" but you might not realize that the output is of very poor quality. Instead I use hw and if it fails I inspect the source and sink properties and then manually set up any conversions in format or sample rate that are needed so that I can apply dither or use a very high quality sample rate converter, etc.
Theoretically, ALSA plugs can be constrained from resampling. I know of two ways. If 'rate' is an accepted plug parameter then you can use 'rate "unchanged"'. Or, you can on a separate line in the config file include 'pcm.plughw.slave.rate = "unchanged";' remove the outer apostrophe ' in either case.

F.
 
Charlie, how do you do that? If I change to a HiFIBerry sound card I shall need to know what the TV SPDIF output is. I think it is 48K because the amps display the rate that they are receiving, but no idea of the bit depth.
Hope I'm not out of order, it is still to do with ALSA.
Andy
To see what are the possible parameters for playback or recording, you use the --dump-hw-params option with aplay (playback) or arecord (recording) and specify your soundcard. For example:

aplay -D hw:x,y --dump-hw-params /dev/zero

The above attempts to play audio from the source /dev/zero (e.g. silence) to the ALSA device at hw:x,y (substitute for x and y the appropriate values for your soundcard, which you can determine via aplay -L and aplay -l). The audio parameters are dumped to the console and will look something like this:

Code:
Playing raw data '/dev/zero' : Unsigned 8 bit, Rate 8000 Hz, Mono
HW Params of device "hw:1,3":
--------------------
ACCESS:  MMAP_INTERLEAVED RW_INTERLEAVED
FORMAT:  S16_LE S32_LE
SUBFORMAT:  STD
SAMPLE_BITS: [16 32]
FRAME_BITS: [32 256]
CHANNELS: [2 8]
RATE: [32000 192000]
PERIOD_TIME: (20 256000]
PERIOD_SIZE: [4 8192]
PERIOD_BYTES: [128 262144]
PERIODS: [2 32]
BUFFER_TIME: (41 512000]
BUFFER_SIZE: [8 16384]
BUFFER_BYTES: [128 65536]
TICK_TIME: ALL
--------------------
aplay: set_params:1299: Sample format non available
Available formats:
- S16_LE
- S32_LE

By looking at this output I can tell (given the example output above) that the only playback formats that are supported are S16_LE and S32_LE, and samples rates between 32kHz and 192kHz. Also, channel counts up to 8 are supported. Not all combinations of these may work, e.g. at 192kHz the device may only support 16 bits, or 2 channels, etc. It depends on the driver and device.

The same approach can be used to look at the allowed record parameters. For example:

arecord -D hw:x,y --dump-hw-params /dev/null

This attempts to record from hw:x,y, sending the data to /dev/null (e.g. throws it away). A similar output will result as what was shown above for the aplay example.

These commands will continue running indefinitely. Simply use control-C to terminate them via the console.

More info is available via the manpages for aplay and arecord.
 
The same approach can be used to look at the allowed record parameters. For example:

arecord -D hw:x,y --dump-hw-params /dev/null

This attempts to record from hw:x,y, sending the data to /dev/null (e.g. throws it away). A similar output will result as what was shown above for the aplay example.

These commands will continue running indefinitely. Simply use control-C to terminate them via the console.

More info is available via the manpages for aplay and arecord.
Thanks Charlie. Have read the man pages, but must have glazed over before realising the significance of that parameter. Will have a go shortly. Andy
 
After the usual wrestling match with ALSA I have a result. The TV outputs 2/48000/16; alsaloop defaults to that; the Cirrus sound card can handle that; so I can take the "plug" out of the parameters. Does it sound different? tested on BBC R3 with the volume quite high, and just a little better, or is that wishful thinking?
 
Is anyone running on a RPi4 with bullseye? I'm having no luck with the setup that worked on RPi3/Stretch. Can aplay to the individual USB amps, but aplay to the asoundrc gives an error:
"aplay: pcm_params.c:170: snd1_pcm_hw_param_get_min: Assertion `!snd_interval_empty(i)' failed"
In hope,

Andy