A Patch Explained
Supercollider patch from SARC gig

Exploring DSP in the feedback loop

A Patch Explained

I developed this patch for our gig at SARC, and found it really rewarding to play. It evolved without much forward planning, and now I'm trying to work out what's going on in the code. Writing this blog post is my way of trying to do this.

I’m really enjoying playing this patch; it has a huge range of dynamics and sensitivity, and also tremendous subtlety in places. The range of sounds is so wide that I didn’t need any other patches for our gig at EarZoom. In fact, I think I’m going to need to play it for a while so get a really sense of how it works, it feels like i’m only just scratching the surface of the possibilities. I’m getting an intuitive understanding of what it does through playing the instrument, but i’m only just getting a handle on what it does logically. I’m going to try and explain how it works.

This code is written in SuperCollider. It receives and augio signal from each string, and outputs two audio signals, one for the speaker and one that is sent to both transducers.

In the first section lines 2-5, functions are defined for reading the positions of the knobs on the control board. ~m maps the value into a linear range, and ~ml maps it into an exponential range.

In the second section lines 11-13, the audio signals from the four strings are read and scaled, and then mixed together. The individual levels of the signals are controllable using knobs 1-4.

The third section, lines 18-27 is the main part of the patch. Line 19 reads in the signal created earlier that is a mixture of the signals from the four strings. The code between 20-23 is an amplitude envelope follower. This follows the peak of a signal. The graph below shows the amplitude follower processing a test signal with various settings, reflecting the maximum values in the patch of 0.03 for attackTime and releaseTime.

Amplitude.ar default

Raising attackTime makes the follower less sensitive to the input, and raising releaseTime makes the effects of the input last for longer.

The patch runs four amplitude followers, one for the signal from each string. Within this, the levels of the string signals can be modified individually using knobs on the cello, and the attack and release time can also be changed from the control knobs. These signals are mixed together by taking the average of the four signals using the mean function, and the result is stored in amps.

Line 24 is taken from another patch, and in itself can provide quite a wide range of complexity. It uses the Integrator UGen which implements the formula out(0) = in(0) + (coef * out(-1)); it’s a very simple low pass filter. The graph below shows what the Integrator produces when fed the absolute values of the test signal, with coef set to 0.98, 0.90 and 0.85.. The test signal is scaled by a factor of 10 to make it more visible.

Amplitude.ar default

The patch then calculates the reciprocal of the output from the Integrator, and multiplies this by the original signal. The stages of this can be seen in the time series below:

Amplitude.ar default

It can be seen from the last time series that this line of code permanently saturates the test signal; if the signal is quiet it raises the gain, if it’s loud then it squashes the signal. The result pushes constant energy through the system, no matter the level of the input.

The patch has now calculated two signals amps and wi. Finally it combines these together in line 25, using a cross-fader, XFade2. One of the parameters for this cross-fader is pan. When this is at 1, the signal w will play; this is the unprocessed sound of the strings. When pan is set at -1, the signal wi will play; this is the saturated sound made by the Integrator. At points in-between -1 and 1, we get a mixture of these signals. The pan is controlled by the amps signal, within a range set by one of the knobs on the cello. This mapping has the effect that as the sound in the feedback system becomes louder, we get a higher mix of the natural unsaturated sound, giving two opposing systems with play against each other. At default we have the loud saturated sound, but if this rises above the threshold then the natural sound of the cello is mixed in, bringing the overall volume down (unless the system is feeding back loudly, in which case the system will stay in this state). At certain settings of the mapping range, the system starts to oscillate between the two states of saturated and unprocessed sound.

From a players experience, this patch gives a really wide range of sound. At different settings, you can have the ‘natural’ sound of the feedback cello, or the saturated version, or oscillations between the two. It’s possible to set up the system to hang in a delicate balance between the two states, such that if you lightly mute a string then it jumps into another state. It can move between very gentle feedback loops into very aggressive walls of noise. Interestingly, this complex behaviour comes from surprisingly little code, with fairly straightforward UGens; the complexity of the instrument itself mixed with these small patch provide a really expressive range of playing modes. I keep discovering new modes and behaviours of this patch, and there are probably plenty more to be revealed.

ALGORITHMS
making, technical, code, algorithm, SuperCollider