LADSPA plugin programming for Linux audio crossovers

Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.
I have tried a few different solutions for playing the audio portion of video through a Linux-based sound system. I use a BBB with USB input via a USBstreamer from miniDSP. This post might veer a bit off-topic, but the original question could also open new doors and expand the uses for Charlie's fine LADSPA filters.

In software on the BBB, I tried three different solutions to processing USB input in Linux. 1) SoX 'recording' from the USB input piped directly to SoX 'playback' with LADSPA crossover filters running in ALSA. 2) Same strategy as 1 but using 'arecord' piped directly to 'aplay'. 3) Ecasound 'recording' to it's own loop, from which LADSPA filters could execute the crossover. I don't want to bias what others decide is best for them, but I can report how these options worked in my system:

Option 3, Ecasound, produced unacceptable latency. Lip synchronization was poor and programs were unwatchable. I didn't even attempt to run crossover filters in Ecasound. I only tested its looping performance to get input to output. Perhaps persistence and greater expertise than mine could get it working with acceptable latency. I, however, moved on...
Code:
ecasound -z:mixmode,sum -x -d -b:4096 -a:in -i:alsahw,1,0 -o:loop,1 -a:out -i:loop,1 -a:out -o:alsahw,0,0

Your ecasound command string produced unacceptable latency because you did not tell it otherwise. Use the -B option with real time low latency setting, like this:
Code:
ecasound -d -z:mixmode,sum -B:rtlowlatency -a:in ...
This will also set the buffer (-b option) automatically to some very low value. When setting the mode via -B, do not use the -b option if you do not need to. Only if you encounter xruns, etc. do you need to increase the buffer setting.

Also, the -x option is really only meaningful when writing the output to a file. It tells ecasound to overwrite any existing file contents. It doesn't make sense with ALSA outputs.

There should not be an inherent advantage of using Sox over ecasound in this case in terms of latency.

Because Sox has some features that are lacking on ecasound (dithering, FIR filters, etc.) I once looked into how to implement a crossover with chains under Sox and it was too confusing at the time. I seem to recall that Sox uses a colon ":" to differentiate chains but I think they do not have the loop function of ecasound. If you figure something out please share it.
 
Last edited:
Member
Joined 2007
Paid Member
Excellent, Charlie! It's only reasonable that Ecasound shouldn't be any slower...
Because Sox has some features that are lacking on ecasound (dithering, FIR filters, etc.) I once looked into how to implement a crossover with chains under Sox and it was too confusing at the time. I seem to recall that Sox uses a colon ":" to differentiate chains but I think they do not have the loop function of ecasound. If you figure something out please share it.

I have been looking into SoX as a crossover engine and have made modest progress. It's not 'ready for prime time' but perhaps input from all of you can get it closer. Here is some background followed by a question, and sample code is at the bottom:

Background: Charlie started a thread a year ago on the SoX message board and I picked it up based on what has worked for me using SoX. With input from that source I have a 2-way crossover running using ACDf filters. The structure is a bit problematic because each ACDf filter is initiated as its own SoX process. However, they seem CPU efficient and seem to process the signal correctly. In the end, the output from SoX needs a tailored destination. I created appropriate plugs in ALSA - that much is simple and reliable.

But here's the current problem: Each SoX process that runs an LADSPA filter has an additive delay. That means that none of the drivers are in sync unless the delay is corrected. SoX makes delay correction very simple - a simple 'delay' effect followed by parameters of a) time in seconds, b) time in relation to the previous delay, and c)number of samples. Samples seems the most appropriate for a crossover.

Question(s): How can we learn the number of samples by which each process (with it's own LADSPA filter(s)) is separated in time? If we can learn that, then we should be in good shape. Is there anything inherent in the filters themselves that can predict their delay in terms of samples? If so, we have a basis for precise refinement. In the example below the 8192 sample spacing is merely 'ballpark'.

I look forward to suggestions and comments!

Frank

Working code:
Code:
# establish the LADSPA filter location:
export LADSPA_PATH=$LADSPA_PATH:/usr/local/lib/ladspa:/usr/lib/ladspa

# this command line parsed by filter
chrt -f 45 sox -M \
 '| sox -t alsa dsnoop:1,0 -p remix 1v1 ladspa ACDf 22 1 0 640 0.707 0 0 delay 24576s' \
 '| sox -t alsa dsnoop:1,0 -p remix 1v1 ladspa ACDf 21 1 0 640 0.707 0 0 delay 16384s' \
 '| sox -t alsa dsnoop:1,0 -p remix 2v1 ladspa ACDf 22 1 0 640 0.707 0 0 delay 8192s' \
 '| sox -t alsa dsnoop:1,0 -p remix 2v1 ladspa ACDf 21 1 0 640 0.707 0 0' \
 -t alsa hw:0,0

# same command line w/o parsing
chrt -f 45 sox -M '| sox -t alsa dsnoop:1,0 -p remix 1v1 ladspa ACDf 22 1 0 640 0.707 0 0 delay 24576s' '| sox -t alsa dsnoop:1,0 -p remix 1v1 ladspa ACDf 21 1 0 640 0.707 0 0 delay 16384s'  '| sox -t alsa dsnoop:1,0 -p remix 2v1 ladspa ACDf 22 1 0 640 0.707 0 0 delay 8192s'  '| sox -t alsa dsnoop:1,0 -p remix 2v1 ladspa ACDf 21 1 0 640 0.707 0 0' -t alsa hw:0,0

# if channel alignment or other ALSA manipulations are desired, finish with...
-t alsa plug:testout4

# corresponding ALSA plugs for /etc/asound.conf

pcm.testout4 {
    type plug
    slave {
     pcm "table2"
     channels 4
     rate "unchanged"
    }
}
pcm.table2 {
    type route
    slave {
     pcm "hw:0,0"
     channels 4
    }
    ttable {
      0.0   1
      1.1   1
      2.2   1
      3.3   1
    }
}
 
Excellent, Charlie! It's only reasonable that Ecasound shouldn't be any slower...

I have been looking into SoX as a crossover engine and have made modest progress. It's not 'ready for prime time' but perhaps input from all of you can get it closer. Here is some background followed by a question, and sample code is at the bottom:

Background: Charlie started a thread a year ago on the SoX message board and I picked it up based on what has worked for me using SoX. With input from that source I have a 2-way crossover running using ACDf filters. The structure is a bit problematic because each ACDf filter is initiated as its own SoX process. However, they seem CPU efficient and seem to process the signal correctly. In the end, the output from SoX needs a tailored destination. I created appropriate plugs in ALSA - that much is simple and reliable.

But here's the current problem: Each SoX process that runs an LADSPA filter has an additive delay. That means that none of the drivers are in sync unless the delay is corrected. SoX makes delay correction very simple - a simple 'delay' effect followed by parameters of a) time in seconds, b) time in relation to the previous delay, and c)number of samples. Samples seems the most appropriate for a crossover.

Question(s): How can we learn the number of samples by which each process (with it's own LADSPA filter(s)) is separated in time? If we can learn that, then we should be in good shape. Is there anything inherent in the filters themselves that can predict their delay in terms of samples? If so, we have a basis for precise refinement. In the example below the 8192 sample spacing is merely 'ballpark'.

I look forward to suggestions and comments!

Frank

Working code:
Code:
# establish the LADSPA filter location:
export LADSPA_PATH=$LADSPA_PATH:/usr/local/lib/ladspa:/usr/lib/ladspa

# this command line parsed by filter
chrt -f 45 sox -M \
 '| sox -t alsa dsnoop:1,0 -p remix 1v1 ladspa ACDf 22 1 0 640 0.707 0 0 delay 24576s' \
 '| sox -t alsa dsnoop:1,0 -p remix 1v1 ladspa ACDf 21 1 0 640 0.707 0 0 delay 16384s' \
 '| sox -t alsa dsnoop:1,0 -p remix 2v1 ladspa ACDf 22 1 0 640 0.707 0 0 delay 8192s' \
 '| sox -t alsa dsnoop:1,0 -p remix 2v1 ladspa ACDf 21 1 0 640 0.707 0 0' \
 -t alsa hw:0,0

# same command line w/o parsing
chrt -f 45 sox -M '| sox -t alsa dsnoop:1,0 -p remix 1v1 ladspa ACDf 22 1 0 640 0.707 0 0 delay 24576s' '| sox -t alsa dsnoop:1,0 -p remix 1v1 ladspa ACDf 21 1 0 640 0.707 0 0 delay 16384s'  '| sox -t alsa dsnoop:1,0 -p remix 2v1 ladspa ACDf 22 1 0 640 0.707 0 0 delay 8192s'  '| sox -t alsa dsnoop:1,0 -p remix 2v1 ladspa ACDf 21 1 0 640 0.707 0 0' -t alsa hw:0,0

# if channel alignment or other ALSA manipulations are desired, finish with...
-t alsa plug:testout4

# corresponding ALSA plugs for /etc/asound.conf

pcm.testout4 {
    type plug
    slave {
     pcm "table2"
     channels 4
     rate "unchanged"
    }
}
pcm.table2 {
    type route
    slave {
     pcm "hw:0,0"
     channels 4
    }
    ttable {
      0.0   1
      1.1   1
      2.2   1
      3.3   1
    }
}

To answer your question about how to determine the delay for each channel, I suggest something along these lines:
1. create a file or files of synthetic input that consists primarily of silence plus a single impulse that is a few samples wide, height=1.0
2. set all the ACDf filters to "type 0" with 0dB gain (all parameters are zero)
3. run the input through the Sox processing and direct the outputs to a file, or capture the ALSA output to a file somehow
4. inspect the output file to see when the input pulse appears on each output channel

By using "type 0 no gain" there is no change applied to the input signal, however, ACDf is still running the exact same code to process this "do nothing" filter as it would for any other ACDf filter. This means you can use it as a benchmark for latency.

By making the input long enough and recording enough output signal you should be able to directly see the input appear sometime later in the output. Do some math knowing the sample rate and voila, you have the delay for each channel.

But this looks like a bit of a mess. Here is one area where ecasound has Sox beaten in spades. Ecasound waits until all chains have processed before sending the outputs to their respective destinations at the same time. Looks like So does not do this. If you change the number of filters, the latency in Sox will change with it (or so I assume) so if you add or remove ACDf filter blocks you will need to remeasure the delay for each channel. But one way around this would be to just assign some predetermined number of ACDf filter blocks to each channel. For the ones that you are not using just set them to type=0 gain=0 and they will not alter the signal. This is like the miniDSP - it has a fixed number of filters implemented in hardware and they are still "inline" even if you do not use them.

Also, I would be careful to check on the performance of the delay plugin you use to compensate for the latency of each channel to make sure it is doing exactly what you want it to. Since you will need to measure the latency of each channel anyway, just remeasure the system after you implement the delay lines as a check.

In the worst case scenario the latency for each channel does not stay the same and is somehow randomly assigned at startup for that invocation of Sox or whatever. Then Sox is not going to work at all. I hope that is not the case.

Hope that gives you some inspiration on a way forward.
 
Member
Joined 2007
Paid Member
Thanks Charlie,

I'm messing with the 2-way SoX crossover from above and it starts and sounds the same each time. Clearly, one would want a quantitative solution to the delay question and the 'empty filter' approach may be good for ACDf but one would still need to characterize the delay of other kinds of effects. The SoX ladspa effect includes an option (-l) for filters whose latency is known and (somehow) included in their compilation. I suppose that could mitigate some of the synch issues.

I believe the strongest use-case for SoX is the possibility to combine SoX's existing effects with the components of the ACDf set. Clearly, Ecasound and ALSA will run ACDf with fewer headaches! So perhaps something like combinations of FIR and ACDf IIR could provide the 'draw'. Then the sticky question of delay could be balanced against the benefits. I had the 2-way 2nd-order SoX crossover sounding very nearly time aligned with a delay of 8192 samples/IIR filter. Then I added a FIR EQ to each of the high-pass channels and, predictably, the synch was gone. [1024 taps added ~7% CPU to each process] But if it is just a matter of a bit of persistence, I have no doubt that somebody will methodically overcome the synch/timing hurdle.

I like to experiment and that's how we now know about the SoX multi-process delay issue. For my own system, I remain happy with all-IIR processing and I'm committed to clock frequency switching. Like Ecasound, the SoX effect setup doesn't lend itself to clock switching. But it is interesting to 'push the envelope' of applications for ACDf, and I think we should keep an open mind. Sox is efficient, and might be just the ticket for someone who only needs to get the channels time-aligned once. :D

Cheers,

Frank
 
Last edited:
Dear all,


I'm currently trying to implement the crossover for a LXmini (2 way speaker) into Alsa (Linux). I startet with the great tutorial by Richard Taylor and used ecasound. As I want to use the dsp with speakers as my default playback device I tried to implement them in Alsa.
I edited the .asoundrc and added the following:
pcm.!default {
type plug
slave.pcm LXmini
}
ctl.!default {
type hw
card 1
}

pcm.LXmini {
type plug
slave.pcm pre
slave.channels 6
}

ctl.LXmini {
type hw
card 1
}


pcm.pre {
type ladspa
slave.pcm crossover
path "/usr/local/lib/ladspa"
channels 6
plugins {
0 {
id 1098 # Identity (Audio) (1098/identity_audio)
policy duplicate
input.bindings.0 "Input";
output.bindings.0 "Output";
}
1 {
label RTparaeq
policy none
input.bindings.0 "Input"
output.bindings.0 "Output"
input { controls [g f q] }
}
2 {
label RTparaeq
policy none
input.bindings.1 "Input"
output.bindings.1 "Output"
input { controls [g f q] }
}
3 {
label RTparaeq
policy none
input.bindings.0 "Input"
output.bindings.0 "Output"
input { controls [g f q] }
}
4 {
label RTparaeq
policy none
input.bindings.1 "Input"
output.bindings.1 "Output"
input { controls [g f q] }
}
5 {
label ACDf
policy none
input.bindings.0 "Input"
output.bindings.0 "Output"
input { controls [0 1 g 0 0 0 0] }
}
6 {
label ACDf
policy none
input.bindings.1 "Input"
output.bindings.1 "Output"
input { controls [0 1 g 0 0 0 0] }
}
}
}
pcm.crossover {
type ladspa
slave.pcm channelmap
path "/usr/local/lib/ladspa"
channels 6
plugins {
# Copy channels 0 and 1 to 2 and 3 for tweeter (crossover after pre-stage)
0 {
id 1098 # Identity (Audio) (1098/identity_audio)
policy none
input.bindings.0 "Input";
output.bindings.2 "Output";
}
1 {
id 1098 # Identity (Audio) (1098/identity_audio)
policy none
input.bindings.1 "Input";
output.bindings.3 "Output";
}
2 {
label RThighpass
policy none
input.bindings.2 "Input"
output.bindings.2 "Output"
input { controls [f q] }
}
3 {
label RThighpass
policy none
input.bindings.3 "Input"
output.bindings.3 "Output"
input { controls [f q] }
}
4 {
label RTlowshelf
policy none
input.bindings.2 "Input"
output.bindings.2 "Output"
input { controls [g f q] }
}
5 {
label RTlowshelf
policy none
input.bindings.3 "Input"
output.bindings.3 "Output"
input { controls [g f q] }
}
6 {
label RTparaeq
policy none
input.bindings.2 "Input"
output.bindings.2 "Output"
input { controls [g f q] }
}
7 {
label RTparaeq
policy none
input.bindings.3 "Input"
output.bindings.3 "Output"
input { controls [g f q] }
}
8 {
label RThighshelf
policy none
input.bindings.2 "Input"
output.bindings.2 "Output"
input { controls [g f q] }
}
9 {
label RThighshelf
policy none
input.bindings.3 "Input"
output.bindings.3 "Output"
input { controls [g f q] }
}
10 {
label RTparaeq
policy none
input.bindings.2 "Input"
output.bindings.2 "Output"
input { controls [g f q] }
}
11 {
label RTparaeq
policy none
input.bindings.3 "Input"
output.bindings.3 "Output"
input { controls [g f q] }
}
12 {
label RTparaeq
policy none
input.bindings.2 "Input"
output.bindings.2 "Output"
input { controls [g f q] }
}
13 {
label RTparaeq
policy none
input.bindings.3 "Input"
output.bindings.3 "Output"
input { controls [g f q] }
}
14 {
label delay_0.01s
policy none
input.bindings.2 "Input"
output.bindings.2 "Output"
input { controls [d 1] }
}
15 {
label delay_0.01s
policy none
input.bindings.3 "Input"
output.bindings.3 "Output"
input { controls [d 1] }
}
16 {
label ACDf
policy none
input.bindings.2 "Input"
output.bindings.2 "Output"
input { controls [0 1 g 0 0 0 0] }
}
17 {
label ACDf
policy none
input.bindings.3 "Input"
output.bindings.3 "Output"
input { controls [0 1 g 0 0 0 0] }
}
#woofer chain
18 {
label RTlowpass
policy none
input.bindings.0 "Input"
output.bindings.0 "Output"
input { controls [f q] }
}
19 {
label RTlowpass
policy none
input.bindings.1 "Input"
output.bindings.1 "Output"
input { controls [f q] }
}
20 {
label RTparaeq
policy none
input.bindings.0 "Input"
output.bindings.0 "Output"
input { controls [g f q] }
}
21 {
label RTparaeq
policy none
input.bindings.1 "Input"
output.bindings.1 "Output"
input { controls [g f q] }
}
22 {
label RTparaeq
policy none
input.bindings.0 "Input"
output.bindings.0 "Output"
input { controls [g f q] }
}
23 {
label RTparaeq
policy none
input.bindings.1 "Input"
output.bindings.1 "Output"
input { controls [g f q] }
}
24 {
label RTparaeq
policy none
input.bindings.0 "Input"
output.bindings.0 "Output"
input { controls [g f q] }
}
25 {
label RTparaeq
policy none
input.bindings.1 "Input"
output.bindings.1 "Output"
input { controls [g f q] }
}
}
}
pcm.channelmap {
type plug
slave.pcm soundcard
slave.channels 6
ttable {
0.0 1 # Woofer left
1.1 1 # Woofer right
2.2 1 # Tweeter left
3.3 1 # Tweeter right
4.4 0 # center
5.5 0 # Subwoofer
}
}
pcm.soundcard {
type hw
card 1
device 7
}
Card 1 is my hdmi output to a Pioneer AV-Receiver. I removed all numbers from the setup, because the speakers are licensed by LinkwitzLabs and replaced them with g for gain, f for frequency, q for q-factor and d for delay.



The speaker test ("speaker-test -D LXmini -c 2") works, but somehow I can't use this device as my default device. ("speakter-test" without additional arguments still uses the internal loudspeakers/ sound card).

I can play music via mpg321 ("mpg321 1.mp3 -o alsa --audiodevice LXmini") using the software dsp on the speakers (LXmini) but am not able to use them as a playback device in e.g. vlc player (even when I select alsa audio output and choose device "LXmini" from the list.
I'm assuming I made a mistake during the definition of the default device in ALSA's .asoundrc, because "speaker-test" doesn't play through the LXmini speakers. Does anyone know help?
 
Last edited:
Dear all,


I'm currently trying to implement the crossover for a LXmini (2 way speaker) into Alsa (Linux). I startet with the great tutorial by Richard Taylor and used ecasound. As I want to use the dsp with speakers as my default playback device I tried to implement them in Alsa.
I edited the .asoundrc and added the following:
Card 1 is my hdmi output to a Pioneer AV-Receiver. I removed all numbers from the setup, because the speakers are licensed by LinkwitzLabs and replaced them with g for gain, f for frequency, q for q-factor and d for delay.



The speaker test ("speaker-test -D LXmini -c 2") works, but somehow I can't use this device as my default device. ("speakter-test" without additional arguments still uses the internal loudspeakers/ sound card).

I can play music via mpg321 ("mpg321 1.mp3 -o alsa --audiodevice LXmini") using the software dsp on the speakers (LXmini) but am not able to use them as a playback device in e.g. vlc player (even when I select alsa audio output and choose device "LXmini" from the list.
I'm assuming I made a mistake during the definition of the default device in ALSA's .asoundrc, because "speaker-test" doesn't play through the LXmini speakers. Does anyone know help?


".asoundrc" is a personal/single user configuration file. "asound.conf" in "/etc" is the global or default config repository. Any subsystem or daemon will have its own user and group distinct from yours. And won't use the same ".asoundrc". Take a backup of asound.conf then replace it with the contents of your ".asoundrc".
 
schaudio: I am afraid you have hit debian/ubuntu configuration "deficiency" where the default device cannot be overriden in .asoundrc without further changes in /usr/share/alsa. I tested your problem (without the ladspa plugins) of unchanged default and ended up with the same result. Here is my communication with the lead alsa developer who explains the situation [alsa-devel] Order of device overrides in config files

Try to remove the extra config /usr/share/alsa/alsa.conf.d/pulse.conf, or comment out the relevant lines of /usr/share/alsa/pulse-alsa.conf where !default is defined. That should let your .asoundrc define your own !default as described in alsa documentation.
 
Member
Joined 2007
Paid Member
I do all of my ALSA manipulations in /etc/around.conf. For something as fundamentally important as a crossover, I think there is no disadvantage to having the LADSPA instructions globally available.

Many programs allow you to select the input point into ALSA user space. For speaker-test, use the -D option with the syntax 'plug:XXX' where XXX is the name of the ALSA plug that will begin the signal processing. This allows you to select or change ALSA parameters depending on the source of the PCM. Example: "speaker-test -Dplug:front -c2" will send left and then right signals into an ALSA plug named 'front', from which you can route the signal to other contributing plugs in sequence. This gives you control over the ALSA processing based on the output plug used by the playing program. It could always be 'default', but it doesn't need to be if you specify 'plug:XXX' as the output. I have used this method to select among EQ functions in separate ALSA plugs before the signal reaches the crossover filters. It's quite flexible.

Examples:
Code:
sox --buffer 512 -r 48000 -c 2 -t alsa hw:miniStreamer,0  -t alsa plug:TV-in &
  # this takes input from a streaming source and sends it out to a specific plug designed for my video display

squeezelite -z -C 1 -o hw:0,0 -a 8192:2048::0
  # this avoids crossover processing using the -o option to specify a hardware output

squeezelite -z -C 1 -o plug:eq5 -a 8192:2048::0
  # this sends the PCM into an equalizer function (named 'eq5') that then sends the signal on to the crossover.
 
Last edited:
Dear all, I'm currently trying to implement the crossover for a LXmini (2 way speaker) into Alsa (Linux). I startet with the great tutorial by Richard Taylor and used ecasound. As I want to use the dsp with speakers as my default playback device I tried to implement them in Alsa.

I'm assuming I made a mistake during the definition of the default device in ALSA's .asoundrc, because "speaker-test" doesn't play through the LXmini speakers. Does anyone know help?
Have a look at my thread
HTML:
 [URL="http://www.diyaudio.com/forums/pc-based/318520-asoundrc-ladspa.html"]asoundrc and ladspa[/URL]
It is important to create the extra channels from the two input channels before doing any other processing (obvious as soon as it's written down).
It is efficient to create them as LADSPA filters 0 to 3 by applying the high/low pass filters using channel 0 as input to channel 2 as output, and channel 0 as input to channel 4 as output, then similarly channel 1 to channels 3 and 5.
See also in my asound.conf the "pcm.Plug_Why".
To test, use aplay with a 30 second or so wav file. You will see some useful messages (in amongst the incomprehensible.)
I reiterate phofman's instructions about ensuring that in "/usr/share/alsa/alsa.conf" the entry " "~/.asoundrc" under "@hooks [" is commented out.
Hope this helps,
Andy
 
Last edited:
Have a look at my thread
HTML:
I reiterate phofman's instructions about ensuring that in "/usr/share/alsa/alsa.conf" the entry " 	"~/.asoundrc" under "@hooks [" is commented out.
[/QUOTE]

The .asoundrc entry is no problem at all. If commented out, it will ignore the user's configuration. I am not sure that is what schaudio wants.

The problem in ubuntu/debian is the file /usr/share/alsa/alsa.conf.d/pulse.conf which instructs the alsa-lib configuration module to lazy-load /usr/share/alsa/pulse-alsa.conf upon accessing the device, if pulseaudio is running. The pulse-alsa.conf config overrides the default device, making any default device definition in /etc/asound.conf or .asoundrc ineffective.
 
phofman,
apologies for clouding the discussion. Standard Raspbian doesn't install pulseaudio, so it is not an issue for me.
The issue that may remain is .asoundrc being (annoyingly, needlessly) overwritten at every reboot in some distributions, so using /etc/asound.conf and commenting out the call to .asoundrc is worthwhile.
Andy
 
Does anyone know if this sound processing is doable when watching youtube videos or hoopla videos? Like how do you pipe the audio into ecasound/ladspa so we can utilize the software-configured crossovers to get the movie experience through the loudspeakers.
Thanks,
Richard

A little late, but ....
I use alsaloop to listen to the TV sound and have no lipsync. problems:

alsaloop -d -C plughw:CARD=RPiCirrus -P default -t 50000

RPiCirrus sound card handles the S/PDIF input from the TV, default is the asound.conf with crossovers and eq.
-t 50000 is called latency in the manual. It seems to increase buffer size, avoiding digital artifacts which were occurring regularly without it.

Is this what you were having problems with? If you are playing the videos on the same machine as the crossovers, then the video software should just find the
"default" "device".
Andy
 
Last edited:
Member
Joined 2007
Paid Member
I didn't know about 'alsaloop' so I looked up its debian manpage [here]. It looks quite adaptable and preferable to sox for applications involving signal synch. I will experiment with it as I revamp the software in my own Debian-based system! In the past I tried other commands like aplay, which worked, but sox proved superior.

One capability in sox, which simply trumps other looping-type commands for routing, is its built-in convolver. It will run FIR filter sets on the fly for pre-ALSA equalization without mucking up the signal phase. So it has proved to be slightly better sounding for sources where the PCM frequency does not shift to follow native sample rates - like spdif. Theoretically, it could preemptively reverse the phase shift of LADSPA IIR crossovers. Unfortunately, my little A8 CPU can't manage a very large coefficient set, so for me it is best for mid and higher frequency manipulations. Perhaps the new RPi could manage significantly more coefficients.

Example syntax:
Code:
chrt -f 45 sox --buffer 1024 -r 48000 -c 2 -t alsa hw:1,0 -t alsa plug:alsa_entry_point  gain -h fir /usr/filter/fir2peak48mild.txt &
  # /usr/filter/fir2peak48mild.txt  is the path to the text file containing the filter coefficients.  
  # I generate EQ filter sets using matlab.
  # "chrt -f 45" increases the priority of sox to preempt casual OS traffic.  To stop it you need to kill from the command line.
 
Last edited:
schaudio: I am afraid you have hit debian/ubuntu configuration "deficiency" where the default device cannot be overriden in .asoundrc without further changes in /usr/share/alsa. I tested your problem (without the ladspa plugins) of unchanged default and ended up with the same result. Here is my communication with the lead alsa developer who explains the situation [alsa-devel] Order of device overrides in config files

Try to remove the extra config /usr/share/alsa/alsa.conf.d/pulse.conf, or comment out the relevant lines of /usr/share/alsa/pulse-alsa.conf where !default is defined. That should let your .asoundrc define your own !default as described in alsa documentation.


phofman, thank you very much for your answer. I'm using Ubuntu (16.04) and changed /usr/share/alsa/pulse-alsa.conf by commenting out
Code:
#pcm.!default {
#    type pulse
#    hint {
#        show on
#        description "Playback/recording through the #PulseAudio sound server"
#    }
#}

#ctl.!default {
#    type pulse
#}
by running "speaker-test -c 2" I received the message:


"speaker-test: pcm_params.c:170: snd1_pcm_hw_param_get_min: Zusicherung »!snd_interval_empty(i)« nicht erfüllt."


I could get it working by changing the beginning of my .asoundrc from
pcm.!default {
type plug
slave.pcm LXmini
}
to
pcm.!default {
type asym
playback.pcm LXmini
}
(but don't know how/ why that works. If someone can explain it to me, I'd be interested).
Now "speaker-test -c 2" works fine.


After disabling Pulse as described in chapter 2.2 of PulseAudio/HOW-TO: Disable PulseAudio and use ALSA (without removing PulseAudio) for Ubuntu - Official Kodi Wiki
and restarting the computer or killing pulse by "pulseaudio --kill"

I can play music using the standard video player (totem) and rythymbox.



But currently I don't get sound from VLC (no matter whether I switch the output to "Automatic" or "ALSA") and I don't get sound from Firefox either (for flash videos or audio streams).
Does anyone know, how to get this sound working too?


Best regards,
schaudio
 
Last edited:
As for the asym plugin - look at ALSA User — Re: Using "plughw" in .asoundrc: snd1_pcm_hw_param_get_min: Assertion `!snd_interval_empty(i)' failed. . I would try to remove the second plug definition, e.g. by naming the LXmini device directly "!default".

When posting messages here always try to run with English locales, e.g. by running before your commands:

Code:
export LC_ALL=C

Instead of non-verbose speaker-test, try to use aplay with parameter -v (--verbose). It lists the whole chain and operations done by each plugin. Very useful for troubleshooting.

Code:
aplay -v -D yourdevice somemusic.wav

You can create any wav of any channel count/samplerate/sample length with sox.

When testing alsa on specific soundcard on pulseaudio-enabled distribution (e.g. ubuntu), it is possible to tell PA to avoid using a specific soundcard. That way PA-only softwares (e.g. skype) will continue to work on other soundcards, yet that specific soundcard will be ignored by PA and available to your software. Just install pavucontrol (apt-get) and set the specific soundcard to "Off". E.g. I use this in my measurement station Headless Amplifier Measurement Workstation where the actual measurement is performed by ESI Juli via wine/Arta + alsa directly and synthesized voice announcements proceed through regular mint/ubuntu sound system - python -> espeak in default configuration -> PA -> internal soundcard -> internal speaker. Juli is never touched by PA.

The VLC/Firefox problem - I would start simple first. Configure your alsa !default without the added ladspa filters, verify correct function, and start adding new parts of your chain, always verifying each step. Troubleshooting such complicated chain without detailed logs (like in aplay -v) is usually just random trial/error.

AFAIK Firefox dropped alsa support some time ago, leaving PA as the only option Firefox Goes PulseAudio Only, Leaves ALSA Users With No Sound - OMG! Ubuntu!
 
Last edited:
I will soon be releasing a new version of my LADSPA plugins, "ACDf". Most of the changes will not have any impact on users of the current version. These include changing or creating default values for each parameter and modifying the parameter names (but not their order). If you are using ecasound with ACDf and update to the new version (version 3.0) you should not experience any changes.

These changes have made it easier to use ACDf filters under Gstreamer and my GSASysCon app. In the past I had used some long and descriptive parameter names and these have to be explicitly named under Gstreamer instead of just presenting the values in order like you do under ecasound. Gstreamer is now my preferred LADSPA host because it is much more versatile, and I have built my GSASysCon helper app around it.

At the same time I will be releasing an update of ACD-L, the Active Crossover Designer tools for LADSPA plugins. I discovered that the second order shelving filters were not being modeled correctly in ACD-L. This motivated me to completely re-code how the filters were being calculated. Now the calculations are done exactly as they are in the LADSPA plugin. I have made a few other minor modifications, but ACD-L remains a great tool for loudspeaker crossover design based on measurement data and can model the loudspeaker response on multiple axes simultaneously while the crossover is being developed.
 
Member
Joined 2007
Paid Member
Greetings Charlie! I hope all is fantastic with you...

This is an interesting development. I've been tweaking my 'primary' system and have the best resolution for PCM that I've ever achieved. I'm still running the ACDf filters in ALSA with a clock-switching kernel. As a part of my optimizing for new ESS DAC chips, I began to realize that simplifying the ACDf filter chain produced better SQ. So, I now am using LR2 curves rather than LR4 even though I would theoretically prefer the LR4. The LR4 just don't sound quite as good.

I've been meaning to contact you for any suggestions. I thought perhaps increasing the precision of calculations was worth a try. What do you think? Any other avenues you'd suggest I explore?

All the best and thanks in advance,

Frank
 
Greetings Charlie! I hope all is fantastic with you...

This is an interesting development. I've been tweaking my 'primary' system and have the best resolution for PCM that I've ever achieved. I'm still running the ACDf filters in ALSA with a clock-switching kernel. As a part of my optimizing for new ESS DAC chips, I began to realize that simplifying the ACDf filter chain produced better SQ. So, I now am using LR2 curves rather than LR4 even though I would theoretically prefer the LR4. The LR4 just don't sound quite as good.

I've been meaning to contact you for any suggestions. I thought perhaps increasing the precision of calculations was worth a try. What do you think? Any other avenues you'd suggest I explore?

All the best and thanks in advance,

Frank

The calculations in ACDf are already done in double precision. That is about as good as its gets. So nothing to worry about there.

It sounds like you are doing some kind of second guessing about your system. Maybe you should revisit the system design, etc. Changing filters and listening is not a good way to get the "best" sound. Rather, it's a recipe for un-ending frustration...
 
Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.