Shifting Veil

supercollider
// 1. Define SynthDef and write to disk
SynthDef(\shiftingVeil, { |freq = 440, amp = 0.5, detune = 0, lfoRate = 0.5, lfoDepth = 10, gate = 1|
    var env = EnvGen.ar(Env.perc(0.01, 2, -3), gate, doneAction: 2);
    var lfo = LFSaw.ar(lfoRate);
    var detunedFreq = freq + (lfo * lfoDepth * detune);
    var sig1 = SinOsc.ar(detunedFreq, 0, 0.5);
    var sig2 = SinOsc.ar(detunedFreq * 1.01, 0, 0.4);
    var sig3 = SinOsc.ar(detunedFreq * 0.99, 0, 0.3);
    var mixed = (sig1 + sig2 + sig3) * env * amp * 0.3;
    var filtered = LPF.ar(mixed, 8000);
    Out.ar(0, filtered ! 2);
}).writeDefFile;

// 2. Build Score with ONLY explicit [time, message] pairs
Score([
    [0.0, [\s_new, \shiftingVeil, 1001, 0, 0, \freq, 261.63, \amp, 0.5, \detune, 0.5, \lfoRate, 0.3, \lfoDepth, 15]],
    [15.0, [\n_set, 1001, \gate, 0]],
    [60.0, [\c_set, 0, 0]]
]).recordNRT(
    outputFilePath: "~/shiftingVeil.wav".standardizePath,
    headerFormat: "WAV",
    sampleFormat: "int16",
    sampleRate: 44100,
    options: ServerOptions.new.numOutputBusChannels_(2),
    duration: 60,
    action: { 0.exit }
);
textural densityslow modulation detuned oscillatorsharmonic/dissonant boundary rhythmic implicationsfrom explicit percussion to implied rhythm how much detuning is too much exploring filter modulation