bmc0 / dsp

An audio processing program with an interactive mode.
ISC License
219 stars 31 forks source link

LADSPA: biquad filter is not applied #53

Closed ariendj closed 4 years ago

ariendj commented 4 years ago

I have the following configuration that I can load as a LADSPA plugin into pulseaudio without issue:

input_channels=2 output_channels=2 effects_chain=gain -16 biquad 1 -0.85352776 -0.11046426 1 -1.866632 0.86705829 st2ms :0 highpass 18 0.707 highpass 18 0.707 eq 10 3 -20 eq 12 3 -20 eq 28 1.5 2.6 :1 highpass 150 0.707 highpass 150 0.707 ms2st zita_convolver /storage/.config/ladspa_dsp/normal-96.wav

As far as I can tell all of the lines are working except the biquad. As the biquad implements a RIAA playback filter it should be clearly audible when the biquad works. The funny thing is that I can successfully plot the frequency response by starting dsp with this command:

dsp -pn gain -16 biquad 1 -0.85352776 -0.11046426 1 -1.866632 0.86705829 | gnuplot

This results a correct bode plot of a RIAA playback filter.

Is there an error in my config file? If there was I'd expect pulseaudio to complain that it cannot load the LADSPA plugin. Yet the plugin loads fine, it just leaves out the biquad.

bmc0 commented 4 years ago

I see an issue that should cause the plugin to fail to load. The st2ms and ms2st effects require a stereo input, but you only have channel 1 selected before ms2st. You can select all channels with a :. I assume that the FIR filter should be applied to both channels here:

effects_chain=gain -16 biquad 1 -0.85352776 -0.11046426 1 -1.866632 0.86705829 st2ms :0 highpass 18 0.707 highpass 18 0.707 eq 10 3 -20 eq 12 3 -20 eq 28 1.5 2.6 :1 highpass 150 0.707 highpass 150 0.707 : ms2st zita_convolver /storage/.config/ladspa_dsp/normal-96.wav

How are you loading the plugin? Is the load-module command preceded by a .nofail statement?

Also, you should make sure that your biquad coefficients are correct for whatever sample rate you're using. The default sample rate for the dsp command is 44.1kHz, but the name of your FIR kernel seems to imply 96kHz.

ariendj commented 4 years ago

Hi Michael! I loaded the plugin manually, without a nofail statement. It loaded without an error message and I was able to load a loopback plugin that plays the signal at the analog line input via this sink.

The biquads are meant for 96kHz sample rate which is what I have pulseaudio configured to use. They are from an article in 'Linear Audio' that deals with DSP based phono EQ. I entered the biquad via copy & paste to avoid typos.

The FIR filter is just a regular Brutefir filter, also configured for 96kHz.

I'll try a modified version of the same config with the st2ms and ms2st removed and will report what happens.

In the mean time I noticed that loading the config I posted above but with the biquad removed works as expected. If I then load another instance of the plugin with a config containing only the biquad then I can use the first instance of the plugin as a sink for the second instance of the plugin. It's not pretty but it works as expected.

Aside from the bug report I want to thank you for publishing this wonderful piece of software. I use it almost every day. The first thing I did with it was to replace a clunky OpenDRC to do apply FIR filters in realtime. From then on I have used dsp on many machines from small computers like the pi zero to my friends Xeon workstation. I've alway found dsp to be very reliable. Thank you!

bmc0 commented 4 years ago

Thanks for the kind words.

I figured out what the problem is: You split your effects chain into multiple lines, so only the gain effect is applied. The rest of the lines are interpreted as (invalid) key-value pairs and a warning is printed (you would not see the warnings if you used pacmd to load the plugin). I suppose I should probably change the code to allow line continuations or at least make invalid options a fatal error. The problem wasn't obvious initially because of your formatting, but I was able to see the original by selecting "edit". You can use ``` to create a code block where the original formatting is preserved (see this guide).

Possible solutions (until I change the parsing code, at least) are to either put the whole effects chain on one line like I did in my previous comment, or put the effects chain in a separate file (this is what I usually do) and source it with @. Example:

config:

input_channels=2
output_channels=2
effects_chain=@eq

eq (in same directory as config):

gain -16
biquad 1 -0.85352776 -0.11046426 1 -1.866632 0.86705829
st2ms
:0 highpass 18 0.707 highpass 18 0.707 eq 10 3 -20 eq 12 3 -20 eq 28 1.5 2.6 :
:1 highpass 150 0.707 highpass 150 0.707 :
ms2st
zita_convolver ~/normal-96.wav
bmc0 commented 4 years ago

Invalid options are treated as an error as of afc8008.

Somewhat off topic, but what's the purpose of the 150Hz highpass on the side channel?

ariendj commented 4 years ago

Thanks, with the effects all in one line everything works as expected! I guess I'll use separate files for effect chains in the future. It does help to make things more modular.

The 150Hz highpass on the side channel is a part of my subsonic filter for vinyl playback. On a LP record the bass below ~150Hz has generally been summed to mono during mastering, so anything that is on the side channels is almost guaranteed to be low frequency noise. I filter it out to keep the woofers happy.

bmc0 commented 4 years ago

Makes sense, I guess I just figured that the subsonic filter would be sufficient.