bmc0 / dsp

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

Plotting Crossover #20

Closed ghost closed 7 years ago

ghost commented 7 years ago

I can plot your 1 channel example. I am trying to plot your two channel two way crossover example. I get the error message -

dsp -pn @example2.txt | gnuplot dsp: parse_selector: error: value out of range: 1 dsp: error: failed to initialize effect: remix

where example2.txt is -

remix 0 0 1 1 :0,2 lowpass 2.2k 0.707 lowpass 2.2k 0.707 :1,3 highpass 2.2k 0.707 highpass 2.2k 0.707

$HOME/.config/ladspa/config is -

input_channels=2 output_channels=4

and $HOME/.asoundrc is -

~/.asoundrc

pcm.dsp { type plug slave { format FLOAT rate unchanged pcm { type ladspa channels 4 path "/usr/lib/ladspa" playback_plugins [{ label "ladspa_dsp" }] slave.pcm { type plug slave { pcm "hw:0" rate unchanged channels unchanged } } } } }

pcm.!default { type copy slave.pcm "dsp" }

Any suggestions would be greatly appreciated.

bmc0 commented 7 years ago

The plotting functionality is a bit limited, so only the effects implemented by biquad.c and gain.c support plotting (as well as stats and delay, since those don't affect the frequency response). In your case, you'll have to temporarily comment out the remix line if you want to plot the file. You also have to set the number of channels explicitly:

$ dsp -c 4 -pn @example2.txt | gnuplot

Another way of looking at an effects chain's frequency response is to run an impulse through the effects chain and then plot the frequency response of the output impulse using an appropriate program (GNU Octave can be used, but Room EQ Wizard would be easier if you don't have any experience with Octave or MATLAB):

$ dsp impulse.wav -oe s32 output.wav remix 0 0 @example2.txt

In the example above, impulse.wav is assumed to be mono and long enough to give the desired frequency resolution (1 second for 1Hz, 100ms for 10Hz).

ghost commented 7 years ago

Thank you for such a quick response. The system I wish to implement a dsp crossover is - man-cave The mid-bass/midrange/tweeter speakers are cbt36k's - https://www.parts-express.com/audio-artistry-cbt36k-line-array-speaker-pair-kit--301-980 designed by Don Keele.

I have not programmed in C/C++ in decades. Currently all my programming is in Python for a symbolic geometric algebra system - https://github.com/brombo/galgebra I hope to make good use of your code since I am an audioholic. Am I correct in stating that what your code does is construct an .asoundrc file appropriate for the required signal processing.

bmc0 commented 7 years ago

Nice system. I've not heard the CBT36K, but I've heard lots of good things about them. What are you currently using to implement the crossover?

I had a look through the manual and noticed that it uses 6 and 12 dB/oct shelving filters, which my program didn't implement directly (you could come up with the correct values with a bit of math though), so I added an easy way of implementing those filters in commit 1ed1e82. As an example, a 6dB/oct highshelf at 1600Hz with a gain of 3dB would be: highshelf 1600 6d 3.

Am I correct in stating that what your code does is construct an .asoundrc file appropriate for the required signal processing.

Not really. My code is what does the actual signal processing and can be used standalone (as the dsp program) or as a LADSPA plugin. It has no (required) ALSA dependency. The .asoundrc file just configures ALSA to load my code as a LADSPA plugin.

bmc0 commented 7 years ago

I decided to go ahead and implement the CBT36K crossover as outlined in the manual:

### Note: mapping is [TL TR WL WR]

### Gain adjustment (note: -15 will clip with a full scale sine sweep, but probably won't clip with a music signal)
:0,1,2,3 gain -15.0 :

### CD correction
## Flat
:0,1,2,3 lowshelf 401 6d -3.0 lowshelf 805 6d -3.0 highshelf 1600 6d 3.0 highshelf 3240 6d 3.0 highshelf 6430 6d 3.0 highshelf 12800 6d 3.0 highshelf 20k 6d 3.0 :
## -0.5dB/oct
#:0,1,2,3 lowshelf 401 6d -2.5 lowshelf 805 6d -2.5 highshelf 1600 6d 2.5 highshelf 3240 6d 2.5 highshelf 6430 6d 2.5 highshelf 12800 6d 2.5 highshelf 20k 6d 2.5 :
## -1.0dB/oct
#:0,1,2,3 lowshelf 401 6d -2.0 lowshelf 805 6d -2.0 highshelf 1600 6d 2.0 highshelf 3240 6d 2.0 highshelf 6430 6d 2.0 highshelf 12800 6d 2.0 highshelf 20k 6d 2.0 :

### Tweeter EQ and time alignment
:0,1 eq 1k 6.3 -4.5 highshelf 1k 12d 4.0 eq 1140 10.0 -2.4 eq 1240 10.0 1.5 eq 3850 5.0 -5.0 highshelf 7010 12d -3.0 gain 1.5 delay 0.00017 :

### Woofer EQ
:2,3 lowshelf 50 12d 15.0 eq 620 2.8 1.8 eq 1090 5.6 -3.0 eq 1780 2.8 -1.5 :

### Crossover (and subsonic filter)
## Tweeter
:0,1 highpass 1k 0.7071 highpass 1k 0.7071 :
## Woofer
:2,3 highpass 20 0.54119610 highpass 20 1.30656296 lowpass 1k 0.7071 lowpass 1k 0.7071 :

This is for flat response with no subwoofer. I've included the -0.5dB/oct and -1dB/oct CD correction filters as well. It assumes 4-channel input, so you need to put a remix effect in front of it. I like to put crossover settings in separate files, so I'd use something like this in a "master" file:

### Add some noise to avoid denormal values
noise -200

remix 0 1 0 1 @cbt36k

You can see the transfer functions here:

CBT36K crossover

There's a bit of frequency response error at high frequencies if run at a 44.1kHz sample rate (not unique to my code; any implementation will have similar error), but it may not be enough to be audible. 96kHz is more accurate.

ghost commented 7 years ago

Thank you for your efforts I feel like I have gotten an early birthday present. I am currently using a miniDSP HD 2x4 but want to get rid of the analog to digital conversion on the input. I wish to do all dsp processing on my htpc (my media server is Kodi) and then use either my Xonar D2 sound card or my Emotiva UMC-200 preamp (it has a direct mode where all dsp processing is turned off so it can be used as a DAC with analog volume control and analog trimming of each channels amplitude) as my DAC. Note I also am configuring my system as two full range (stereo) speakers crossing over each cbt36k to it own subwoofer at 80Hz.

ghost commented 7 years ago

I forgot to ask. Are you lowpass and highpass filters Linkwitz-Riley's? You did not explicitly state the type of low and high pass filters in you documentation.

bmc0 commented 7 years ago

Here's a version with an 80Hz sub crossover:

### Note: mapping is [TL TR WL WR SL SR]

### Gain adjustment
## Main speakers (note: -15 will clip with a full scale sine sweep, but probably won't clip with a music signal)
:0,1,2,3 gain -15.0 :
## Subwoofers
:4,5 gain -2.0 :

### CD correction
## Flat
:0,1,2,3 lowshelf 401 6d -3.0 lowshelf 805 6d -3.0 highshelf 1600 6d 3.0 highshelf 3240 6d 3.0 highshelf 6430 6d 3.0 highshelf 12800 6d 3.0 highshelf 20k 6d 3.0 :
## -0.5dB/oct
#:0,1,2,3 lowshelf 401 6d -2.5 lowshelf 805 6d -2.5 highshelf 1600 6d 2.5 highshelf 3240 6d 2.5 highshelf 6430 6d 2.5 highshelf 12800 6d 2.5 highshelf 20k 6d 2.5 :
## -1.0dB/oct
#:0,1,2,3 lowshelf 401 6d -2.0 lowshelf 805 6d -2.0 highshelf 1600 6d 2.0 highshelf 3240 6d 2.0 highshelf 6430 6d 2.0 highshelf 12800 6d 2.0 highshelf 20k 6d 2.0 :

### Tweeter EQ and time alignment
:0,1 eq 1k 6.3 -4.5 highshelf 1k 12d 4.0 eq 1140 10.0 -2.4 eq 1240 10.0 1.5 eq 3850 5.0 -5.0 highshelf 7010 12d -3.0 gain 1.5 delay 0.00017 :

### Woofer EQ
:2,3 lowshelf 50 12d 15.0 eq 620 2.8 1.8 eq 1090 5.6 -3.0 eq 1780 2.8 -1.5 :

### Crossover
## Tweeter
:0,1 highpass 1k 0.7071 highpass 1k 0.7071 :
## Woofer
:2,3 highpass 80 0.7071 highpass 80 0.7071 lowpass 1k 0.7071 lowpass 1k 0.7071 :
## Subwoofer
:4,5 lowpass 80 0.7071 lowpass 80 0.7071 :

This requires two extra channels, of course, so the remix effect needs to be changed:

### Add some noise to avoid denormal values
noise -200

remix 0 1 0 1 0 1 @cbt36k

Are you lowpass and highpass filters Linkwitz-Riley's? You did not explicitly state the type of low and high pass filters in you documentation.

That depends on the width parameter. Linkwitz-Riley filters are made by cascading two butterworth highpass/lowpass filters of order n/2, where n is the LR filter order. A 2nd order highpass/lowpass filter with a Q of 0.5 is equivalent to two cascaded first-order butterworth filters, so an LR2 highpass at 1kHz can be implemented like this highpass 1k 0.5. A 2nd order butterworth highpass/lowpass has a Q of 1/sqrt(2), so an LR4 highpass can be implemented like this: highpass 1k 0.7071 highpass 1k 0.7071. Higher order crossovers simply require more cascaded filters with specific Q-values. For example, an LR8 highpass would be: highpass 1k 0.5412 highpass 1k 1.307 highpass 1k 0.5412 highpass 1k 1.307. This PDF has the required Q-values for butterworth filters of order 2 through 20.

ghost commented 7 years ago

Now it feels like Christmas as well as my birthday. My current hardware is -

1 - i3 cpu htpc running ubuntu 16.04 and Kodi 2 - Emotiva UMC-200 preamp 3 - miniDSP HD 2x4 4 - Emotiva Gen 3 4 channel amplifier for cbt36k's 5 - 2 x cbt36k speakers 6 - 2 x Dayton audio 18 inch subwoofers + Dayton audio enclosure kit + Dayton audio 900W plate amplifier. 7 - Optoma 1080P DLP projector 8 - 2 X Silicondust HDHomerun Prime networked turners

What's your system?

bmc0 commented 7 years ago

I currently use a pair of self-designed stand-mount speakers with a 6.5in woofer (Peerless SDS-160F25PR01-08) and a 1in tweeter (Dayton ND25FN-4) mounted in a 3D printed waveguide, along with two Definitive Technology subwoofers. The crossover is implemented using my software and I use an Asus Xonar U7 as a DAC.

It is, in part, an experiment to see how good I can make cheap components sound (the woofer is only about $20 and the tweeter is $15). I have the parts for a pair of much larger and more expensive speakers that will be similar to Earl Geddes' designs or the DIY Sound Group SEOS-based speakers, but I haven't built them yet. I also have two RSS390HF-4 subwoofers to go along with the aforementioned speakers.

My current setup works surprisingly well considering its low cost. The anechoic frequency response is better than ±1dB on the listening axis and the off-axis response is smooth and well behaved. Harmonic distortion is fairly low (probably inaudible in most cases, though not quite as low as I'd like).

ghost commented 7 years ago

If you have not done so already look at the links at Parts Express to the theory behind Don Keele's CBT's. Also of interest is Richard Taylor's website (he sent me a link to your dsp site) -

http://rtaylor.sites.tru.ca

http://rtaylor.sites.tru.ca/2013/06/25/digital-crossovereq-with-open-source-software-howto

I can't use his solution for a dsp crossover because Kodi does not have an option to redirect the audio output. I needed your ladspa alsa solution.

bmc0 commented 7 years ago

I've looked through much of the documentation available on the CBTs. Really cool technology.

You would probably be able to use Richard Taylor's ecasound solution if you use ALSA's loopback device (run modprobe snd_aloop as root to load the module), but I actually wrote the LADSPA frontend for my DSP code in order to avoid having to use the loopback device.

Anyway, good luck setting everything up. Let me know if you run into problems.