Constant Folding

AudioNodes has an automated optimization process for Nodes, called constant folding. The point of this article is to help you understand how it works, and how to use it to:

  • Increase performance, allowing you to create more complex, more exciting projects without performance issues and glitching
  • Reduce power consumption, which is good for your planet, your battery (if any), and your electricity bill

What is Constant Folding?

Constant folding is a generic optimization process used by software applications, and the Wikipedia article on Constant folding summarizes it well:

Constant folding is the process of recognizing and evaluating constant expressions at compile time rather than computing them at runtime.

https://en.wikipedia.org/wiki/Constant_folding

Its point, simply put, is to avoid a situation where repeated computations would just produce the same result, over and over again (such as multiplying 2 numbers that never change), thus wasting computing power on something that doesn’t need doing.

In AudioNodes, the same principles are applied to patches, and ultimately help reduce your CPU use, battery use (if any), and enable you to create more complex patches without performance issues.


Constant Folding & Digital Signal Processing

To understand how constant folding applies to patches you create in AudioNodes, you need a basic understanding of DSP (or digital signal processing). The Wikipedia article on Digital signal processing summarizes it well:

Digital signal processing (DSP) is the use of digital processing, such as by computers or more specialized digital signal processors, to perform a wide variety of signal processing operations. The digital signals processed in this manner are a sequence of numbers that represent samples of a continuous variable in a domain such as time, space, or frequency.

https://en.wikipedia.org/wiki/Digital_signal_processing

So how does this apply to AudioNodes?

The short answer is: every Node that processes an audio/control signal in AudioNodes actually processes several thousand numbers — or samples — per second, based on your sample rate, to ultimately form a continuous signal you can hear. With a sample rate of 44100 (a common sampling rate on many systems), each Node processes 44100 samples per second (per channel, in case of non-mono signals).

A quick example of what this means: if you have 5 Gain Nodes connected in a series, and a sample rate of 44100, the Gain Nodes alone will process 220500 samples. That’s every second, and for each channel. And then you still haven’t done anything remotely interesting in your patch.

5 Gain Nodes in a chain, processing a total of 220500 samples per second at 44.1 kHz (per channel)

Of course, any modern device (including even low-end phones) will have no problem processing this, or even a hundred times this. But as your project grows and its processing complexity increases, so does the number of samples processed per second. And in many cases, many of these samples will be processed unnecessarily, with the same result over and over again.

This is where constant folding comes into play.


Constant Folding in AudioNodes

AudioNodes automatically identifies Nodes, as well as chains of Nodes, which don’t change their output over time (unless changed by hand), and optimizes them to avoid processing the exact same values every time. Take the following Nodes, for example:

The Envelope Follower Node’s internal patch, with constant folded Nodes visualized as dashed connections between them

The Clamp Node in this example, as well as every other Node leading up to the Clamp Node, output a value that doesn’t change until you either turn the Tension knob, or make some other change to these Nodes.

As a result, instead of computing the output of each these Nodes 44100 times per second, AudioNodes will only compute them once, making these Nodes 100% free when it comes to performance.


How Do I Enable Constant Folding?

That’s the neat thing, you don’t.

Constant folding automatically works in the background by identifying optimizable Nodes, all on its own. You don’t have to do anything for it to work.

However, if you have an AudioNodes HD subscription (which takes only a minute to set up, and is a really good set of bonus features on top of the base AudioNodes), you can enable an advanced setting to make constant-folded control connections appear as dashed connections. To do this:

  • Set up AudioNodes HD if you haven’t already
  • Go to the top left menu and hit Settings
  • On the left, go to Misc Settings
  • Enable Visualize constant folding

This will make constant folded connections appear as a dashed line, giving you a bit of a help to optimize your projects better. Speaking of optimizing projects…


Optimizing Your Project for Constant Folding

Like the previous section explained, you don’t have to do anything for constant folding to work. It just does its own thing automatically in the background.

However, there are a few best practices you can follow to make the most of it, and improve your project performance even further. The rule of thumb is this:

  • Try to keep a constant folded series of Nodes for as long as you can
  • If you have to mix your constant folded connection with a non-constant connection, mix them as late as possible

Take a look at this patch, for example, which outputs a signal between 0-2, multiplied by a knob:

Incorrect – a non-constant signal is mixed with a constant signal early on, breaking constant folding (as indicated by a solid connection)

Because it multiplies the knob with an LFO Node’s active signal early on, constant folding does not occur, and we need to do 2×44100 multiplications per second.

Now if you instead move the LFO Node later into this patch:

Correct – a non-constant signal is mixed with a constant signal as late as possible, enabling constant folding across multiple nodes (as indicated by the dashed connection)

In this example, the first multiplication now instead happens on a constant folded path, and thus AudioNodes now only has to do 44100 multiplications per second (when you multiply with the LFO), which is half of what we had before. A simple change, yet already a 50% performance gain.

Of course, anything remotely complex or interesting will likely take more than just swapping Nodes around. If additions were mixed into this example, then at a minimum we’d have to consider order of operations, and change some constant values accordingly.

But still, the basic principles are the same: try to keep a constant folded path for as long as you can, and you should see quick gains in performance.