User:Hpyle
From DRC
Contents |
SlimServer Room Correction
There's no point in storing music on anything other than a big hard disk.
The Squeezebox/Tranporter model is an interesting playback architecture: a small networked device with enormous attention to audio detail.
One of the reasons this system is so nice is its flexiblity. The server is separate from playback; and the server is extensible. What better use of all that spare CPU, than running long FIR filters? So, here we are.
This started as some tinkering with DRC and C# in an attempt to make my cheapish home system sound better than it rightfully should. A year and more later, inguz audio (..."out comes music", heh) is a pretty stable and robust piece of software with several dozen happy users on Windows, Linux and Mac.
Components
My home system has four components:
- Just one source, the Slim Devices Transporter;
- PC running SlimServer on Windows, with my convolver and plugin;
- Self-built four-channel LM3886 power amplifier;
- Bi-amped speakers: Klipschorn bass bins, JBL 2350 horns with 2441 drivers, BC125 tweeters, and a flying aspidistra or two to round off the aesthetics.
Room measurement using Behringer ECM8000 and Tascam US-122, USB to laptop. The DSP plugin produces log-sweeps; recorded stereo via the Tascam and laptop. Then the sweeps are processed to produce the impulse response, using a utility which also wraps execution of DRC and creates a set of correction filters without needing to mess around with config files. Sweeps in, filters out.
Filter processing happens in "real-time", by inserting a convolver in the SlimServer transcoding pipeline. SlimServer decodes each track to a WAV stream on the PC as it's queued up to play; then piped through my convolver, then sent as 24-bit FLAC to the Squeezebox. There's no need to store a processed version of the music; convolution happens on-the-fly. Latency is not at all important; there's maybe a half-second delay between pressing "Play" and music starting.
Convolver
The processor is in two parts:
- "InguzDSP", a general-purpose convolver and filter processor; and
- "InguzEQ", a SlimServer plugin, which lets you configure things using the SqueezeBox remote control.
The plugin (written in perl) has oodles of options: EQ in up to nine bands, Balance, Width, Flatness, Quietness, Presets, and room correction filter selection. It's maybe a little too full-featured, but I like it. The plugin simply writes a series of XML configuration files corresponding to the chosen settings.
Then the convolver (written in C#) looks for configuration files in this format, and processes the signal accordingly. Equalization (tone controls, flatness and quietness) are implemented by building fairly long (usually 8192-tap) FIR filters on-the-fly, with gentle cosine shelves between the user's chosen frequency/gain parameters.
Provided you have enough hardware, the plugin and processor will support multiple squeezeboxes each with individual room correction and equalization filters. For a single squeezebox, it needs about a 2GHz PC with 512MB RAM, Windows XP (or linux, OSX, etc), and .NET Framework 2.0 or Mono 1.2. With my own 3GHz/1GB main machine, the convolver uses around 6% CPU when active.
Gain control is automatic, loudness-based. A config file specifies a default attenuation (-6.02dB is a good choice which gives enough headroom for most situations). Before processing, or anytime the filter parameters change, the convolver analyzes the filter chain to calculate the gain for equivalent loudness to a no-op filter. This way, the room correction filter doesn't need to be specially normalized, you can use any stereo WAV; there aren't any sudden surprises when EQ settings change; and most combinations of source material and filters stay comfortably below clip. The convolver adjusts gain down by a half-dB if the output ever hits digital clipping, and resets at the start of the next track.
The DSP has a few other features: Ambisonic B-format downmix to UHJ stereo, and cross-feed for Stereo Dipole, enhanced stereo image width, or headphone/binaural listening.
Prep Tools
Measuring your room and creating a DRC filter is quite a laborious affair. I don't think room correction will be widely adopted until this barrier is removed.
I'm really happy using DRC filters with a "flat" target curve. But this is not a good choice for first-time users; if you're used to an uncorrected system and correct to flat response, a lot of the dynamics seem to be removed, making the sound "lifeless" in comparison (more precise, tighter, but less lively). The soundstage definitely recedes from appearing to fill the room, to sit between the loudspeakers.
So I build a series of target curves automatically, based on the measured response. The "start here" target is a fairly close match to the system's actual frequency response, smoothing out some of the nasties but retaining lots of the character which you're used to (even if that means an overblown bass or peaky mid). For a first-time user of room correction this is much more acceptable, since the tonal character remains familiar while the correction improves tautness and soundstage positioning. Then a "middle-road" correction target should be a flattened version (but not completely flattened); after listening to the un-flattened target for a while, you're likely to prefer this one. Finally a near-truly-flat target, and equalization options to adjust for personal preference. This all ends up as a single menu on the squeezebox: "Flatness", from zero to ten.
( - - quietness too - - )
( - - insert more stuff here - - )
My measurement-preparation package, "ImpulsePrep", is a first run at a more automated process. It takes raw measurements, and turns them into a set of three correction filters: "normal", "soft" and "strong", corresponding to the three standard DRC configuration files.
( - - insert more stuff here - - )
How this works with SlimServer
SlimServer doesn't really have a "audio bits pipeline" in the way most soundcard-based software would. It has a fairly clunky, but flexible enough, "transcoding" system which pipes raw audio to external helper applications if it needs to convert into file formats which the SqueezeBox player understands natively. (SB2 and SB3 support at least WAV, MP3, FLAC and WMA, so there's rarely any need to transcode, unless you like OGG or APE). Anyhow; my convolver is inserted into this pipeline by forcing everything to transcode to WAV first. So the transcode line for FLAC looks like this:
[flac] -dcs --force-raw-format --endian=little --sign=signed --skip=$START$ --until=$END$ -- $FILE$ | [InguzDSP]
The convolver (InguzDSP) is executed once per track, reads 16-bit RAW on stdin, convolves, quanitizes and dithers, sending 24-bit RAW to stdout. This is then encoded again to FLAC (to save bandwidth) for streaming to the Squeezebox.
For live albums and other situations where you need gapless playback, this one-instance-per-track model presents a little challenge: the convolved file has a reverberation tail which isn't present in the source, and should wrap around to the beginning of the next track. So my convolver often writes its leftovers to disk and picks them up next time it runs.
The transcoding structure should let you use just about any filter processor which can read and write RAW on stdin/stdout. For example, on linux, brutefir sounds like a really good option. The "gapless convolution" process is quite important, though (otherwise you get a break between tracks and might lose the last fraction of a second of each track); I don't think brutefir has this option. Also, I don't know whether brutefir can create arbitrary EQ filters. There's an early wikipage documenting the brutefir-plus-SlimServer setup.
Next steps
It sounds pretty darn good. The electronics are really high quality (Transporter is very fine) and the room is fairly well treated (unobtrusively) even before correction. But there's always more tinkering to be done...
The next direction on this journey I think is toward multi-channel. The Klipschorn-based speakers could really use active crossovers for time compensation, and that needs at least four channels. And why stop there? It would be kinda fun to set up a fill-periphonic Ambi rig with eight channels... who knows...
