iDFT-based XOs (FIR)

Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.
Just in case you want to experiment with FIRs in a digital XO, here are a few utilities relying on the iDFT (inverse discrete Fourier transform).

For more info about the iDFT and the DFT, please visit Steven W. Smith website Notation and Format of the Real DFT

In a nutshell, if you plan using a N-tap FIR at the heart of your digital XO, you need to define a lowpass Bode plot (gain and phase) as target, from DC to Fs/2, using N equally spaced (in linear scale) frequency bands.

Say Fs is 48,000 Hz. If you plan using a 10-tap FIR, you only have 10 equally spaced (in linear scale) frequency bands at your disposition. Each will thus be 4,800 Hz wide. Don't expect good results. Unless you want to split the audio in two bands like below 4,800 Hz (the lowpass) and above 4,800 Hz (the corresponding complementary highpass). This is something worth trying indeed.

Say Fs is 48,000 Hz. If you plan using a 100-tap FIR, you have 100 equally spaced (in linear scale) frequency bands at your disposition. Each will thus be 480 Hz wide. Of course you need some fast hardware, able to execute 100 multiply accumulate (MACC) per audio sample that's incoming. A stereo 2-way XO operating this way will thus require 48,000 x 4 x 100 MACC = 19.2 Mega MACC/s. A Microchip PIC32MX2 (two I2S ports) may be able to execute this, clocked at 40 MHz. Some ARM Cortex-M0 like NXP LPC111x (the ones equipped with two SSP) may be also be able to execute this, clocked at 50 MHz. Any decent PC running BASS, BASSASIO and ASIO (or ASIO4ALL) can execute this.

So, what's the point with the iDFT here?

Once you have defined the lowpass target Bode plot, you know everything about the system, in frequency domain.
Applying the iDFT on the corresponding data set (gain array and phase array), you get the corresponding time domain impulse response.
Such time domain impulse response can be viewed as a file, listing the required FIR coefficients.
So simple.

It's entirely up to you to define a lowpass target Bode plot that makes sense for a crossover. As lowpass target Bode plot, you may specify some Butterworth equivalent. Of any order. Even a non-integer order if you want. Or some Bessel equivalent. Of any order. Even a non-integer order if you want. Or a Brickwall. Or some asymptotic lowpass, of any order. Etc ...

Quite obligatory is to design the crossover as perfectly complementary. This means that when summing the lowpass and the highpass outputs, you get back the input signal. You thus can expect a perfect reconstruction, both in amplitude and in phase.
How to compute the complementary highpass from the lowpass FIR? That's quite simple, knowing that in time domain, the lowpass + highpass sum must equal the Dirac. As consequence, generally speaking, the highpass FIR is the lowpass FIR with a minus sign. This way, the sum is zero outside of the Dirac pulse. Which is what we want. The notable exception being the midpoint, where we must ensure that the highpass midpoint FIR coefficient equals unity less the lowpass midpoint FIR coefficient.
So simple.

The "iDFT XO" app illustrates all this.
I encourage you to play with.
The light-blue crossmarks make up the target lowpass amplutide curve.
The solid blue line shows you how the iDFT obeys the target lowpass.
The solid red line shows you the complementary highpass.
The lowpass FIR coefficients get written on your hard disk, in your "My Documents" directory.
 

Attachments

  • iDFT XO.zip
    215 KB · Views: 78
  • iDFT XO CGn.zip
    219 KB · Views: 52
  • iDFT XO CSRn.zip
    218.5 KB · Views: 50
  • iDFT XO CSTBSL.zip
    219.2 KB · Views: 47
  • iDFT XO CSTBSi.zip
    218.8 KB · Views: 49
Last edited:
The "iDFT XO CGn" app zooms on a particular lowpass target family.

XO for Crossover
C for Complementary.
Gn for Gauss any order

I designed it for answering all sorts of recurrent questions about "pure Gauss" and "Gauss-derived" crossovers. It illustrates the fact that if you select a "Gauss" order that's higher than 2, yes indeed the lowpass and highpass slopes do improve, but unfortunately the particular "Gauss" quality isn't there anymore as we observe preshoot and ringing in time domain. That's exactly what Berchin says (1999 publication).
If you want a neat, clean XO exhibiting no preshoot and ringing, select the "true" Gauss (thus with an order that's equal to 2), aka "Berchin", and you are done. Just make sure your tweeter can cope with the 2nd-order highpass slope.
If your tweeter needs a steeper highpass slope, select a higher "Gauss" order, but beware preshoot and ringing in time domain.
 
A few words about Windowing.

As it is always the case with FIRs, you can apply some Windowing.
Selecting "rectangle" means "no window" actually.
The window gets embedded in the FIR coefficients, at design stage. From a processing power perspective, it costs nothing to introduce a windowing function. During runtime, your PIC32, ARM Cortex-M, or x86 PC won't see any difference.

Playing with the apps, you will observe that most Windowing functions tend to smooth the amplitude curve, erasing out-of-band irregularities. The price to pay are somewhat relaxed slopes.

Playing with the apps you will observe that using some Windowing functions, you get nice amplitude curves exhibiting a good balance between selectivity, out-of-band rejection and sharpness, without relying on extra long FIRs.
 
Last edited:
A few examples running iDFT XO.

Say your harware is not so powerful. You want to reduce the FIR length. Let's try with a 31-tap FIR. This means 48,000 x 4 x 31 = 6 million multiply-accumulate per second. Any Microchip PIC32, ARM Cortex-M0/3/4 or x86 PC can do this. Digital diyAudio nowadays can (and needs) to base on proletarian hardware. The real issue are the I2S interfaces. How many PIC32 and ARM Cortex-M0/3/4 do you know, equipped with one I2S acting as digital audio input plus two I2S acting as digital audio outputs? Answer : PIC32MX2, STM32F4, Infineon XMC4500, and NXP LPC4330. Of course we still have the Freescale DSP56K family (not recommended for new designs) and the ADI SigmaDSP (currently used in miniDSP). Of course we can use an x86 PC running BASS, BASSASIO and ASIO (or ASIO4ALL).

We'll use a somewhat high crossover frequency. Say 3,800 Hz as starting point. Therefore, no question of using a big woofer. The woofer shall exhibit a consistent frequency response and wide polar diagram until 6 kHz or so. Say two 5 inch midbass drivers in a 2-way d'Appolito setup supposed to reproduce 50 Hz to 20 kHz. Say one or two 4 inch midbass drivers if we are dealing with a 2-way satellite unit supposed to reproduce 160 Hz to 20 kHz. There is nothing expensive here. Being crossed at 3,800 Hz, the tweeter can be anything from a miniature 13mm dome (Visaton CP13), miniature 16mm dome (Dayton ND16) or miniature 20mm dome (Dayton ND20). Again, there is nothing expensive here.

Say you heard about Bessel filters, exhibiting no preshoot and ringing. This is figure 1. You may feel happy with such Bessel 2nd-order.

Wanting some more slope regarding the woofer? Try the Bessel 4th-order. This is figure 2. Note the tweeter slope : it hasn't changed. It's still a 2nd-order highpass.

Wanting to improve the tweeter slope? Try the Butterworth 2nd-order "double". Kind of Linkwitz-Riley. This is figure 3. Better than Linkwitz-Riley as this time, there is no phase distorsion in the reconstructed signal. Dirac in, Dirac out. What about preshoot and ringing? Looks decent. Why not trying this, after all?

All this with "rectangular" windowing, aka no windowing at all.

Amazing, isn't ?

For the same price, we can embed a driver linearization feature into each FIR.

What about 3-way systems? Do we need a 310-tap FIR for crossing at 380 Hz instead of 3,800 Hz? At the moment I would say yes. Which means 60 million multiply-accumulate per second. Are Microchip PIC32 and ARM Cortex-M0/M3 ruled out here ? Maybe not. The trick, as explained by CopperTop, is to apply a 256-tap or 512-tap FFT, execute the filter in frequency domain, then execute an inverse FFT.
 

Attachments

  • 31-tap FIR 3800 Hz Butterworth 2nd-order double.jpg
    31-tap FIR 3800 Hz Butterworth 2nd-order double.jpg
    218.4 KB · Views: 382
  • 31-tap FIR 3800 Hz Bessel 4th-order.jpg
    31-tap FIR 3800 Hz Bessel 4th-order.jpg
    219.4 KB · Views: 393
  • 31-tap FIR 3800 Hz Bessel 2nd-order.jpg
    31-tap FIR 3800 Hz Bessel 2nd-order.jpg
    219 KB · Views: 402
A few examples iDFT XO CGn.

What if trying a kind of infinite order Bessel as lowpass? This is the purpose of the "iDFT XO CGn" app.

First of all, we need to define the target Bode plot (amplitude) as a typical bell-shaped curve. Actually this is half a Gauss curve, only the right part of it, with the transmission equal to 1.0 for DC , 0.5 for the crossover frequency, and zero for the infinite frequency. You may see it as a bell-shaped curve if you extend the left part using negative frequencies.

The target Bode plot is thus generated this way, very simply:

order = 2
For i = 0 To N
- F = FS * (i / N)
- If F < Fcut Then GAIN(i) = Math.Exp(((F / Fcut) ^ order) * Math.Log(0.5))
- If F = Fcut Then GAIN(i) = 0.5
- If F > Fcut Then GAIN(i) = Math.Exp(((F / Fcut) ^ order) * Math.Log(0.5))
- PHASE(i) = 2 * Math.PI * (MID * i / N) 'take FIR delay in account for the phase
Next

The "order = 2" instruction at the beginning is of importance. You only get a true Gauss function if specifying 2 as exponent. I suggest you pay a visit to Wikipedia about Gauss and the Normal Distribution.

Better not say a "Gauss order". Better say a "Gauss exponent". I'll change the name of the selection box app.

Thus at this stage we know that a) the Gauss idea here is not about the time-domain impulse response, b) the exponent parameter has nothing to do with a filter order or decibels per octave or decade, c) the exponent parameter is equal to 2 when applying a "true" bell-shaped (Gauss) curve as target lowpass amplitude.

What's so special about specifying a true bell-shaped (Gauss) curve as target lowpass amplitude?

See for yourself running iDFT XO CGn. Looking at the lowpass curve, it seems that we get a very high order Bessel, perhaps an infinite order Bessel. This is substantiated by the fact that the complementary highpass is a kind of 2nd-order. This is figure 1.

We thus know that for a given FIR length (here, 31), using the Gauss approach, we get a lowpass exhibiting an impressive, maximal slope. Indeed, the lowpass is more selective than when relying on the traditional "Bessel order N" approach like proposed in the "iDFT XO" app. All this without the slightest preshoot, overshoot or ringing in time domain.

The highpass remains a 2nd-order, unfortunately this is the Bessel / Gauss Achille's heel.

Now let's investigate when specifying an exponent greater than 2. This is figure 2. The exponent is now equal to 3.3. The highpass slope improves. At the expense of some time domain preshoot and ringing. Still looks very decent.

All this with "rectangular" windowing, aka no windowing at all.

Worth trying, isn't?
 

Attachments

  • 31-tap FIR 3800 Hz Gauss (true Gauss order 2 aka Berchin).jpg
    31-tap FIR 3800 Hz Gauss (true Gauss order 2 aka Berchin).jpg
    224.9 KB · Views: 372
  • 31-tap FIR 3800 Hz Gauss (pseudo Gauss exponent 3.3 instead of 2.0).jpg
    31-tap FIR 3800 Hz Gauss (pseudo Gauss exponent 3.3 instead of 2.0).jpg
    222.5 KB · Views: 364
Last edited:
An example running iDFT XO CSRn

XO for Crossover
C for Complementary
S for Symmetric
Rn for Ratiometric any order

"Symmetric" is the new feature.
The lowpass and highpass now exhibit the same shapes and slopes.
Don't know if this helps delivering good sound.
Anyway, it looks nice on paper.

The attached .jpg sketch illustrates the symmetry principle and the design constraints that we need to introduce when specifying the target lowpass Bode plot.
From DC to Fc, we draw a said-to-be arbitrary lowpass attenuation curve. The curve segment starts at DC with a 1.0 amplitude and end at Fc with a 0.5 amplitude. This is segment 1 in blue.
Let's now apply the lowpass-highpass symmetry. We thus know what shape the highpass will exhibit between Fc and Finfinite. This is segment 2 in red.
We also know that our crossover is complementary. This means that, knowing segment 2 in red (highpass), we know how much the lowpass must deliver for ensuring highpass + lowpass = unity between Fc and Finfinite. See dy1 and dy2 in red. We thus obtain segment 3 in dashed blue.
Let's use the same logic, starting with segment 1 (lowpass between DC and Fc), for determining how much the highpass must deliver for ensuring lowpass + highpass = unity between DC and Fc. See dy1 and dy2 in blue. We thus obtain segment 4 in dashed red.
The conclusion is that the said-to-be arbitrary lowpass attenuation segment between DC and Fc needs to be replicated using symmetry rules. On a Bode plot using linear Y axis and log X axis, this becomes evident. See the .jpg sketch. The (Fc, 0.5) points needs to act as central symmetry centre.

For designing Complementary Symmetric crossovers, we only need to scratch our heads, finding some simple and elegant mathematical function obeying such symmetry rule when graphed using linear Y axis and log X axis.

An easy one is:

order = 3
For i = 0 To N
- F = FS * (i / N)
- If F < Fcut Then GAIN(i) = 1 - (((F / Fcut) ^ order) / 2.0)
- If F = Fcut Then GAIN(i) = 0.5
- If F > Fcut Then GAIN(i) = (((Fcut / F) ^ order) / 2.0)
- PHASE(i) = 2 * Math.PI * (MID * i / N) 'take FIR delay in account for the phase
Next

The order can be any value, including non-integer values.

This time we selected a 51-tap FIR.
Crossover frequency still 3,800 Hz.

I selected a 3rd-order for guaranteeing a solid highpass function to the tweeter. As most tweeters exhibit a natural 2nd-order acoustic highpass, a bulletproof practice is to ask for an acoustic 3rd-order highpass. This way, the tweeter will remain protected against low frequency content. The magnetic circuit won't need to endure intense low frequency content. Sweet and precise highs guaranteed, even at high listening volume, using virtually any tweeter, including most miniature neodyme ones.

Selecting a higher order like 4 will provide an even better protection to the tweeter, at the expense of more preshoot and ringing.

Such 3rd-order Complementary Symmetric XO is a simple and solid design, even using fragile tweeters.
 

Attachments

  • symmetric complementary crossover.jpg
    symmetric complementary crossover.jpg
    45.1 KB · Views: 103
  • FIR 51-tap 3800 Hz Complementary Symmetric  Ratiometric 3rd-order.jpg
    FIR 51-tap 3800 Hz Complementary Symmetric Ratiometric 3rd-order.jpg
    183.5 KB · Views: 98
  • FIR 51-tap 3800 Hz Complementary Symmetric Ratiometric 4th-order.jpg
    FIR 51-tap 3800 Hz Complementary Symmetric Ratiometric 4th-order.jpg
    186.5 KB · Views: 89
Last edited:
Bonjour Stéphane,

Many thanks for sharing this with us.

Today I succesfully loaded a set of coëfficiënts into my digital loudspeaker management system, used to separate low from high at 2800Hz on my studio monitors. It runs at 96KHz and uses 121 taps.

Those monitors are using a d'Apollito config, and I'd like to try and lowpass one of the midwoofers at eg 500Hz to avoid path length differences causing comb filtering in the midrange. It'd be interesting to see if this makes an audible improvement...

Is there a way I can calculate coëfficiënts for a LPF @ 500Hz and somehow "merge" them with the coëfficiënts for the HPF at 2K8? Can sets of coëfficiënts be combined somehow?

Thanks again, I find the new linear phase crossover to result in a much more forward sounding vocal range, compared to traditional 2nd- or 4th order Linkwitz-Riley crossover.

Best Regards,

Igor
 
24-bit audio PIC32-based developments boards

Could be useful for a low cost two way dsp active crossover ;)

PIC32 USB DIGITAL AUDIO ACCESSORY BOARD

PIC32 USB DIGITAL AUDIO ACCESSORY BOARD
Part Number: DM320014

The PIC32 USB Digital Audio Accessory Board showcases a 16/24-bit quality digital stereo audio development platform using the PIC32 microcontroller (MCU). It can be used for 16/24-bit stereo audio playback and recording with a sample rate of up to 48 kHz. This accessory board is powered by the USB Host and can be used with any personal computer (PC), tablet, gaming station, or mobile device that supports the USB Audio Device Class. The digital audio stream is transferred over USB isochronous transfers. The PIC32 USB Digital Audio Accessory Board features the PIC32 MCU, which has a USB module with Host and Device capability, SPI module with Audio Mode that supports I2S, LJ, RJ, DSP/PCM modes, and a flexible audio reference clock output generation module that can be used as time base for the external codec or Digital-to-Analog Converter (DAC).

Key Features:

PIC32MX250F128B MCU: 40 MHz, 128 KB of program memory and 32 KB of RAM
PIC32 I2S support (LJ, RJ, DSP/PCM modes supported) – all modes can be 16/24-bit
PIC32 reference clock output for codec master clock
Audio codec (AK4645A) with up to 48 kHz sampling rate and 16/24-bit resolution
Supported codec-based audio processing features:

o 5-band equalizer

o Analog output mixing

o Stereo separation emphasis and wind-noise filtering

o Auto-level control
 
Is there a way I can calculate coëfficiënts for a LPF @ 500Hz and somehow "merge" them with the coëfficiënts for the HPF at 2K8? Can sets of coëfficiënts be combined somehow?
Hello Igor, "merging" is combining the two filters (500 Hz lowpass and 2K8 lowpass) for feeding one of the two midbass drivers. It should work painless if both lowpass filters are phase-linear and time-aligned.

You'll need to add a global shelving equalizer at the signal input for restoring global amplitude linearity.

However, dealing with a 500 Hz lowpass and a 500 Hz shelving eq with Fs 96 kHz, I'm not sure that 121 taps are sufficient.

Try doing the 500 Hz job in analog using a 1st order passive lowpass, just like Philips DSS930 did.
 
Microchip DM320014 24-bit audio PIC32MX2-based developments board
At $69.99, this is indeed a nice opportunity. Source code is going to be interesting, especially the USB-audio function (really working like any USB-audio soundcard?) and the I2S codec interfacing. Have you got the opportunity to try it? How many MIPS consumed by the USB-audio process? How many MIPS remaining for audio DSP?
 

Attachments

  • Microchip DM320014.jpg
    Microchip DM320014.jpg
    32.7 KB · Views: 205
Last edited:
Today I went looking the Microchip DM320014 USB Digital Audio Accessory Board.
I've downloaded and looked the demo sources files available from Microchip website. Audio comes from USB (isochronous), and gets played by the AK4645a audio codec. They call this a "High-Quality Audio Application", however they continuously adjust the master clock sent to the AK4645a codec for software-emulating the fractional divider that's required from the USB clock, for avoiding buffer underrun errors.
I guess most people will get frightened by the complexity of the source code.
Can you believe, seeing this I'm regretting my old DSP56002 EVM coupled to the Domain Technologies debugger running under Windows 3.11. This is more than 15 years ago. The audio codec was a CS4215. Happy memories. A few pictures attached.
 

Attachments

  • DSP56002 EVM.jpeg
    DSP56002 EVM.jpeg
    73.9 KB · Views: 199
  • Medical Office.jpg
    Medical Office.jpg
    86.2 KB · Views: 187
  • DSP56K assembly.jpg
    DSP56K assembly.jpg
    165.1 KB · Views: 193
Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.