page.layout: post page.title: Strikes and Resonance page.date: 2021-06-20 00:00:00 +0000 page.url ⛓️: /2021/06/20/1-filter-ping-sc/ page.content_id: 5 page.author: Ryan page.type: Praxis page.ascii: + page.x: 2 page.y: 2 page.class: red page.attributes: filter, resonance, comb, karplus-strong
Pinging resonant bandpass, low pass, or high pass filters creates a sine-like ringing as the filter sculpts an incoming peak into its native rippling, just as the surface of a pond does to sudden interruption by a rock. The relationship of a quick strike agitating a vibrating, ringing body can be found in abundance elsewhere in the physical and sonic universe.
SuperCollider Example One: Two sides of a coin
Here is an example in SuperCollider of a pinged filter alongside a simple Karplus-Strong model. The two filters differ both in ringing and excitation. The mix between is controlled by the X-axis of the mouse, so the further left, the more bandpass filter, and the less the comb filter.
({
// variables
var trig, note, env, fade, bpf, comb;
// rhythm: 8th notes @ 120bpm
trig = Impulse.kr(4);
// note: randomly, from a scale
note = Demand.kr(trig: trig,
reset: 0,
demandUGens: Drand(
list: [48,60,72] +.x [0,2,7,9], // 3 octaves
repeats: inf));
// exciter: a simple, fast envelope
env = EnvGen.ar(
envelope: Env.perc(
releaseTime: 0.01,
level: 50,
curve: 0),
gate: trig);
// mix control: mouse
fade = MouseX.kr(minval: 0, maxval: 1);
// filters: bandpass + comb
bpf = Resonz.ar(
in: env,
freq: note.midicps,
bwr: 0.01, // lower is ringier
mul: (1 - fade) * 5).tanh; // soft clip
comb = CombL.ar(
in: env * PinkNoise.ar(0.03),
delaytime: note.midicps.reciprocal,
decaytime: 0.5,
mul: fade * 0.2);
// output: sum, remove bias, stereoize
LeakDC.ar(bpf + comb) ! 2
}.scope);
SuperCollider Example Two: Geometric Ripples
This example uses the same filter types, but there are some important differences:
- The bpf is now in serial before the comb.
- The comb is now tuned statically to 55Hz.
- The bpf now plays harmonics of 55Hz.
({
// variables
var trig, harmonic, env, bpf, comb;
// rhythm: 8th notes @ 120bpm
trig = Impulse.kr(4);
// harmonics: random from 1 to 12
harmonic = Demand.kr(trig: trig,
reset: 0,
demandUGens: Diwhite(lo: 1, hi: 12, length: inf));
// exciter: a simple, fast envelope
env = EnvGen.ar(
envelope: Env.perc(
releaseTime: 0.001,
level: 50,
curve: 0),
gate: trig);
// filters: bandpass, comb
bpf = Resonz.ar(
in: env,
freq: 55 * harmonic,
bwr: 0.1,
mul: 0.2
);
comb = CombL.ar(
in: bpf,
delaytime: 55.reciprocal,
decaytime: 1);
// output: soft-clip, remove bias, stereoize
LeakDC.ar(comb).tanh ! 2
}.scope);
SuperCollider Example Three: Simple Allpass Reverb
This example is quite a bit different from the other two. Now, the tuning is completely random, and instead of a bandpass or comb filter, we have 10 allpass filters. This creates a primitive reverb. As in the first example, the mouse X axis controls the audio - this time, it is the maximum length of the allpass delay, as sampled each strike.
This sounds much different from the previous two but is another example of a strike exciting a resonator to create a percussive sound with a natural decay.
({
// variables
var trig, reverb, maxTime;
// rhythm: once every four seconds
trig = Impulse.kr(1/4);
// maxTime: sampled on each strike
maxTime = MouseX.kr(minval: 0.001, maxval: 0.2, warp: 1);
// filters: allpass
reverb = Mix.ar(((1..10)).collect({
var delayTime = Demand.kr(
trig: trig,
reset: 0,
demandUGens: Dwhite(lo: 0.01, hi: maxTime));
var pan = Demand.kr(
trig: trig,
reset: 0,
demandUGens: Dwhite(lo: -1, hi: 1));
var filter = AllpassC.ar(
in: trig,
delaytime: delayTime,
decaytime: 4);
Pan2.ar(in: filter, pos: pan, mul: 2);
}));
// amplify
reverb = reverb * 5;
// output: mix, soft clip
(reverb + trig).tanh;
}.scope);
Observations
- How do the filters’ timbre differ?
- How do the filters’ low/high end differ?
- How do the filters’ dynamics differ?
- How does their behavior change based on frequency?
- How does seeing or hiding the scope feel different?
- What other configurations come to mind?