• Disclaimer: This Vendor's Forum is a paid-for commercial area. Unlike the rest of diyAudio, the Vendor has complete control of what may or may not be posted in this forum. If you wish to discuss technical matters outside the bounds of what is permitted by the Vendor, please use the non-commercial areas of diyAudio to do so.

LADSPA filters for digital crossovers on the BBB

Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.
You're probably increasing the signal over 0db somewhere or another. Check alsamixer, set your level to 90. Make sure your total level boost doesn't go above 0.

Also, make sure your squeezelite is running as the same user as your asound.conf user. If you get different sound results when running speaker-test and sudo speaker test, that could be the case.
Thanks,
this is the basic botic v5 build with Squeezelite v1.5 on top
everything is running as root

Code:
root@botic:~# speaker-test -c 2 -t sine -D botic-split
gives sound at each speaker as expected, but it's a glitched overdriven noise, not a sine wave.

For some reason I can't run alsamixer. When I try to call it I get
Code:
root@botic:~# alsamixer -D default
cannot load mixer controls: No such file or directory

I don't understand enough about how volume levels are controlled digitally to have a theory on what can be happening. I guess something is clipping before the signal gets to the dac? By my estimations, the volume is 8 to 10 times more than I would expect compared to previous method of feeding i2s into the dac and relying on shift registers to output the right justified data

thanks,
James
 
ah ha!
I have changed my squeezelite startup options and now have regular volume levels.
Previously I had
Code:
squeezelite -o botic-split -n JRdddac -a 16384:1024::
and if I change this to
Code:
squeezelite -o botic-split -n JRdddac -a 16384:1024:24:
then I have normal volume levels back, but there was a very slight digital swishing noise present in the background and if I lowered the volume via squeezelite to say 60% it very quickly becomes quite grainy as the music volume lowers but the digital noise doesn't.

So I changed the botic snd_soc_botic.blr_ratio=64 instead of 32 as recommended as a fix to someone else with weird noises and that's cured it for me.

I think I'm sorted and wow it sounds good! :)

thanks for your help guys,

James
 
ah ha!
I have changed my squeezelite startup options and now have regular volume levels.
Previously I had
Code:
squeezelite -o botic-split -n JRdddac -a 16384:1024::
and if I change this to
Code:
squeezelite -o botic-split -n JRdddac -a 16384:1024:24:
then I have normal volume levels back, but there was a very slight digital swishing noise present in the background and if I lowered the volume via squeezelite to say 60% it very quickly becomes quite grainy as the music volume lowers but the digital noise doesn't.

So I changed the botic snd_soc_botic.blr_ratio=64 instead of 32 as recommended as a fix to someone else with weird noises and that's cured it for me.

I think I'm sorted and wow it sounds good! :)

thanks for your help guys,

James
Awesome!
Glad you got it sorted.
 
Member
Joined 2007
Paid Member
OK, the USB problem mentioned above is solved and I have a really nice-sounding 3-way setup using ACDf (Charlie's Audio Home Page) in ALSA plus Jessie 8.3. Thanks to Charlie for generously sharing this excellent code!

The current 'first generation' asound.conf file is on GitHub for anyone who is interested:
https://github.com/francolargo/BBB-audio/blob/master/asound.conf.ACDf.3-way

A few notes:
1. In my 'difficult' room, I found that nothing surpassed the clarity of LR4 alignments.
2. I tried two organizations for the configuration. One was to do all equalization in stereo mode and then crossover. The other was to crossover and then do the needed equalizations on each of the 6 output channels. Both layouts ran with the same CPU load, but one sounded better - equalization after crossover filtering. This seems natural because the faults being addressed originate with each individual driver, so any downside of each EQ on signal quality is restricted to only one driver and channel.
3. CPU load is right near the practical max - with 96/24 data the CPU runs @ just under 80%.
4. I would like to try to counter the phase disturbance by the two midrange EQ filters. ...need to research that a bit more...
5. A carry-over from the RT filter configurations arose as an issue, or perhaps, point of attention. In order to prevent the RT filters from automatically upsampling within each plug, I added 'pcm.plughw.slave.rate = "unchanged";' as the bottom line of the configuration. I found that some alignments of ACDf filters needed that limitation to be commented-out. So I moved filters around until the configurations ran while the no-resample limitation was active. This acts as a simple efficiency and QC test.

Well, how does it sound? Really quite good! :D With the LR4 alignments it seems that the sound outside of the main listening area is more smeared, but inside the generous listening area it is the best yet. This particular system has the potential for super-critical resolution, so phase issues are really obvious with complex music. Thus, from here I will look into different ways to improve phase alignments. But no hurry. Summer is upon us. ;)
 
Member
Joined 2007
Paid Member
I have been using data from Room EQ Wizard to try to improve the listening experience in my very difficult room. I have a mode at 760, 2450, and a minor one at ~2900Hz. These modes can be addressed using 2nd order eq filters in the ALSA LADSPA plugins, and they work fine. However, when running these eq filters on the raw Squeezelite output, I lose some of the expansive spatial presentation of the soundstage. The loss is directly related to the amount that I cut each of the three bands. For loud play I need more attenuation, while for mid-level play I can halve the peak attenuation and improve the spatial presentation somewhat. I'd like "all the best all the time" even knowing that audio is inherently a shell game of trade-offs.

Hoping to avoid the phase shifts of IIR EQ filters, I am in the process of investigating FIR filters for this step. Knowledge-wise I'm starting from scratch, as always! I think of these filters as 'pre-eq' because they are ahead of the IIR crossover (3-way, LR4) plus a couple of minor bottom-end corrections limited to the bass channels. I was able to approximately match the IIR 'pre-eq' filters using the 'fir2' algorithm in Matlab - graph below. The easiest way to test them is using the FIR convolver in SoX. I find that 1024 taps at 48kHz uses about 18% of the BBB's available CPU. That's about the max I can support if the system is going to function as high as 96kHz. Sure enough, there *is* better spatial representation.

However, the down-side is that there is less sensation of 'smoothness', for lack of a better term. A bit of a gritty edge comes along with that soundstage. At this stage, I'm thinking I should try BruteFIR - which will be a shallow learning curve for sure! But then I can try FIR with reference tracks whose resolution is better than the stuff I'm now playing via USB.

Assuming that the details of the implementation are all important, I'd love to hear any suggestions from any of you with experience designing and using FIR. I've only tried a few linear-phase coefficient sets - single precision. Again, I think 1024 taps will be max. Any and all suggestions/comments much appreciated!

Cheers,

Frank
 

Attachments

  • FIR1024.jpg
    FIR1024.jpg
    98.7 KB · Views: 201
Last edited:
Hello, just arrived from "Pc Based", where I've been looking for plugins for ALSA/LADSPA.

Main question is this. Is there a plugin out there that can implement a simple (!?!) baffle step compensation filter. I think this is also known as a "shelf" or "shelving" filter.

J.
 
Running alsa plugins from mpd. This works for me to run ALSAEQUAL.

Main asound.conf file
Code:
pcm.!default {
 type plug
 slave.pcm plugequal;
}
ctl.!default {
 type hw card 0
}
ctl.equal {
 type equal;
}
pcm.plugequal {
 type equal;
 slave.pcm "plughw:0,0";
}
pcm.equal {
 type plug;
 slave.pcm plugequal;
 }

Main mpd.conf extract.
Code:
audio_output {
type "alsa"
name "ALSA Eqiul Output"
device "plug:plugequal"
dsd_usb "yes"
}

Command used to set mixer settings and have them applied. Equaliser settings are held in the users home folder in ".alsaequal.bin".

Code:
sudo -u mpd alsamixer -D equal
 
Member
Joined 2007
Paid Member
Greetings @Jerms,

It's extremely simple to configure a shelf filter. The other 'details' of running in Linux are probably more restrictive than the filter itself. Two questions:

A. Do you run with a fixed sampling frequency? The advantage of running a filter in ALSA is that the player and post-player filtering can adapt to match any recording frequency (if you use a clock-switching kernel).
B. Ahhh, you just answered my second question as I'm typing this... It is possible that I never came across the proper syntax for 'device' in the mpd.conf file. If the syntax you show works for one plugin, it should work for others. So question 2 becomes: Whose LADSPA filter set do you want to use? In my system, Charlie's sound better...

This will be simple as long as the 'device' syntax works.

Frank
 
Member
Joined 2007
Paid Member
@Jerms, you simply need to add a 'type-LADSPA' plug somewhere between the input and output of asound.conf. ...one plug containing a filter for each channel. If you install Charlie's filters, this one should get you started. Change 'default' and 'equal' to output to 'filter1', and change mpd.conf device to output to 'equal'.

Code:
pcm.filter1 {
     type ladspa
     slave.pcm plugequal
     path "/usr/lib/ladspa"  # must indicate filter directory
     channels 2  # two is default, other channel counts must be specified
     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 shelf filter is channel 0
               output.bindings.0 "Output"  #output from shelf filter is channel 0
               input { controls [29 -4 740] }   # high shelf 740Hz, -4dB
          }
          1 {
               label ACDf
               policy none
               input.bindings.1 "Input"
               output.bindings.1 "Output"
               input { controls [29 -4 740] }   
          }
     }
}
 
@Jerms, you simply need to add a 'type-LADSPA' plug somewhere between the input and output of asound.conf. ...one plug containing a filter for each channel. If you install Charlie's filters, this one should get you started. Change 'default' and 'equal' to output to 'filter1', and change mpd.conf device to output to 'equal'.

Code:
pcm.filter1 {
     type ladspa
     slave.pcm plugequal
     path "/usr/lib/ladspa"  # must indicate filter directory
     channels 2  # two is default, other channel counts must be specified
     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 shelf filter is channel 0
               output.bindings.0 "Output"  #output from shelf filter is channel 0
               input { controls [29 -4 740] }   # high shelf 740Hz, -4dB
          }
          1 {
               label ACDf
               policy none
               input.bindings.1 "Input"
               output.bindings.1 "Output"
               input { controls [29 -4 740] }   
          }
     }
}

Hi Frank,

Is this missing some zeros?
Code:
 input { controls [29 -4 740] }   # high shelf 740Hz, -4dB
Would you not want this:
Code:
 input { controls [29 0 -4 740 0 0 0] }   # high shelf 740Hz, -4dB
There are in total 7 input parameters for ACDf...
 
Member
Joined 2007
Paid Member
Hi Frank,

Is this missing some zeros?
Code:
 input { controls [29 -4 740] }   # high shelf 740Hz, -4dB
Would you not want this:
Code:
 input { controls [29 0 -4 740 0 0 0] }   # high shelf 740Hz, -4dB
There are in total 7 input parameters for ACDf...

Interesting - I haven't fiddled with the upgrade yet, but with the older set the missing zeros are ignored in, for example, filter type 21 & 22. But you da man, and I see the missing zero before the dB parameter. We'll do whatever you say! :) Suggestion? Maybe the documentation for 'filter types and their required parameters', which I was just looking at, should be edited to show where zeroes are required?

Cheers!
 
Last edited:
Interesting - I haven't fiddled with the upgrade yet, but with the older set the missing zeros are ignored in, for example, filter type 21 & 22. But you da man. We'll do whatever you say! :)


NOTE THAT I HAVE CHANGED THE NUMBERING FOR ACDf VERSION 2!!! There is no type 29 now. Shelf filters are 4/5 (first order) and 24/25 (second order) for low/high shelving respectively. Please use the new version 2 numbering scheme - versions earlier than 2.0 for ACDf are not longer available for download. I changed this in the post, below.

Yes missing zeroes are ignored, but this only applies to AFTER the last parameter. For instance if you supply these parameters.

Code:
ACDf 25 -4 740
I believe that the zeros are filled in like this:
Code:
ACDf 25 -4 740 0 0 0 0
And what you would get is:
Code:
ACDf filter
Type = 25 (ACDf ver 2 second order high shelf)
polarity = -4
gain = 740
Fs = 0
Qp = 0
Fz = 0
Qz = 0

That's not really what you want!

So, you can only leave "blank" any and all parameters after the last non-zero parameter. Also, the behavior of ecasound is to supply zeros for missing parameters. I have absolutely no idea what ALSA does in that case.

I advise you to ALWAYS supply zeroes for unused parameters. This helps to prevent mistakes in the parameter order or number that might result in something completely different.

Anyway, after all of that, I think this is what you want:
Code:
input { controls [25 0 -4 740 0 0 0] }   # high shelf 740Hz, -4dB
 
Last edited:
Member
Joined 2007
Paid Member
Great explanation, and consistent with what I have working using the older filter set in ALSA.
Thanks, Charlie! :)

BTW (and OT), I'm messing with using one FIR filter to replace several individual parametric EQ filters, and finding that a) with limited CPU horsepower, Fir are only practical for 'higher' frequencies, but b) using 1024 taps the FIR convolution route is noticeably faster than several IIR EQs. So processing the audio side of video program material, I get perfect lip-synch. All of this is happening in SoX, which is a pretty amazing package...
 
Last edited:
I have made some progress but as yet don't have sound.

ACDf installed to /usr/local/lib/ladspa.
asound.conf updated
mpd.conf updated.

Just read Charlie's latest post. Seems I need another zero somewhere.... At the least, MPD thinks it's working, no errors from it.... just no sound (yet).

J.
 
I have made some progress but as yet don't have sound.

ACDf installed to /usr/local/lib/ladspa.
asound.conf updated
mpd.conf updated.

Just read Charlie's latest post. Seems I need another zero somewhere.... At the least, MPD thinks it's working, no errors from it.... just no sound (yet).

J.

You may (should) find the usage notes helpful for figuring out how to invoke the filter that you want... these are provided as part of my LADSPA plugin download.
 
Member
Joined 2007
Paid Member
I have made some progress but as yet don't have sound.

ACDf installed to /usr/local/lib/ladspa.

Seems like good progress. Note that I put my LADSPA filters in: "/usr/lib/ladspa". The very helpful commands 'listplugins' and 'analyseplugin' apply only to that particular directory, in my experience. Knowing all you do about the ACDf suite, those commands won't help you much. Just change the filter path in the filter1 plugin. Also, add this line to /etc/rc.local:
Code:
export LADSPA_PATH=$LADSPA_PATH:/usr/local/lib/ladspa:/usr/lib/ladspa

One of my favorite ways to test the ALSA side of a rig is with 'speaker-test' or 'aplay', both using the -D spec to list the input plug of choice. 'aplay' has amazing debug info if you run it in verbose mode.

Good luck!
 
Last edited:
Member
Joined 2007
Paid Member
One more thought, if there is a problem with asound.conf it will sometimes (but not always) show up when you execute 'aplay -L'. Be sure that the plugins you expect are in that list... Finally, use a cold re-boot to be sure that mods to asound.conf are in effect. ;)
 
Last edited:
I distilled the asound.conf to simplify the path to the hardware. So only trying to invoke the BSC now. Are my ACDf parms correct?

Code:
pcm.!default {
 type plug
 slave.pcm plugequal;
}
ctl.!default {
 type hw card 0
}
ctl.equal {
 type equal;
}
pcm.plugequal {
 type equal;
 slave.pcm "plughw:0,0";
}
pcm.equal {
 type plug;
 slave.pcm plugequal;
 }

pcm.filter1 {
     type ladspa
     slave.pcm "plughw:0,0"
     path "/usr/lib/ladspa"  # must indicate filter directory
     channels 2  # two is default, other channel counts must be specified
     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 shelf filter is channel 0
               output.bindings.0 "Output"  #output from shelf filter is channel 0
               input { controls [25 1 -4 950 0 0 0] }   # high shelf 740Hz, -4dB
          }
          1 {
               label ACDf
               policy none
               input.bindings.1 "Input"
               output.bindings.1 "Output"
               input { controls [25 1 -4 950 0 0 0] }
          }
     }
}

Running speaker-test I can see it running but I get no audio output.

Code:
root@MoOdey-Lounge:/etc# speaker-test -Dplug:filter1 -c2

speaker-test 1.0.28

Playback device is plug:filter1
Stream parameters are 48000Hz, S16_LE, 2 channels
Using 16 octaves of pink noise
Rate set to 48000Hz (requested 48000Hz)
Buffer size range from 8 to 65536
Period size range from 4 to 32768
Using max buffer size 65536
Periods = 4
was set period_size = 16384
was set buffer_size = 65536
 0 - Front Left
 1 - Front Right
Time per period = 6.096419
 0 - Front Left
 1 - Front Right

Running speaker-test to "-Dplug:plugequal" results in output to both speakers.
 
Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.