What is Brick?
Brick is an arbitrary-quality audio resampler, pitch-shifter, and format converter written and maintained by William Andrew Burnson.
I have created a simple graphic interface for Mac OS X 10.4+ Universal. If you have a different platform and are interested in using Brick, please contact me.
Brick also takes form as a console application that can be run from Terminal. I have only built binaries for Mac OS X Universal so far, but it should eventually be on Windows and Linux as well. Typical usages are:
- brick a.wav b.aiff --samplerate=44100Hz (resample at 44100Hz)
- brick a.wav b.aiff --pitchshift=3/2 (pitch shift up by a ratio of 3 to 2)
- brick a.wav b.aiff --pitchshift=+1M3.5 (pitch shift up an octave and a major third and a quarter tone)
Browse the full command-line parameter usage.
Download a presentation on sample rate conversion and Brick.
Visit the InfiniteWaves sample rate conversion comparison site. (Important: Brick's performance is beyond the scope of these tests. See notes below in Changes in 1.1 for specifics. The graphs below are far more accurate representations of the performance of Brick.)
Browse the SVN source code repository.
Changes in 1.2 (console only)
- Added stereo spectrogram support.
- Official documentation for convolution (--convolve) and filter analysis (--exportfilter).
- Fixed --acquirewisdom so that it takes a finite amount of time.
Changes in 1.1
- Added spectrogram feature (console version only)
- Added ability to convolve with another audio file using the same block convolution algorithm the resampler uses (undocumented: use --convolve=somefile.aiff)
- Added ability to export raw resample filter for the purpose of analysis and verification with Mathematica (undocumented: use --exportfilter=filterdata.fft)
- Added auto-normalization for conversions that exceed 0dB. The peak of the audio will be attenuated to exactly 0dB.
- Many minor bug fixes (none related to the core resampling algorithm) including resolution of why the InfiniteWave graphs show faint background noise.
- A now-fixed parsing error in the command-line interpreter forced an implicit conversion to 'int24' when no sample format was specified. Thus the original int32 test files were downsampled to int24 causing the expected background dither noise around -170dB. This would have been avoided merely by adding '--sampleformat=int32'.
- Verification that the InfiniteWave phase graph incorrectly shows a rise in phase. This occurs because the width of the test pulse train was more narrow than the width of the resampling filter, thus causing an overlap in the sinc-functions of the low-pass filters.
- Verification that the InfiniteWave transition band graph incorrectly shows a roll-off occuring after the the cutoff point. This again occurs due to the pulse-train width being narrower than the resampling filter. Using the above export filter feature, it can be shown using a high resolution FFT that the roll-off occurs sharply before the cutoff point as intended. See the below new graphs.
What is different about Brick?
Brick uses a different algorithm than most audio resamplers which enables it to leverage your computer's memory against your CPU's speed to get the highest-quality conversion in the least amount of time. It uses a well-known algorithm called block convolution (overlap-and-add). Brick does not use the dominant algorithm, polyphase resampling, since it has exponential tendencies for longer (higher quality) filters. In fact, it can be shown that block convolution can maintain several orders of efficiency ahead of the polyphase algorithm even when memory (eventually) runs out.
Brick's resampling has two main requirements: first, that the signal is minimally aliased and, second, that the filter operating on the signal is linear phase (the phase of your signal will not change). Brick always satisfies these requirements because it specifically designs its filters to do so. Aside from these givens, there are two knobs for quality.
- The stopband attenuation (depth) which defaults to 200dB. In general you do not need to change this because 200dB is beyond the dynamic range of all audio formats, except 64-bit double. This effectively controls the attenuation of the aliasing. Aliasing always exists, but the strength of the attenuation can bring it down below the dynamic range of the audio format.
- The transition width (bandwidth loss) which defaults to 0.1% of the destination sample rate. This refers to the bandwidth loss at the highest frequencies of the given destination sample rate. My current estimates show that existing audio resamplers have at best a 0.4% bandwidth loss. Brick allows you to lower this value as far as you like. After some point, depending on the resampling ratio, Brick will not be able to increase the size of the FFT, and resorts to a backup mode which uses shorter FFTs, but more of them. These are called passes in the program. In this mode, cutting the bandwidth loss in half results in twice the number of passes. Though this characteristic is in the end an exponential problem, it will still always require less calculation than the polyphase approach because of the aforementioned leverging of memory against time. The polyphase approach takes very little memory and makes certain assumptions that prevent it from using an FFT-based approach. Brick's FFTs are efficient but can consume a lot of memory. A 96 kHz to 44.1 kHz conversion with default settings is using a 67.1-million point FFT!
Note: that the default settings lead to conversions that can take longer with respect to conversion times you may be used to. However, given the amount of time that it takes, you are getting the highest quality conversion for a given amount of processing time (or nearly so) given processing resources. This is guaranteed by the aforementioned block-convolution algorithm. On my 2 GHz Intel Core Duo, it typically takes about 1 second for every 1 second of a mono track to do a 96 kHz to 44.1 kHz conversion. However, this speed-to-quality ratio guarantee does not apply if the operating system runs out of physical memory. Brick attempts to predict the maximum amount of memory it will be able to use, and split up very large filters into smaller filters that run in multiple passes, before your operating system starts using the swap file. If you do see your available physical memory go to zero (check Activity Monitor), Brick will probably grind to a halt. First try quitting all applications (or restarting your computer) to free up physical memory. If this does not help then try increasing the transition width (bandwidth loss) so that smaller FFTs are used.
Also important to Brick are its tools for verifying that its output is both diligent and within tolerances to the required task. The following graphs were created based on Brick's own FFT analysis of the default sample-rate conversion filter used for a 96 kHz to 44.1 kHz (0.1% bandwidth loss at 200dB stopband attenuation) conversion and are graphed using Mathematica:
And here is the new spectrogram feature (black = 0dB, white <= -255dB). These spectrograms are carefully calibrated so that the gray value of each pixel reflects the dB of attenuation. Here is a 64-bit float precise 80-second sweep from DC to Nyquist at 96 kHz converted to 44.1 kHz like above.
The same graph using the InfiniteWave color gradient (dynamic range to 180dB):
Comments, Suggestions, Bug Reports
Please send me your comments, suggestions and bug reports: email@example.com.