$0.00 0

YOUR CART
Checkout

SUBTOTAL
DISCOUNT
TOTAL
Checkout
In this tutorial, I hope to shed some light on the subject of the design of zero delay feedback...

In this tutorial, I hope to shed some light on the subject of the design of zero delay feedback filters, and how they work. I’ll also make a simple 1 pole pass filter based upon Vadim Zavalishin’s book in preparation for designing something more complex in a follow-up tutorial. You may recognize Zavalishin as the man behind Reaktor Core.

This tutorial relies heavily upon Zavalishin’s book. I have made an effort to condense it down to it’s most essential parts relating to zero delay feedback, and to make the material more accessible.

However, this is an advanced tutorial. It is assumed you have read and understood my previous tutorials on filter design (1, 2, 3), have a working understanding of the Reaktor Core environment, and have a decent recollection of high school algebra.

I’ll walk through the math step by step as much as I can, since in my own experience the biggest obstacle to understanding DSP papers is an expectation that the reader has a degree in engineering. It’s important to not gloss over the math in this tutorial if you wish to build your own zero delay filters.

One last thing before we start: I am a beginner in the world of zero delay feedback myself, so I apologize in advance for any inadvertant errors in this work.

WHY USE ZERO DELAY FILTERS?

One problem associated with the translation of analog filters into the digital domain is that the analog prototypes often contain a delayless loop. Zavalishin uses the following diagram of an analog one pole low pass as an example in his book:

Zero Delay Feedback Filters in Reaktor - ADSR

The ‘F’ block denotes an integrator, which is a common element in filter design.

Translating this diagram into the digital domain, we encounter a problem – in order to calculate the output, y(t), we must first calculate the input to the integrator. However, we can’t calculate the input to the integrator without first knowing the value of y(t), since the integrator takes an input value of x(t) – y(t).

A traditional way to solve this problem is to introduce a unit delay (known in core as the z^-1 module) into the feedback loop, leaving us with a digital version of the above diagram that looks like this:

Zero Delay Feedback Filters in Reaktor - ADSR

This way, we can simply subtract the previous output from the current input.

However, this creates another problem – the frequency response becomes warped, meaning the chosen cutoff point will not necessarily correspond to the actual cutoff point of the filter. The phase response will become warped as well.

Zero delay filters introduce a way to solve this problem without introducing the unit delay – leaving us with a better frequency response, and in my experience, improved behavior all around.

This graph illustrates this quite well:

Zero Delay Feedback Filters in Reaktor - ADSR

Here, the red line is the frequency response of a virtual MS-20 filter made using the bi-linear transform (I’ll make another tutorial soon on this topic) to convert from an analog prototype, by inserting a unit delay in the feedback path.

The blue line is the same filter, made using the zero delay technique, and the yellow line is the chosen frequency cutoff point. Both filters have their resonance set to max.

Notice how the zero delay version matches the cutoff point exactly, while the unit delay method is off by 2 kHz or more! Worse, the traditional version becomes unstable outside a certain frequency range, while the zero delay filter is stable across the spectrum. In the next tutorial, I will cover the creation of this filter.

INTEGRATOR TYPES

Before we can do much of anything with the filter diagram above, let’s talk about how to make a digital version of the integrator block. There are a few different ways to achieve this, but the type that seems to be favored by Zavalishin is the trapezoidal integrator (also called a bi-linear integrator), which has a Core structure that looks like this:

Zero Delay Feedback Filters in Reaktor - ADSR

Where g is a variable dependent upon the cutoff point – we will go over g in full in a bit.

Here’s where things get interesting (and potentially confusing!). We define the input of the integrator as x[n], the output as y[n], and the output of the unit delay as s[n]. Therefore, we can say that

y[n] = gx[n] + s

Or, dropping the time notation for simplicity, simply

y = gx+s

ONE POLE LOW PASS

Now, let’s look again at the one pole filter. In fig 1, the input to the integrator is x-y. The output of the filter, y[n], is taken from the output of the integrator. Thus,

y[n] = g(x[n]-y[n]) + s

Okay, so we want to solve for the output of the filter, y[n]. The trouble with the above equation is that there is a y[n] on both sides of the equation so we can’t compute one side without knowing the value of the other. We can fix this, however. Ready for a bit of math?

Using the distributive property, and dropping the [n] notation for simplicity again, we can re-write the above equation as:

y = gx – gy + s

Then we arrange the equation such that all references to y are on the same side:

y + gy = gx + s

Next, we can factor out y from the left side ( IE – y+gy = y(1+g), like the distributive property in reverse, basically), leaving us with:

y(1+g) = gx+s

And finally, solving for y, we divide both sides by (1+g), leaving:

y = (gx+s)/(1+g)

This function gives us the output of the filter! In a strange quirk, we actually had to calculate the output of the filter before calculating the input to the integrator, which happens next. Here’s how it all looks (the TPT macro is the trapezoidal integrator):

Zero Delay Feedback Filters in Reaktor - ADSR

The trapezoidal integrator macro from above has been edited to output the value of s[n]. Notice that we no longer use the other output of the integrator to control anything, since we calculated that value (y) previously – the integrator’s purpose now is to update the value of s[n] for us in preparation for the next sample.

One other thing is required to make this structure work. In the function tab of properties, the TPT macro must have it’s ‘Solid’ parameter un-selected. If ‘Solid’ is set, it will stop the value of s from being sent at the correct time. For more on this subject, please check the Core manual section 5.4 – Feedback Around Macros, starting on page 113.

This structure gives us a simple low pass response:

Zero Delay Feedback Filters in Reaktor - ADSR

CALCULATING G

Of course, none of this is worth much without a good method to control the value of g. Fortunately, this is easy. You can use two simple factory macros to do the job:

Zero Delay Feedback Filters in Reaktor - ADSR

The P2F macro should be easy to find. The Prewarp BT macro can be found inside the 6dB LP/HP EQ macro. And of course, the ‘P’ input refers to the cutoff pitch.

Our filter so far looks like this:

Zero Delay Feedback Filters in Reaktor - ADSR

CONCLUSION

There is still some further simplifications that can be made to improve this structure. Once complete, this one pole filter can be used as a building block to make more complex filters such as the MS-20 design mentioned above.

These subjects will be covered in the next tutorial, alongside a traditional version of the MS-20 filter for the sake of comparison.

As always, let me know if anything is unclear or needs to be covered in more detail.

For now, you can download a core macro of today’s work here.

RELATED COURSES

Creative Ways To Use Delay In Electronic Music

ADSR Courses

Add to cart

Creative Delays - Sound Design Course

Quantize

Add to cart

Walkthrough & Sound Design with Fabfilter Plugins

ADSR Courses

Add to cart

Delay For Electronic Producers - A Creative Guide

ADSR Courses

Add to cart
Waveform Loaded
Waveform Played
×
PLAYLIST
Clear all
WISHLISTS
Create an account to use wishlists
×
SAVE TUTORIALS
Create an account to save tutorials
×
FOLLOW YOUR FAVORITES
Follow your favourite labels, formats and genre's and ADSR will show what's new in those on your next visit.
×
  • Create product wishlist
  • Save your favorite tutorials
  • Regular discounts and exclusives
  • Never miss a sound! Follow your favorite labels.
Sign up to My ADSR to ensure you're ahead of the pack. Save your favorite content and be notified of new content. You'll never miss a thing!
Create your account now!
CREATE ACCOUNT
Sign up to My ADSR to ensure you're ahead of the pack. Save your favorite content and be notified of new content. You'll never miss a thing!
  • Get 7 days all ADSR courses free
  • Create product wishlist
  • Save your favorite tutorials
  • Regular discounts and exclusives
Create your account now!
SIGN IN
adsrsounds.com login Video streaming login
Remember me
Forgot your password?
DON'T HAVE AN ADSR ACCOUNT?
Create your account
FORGOT PASSWORD

Send info
  1. Enter your email address
  2. Click "Send info"
  3. Check your inbox for an activation link
  4. Visit activation link and enter set new password
Sign in
DON'T HAVE AN ADSR ACCOUNT?
Create your account
{"uid":-1,"ud":{"fname":"","lname":"","eml":"","vndr":0,"admin":0,"editor":0,"content":0,"coursesub":0,"uname":"","ufst":0,"sbt":0,"lua":1560880110,"ap":[]},"vf":[],"pw":[],"tu":[],"wcc":[],"wct":{"upsell_coupons":[],"applied_coupons":[],"coupon_amounts":[],"coupon_excerpt":"","subtotal":null,"total":null},"crncy":{"usd":1,"cusd":"$","eur":0.883509,"ceur":"\u20ac","gbp":0.787982,"cgbp":"\u00a3","jpy":108.359,"cjpy":"\u00a5"},"ga":null,"wplourl":"https:\/\/www.adsrsounds.com\/wp-login.php?action=logout&_wpnonce=a71a17ccd3","usmsg":"","sbswtch":[],"sbsfav":[],"sbscmpl":[],"wpt":1560909087,"pccvc":[]}