Joint live coding performance as Sync Union (Laila Kamil & Niklas Kleemann) using Tidal Cycles in the Troop Editor. In preparation, the track was composed, and it's sections arranged on paper. Watch the performance:
Here are some of the synth patches we used for the track, starting with the pluck synth playing the main melody:
-- trance style fm pluck
-- brightness adds harmonics
-- timbre adds detune
-- time elongates the pluck-like amp envelope
-- fx adds an upper harmonic, creating a bell like sound
fpluck brightness timbre time fx =
s "superfm"
# amp1 1
# amp2 0
# amp3 0
# amp4 0
# amp5 0
# amp6 0
# ratio1 1
# ratio2 (2.007 * (1-(timbre*10)))
# ratio3 (2.000993 * (1-(timbre*10)))
# ratio4 0.005
# mod12 (1.9 * (brightness*1.5))
# mod23 0.3
# mod34 0.9
# feedback ((brightness*0.5) + range 0.0 (fx*0.8) perlin)
# mod33 2.8
# mod44 (fx*5)
# egrate11 10
# eglevel11 1
# egrate12 (0.1993 * (((1-time)*1.75)))
# eglevel12 0.0
# egrate13 10
# eglevel13 0.0
# egrate14 10
# eglevel14 0.0
# egrate21 10
# eglevel21 1
# egrate22 (0.993 * (((1-time)*1.75)))
# eglevel22 0.0
# egrate23 2
# eglevel23 0.0
# egrate24 10
# eglevel24 0.0
# legato 2
# rel 0.9
For the fm reese bass, we also used FM synthesis:
-- REESE
-- timbre adds detune
-- fx modulates timbre
freese brightness timbre time fx
= s "superfm"
-- voices
# amp1 1
# amp2 0.8
# amp3 0.8
# cut 1
-- ratio
# ratio1 2
# ratio2 (0.99 + (timbre * 0.05))
# ratio3 1.008
-- fb
# mod11 0
# mod22 1.8
# mod33 1.6
# feedback (brightness + (range 0.0 fx perlin))
-- mod
# mod21 (0.1 + fx*0.2)
-- time (reese doesnt need time)
-- fx
# shape 0.3
# triode 2
For the counter melody, I designed an analog-sounding synth voice in SuperCollider:
// "25midi - Aura" pluck style synth voice
(
SynthDef(\aura, {
|out, att=0, dec=0, sus=0.5, rel=0.7, curve=0, lfo=0.7, detune=0.2, vcut=1.0, vcutmx=0.5, vfx=0, sustain, pan, freq|
var phaserEffect;
// AMP ENV
var begin = Impulse.ar(0);
var env = EnvGen.ar(
Env.adsr(att, dec, sus, rel, 1, curve),
Trig.ar(begin, sustain-rel));
// OSC
var pwmMOD = LFTri.kr(lfo);
var sound = (Pulse.ar(freq, pwmMOD*detune + 0.2) ! 2);
// FILTER ENV
// first, remap vcutmix so we only get values between 0-1
var remappedVCutMx = vcutmx.clip(0.0, 1.0);
// create filter envelope, use vcutmx to mix the envlope in/out
var filtEnv = XLine.kr(1.0, remappedVCutMx.linexp(0.0, 1.0, 1.0, 0.01), rel, doneAction: 2); // vcutmx scales the envolope
// set the the envlope strength 0=full pluck, 1=open
var remappedVCut = vcut.clip(0.0, 1.0).linlin(0.0, 1.0, 0.01, 0.99); // Remap vcut values to [0.01, 0.99]
sound = LPF.ar(sound, 20000*remappedVCut*filtEnv.linlin(0.0, 1.0, 0.0, remappedVCut));
sound = sound * env;
phaserEffect = AnalogPhaser.ar(
sound,
SinOsc.ar(0.22),
skew: SinOsc.kr(0.059),
feedback: SinOsc.kr(0.005, 1pi).range(0.0,0.85),
modulation: SinOsc.kr(0.0192, 2pi).unipolar,
stages: 50
);
sound = XFade2.ar(sound, phaserEffect, 2 * vfx - 1); // Blend/mix the dry/chorus signal based on vfx
// adjust vol down a bit in relation to other sounds
sound = sound*0.7;
// OUT
OffsetOut.ar(out, DirtPan.ar(sound, ~dirt.numChannels, pan));
}).add;
~dirt.soundLibrary.addSynth(\aura,
(instrument:\aura, att:0, dec:1, rel:1, legato:1, sustain: {
(~delta*~legato).max(~att+~dec)+~rel}));
);