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.
Hi Charlie,

The downloading link does not seems to work at the moment. It gives a 404 Error.

y the way, did yo finally changed the input parameters for the Shelf filtrs (center frequency instead of side frequencies) or did you keep t same as before?

Bst regards,

JMF

The download link works fine for me. Note that the tar file has been renamed so if you are trying to use a bookmark to the file that will give you a 404. Use the link in my signature to the download page.

Yes, I did change the shelf behavior so that the frequency you supply for Qp, the type of shelf, and the amount of gain is what determines the shelf. Qp is now the "center" of the shelf transition.
 
Hello,

This still seems not to work from here. I follow the link in your signature (LADSPA-plugins). Then on the download page, if I left click on http://audio.claub.net/software/LADSPA/LAUB-LADSPA-PLUGINS.tar then get the error 404. If I right click on the link, then I can download a 8ko file called LAUB-LADSPA-PLUGINS.tar but I can't open or extract the archive (neither on Linux, nor Windows).

Strange...

Best regards,

JMF
 
Hello,

This still seems not to work from here. I follow the link in your signature (LADSPA-plugins). Then on the download page, if I left click on http://audio.claub.net/software/LADSPA/LAUB-LADSPA-PLUGINS.tar then get the error 404. If I right click on the link, then I can download a 8ko file called LAUB-LADSPA-PLUGINS.tar but I can't open or extract the archive (neither on Linux, nor Windows).

Strange...

Best regards,

JMF

I just checked. I can both left click and right click. I can save the file (it's 232kB in size). I downloaded it and after doing so I was able to access/open files from the archive. This was all done from a Windows machine using 7-Zip, the same program I used to create the tar image, exactly like I did with earlier versions.

I also was able to download and open the archive on an Ubuntu machine here.

Something may be going wrong on your end...

Anyone else having problems downaloading the tar file?
 
Last edited:
Hi Charlie,

This is really strange and may be an issue on my side. It is the very first time I notice something like this:
- if I open LADSPA-plugins with firefox (v47.0), I get an old web page with a revision history that stops at April 2016. On that page I can download a plugin file without date in the name, that doesn't work,
- if I open the same page with Chrome, I get a more recent web page with revision history that stops at 1/06/2016. On this page I can download your tar file with 11JUN2016 in the name of the file.

Could this be a problem of cache?

However, the important is that I have the files now :)

Best regards,

JMF
 
I appreciate that my question may not be specific for this topic but....

Is there a simple recipe "mpd -> ALSA (with plugins)" that can implement a baffle step compensation filter (BSC)?

IMHO no, not simple. Can it be done? Yes, quite possibly, but not necessarily without problems. Check out this thread for examples of how to implement LADSPA filters in ALSA:
http://www.diyaudio.com/forums/twisted-pear/277564-ladspa-filters-digital-crossovers-bbb-17.html
Users jrubins and fancolargo have been working on this approach on the Beagle Bone Black (BBB) platform.

I would ask for help over in that thread since that was focused more on the ALSA implementation of LADSPA filters. I can't help you with that. I stick to ecasound, which I find to be very dependable.
 
Member
Joined 2007
Paid Member
IMHO no, not simple. Can it be done? Yes, quite possibly, but not necessarily without problems.

I can save you the trip... :) I've never been able to find a configuration for ALSA output in /etc/mpd.conf that will send output to an ALSA plugin. I've only ever seen it work sending a signal to non-configurable 'hardware' space (for example 'hw:0,0'). That's why I stopped using MPD and started using squeezelite, which can address ALSA's user space.

Anything further, glad to chat on the other thread...

Best,

Frank
 
I can save you the trip... :) I've never been able to find a configuration for ALSA output in /etc/mpd.conf that will send output to an ALSA plugin. I've only ever seen it work sending a signal to non-configurable 'hardware' space (for example 'hw:0,0'). That's why I stopped using MPD and started using squeezelite, which can address ALSA's user space.

Anything further, glad to chat on the other thread...

Best,

Frank

Interesting.... Previously I've setup ALSAEQUAL for use with MoOde and it works.
Code:
device "plug:plugequal"
is needed in mpd.conf to route output through the equaliser rather than straight to the hardware. I can post the asound.conf if someone can tell me how to copy/paste out of a putty ssh session. :)

IMHO no, not simple. Can it be done? Yes, quite possibly, but not necessarily without problems. Check out this thread for examples of how to implement LADSPA filters in ALSA:
http://www.diyaudio.com/forums/twisted-pear/277564-ladspa-filters-digital-crossovers-bbb-17.html
Users jrubins and fancolargo have been working on this approach on the Beagle Bone Black (BBB) platform.

I would ask for help over in that thread since that was focused more on the ALSA implementation of LADSPA filters. I can't help you with that. I stick to ecasound, which I find to be very dependable.

OK, will pop over there for further discussion.
 
Last edited:
Hi,

Just a message to say that the new version of your ACDf 2.0 plugins is now up and running on the Orange Pi PC.

The fit of the shelf filter at 10kHz is on spot. This is a real improvement for me.

On the Orange Pi PC, the load for MPD + ecasound+ACDf plugins implementing 14 biquad filter for one stereo channel is about 45% of one core, with the 3 other one almost idle.

I could not perform yet extended tests about how it sounds, but it will come.

Thanks for those plugins !

JMF
 
Hi,

Just a message to say that the new version of your ACDf 2.0 plugins is now up and running on the Orange Pi PC.

The fit of the shelf filter at 10kHz is on spot. This is a real improvement for me.

On the Orange Pi PC, the load for MPD + ecasound+ACDf plugins implementing 14 biquad filter for one stereo channel is about 45% of one core, with the 3 other one almost idle.

I could not perform yet extended tests about how it sounds, but it will come.

Thanks for those plugins !

JMF

That's great! I'm glad it it working for you. Did you have a chance to listen yet?

Also, are you resampling or running at a high sample rate? That CPU utilization seems rather high compared to what I am used to seeing for ecasound + LADSPA.
 
Hi, Listening music now. Works very well. The limiting factor is at the moment the speaker placement in the room.

No resampling at the moment. Working at 44100. I want to make tests at 48k and 96k.

What would you expect as CPU load on one of those 1.2 GHz CPUs for MPD+ecasound+LADSPA.

Looking again, load oscillates between 35 and 50%

JMF
 
Hi, Listening music now. Works very well. The limiting factor is at the moment the speaker placement in the room.

No resampling at the moment. Working at 44100. I want to make tests at 48k and 96k.

What would you expect as CPU load on one of those 1.2 GHz CPUs for MPD+ecasound+LADSPA.

Looking again, load oscillates between 35 and 50%

JMF

Actually, I misspoke. I was thinking of my Raspberry Pi systems but they do not have the MPD player - audio is streamed to them. So, CPU utilization is less.

That CPU utilization is probably fine.
 
Hi again. I'm having a problem running "25". The 2nd order high shelf.
I can run simple low pass "1" and simple high shelf "5" with no issues. However, when I try to run "25", I get silence as the output.

Plugins I'm running.
Code:
root@MoOdey-Lounge:/etc# analyseplugin ACDf

Plugin Name: "ACDf v2.0: Active Crossover Designer LADSPA filters"
Plugin Label: "ACDf"
Plugin Unique ID: 5221
Maker: "Charlie Laub, 2016"
Copyright: "GPLv3"
Must Run Real-Time: No
Has activate() Function: Yes
Has deactivate() Function: No
Has run_adding() Function: No
Environment: Normal or Hard Real-Time
Ports:  "ACD Filter Type" input, control, 0 to 29
        "Filter polarity; 1=normal, -1=reverse" input, control, -1 to 1
        "Filter Gain in dB" input, control, -20 to 20
        "Filter Pole Frequency in Hertz" input, control, 10 to 20000
        "Filter Pole Q" input, control, 0.3 to 15
        "Filter Zero Frequency in Hertz" input, control, 10 to 20000
        "Filter Zero Q" input, control, 0.3 to 15
        "Input" input, audio, -1 to 1
        "Output" output, audio, -1 to 1

Current asound.conf

Code:
pcm.!default {
     type plug
     slave.pcm filter1
}

ctl.!default {
     type hw
     card 0
}

pcm.filter1 {
     type ladspa
     slave.pcm speaker
     path "/usr/local/lib/ladspa"  # must indicate filter directory
     channels 2                    # two is default, other channel counts must $
     plugins
     {
          0 {        # must start with zero and not skip numbers in sequence
               label ACDf     # you could instead use the filter id number
               policy none
               input.bindings.0 "Input"     #input to filter is channel 0
               output.bindings.0 "Output"  #output from filter is channel 0
               input { controls [1 1 -6 200] }   # simple LP to start with
          }
          1 {
               label ACDf
               policy none
               input.bindings.1 "Input"
               output.bindings.1 "Output"
               input { controls [1 1 -6 200] }
          }
     }
}

pcm.filter2 {
     type ladspa
     slave.pcm speaker
     path "/usr/local/lib/ladspa"  # must indicate filter directory
     channels 2                    # two is default, other channel counts must $
     plugins
     {
          0 {        # must start with zero and not skip numbers in sequence
               label ACDf     # you could instead use the filter id number
               policy none
               input.bindings.0 "Input"     #input to filter is channel 0
               output.bindings.0 "Output"  #output from filter is channel 0
               input { controls [5 0 -4 950] }   # simple high shelf
          }
          1 {
               label ACDf
               policy none
               input.bindings.1 "Input"
               output.bindings.1 "Output"
               input { controls [5 0 -4 950] }
          }
     }
}

pcm.filter3 {
     type ladspa
     slave.pcm speaker
     path "/usr/local/lib/ladspa"  # must indicate filter directory
     channels 2                    # two is default, other channel counts must $
     plugins
     {
          0 {        # must start with zero and not skip numbers in sequence
               label ACDf     # you could instead use the filter id number
               policy none
               input.bindings.0 "Input"     #input to filter is channel 0
               output.bindings.0 "Output"  #output from filter is channel 0
               input { controls [25 1 -4 950 0 0 0 ] } # 2nd order high shelf
          }
          1 {
               label ACDf
               policy none
               input.bindings.1 "Input"
               output.bindings.1 "Output"
               input { controls [25 1 -4 950 0 0 0] }
          }
     }
}

pcm.speaker {
    type plug
    slave {
     pcm "hw:0,0"
     channels 2
     rate "unchanged"
    }
}

pcm.plughw.slave.rate = "unchanged";

running with...

Code:
speaker-test -c2 -Dplug:filter1    etc

J.
 
Honestly I'm not sure if I can be of much help. I don't ever implement the filters via ALSA. But I did notice an inconsistency in the way you declared the parameters in filter 3 on this line:
Code:
input { controls [25 1 -4 950 0 0 0 ] } # 2nd order high shelf
                                   ^seem like an extra space there, before "]"
I have heard that ALSA is EXTREMELY picky about how the parameters are declared. There are some posts by jrubins in the Twisted Pear forum thread on LADSPA filters (not sure but I recall is was about a month or two ago) in which he finally got it to work after experimenting with all sorts possibilities.

Anyway, I would try to remove that space, and even remove the extra zeros at the end. Make it just like the type 1 and 5 filters that DO work. If I think of anything else I will post about it...

The type 25 filters definitely works. I verified everything using ecasound. So its likely the cause lies with the ALSA code.
 
Last edited:
Honestly I'm not sure if I can be of much help. I don't ever implement the filters via ALSA. But I did notice an inconsistency in the way you declared the parameters in filter 3 on this line:
Code:
input { controls [25 1 -4 950 0 0 0 ] } # 2nd order high shelf
                                   ^seem like an extra space there, before "]"
I have heard that ALSA is EXTREMELY picky about how the parameters are declared. There are some posts by jrubins in the Twisted Pear forum thread on LADSPA filters (not sure but I recall is was about a month or two ago) in which he finally got it to work after experimenting with all sorts possibilities.

Anyway, I would try to remove that space, and even remove the extra zeros at the end. Make it just like the type 1 and 5 filters that DO work. If I think of anything else I will post about it...

The type 25 filters definitely works. I verified everything using ecasound. So its likely the cause lies with the ALSA code.

Success!
I rechecked JRubinstein's Github.
https://github.com/jrubinstein/raspiDSP/blob/master/alsa configuration asoundrc-experimental2.cpp

I noticed his asound.conf contains many "1"s. I replaced the "zeros" in my config with "ones" and I get output. :)
Whether that's an accurate or appropriate way to execute the filter, I've yet to understand.

I've just run another test. I'd noticed the acceptable range for Qp was "0.3 to 15".
This works.
Code:
input { controls [25 1 -4 912 1] } # 2nd order high shelf

J.
 
Last edited:
Success!
I rechecked JRubinstein's Github.
https://github.com/jrubinstein/raspiDSP/blob/master/alsa configuration asoundrc-experimental2.cpp

I noticed his asound.conf contains many "1"s. I replaced the "zeros" in my config with "ones" and I get output. :)
Whether that's an accurate or appropriate way to execute the filter, I've yet to understand.
Great! I knew you were probably close, but I don't have much practical experience with ALSA used in this way. Glad you sleuthed your way to success.

The only problem with putting "1" in there is that you might accidentally be using that as a parameter, where as "0" will usually cause something to fail and then you get silence and know that something is wrong.

I've just run another test. I'd noticed the acceptable range for Qp was "0.3 to 15".
This works.
Code:
input { controls [25 1 -4 912 1] } # 2nd order high shelf

J.

Ah funny about that. There really isn't any restriction per se. I added min and max suggested range "hints" to the controls because in another LADSPA plugin I released as a beta for awhile someone loaded it up in their DAW software (Ardour?) and then just twiddled with the sliders that control each parameter. Unfortunately, since Ardour did not have any info about appropriate ranges for the control, it took a flying leap and guessed 0..1 for everything: frequency, Q, etc. Obviously this didn't work too well! I never anticipated this kind of use of the plugins, but now that I know you can get into trouble unless the HOST has some info I put it in there.

Previously I had fixed the Q value for the second order shelf to Q=0.707 but in version 2 the user can choose what Q to use. This is following the miniDSP second order shelf filter prototype, which also takes a Q value. I don't currently do any error checking for "crazy" values of F or Q, but perhaps I should do that to prevent problems and misunderstandings.

So, in the end, the problem might have been caused by you using a value of "0" for the control parameter Qp. I suggest you use the value 0.707, which makes the level "maximally flat" before the shelf transition occurs.
 
Last edited:
I thought I was getting somewhere when I got no errors - but no sound. Deciding to reduce the problem to the smallest set in asound.conf - with a simpler filter (1st order low pass) allowed me to continue making progress. I haven't worked with apps development in years but I remembered "eureka" moments when I spotted that Q parameter and ested it and it worked. :)

I think I would have given up or looked at alternatives if not for the help I've had here, from yourself and FrankoLargo and from being able to compare my attempts with JRubenstein's effects in Github.

As regards Q in filters. I've seen several examples across the web in the past 48 hours. The inference is it should be > 0 but can be very low, depending on implementation, I suppose. One example allowed 0.01 - 20.

Can I assume that Q in the shelf filters is the width of the shelving effect "between plateaus"? Or does it do more than that?

J.
 
watching movies through ladspa or ecasound?

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
 
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

There is a few hundred milliseconds of delay to contend with. Otherwise, sure, doable. Get a Behringer UCA202 or UCA222.
 
Member
Joined 2007
Paid Member
There is a few hundred milliseconds of delay to contend with. Otherwise, sure, doable. Get a Behringer UCA202 or UCA222.
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

Option 2, 'arecord' piped to 'aplay'. For this to work you need your crossover running in ALSA, but I had that working already. I found it worthwhile to raise the priority of the two commands. The sound quality was very good and latency was acceptable.
Code:
chrt -f 45 arecord --buffer-size=80 -c 2 -t raw -f S24_3LE -r 48000  -D hw:1,0 | chrt -f 45 aplay --buffer-ze=160 -c 2 -t raw -f S24_3LE -r 48000 -D <ALSA crossover>

Option 1 is what I'm using now - SoX. I never notice lip-synch issues. The flash of a gun and the 'bang' from the speakers seem dead-on. For those with command-line acumen :p, SoX is pretty amazing. It has its own filter set for the experimenter and SoX can also run LADSPA filters. However, I simply sent stereo output from SoX to the LADSPA crossover already running in ALSA. This gave the best (lowest) latency I could achieve. I think there is merit in investigating and sharing the command-line syntax needed to execute Charlie's LADSPA filters in SoX. I have not tried LADSPA filters in SoX but I have explored SoX's FIR convolver to replace some of the steps that otherwise used serial IIR filters in ALSA. That filtration step further improved latency. [But, the BBB doesn't have enough CPU power to rapidly manipulate low frequencies using FIR - only for midrange and higher.]

Code:
chrt -f 45 sox --buffer 1024 -r 48000 -c 2 -t alsa hw:1,0 -t alsa plug:<ALSA crossover> &

...and with FIR...

chrt -f 45 sox --buffer 1024 -r 48000 -c 2 -t alsa hw:1,0 -t alsa plug:<ALSA crossover> gain -h fir /usr/filter/fir2peak48mild.txt &

Of course there are other ways than using a linux-based processor to implement DSP crossovers for captured signals. But I consider the linux route to offer great flexibility, especially considering the other myriad uses for linux, SoX and the inexpensive power of SOIC boards like RPi & BBB.

Cheers,

Frank
 
Last edited:
Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.