Jackdaw Reverb
Jackdaw is a free, keyboard-focused Digital Audio Workstation (DAW), currently in progress. Source code and a user manual are available on github.
One of the latest additions to Jackdaw is a reverb effect, based on Julius Orion Smith III’s description1 of the famous Freeverb algorithm, by “Jezar at Dreampoint.” Jackdaw’s reverb design differs slightly from Freeverb, and the differences are described below. First, some background:
Schroeder reverberators
Manfred Schroeder and B.F. Logan laid the groundwork for what is today called a “Schroeder reverberator” in a 1961 paper titled “Colorless Artificial Reverberation.”2
Schroeder offered the first description of the entire design the following year in “Natural Sounding Artificial Reverberation.”3
A Schroeder reverberator comprises a series connection of all-pass delays4 followed by (or following5) a parallel bank of comb delays, all with “incommensurate” (typically, mutually prime) delay lengths. In Schroeder’s work, the comb delays are secondary, designed to provide frequency response fluctuations that more closely match what one would hear in a physical space. In practice, (at least in the case of Freeverb,) the parallel comb delays are really the meat of the reverb, modeling wall-to-wall echoes in a way that embodies the distinguishing characteristics of the physical space being emulated; the series all-pass delays function to increase the echo density, reducing artificial-sounding granularity or “flutter” in the reverberation. For this reason, the series all-pass section is often referred to as a “diffuser,” analogous to the physical panels used in acoustic treatment that go by the same name.
A simple low-pass filter can be placed in the feedback path of each comb delay to provide “frequency-dependent reverberation time” – that is, to cause high-frequency sounds to decay more quickly than low-frequency sounds. Real physical spaces have this acoustic property, since physical surfaces disproportionately absorb higher frequencies. The comb delay outputs can be mixed to different spatial output channels (e.g. panned in stereo) to create a more three-dimensional sound (“ambiophonic reverberation”, in Schroeder’s words).
Freeverb
Freeverb is a public-domain Schroeder reverberator with delay lengths tuned by ear by its author. Its main contribution is perhaps these specific delay lengths; the quality of Schroeder reverberators can vary substantially depending on the selection of delay lengths. It’s worth noting here that drastically different sounds can be achieved even with a single fixed set of delay lengths, by altering the comb delay coefficients. In terms of the acoustic analogy, these coefficients determine how much sound is absorbed with each reflection (think carpet vs. concrete), and how strong the low-pass filtering applied to each reflection (probably also carpet vs. concrete. I imagine that decoupling overall reflection strength from high-frequency damping is more difficult in actual acoustics, and that the ability to treat them independently is therefore a perk of algorithmic reverb).
Jackdaw reverb
Parameters
In developing an interface to a Schroeder reverberator, one has some leeway in the selection of the parameters exposed to the user, their allowed ranges, and how they affect the internals of the reverb. I made no effort to copy Freeverb or any particular Freeverb implementation in this respect.
The parameters in Jackdaw’s implementation are:
1. Decay time
Decay time is basically a proxy for the main comb
delay coefficient, which determines how loud each echo is relative
to the original sound. A coefficient value of 1.0 means that each
echo is as loud as the original, and the sound could reverberate
forever (depending on Brightness).
Coefficient values under 0.6 are almost indistinguishable from the dry input sound, and incremental variations have a greater effect as the coefficient approaches 1.0, so the raw slider value (in range 0.0 - 1.0) is mapped to more useful range:
There is also an adjustment to account for room size; at lower room sizes, in order to maintain decay time, the raw coefficient must be higher to account for more frequent accumulation.
Increasing decay time:
2. Brightness
The Brightness value is exactly the low-pass
coefficient inside each comb delay’s feedback loop. A value of 1.0
preserves high-frequency sounds and low-frequency sounds in equal
measure.
The low-pass coefficient is commonly associated with a “damping” parameter. I chose not to do this because:
- “Damping,” to me, is ambiguous: it could mean overall amplitude attenuation, or high-frequency attenuation, or some arbitrary combination of both.
- Intuitively, moving a slider to the right should result in more sound, and more high-frequency content. In other words, “damping” is the inverse of the intuitive underlying parameter (for me).
I haven’t tested other Freeverb implementations except Audacity’s6, which seems to disallow a fully “bright” configuration (i.e. a coefficient value of 1.0). Why? The sound at full brightness is acoustically unrealistic, and reveals the worst characteristics of Schroeder reverbs, but why not let the user experiment within the full range of what the algorithm is capable of?7
Increasing brightness:
3. Room size
Room size does the brute-force thing that you
would expect if you consider the reverb’s delay lengths to
represent the time it takes for sound to echo between a room’s
walls: it scales all of the delay lengths down, by a value between
0.01 and 1.0. The reverb generally sounds “best” when the
Room size slider is all the way to the right; that
is, after all, the only configuration under which those
carefully-tuned Freeverb delay lengths are heard as originally
conceived. Lower room sizes have audible resonances.
The displayed value, in square meters, is a rough approximation
based on experimentation. The fundamental resonant frequency of a
pair of parallel walls is S * 1 / 2d,8 where d is the
distance between the walls and S is the speed of
sound. The speed of sound in air is 343 m/s, so one would expect a
resonant peak at 343 m/s * (1 / 2m) == 171.5 Hz
between two walls that are 1 meter apart. So, I adjusted the raw
room size value until I was able to identify a resonant peak at
~171.5 Hz, and defined that raw value as 1 square meter. (The
calculation is in terms of distance, but I’m displaying an area in
square meters to appeal to the intuition of all of you musicians
who are also into… real estate. And the metric system.)
The maximum room size is 175.56 square meters, but you can achieve something that sounds (to me at least) like a much bigger space depending on the values of the other parameters.
Increasing room size:
4. Stereo spread
How “wide” the reverb sounds. This is covered more in the next section.
Increasing stereo spread:
5. Pre-delay
Standard pre-delay. (You can find information about reverb pre-delay online, all of which I expect to apply equally to Jackdaw’s reverb.)
Increasing pre-delay:
6. Dry / wet
How much of the original, un-altered signal is mixed in. Nothing groundbreaking here.
From 100% dry to 100% wet:
Stereo
Julius Smith’s description of Freeverb states the following:
Processing for the right channel is obtained by adding an integer to each of the twelve delay-line lengths [as compared with the left channel]. This integer is called stereospread, and its default value is 23.
I eschewed this design because – if I understand it correctly –
a high stereospread value will create a somewhat
predictable asymmetry between the channels, as opposed to
merely a decorrelation. Longer delay lengths mean that
the attenuative effects of the comb delays and low-pass filtering
will take longer to accumulate, and that therefore the right
channel will sound slightly louder and slightly brighter than the
left. This might be fine – I admittedly have not tested it – but
it was enough of a concern that I wanted to do something
different.
The way Jackdaw’s reverb handles the stereo field is more
closely aligned with Schroeder’s original “ambiophonic” design:
each comb delay output is panned to one channel or the other, with
the pan amount determined by the Stereo spread
parameter.
There’s a problem, which is that Freeverb only provides eight comb delay lengths, and if only four of the eight are heard in one channel or the other, the quality of that channel will deteriorate compared with a mono output that includes all eight.
To solve this, Jackdaw includes eight additional delay lengths, in the same range as Freeverb’s, all mutually prime with the Freeverb delay lengths and with one another.
Freeverb sums the left and right input channels and passes the sum into the reverberator as a mono input. Jackdaw instead passes the left input channel through the eight Freeverb comb delays, and the right input channel through the eight new delays, each after an all-pass diffuser section. The sixteen resulting channels are panned to the left and right output channels in new groupings, so the original stereo channels are still mixed together in the wet signal.
AP = “All-pass”, LFBC = “Low-pass feedback comb”
The numbers represent delay times in samples at 44.1kHZ. (These are scaled for Jackdaw’s native 96kHz.)
Note that combs 5-8 for each input channel are passed to the opposite output channel.
Hypothetically, since the left and right input channels are each treated with their own distinct sets of delay lengths, some information related to the stereo separation in the original mix is retained in the final wet stereo output, albeit radically transformed. But here I’m being almost superstitious.
Polarity (“Early reflections”)
On a whim, I tried reversing the polarity (sign) of every other comb delay output. This dramatically altered the sound, especially in the early part of the reverberation.
100% wet signal without polarity alternation:
100% wet signal with polarity alternation:
Note that the first version sounds much more present, and the second sounds more distant.
To understand why, we must first consider the fact that each comb delay includes an un-delayed input->output signal path. If the comb delay has been fed only silence, it will pass only an un-delayed, low-pass-filtered9 copy of its dry input until the delay length is reached and the first echo is heard. This “phantom dry” signal is precisely the audible difference; when the sign of every other comb delay’s output is inverted, the phantom dry signal (and only the phantom dry signal) is phase canceled (silenced).
The important point here is that the things that distinguish the sixteen comb delays from one another – their delay lengths – have no effect on the phantom dry signal. What you hear is the raw output of the all-pass diffuser sections, plus one round of low-pass filtering.
Is the phantom dry signal desirable, or should we phase-cancel it? If we believe that a fully wet reverb output ought to be subject in its entirety to the frequency-domain fluctuations and stereo effects of the sixteen comb delays, then we should cancel. But if the raw low-pass-filtered diffuser output is taken to represent desirable “early reflections” of the reverberator, then we should not.
I tend to find the phase-canceled version of the sound more useful, but not always, and there seems to be a small trade-off in the quality of the long reverb tail. I ultimately decided I could not give up the large class of sounds achievable only with the phantom dry signal included; hence, another parameter (“Early reflections”), which might be confusing or idiosyncratic, but that is what default values are for.
Here’s another example of a case where you would likely want to keep early reflections “off”:
50% wet, without early reflections (with polarity reversal).
With early reflections. Note the “flamminess” of the drum hits.
Two additional all-pass delays
The imperfections of Freeverb are clearest in its response to
fast transients, especially when high frequencies are allowed to
persist (a high Brightness value):
Dry finger snap followed by 100% wet, 100% bright reverb.
The audible graininess or fizzing that you hear especially in the long tail of the reverberating sound is caused by an insufficient echo density, or excessive consolidation of echoes interspersed with periods of overly sparse echoes.
Freeverb’s readme10 states:
Adding more than four all-passes doesn’t seem to add anything significant to the sound.
This holds true in most of my experimentation. However, when passing a unit impulse (a perfect “click”) through the reverberator to hear its raw impulse response, adding two additional all-pass delays at shorter delay lengths makes a significant difference (audible on headphones):
Reverb IR with 4 all-pass delays:
Reverb IR with 6 all-pass delays:
I tried adding more all-pass delays, but could not detect any audible improvement beyond the additional two.
Outside of the impulse response example, I can rarely hear a difference. However, there is a clear difference in some cases when the reverberated sound is slowed down; this suggests that the two additional all-pass delays may improve the reverberation quality in high-frequency ranges that are not audible to me. (My own hearing seems to drop off a cliff at around 15kHz.) The raw difference may or may not be audible to people with more acute hearing, but it will certainly be audible when the reverb output is subject to certain types of additional processing, including slowing it down.
The finger snap recording from above happens to be one of the few cases where I can hear the difference that these two additional all-pass delays make. Can you hear it?
Same as above, with six all-pass delays instead of four.
Reverb 2?
Schroeder reverbs are today somewhat unfavored, with their characteristic sound often derided as metallic or artificial. To my ears, the reverb effect in Jackdaw today is totally adequate for a wide range of uses. But not for every use. There are many other established reverb designs and infinite possibilities for further exploration.
I’ve done some cursory experiments with feedback delay networks (FDNs), which are fascinating, but present what to me feel like severe problems of interface design and iteration; it’s very hard to develop an intuitive connection between the properties of an FDN (particularly the mixing matrix) and the audible result. (It doesn’t help that I don’t remember any of the linear algebra I learned(?) in college, and a wrong answer to a matrix problem can blow your ears out!) Sean Costello of Valhalla DSP mentions in an excellent talk11 that FDNs are somewhat over-represented in academic literature relative to their use in industry, and points to other intriguing algorithmic reverb designs. I separately came across his post highlighting Schroeder’s nested all-pass design, which is very easy to implement and seems like it would be a lot of fun to tweak and extend.
In theory, arbitrary-length convolution is something I would only need to implement once to give users access to reverbs derived from any and every impulse response (IR) file they already have or feel inspired to create.
I could (and would be delighted to) spend years exploring this subject, of which I’ve only scratched the surface; but I have other priorities and will let it be for now.
This Jackdaw update also includes:
Mid-side processing on all effects. (A short blog post on this is forthcoming.)
You can pass a directory to the
jackdawcommand on the command line, and the program will open all of the.wavfiles found in that directory (after confirming your intention), each on its own track. This is very useful for creating a new project from a folder containing stems. E.g.:$ ./jackdaw ~/Desktop/my_song/ Load 19 stems in new project? (y/n)Significant improvements in waveform drawing
Cosmetic menu improvements; try
C-m(ctrl or cmd + m)VU-meter-style input and output levels are shown on the compressor effect, making it much easier to set a suitable makeup gain value.
The audio processing chain was refactored somewhat to handle stereo better, and this will improve overall performance on most systems.
Meta note:
My original intention for this post was to write a ground-up description of how Schroeder reverberators work, in a way that would be accessible to people with little or no knowledge of DSP (as I had, ~2 years ago). But to do it right would require more time and dedicated attention than I can give right now. I hope to be able to write that kind of thing someday.
Meta note 2:
I am no expert! If you have corrections, clarifications, or questions on anything I’ve written here, please contact me.
Julius Orion Smith III, Physical Audio Signal Processing. W3K Publishing, 2010, ISBN 978-0-9745607-2-4. Center for Computer Research in Music and Acoustics (CCRMA), Stanford University. Copyright © 2026-04-01 by Julius O. Smith III. (https://ccrma.stanford.edu/~jos/pasp/Freeverb.html)↩︎
M. R. Schroeder and B. F. Logan, “Colorless Artificial Reverberation,” IRE Transactions on Audio, vol. AU-9, pp. 209–214, Nov–Dec 1961. (https://hajim.rochester.edu/ece/sites/zduan/teaching/ece472/reading/Schroeder_1961.pdf)↩︎
M. R. Schroeder, “Natural-Sounding Artificial Reverberation,” Journal of the Audio Engineering Society, vol. 10, no. 3, pp. 219–223, 1962. (https://hajim.rochester.edu/ece/sites/zduan/teaching/ece472/reading/Schroeder_1962.pdf)↩︎
“Comb filter” and “all-pass filter” are somewhat overused and confusing terms in my opinion, because the fundamental purpose of these things in most applications (including this one) is as delay lines, not as filters; the frequency-response characteristics for which they are named are merely desired (or often incidental, in the case of comb filters) properties of a particular type of delay line.↩︎
Each of the two sections of the Schroeder reverberator is itself a linear, time-invariant (LTI) system, and LTI systems commute (can be applied in any order), at least theoretically (ignoring possible differences in the accumulation of floating point error).↩︎
Audacity Team, “Reverb,” Audacity Manual [Web page]. (https://manual.audacityteam.org/man/reverb.html)↩︎
- There’s more of an argument for limiting the range of
the
Decay timeparameter to guarantee system stability. I nevertheless allow this value to be 1.0, because it can be fun to make a sound reverberate forever, or until you pull the slider down yourself:When I write a sampling instrument, I might use something like this as one option for sustained notes.↩︎
Sengpiel Audio, “Room Modes,” Sengpiel Audio [Web page]. (https://sengpielaudio.com/RoomModes.htm)↩︎
In implementing a low-pass-feedback comb delay, one can choose to place the output path before (configuration ‘A’) or after (configuration ‘B’) the low-pass filtering, which must affect the main delay feedback path, but needn’t affect the actual output. In configuration A, an unfiltered dry signal is always included in the output. Configuration A is the more natural implementation if you were using the construct as an effect on its own, especially if you didn’t want to include a dry/wet mix parameter for a simple delay effect; the unaltered dry signal is passed through by default, plus echoes. In configuration B, the un-delayed dry signal is low-pass-filtered before being output. Configuration B is more appropriate in the context of a reverb; since the un-delayed portion of the output signal comprises all the echoes created by the all-pass delays, and those echoes are hypothetically subject to the same damping as those governed by the comb delays, they should be subject to the same low-pass filtering.↩︎
sinshu, Freeverb [Software]. GitHub. (https://github.com/sinshu/freeverb)↩︎
Seattle Music Machine Salon, Sean Costello (Valhalla DSP) on Reverb Design, March 2019 [Video]. YouTube, August 28, 2019. (https://www.youtube.com/watch?v=aJLhqfHrwsw&t=992s)↩︎