$0.00 0

YOUR CART
Checkout

SUBTOTAL
DISCOUNT
VAT
TOTAL
Checkout
Banner
This tutorial seeks to resolve some of the troubles associated with inserting non-linearities...

This tutorial seeks to resolve some of the troubles associated with inserting non-linearities within zero-delay feedback filters, specifically by using an iterative filter design. It builds upon my many previous tutorials on filter design, which can be found in their totality here.
THE TROUBLE WITH TANH

Adding non-linear elements to the filters introduced in the previous two tutorials (1 + 2) proves to be a pretty complicated task. Specifically, many filter designs have non-linearities within the feedback path, that are often modelled in the digital domain with tanh functions and polynomial expressions.

However, attempting to add these functions to the simple filters previously introduced results in either an overwhelming amount of math or many times will have no solution whatsoever, as far as I can tell.

Take, for example, the MS-20 filter from the previous tutorial – initially made by solving for y in the equation:

However, placing a tanh in the feedback path would mean replacing the ky values in the above equation with tanh (ky), leading to a problem with no solution (we cannot solve for y).

Similarly, adding polynomial shapers leaves us with equations that can be solved, but are extremely tedious and in my experience do not leave you with usable functions anyhow (IE the equations seem to have more than one possible solution).

This leaves us without shapers in our feedback, which kind of defeats the purpose of modelling an analog filter in the first place. There are a few different workarounds I am aware of for this problem, but let’s work on the easiest one first!

ITERATIVE FILTERS

I stumbled across the concept of iterative filters in the KVR forums, specifically in this thread here, so thanks to user Neotec for this concept.

The basic idea that he outlines is to make a filter with a unit delay in the feedback path, then to iterate through the filter several times each sample until a more or less constant feedback value is found. When the feedback is found to be constant, the output of the that filter iteration can be used as to feed the output of the filter and the unit delay in the feedback path. This basically allows the feedback to ‘catch up’ to the current time.

So, strange as it is, I modified my zero delay filter to use a delay instead! This actually saves us a substantial amount of math for each iteration of the filter, which means that the CPU hit of iterating the filter is not as bad as you might expect.

IMPLEMENTING ITERATION

For reference, here is the initial filter:

and the ZDF (Zero Delay Feedback) macro looks like this:

1 Pole Low Pass Zero Delay Feedback Filter

In this filter, we are calculating the output of the filter first, then using that value to calculate the state variables for the next iteration of the filter. In this tutorial, I’ll be modifying the structure so that we’ll simply use the feedback given to us from a unit delay holding the previous output.

This will enable us to add numerous non-linearities at will. The filter introduced in this tutorial can also handle frequency sweeps at high resonance more gracefully than the design from the previous tutorial. In general, the new filter will handle high resonance better than it’s predecessor: if carefully designed, it can allow for self oscillation, and it won’t head off into infinity if the maximum recommended resonance value is exceeded.

To implement iteration, we can strip out a substantial amount of math (all the calculations that went towards finding the value of y), and simply replace them with a new input that will supply the value of y.

The values of G, s1 and s2 need their own inputs to the filter as well, and s1 and s1 need outputs, as we will see eventually, leaving us with an overall filter structure that looks like so:

Changes have been made to the ZDF and TPT macros as well:

These changes are to accomodate the fact the S values are now coming from outside the TPT structure.

This whole structure just presented represents one iteration of our filter! Thus, we need to enclose this macro in a larger structure and have a different copy of it for each iteration.

A brief aside – Alternately, we could use an Iteration module from outside of Core to run our iterations for us, but I have found that this method is often slower than simply ‘unrolling the loop’ inside Core, which is as easy as copy/pasting a properly designed structure and linking them together.

Here is our filter, with an unrolled loop inside of Core:

And now we see the purpose for the G, s1, and s2 inputs for each macro – this way, the G value only needs to be calculated once when it changes, and the s1 and s2 values are used from the last iteration. The ‘scaling’ factor was used because I was driving this filter with very extreme values (+- 350 as opposed to the usual +-1), which can be useful for testing frequency response.

Notice that rather than comparing the feedback values each time to see if they are changing as I outlined above, here I have merely iterated through the filter 8 times. I checked this filter a variety of different ways, from 1 to 8 iterations.

Obviously, with only one iteration, we are left with the classical frequency warp problem that we implemented zero delay feedback to avoid in the first place. With each added iteration, the closer to the zero delay version we achieve, in terms of frequency response.
By the time we reach 8 iterations, the two filters are nearly identical, except of course, that our new version takes quite a bit more CPU and doesn’t even do anything different yet!

Well, fortunately, we can now implement non-linear waveshapers into our feedback loop.

Here’s how:

Now, I am fairly new to filter design, and have no idea what real non-linear feedback shaping does to a signal. So I simply added some basic known shaping functions – the effect seems subtle, however. I also read that some folks have had success saturating the s1 and s2 signals, so I tried that as well.

Here is the shaper function I used:

This section could probably use substantial improvement (such as oversampling, and a better shaping function), but we are now able to try whichever functions we like in the feedback path, while retaining the topology of the filter as before.

CONCLUSION

Download here.

This filter can still be improved upon – I have not yet had time to make the loop exit once a suitable value is found, for example, which should save a substantial amount of CPU at lower resonance settings. It’s also likely that more iterations could be added to the loop for very extreme settings.

Further, the non-linearities I added are sort of milquetoast. While researching this project, I read a comment from Urs Heckman, designer of DIVA. I can’t find it now, but he said something to the effect of “filters that only have non-linearities in the feedback path are boring.” In another thread, he hints that DIVA uses a method that combines the zero delay feedback and the iterative approaches, but I have yet to discern what is meant by this.

In any event, this filter does exhibit very favorable behavior at extreme settings, so some of you may find it useful.

RELATED COURSES

Building in Reaktor for Beginners

ADSR Courses

Add to cart

Sequencer Modules in Reaktor

ADSR Courses

Add to cart

FFT (Fast Fourier Transform) with Reaktor

ADSR Courses

Add to cart

Reaktor Core Masterclass

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 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
IMPORTANT: Is this product compatible with your system? Please check the product system requirements tab before purchasing. To proceed with this purchase you must check the box to confirm you have checked the requirements.


I have read the system requirements and agree to the return policy. I understand that refunds will not be given due to limitation of my software or operating system.

I don't agree
, you have loyalty credit available. To redeem click the button to claim !
Claim
Claim your free sounds

For every $5 you spend on ADSR receive 1 free credit for Sample Manager.

Even better, we have back-dated this so any purchases you made since 2017 have also been credited to your account!

Click the button below to claim your free credit.

Get my free credits
Loyalty credits
1Every purchase you make on ADSR* now earns you 1 loyalty credit for every $5 spent
2Once you make a purchase your credits are added to your account
3Credits can be redeemed in ADSR Sample Manager to download individual loops and samples
4To redeem simply download ADSR Sample Manager and/or log into Sample Manager with your ADSR login details
5Credits will have been automatically added to your account
6Loyalty credits expire 30 days after initial purchase
* Not including video subscriptions