Using CamillaDsp with a Motu-M4 as a Crossover
--
Traditionally, loudspeakers have internal passive crossovers to funnel highs to tweeters and lows to woofers. This article is about using a Motu-M4 as an electronic crossover to drive multiple power amplifier signals into each individual speaker driver.
TLDR;
This was a difficult project to get working completely right. The goal is an unattended {Motu-M4 + Computer} that acts like an active crossover. After trying Raspberry Pi and Windows PC, I ended up with a Mac M1 Mini as the ONLY good working M4 solution.
Background
I started this project 12 years ago and the loudspeakers have been sitting waiting for technology to catch up.
Two good historical examples of inexpensive (<$500) packaged solutions are the MiniDsp 2x4 (2015) and the Dayton Audio DSP-408 (2018). These are programmable active crossovers, but even as the best quality of their time barely listenable.
A passive crossover contains high voltage/power resistors, inductors, and capacitors and funnels the high-power audio signals to loudspeaker drivers. Unfortunately the parts are so large and so expensive that crossovers are generally so-so.
In my current loudspeaker I use a simple 2nd order passive crossover for the tweeter and midranges (the one in the diagram below, actually) and then use an active crossover to funnel to the ‘speaker’ or the woofers. Just one inductor for a mediocre woofer crossover would cost about $50 (the lower the frequency the greater the cost).
By using the M4 instead of a simple passive crossover, we can room-correct and time-align the drivers and … and end up with almost a flat frequency response curve. This is a difficult task and it takes very good A/D and D/A converters and a fast DSP/CPU to get high quality audio.
It’s only been the last year or so (I write this in 2023) where you can buy off-the-shelf equipment to produce transparent sound.
Other Choices
Parts Express has an entire line of amplifiers (from Dayon-Audio/Sure Electronics) that include an on-board 2x4 DSP subsystem (A/D -> DSP -> D/A). Example is the Dayton Audio KABD-250 2 x 50W.
The newer MiniDsp units are very high quality and expensive. The Dayton Audio stuff is likely to be mediocre. The original Minidsp2x4, the DSP408 , and the KABD boards all use an ADAU1701 chip — which is pretty much 16bit x 48 or 44.1KHz with very mediocre A/D and D/A. Rather moderate fidelity.
The Loudspeakers
The testing speakers are a traditional MTM with woofer using mainly Parts-Express drivers.
Speaker detail
The speakers have one tweeter, two mid-woofers, and one very large woofer. The mids/tweeter use the passive crossover on the speaker top. It would produce better audio to use a Motu M6 with 3 amplifier stages per loudspeaker (removing the passive crossover) but this much-less-expensive design does nearly as well with 2 amplifier stages per loudspeaker and it’s a great test of the approach.
Which OS to Use
CamillaDSP is a very nice application from Henrik Enquist that is perfect for using the M4 as a crossover. It’s cross-platform (PC/Mac/Pi) and supports very complex crossovers and automatic room-correction.
Pi
Almost everyone I saw online supported using a Raspberry PI with CamillaDSP to do a crossover. I tried and tried with a PI3 B+ and just like most of my complex PI projects it failed. Maybe a Pi4 would work?
First, the PI OS itself is unstable. I had sporadic crashes and in one case the software started an infinite loop screaming into the loudspeakers — not something my wife (or I) want. Also, no matter what I did, it sounded like garbage — the PI is noisy, too slow, and the end result sounded just awful — clicks, pops, dropouts, and breathing.
Windows PC
After the PI I tried using a MAC and had enough issues that I then tried a Windows PC — an Intel NUC. The NUC is a wonderful computer but the M4 windows (WASAPI) drivers are just bad. Motu provide an ASIO driver that is 4-channel, but not WASAPI. Instead they publish two stereo devices — so I had to run two instances of CamillaDSP that caused all sorts of maintenance and synchronization issues and again it sounded just awful and fuzzy. If CamillaDSP supported ASIO this might have been an ok solution.
Mac Mini
I returned to my Mac M1 Mini as the best-sounding after PI and PC failures. The Mac driver is solid (both the default Mac USB driver and the MOTU specific M4 driver) and the M1 is incredibly fast so no performance issues.
The biggest issue with the M1 was getting the software to run at startup. None of the documentation is accurate about using MacOS — anywhere — so it took three days to write a simple reliable PLIST script.
Finally : using the Mac Mini
So, it finally works reliably. There are two ways to use this.
- Use a good Bluetooth receiver and send output to the analog inputs to the M4 and split them into 4 outputs (as shown above). The M4 A/D converters are very good and the quality doing it this way is excellent.
- Stream via Wifi to the Mac. The signal flow is then Mac->USB->M4 outputs with no A/D conversion required and no analog noise input.
Bluetooth is really too slow for great audio quality and none of the high quality decoders (like AptX) are available in software. Still, using a retail Bluetooth receiver adds AptX-HD and Sony LDAC support — which are good quality.
The problem with wifi streaming is that the only supported quality way to send music to a Mac is via AirPlay so my iPad could stream well to the Mac and nothing else in the house (Windows PC, Android Phones) could talk to it at all (except via just awful-sounding SBC). Thanks Apple.
I ended up with, for now, using analog inputs with a Bluetooth receiver, so fundamentally it acts like a very high quality, very smart Minidsp 2x4 box.
There are just two important files: the CamillaDSP configuration for the crossover and the startup file for CamillaDSP that runs it at bootup.
The crossover
This crossover uses low pass filters for the woofers and high pass filters for the mid/tweeter speaker along with a small boost in the midrange for the mid/tweeter. I run everything at 96Khz so filtering is smooth. This is a pretty simple crossover for test purposes.
The capture device is the M4 inputs (analog lines 1,2 here) and the output is all 4 outputs of the M4. The M4 is driven by a nice Bluetooth receiver line output — adding solid LDAC and AptX support.
devices:
adjust_period: 3
capture:
change_format: false
channels: 4
device: M4
format: S32LE
type: CoreAudio
capture_samplerate: 96000
chunksize: 1024
enable_rate_adjust: true
enable_resampling: false
playback:
change_format: false
channels: 4
device: M4
exclusive: true
format: S32LE
type: CoreAudio
queuelimit: 4
rate_measure_interval: 1
resampler_type: Synchronous
samplerate: 96000
silence_threshold: -85
silence_timeout: 10
stop_on_rate_change: false
target_level: 0
filters:
HiP:
parameters:
freq: 80
q: 0.7
type: Highpass
type: Biquad
LoP:
parameters:
freq: 100
q: 0.7
type: Lowpass
type: Biquad
Peak:
parameters:
freq: 300
gain: 3
q: 0.4
type: Peaking
type: Biquad
mixers:
copy:
channels:
in: 4
out: 4
mapping:
- dest: 2
mute: false
sources:
- channel: 1
gain: -12
inverted: false
mute: false
- dest: 3
mute: false
sources:
- channel: 1
gain: -12
inverted: false
mute: false
- dest: 0
mute: false
sources:
- channel: 0
gain: -12
inverted: false
mute: false
- dest: 1
mute: false
sources:
- channel: 0
gain: -12
inverted: false
mute: false
pipeline:
- name: copy
type: Mixer
- channel: 0
names:
- HiP
type: Filter
- channel: 2
names:
- HiP
type: Filter
- channel: 1
names:
- LoP
type: Filter
- channel: 3
names:
- LoP
type: Filter
- channel: 0
names:
- Peak
type: Filter
- channel: 2
names:
- Peak
type: Filter
Here channels 0,2 are the primary speaker and 1,3 are the woofers. It makes more sense to have 0,1 be the primary speaker and then the front panel volume control controls the ‘speakers’ (it only adjusts channels 1&2) but this was done to match the Windows setup for testing.
The startup file
Nowhere did I see this documented, but it turns out that to have an app autostart the simplest approach is to just copy the PLIST script to /Library/LaunchAgents. They call it a script but it’s really an XML config file to run an app with multiple arguments.
That’s it. The PLIST file is below. It just invokes a shell script (see below).
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN
http://www.apple.com/DTDs/PropertyList-1.0.dtd >
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.camilladsp</string>
<key>ProgramArguments</key>
<array>
<string>/bin/zsh</string>
<string>/Users/me/camilladsp/runbkgd.sh</string>
</array>
<key>WorkingDirectory</key>
<string>/Users/me/camilladsp</string>
<key>StandardOutPath</key>
<string>/Users/me/camilladsp/camilladsp.log</string>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
Note the RunAtLoad key (without which nothing actually runs) and the StandardOutPath to set stdout the ‘right’ way. Also, the use of WorkingDirectory to make the shell scripts relocatable.
The shell script in ~/camilladsp that gets called by the PLIST startup ‘script’.
sleep 10
date >>runme.txt
echo running camilladsp >>runme.txt
while TRUE
do
./camilladsp ./configs/Crossover.yml -p 1234 --logfile ./camilladsp.log
done
The script waits 10 seconds at boot for the audio subsystem to load and then it runs camilladsp with the crossover yaml file. Since this crashes every now and then it does a KeepAlive by rerunning on crash. It’s possible to set the working directory and not need the long paths.
The CamillaDsp GUI
The CamillaDSP user interface is slick and it runs via a web browser so portable and doesn’t require you to login to the Mac. I won’t duplicate the excellent installation instructions (see the camillagui-backend).
Results
Here is the original (no woofer, no correction) frequency response curve. The low end is not accurate because of room modes and I did not do a nearfield test. Still, this music sounded like this picture — it has a serious midrange suckout and not much low-end.