Last time around, we had a look at creating a basic grain delay from scratch. It’s usable, but why stop there? Here are some improvements.
Download the latest version and dig right into the structure.
One problem you may have noticed about the first version is that the grain length control doesn’t know how the delay control is set, so it can go out of bounds. A bit of (non-scary) math is in order to set that right.
Here we see the use of an X+ module. I’ve changed the “Delay” control so it ranges from zero to 1 (actually 0.99, but close enough) in order to use an AddMovement macro I designed as a basic compound LFO. This is a habit you should pick up, by the way – work with zero to one ranges whenever possible, because they’re ridiculously easy to scale and shift around. This is exactly what happens here when the output of the LFO modified Delay control hits the X+ module.
The first port takes the value you want to multiply. The second takes the number you want to multiply it by, and the third takes the value you want to add to it. This is the best way to scale something and set its start point – think of the second port (the multiplier) as a size control. Here, we’re multiplying the zero to 0.99 range of the Delay knob with the buffer size – 1000 milliseconds. The GrainLen(gth) goes to the + port, shifting the delay point over by whatever length of grain you set. This keeps the range of the delay buffer being scanned from “falling off the edge of the world”, so to speak – what programmers call an index out of bounds error. All the error will do in this case is cause silence or intermittent silence, but still, we have a separate control for adding that deliberately if we want – the Distance knob – so there’s no need to have it occur accidentally elsewhere.
If you want to see how the controls and the X+ module interact to produce values, hook them up to some of the input ports on the Event Watcher debugging tool we discussed earlier.
Now let’s take a look inside the AddMovement LFO for the Delay value.
The heart of this macro is two LFO units whose frequencies are modified by Slow Random modules. The values are multiplied together and then multiplied by the Delay value to create a varying output. A selector crossfades between a value of 1 (Delay value therefore not modified at all) and whatever value is produced by the two LFO units. This allows you to set the degree to which the AddMovement macro modifies the Delay value. The Pos input is controlled by an XY module.
I’ve used an XY control instead of a knob or slider because it looks nicer on the panel, and it’s quick and dead easy to implement – if you’re using the X value as a control, loop it back into its input using a Merge module so you get a graphical representation of the value, and send a constant of 1 to the Y input.
If you look inside the AddMovement macro used for the Distance control, you will see that the LFO is adding to (and subtracting from, when the LFO value goes negative) the Distance control, rather than multiplying. That’s because I want the value to be greater than one sometimes, so there can be space between grains.
Now, why bother with all this LFO malarkey when there are perfectly good jitter inputs on the Cloud Delay modules that do something similar? For me it comes down to artistic preference. I find I get a more unique sound this way. Instruments that use the jitter inputs sometimes come across as a bit same-y. It depends what you’re after. If you build your own little LFO macros and whatnot, you may find yourself reusing them and modifying them all over the place in your creations – and that can give you a unique voice.
Another change is the multiplier module between the Attack control and the Att and Dec inputs on the Grain Cloud.
Why are we multiplying the value by itself? Because that creates an exponential curve – with a zero to one input (there’s that magic range again) the values swoop down to very small numbers very quickly when you turn the control down. Here’s what that curve looks like:
I’ve also added, at Eoin Rossney’s suggestion, 1 and -1 values to the Pan inputs, to get hotter signals out of the L and R outputs. Finally, two Crossfade modules are used to control the dry/wet effect mix. This is a structure you’ll be using a lot if you plan to build other effects.
With the addition of the LFOs, this becomes as much of a wind chime as an effect. If you capture a really interesting bit of audio in the buffer and set the controls just so, you’ll end up sitting back and listening to the results for some minutes. One last tip: if you’ve captured live audio and created a magic moment, you can save the audio buffer by right clicking on the waveform display on the frong panel and choosing “Save Delay Buffer”. You can’t load buffers directly, but it’s a snap to feed something back in using the looper I included in the downloadable patch last time.
What improvements do you want to add next? I’m all ears.