random stuff
parent
53018120f4
commit
f4aabcc61f
@ -0,0 +1,174 @@
|
|||||||
|
// ===================================================
|
||||||
|
// SuperCollider: GrainFM Examples and Use Cases
|
||||||
|
// ===================================================
|
||||||
|
|
||||||
|
// Load this file into SuperCollider and evaluate each section as needed
|
||||||
|
|
||||||
|
// ---------------------------------------------------
|
||||||
|
// 1. Tonal Ambient Pad (Stable Pitch, Gentle Movement)
|
||||||
|
// ---------------------------------------------------
|
||||||
|
(
|
||||||
|
SynthDef(\grainFMPadClean, {
|
||||||
|
|out=0, freq=440, amp=0.3, dur=10|
|
||||||
|
var trig = Impulse.kr(15); // grains per second
|
||||||
|
var snd;
|
||||||
|
|
||||||
|
snd = GrainFM.ar(
|
||||||
|
numChannels: 2,
|
||||||
|
trigger: trig,
|
||||||
|
dur: 0.2,
|
||||||
|
carfreq: freq,
|
||||||
|
modfreq: freq * 2, // simple ratio
|
||||||
|
index: 1.5,
|
||||||
|
pan: LFNoise1.kr(0.2),
|
||||||
|
envbufnum: -1
|
||||||
|
);
|
||||||
|
|
||||||
|
snd = snd * EnvGen.kr(Env.linen(1, dur-2, 1), doneAction: 2) * amp;
|
||||||
|
Out.ar(out, snd);
|
||||||
|
}).add;
|
||||||
|
)
|
||||||
|
|
||||||
|
// Example usage:
|
||||||
|
Synth(\grainFMPadClean, [\freq, 330, \dur, 12]);
|
||||||
|
|
||||||
|
// ---------------------------------------------------
|
||||||
|
// 2. Cloudy Texture (Randomized Frequencies)
|
||||||
|
// ---------------------------------------------------
|
||||||
|
(
|
||||||
|
SynthDef(\grainFMCloud, {
|
||||||
|
|out=0, amp=0.2, dur=8|
|
||||||
|
var trig = Dust.kr(25);
|
||||||
|
var freq = TExpRand.kr(200, 800, trig);
|
||||||
|
var snd;
|
||||||
|
|
||||||
|
snd = GrainFM.ar(
|
||||||
|
numChannels: 2,
|
||||||
|
trigger: trig,
|
||||||
|
dur: 0.1,
|
||||||
|
carfreq: freq,
|
||||||
|
modfreq: freq * 1.5,
|
||||||
|
index: TRand.kr(1, 10, trig),
|
||||||
|
pan: TRand.kr(-1, 1, trig),
|
||||||
|
envbufnum: -1
|
||||||
|
);
|
||||||
|
|
||||||
|
snd = snd * EnvGen.kr(Env.linen(1, dur-2, 1), doneAction: 2) * amp;
|
||||||
|
Out.ar(out, snd);
|
||||||
|
}).add;
|
||||||
|
)
|
||||||
|
|
||||||
|
Synth(\grainFMCloud);
|
||||||
|
|
||||||
|
// ---------------------------------------------------
|
||||||
|
// 3. Evolving Drone (Slow Modulation of Grain Rate & Pitch)
|
||||||
|
// ---------------------------------------------------
|
||||||
|
(
|
||||||
|
SynthDef(\grainFMEvolvingDrone, {
|
||||||
|
|out=0, baseFreq=100, amp=0.3, dur=20|
|
||||||
|
var trig = Impulse.kr(LFNoise1.kr(0.1).range(5, 30));
|
||||||
|
var freq = LFNoise1.kr(0.05).range(baseFreq, baseFreq * 4);
|
||||||
|
var modfreq = freq * LFNoise1.kr(0.02).range(0.5, 2);
|
||||||
|
var snd;
|
||||||
|
|
||||||
|
snd = GrainFM.ar(
|
||||||
|
numChannels: 2,
|
||||||
|
trigger: trig,
|
||||||
|
dur: 0.15,
|
||||||
|
carfreq: freq,
|
||||||
|
modfreq: modfreq,
|
||||||
|
index: 3,
|
||||||
|
pan: LFNoise1.kr(0.3),
|
||||||
|
envbufnum: -1
|
||||||
|
);
|
||||||
|
|
||||||
|
snd = snd * EnvGen.kr(Env.linen(2, dur-4, 2), doneAction: 2) * amp;
|
||||||
|
Out.ar(out, snd);
|
||||||
|
}).add;
|
||||||
|
)
|
||||||
|
|
||||||
|
Synth(\grainFMEvolvingDrone);
|
||||||
|
|
||||||
|
// ---------------------------------------------------
|
||||||
|
// 4. Percussive Metallic Hits
|
||||||
|
// ---------------------------------------------------
|
||||||
|
(
|
||||||
|
SynthDef(\grainFMHit, {
|
||||||
|
|out=0, freq=400, amp=0.4|
|
||||||
|
var trig = Impulse.kr(1);
|
||||||
|
var snd;
|
||||||
|
|
||||||
|
snd = GrainFM.ar(
|
||||||
|
numChannels: 2,
|
||||||
|
trigger: trig,
|
||||||
|
dur: 0.05,
|
||||||
|
carfreq: freq,
|
||||||
|
modfreq: freq * 3,
|
||||||
|
index: 12,
|
||||||
|
pan: 0,
|
||||||
|
envbufnum: -1
|
||||||
|
);
|
||||||
|
|
||||||
|
snd = snd * EnvGen.kr(Env.perc(0.01, 0.3), doneAction: 2) * amp;
|
||||||
|
Out.ar(out, snd);
|
||||||
|
}).add;
|
||||||
|
)
|
||||||
|
|
||||||
|
Synth(\grainFMHit);
|
||||||
|
|
||||||
|
// ---------------------------------------------------
|
||||||
|
// 5. Blending with a Pure Tone (Stable Pitch)
|
||||||
|
// ---------------------------------------------------
|
||||||
|
(
|
||||||
|
SynthDef(\grainFMWithTone, {
|
||||||
|
|out=0, freq=440, amp=0.3, dur=10|
|
||||||
|
var trig = Impulse.kr(20);
|
||||||
|
var grain = GrainFM.ar(2, trig, 0.15, freq, freq * 2, 2, LFNoise1.kr(0.2), -1);
|
||||||
|
var tone = SinOsc.ar(freq) * 0.1;
|
||||||
|
var sig = Mix([grain, tone]);
|
||||||
|
|
||||||
|
sig = sig * EnvGen.kr(Env.linen(1, dur-2, 1), doneAction: 2) * amp;
|
||||||
|
Out.ar(out, sig);
|
||||||
|
}).add;
|
||||||
|
)
|
||||||
|
|
||||||
|
Synth(\grainFMWithTone);
|
||||||
|
|
||||||
|
// ---------------------------------------------------
|
||||||
|
// 6. MIDI-Controlled GrainFM Synth (For Sequencing)
|
||||||
|
// ---------------------------------------------------
|
||||||
|
(
|
||||||
|
SynthDef(\grainFMMidi, {
|
||||||
|
|out=0, freq=440, amp=0.3, gate=1|
|
||||||
|
var trig = Impulse.kr(10);
|
||||||
|
var snd;
|
||||||
|
|
||||||
|
snd = GrainFM.ar(
|
||||||
|
numChannels: 2,
|
||||||
|
trigger: trig,
|
||||||
|
dur: 0.2,
|
||||||
|
carfreq: freq,
|
||||||
|
modfreq: freq * 2,
|
||||||
|
index: 2,
|
||||||
|
pan: LFNoise1.kr(0.2),
|
||||||
|
envbufnum: -1
|
||||||
|
);
|
||||||
|
|
||||||
|
snd = snd * EnvGen.kr(Env.asr(0.01, 1, 1), gate, doneAction: 2) * amp;
|
||||||
|
Out.ar(out, snd);
|
||||||
|
}).add;
|
||||||
|
)
|
||||||
|
|
||||||
|
(
|
||||||
|
MIDIIn.connectAll;
|
||||||
|
|
||||||
|
~grainFMResponder = NoteOnResponder({
|
||||||
|
|src, chan, num, vel|
|
||||||
|
var freq = num.midicps;
|
||||||
|
Synth(\grainFMMidi, [\freq, freq, \amp, vel/127]);
|
||||||
|
});
|
||||||
|
)
|
||||||
|
|
||||||
|
// ---------------------------------------------------
|
||||||
|
// You can now play GrainFM like an instrument from a MIDI controller!
|
||||||
|
// ---------------------------------------------------
|
||||||
@ -1,91 +0,0 @@
|
|||||||
(
|
|
||||||
// ========== Spectral SynthDef with expanded modulation ==========
|
|
||||||
SynthDef(\pv16knob, {
|
|
||||||
arg bufnum, fftSize = 1024,
|
|
||||||
amp = 0.3, smearAmt = 5, randRate = 6, binScrambleAmt = 0.5,
|
|
||||||
pvRouting = 0, grainSize = 0.1,
|
|
||||||
delTime = 0.3, delFeedback = 0.4, verbMix = 0.2,
|
|
||||||
lfoFreq = 0.2, bitcrushAmt = 0.0, distAmt = 1.0,
|
|
||||||
ringFreq = 200, freezeAmt = 0.5,
|
|
||||||
transpose = 1.0, filterCutoff = 8000;
|
|
||||||
|
|
||||||
var in, chain, lfo, dry, fx, delay, verb;
|
|
||||||
var chain0, chain1, chain2, chain3, chain4;
|
|
||||||
|
|
||||||
// Audio input and bitcrushing
|
|
||||||
in = PlayBuf.ar(1, bufnum, BufRateScale.kr(bufnum) * transpose, loop: 1);
|
|
||||||
in = Decimator.ar(in, (1 - bitcrushAmt).linexp(0, 1, 44100, 1000), 8 - (bitcrushAmt * 7));
|
|
||||||
|
|
||||||
// FFT
|
|
||||||
chain = FFT(LocalBuf(fftSize), in);
|
|
||||||
lfo = SinOsc.kr(lfoFreq).range(0.1, 1.0);
|
|
||||||
chain = PV_MagFreeze(chain, freezeAmt);
|
|
||||||
|
|
||||||
// Spectral branches
|
|
||||||
chain0 = PV_BinScramble(PV_MagSmear(PV_RandComb(chain, 0.1, Impulse.kr(randRate)), smearAmt + lfo), binScrambleAmt, 0);
|
|
||||||
chain1 = PV_BrickWall(chain, lfo.range(0.05, 0.2));
|
|
||||||
chain2 = PV_BinShift(chain, lfo * 20, 0.5);
|
|
||||||
chain3 = PV_BinWipe(chain, lfo);
|
|
||||||
chain4 = PV_SpectralEnhance(chain, 0.8, 1.5, 0.2);
|
|
||||||
|
|
||||||
// Select
|
|
||||||
chain = SelectX.kr(pvRouting.clip(0, 4), [chain0, chain1, chain2, chain3, chain4]);
|
|
||||||
dry = IFFT(chain);
|
|
||||||
|
|
||||||
// Post-PV grain
|
|
||||||
dry = TGrains.ar(2, Impulse.ar(20), bufnum, 1, Phasor.ar(0, 1, 0, BufFrames.ir(bufnum)), grainSize, 0, 0.1, 1);
|
|
||||||
dry = Ringz.ar(dry, ringFreq, 0.2);
|
|
||||||
dry = (dry * distAmt).tanh;
|
|
||||||
dry = LPF.ar(dry, filterCutoff);
|
|
||||||
|
|
||||||
// FX
|
|
||||||
delay = CombC.ar(dry, 1, delTime, delFeedback);
|
|
||||||
verb = FreeVerb.ar(dry, verbMix, 0.8, 0.3);
|
|
||||||
|
|
||||||
// Mix and output
|
|
||||||
fx = Mix([dry, delay, verb]);
|
|
||||||
Out.ar(0, fx.dup * amp);
|
|
||||||
}).add;
|
|
||||||
)
|
|
||||||
|
|
||||||
(
|
|
||||||
// ========== Load buffer ==========
|
|
||||||
b = Buffer.read(s, Platform.resourceDir +/+ "sounds/a11wlk01.wav"); // Use your own file if you want
|
|
||||||
)
|
|
||||||
|
|
||||||
(
|
|
||||||
// ========== Instantiate synth ==========
|
|
||||||
~pvSynth = Synth(\pv16knob, [\bufnum, b]);
|
|
||||||
)
|
|
||||||
|
|
||||||
(
|
|
||||||
// ========== MIDI CC Mapping (channel 2) ==========
|
|
||||||
[
|
|
||||||
[\amp, 0, 0.0, 1.5],
|
|
||||||
[\smearAmt, 1, 1, 40],
|
|
||||||
[\randRate, 2, 0.5, 20],
|
|
||||||
[\binScrambleAmt, 3, 0.0, 1.0],
|
|
||||||
[\pvRouting, 4, 0, 4],
|
|
||||||
[\grainSize, 5, 0.01, 0.2],
|
|
||||||
[\delTime, 6, 0.05, 1.0],
|
|
||||||
[\delFeedback, 7, 0.0, 0.95],
|
|
||||||
[\verbMix, 8, 0.0, 1.0],
|
|
||||||
[\lfoFreq, 9, 0.01, 5.0],
|
|
||||||
[\bitcrushAmt, 10, 0.0, 1.0],
|
|
||||||
[\distAmt, 11, 0.5, 10.0],
|
|
||||||
[\ringFreq, 12, 50, 2000],
|
|
||||||
[\freezeAmt, 13, 0.0, 1.0],
|
|
||||||
[\transpose, 14, 0.25, 2.0],
|
|
||||||
[\filterCutoff, 15, 100, 15000]
|
|
||||||
].do { |spec|
|
|
||||||
var param, cc, min, max;
|
|
||||||
#param, cc, min, max = spec;
|
|
||||||
|
|
||||||
MIDIdef.cc(param.asSymbol, { |val, num, chan, src|
|
|
||||||
if(chan == 2) {
|
|
||||||
var mapped = val.linlin(0, 127, min, max);
|
|
||||||
~pvSynth.set(param, mapped);
|
|
||||||
}
|
|
||||||
}, cc);
|
|
||||||
};
|
|
||||||
)
|
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
(
|
||||||
|
SynthDef(\sineCC, {
|
||||||
|
var freq = \freq.kr(440);
|
||||||
|
var sig = SinOsc.ar(freq) * 0.1;
|
||||||
|
Out.ar(0, sig ! 2);
|
||||||
|
}).add;
|
||||||
|
)
|
||||||
|
|
||||||
|
~sine = Synth(\sineCC);
|
||||||
|
|
||||||
|
(
|
||||||
|
~ccToFreq = MIDIdef.cc(\ccFreqControl, {
|
||||||
|
arg val, num, chan, src;
|
||||||
|
|
||||||
|
if (chan == 0 and: { num == 0 }, { // channel 2 = index 1
|
||||||
|
var freq = val.linexp(0, 127, 100, 2000); // map CC value to frequency range
|
||||||
|
~sine.set(\freq, freq);
|
||||||
|
("CC " ++ num ++ " = " ++ val ++ " → freq: " ++ freq).postln;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
)
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,81 @@
|
|||||||
|
(
|
||||||
|
// PARAMETERS
|
||||||
|
~musicalParams = (
|
||||||
|
scale: Scale.minor,
|
||||||
|
key: 0,
|
||||||
|
progressionSeed: 0,
|
||||||
|
bpm: 90
|
||||||
|
);
|
||||||
|
|
||||||
|
// BASIC CHORD PROGRESSION (Golden Age Cantorial Style with chaotic tunings)
|
||||||
|
~makeProgression = { |seed|
|
||||||
|
var chords = [
|
||||||
|
[0, 3, 7], // I (minor)
|
||||||
|
[2, 5, 9], // ii (minor)
|
||||||
|
[4, 8, 11], // III (augmented)
|
||||||
|
[5, 9, 0], // IV (major)
|
||||||
|
[7, 11, 2, 5], // V7 (dominant seventh)
|
||||||
|
[9, 0, 4], // vi (major)
|
||||||
|
[11, 2, 5], // vii° (diminished)
|
||||||
|
[0, 4, 7, 10], // I augmented (dramatic effect)
|
||||||
|
[3, 6, 10], // iv (minor)
|
||||||
|
[6, 9, 1, 4], // V7 (dominant seventh)
|
||||||
|
[0, 3, 7], // Freygish I (minor)
|
||||||
|
[2, 5, 9], // Freygish ii (minor)
|
||||||
|
[7, 10, 2, 5], // Freygish V7 (dominant seventh)
|
||||||
|
[0, 4, 7], // Double Harmonic I (major)
|
||||||
|
[5, 9, 0], // Double Harmonic IV (major)
|
||||||
|
[7, 11, 2, 5], // Double Harmonic V7 (dominant seventh)
|
||||||
|
[0, 2, 6, 9], // Dissonant I chord (almost suspended, unstable)
|
||||||
|
[3, 5, 8], // Flat VI (minor)
|
||||||
|
[7, 10, 1], // Inverted V7
|
||||||
|
[1, 4, 8], // Added dissonance with suspended 2nd and 5th
|
||||||
|
[5, 9, 12], // Augmented 4th (tense)
|
||||||
|
[1, 6, 10], // Major 7th on a diminished scale (creates tension)
|
||||||
|
[0, 7, 4], // Unconventional I chord (doesn't resolve)
|
||||||
|
[8, 11, 4] // Diminished 5th (added dissonance)
|
||||||
|
];
|
||||||
|
|
||||||
|
var prng = Pseed(seed, Pseq((0..6).scramble, inf)).asStream;
|
||||||
|
var progression = Array.fill(4, { chords.wrapAt(prng.next) });
|
||||||
|
|
||||||
|
// Some unpredictable modulations for more drama
|
||||||
|
progression = progression.collect { |chord|
|
||||||
|
chord.scramble
|
||||||
|
};
|
||||||
|
|
||||||
|
progression
|
||||||
|
};
|
||||||
|
|
||||||
|
// SYNTH DEF (Pad with chaotic organ-like sound)
|
||||||
|
SynthDef(\chaoticPad, {
|
||||||
|
|out=0, freq=440, amp=0.2, gate=1, pan=0|
|
||||||
|
var env = EnvGen.kr(Env.asr(2, 1, 2), gate, doneAction: 2);
|
||||||
|
var sig = Mix.fill(4, {
|
||||||
|
|i| VarSaw.ar(freq * (1 + Rand(-0.01, 0.01)), 0, 0.5)
|
||||||
|
});
|
||||||
|
sig = LPF.ar(sig, freq * 2);
|
||||||
|
sig = Splay.ar(sig * env * amp, 0.3, center: pan);
|
||||||
|
Out.ar(out, sig);
|
||||||
|
}).add;
|
||||||
|
|
||||||
|
// PATTERN (Cantorial-like progression and improvisation)
|
||||||
|
~pattern = Pbind(
|
||||||
|
\instrument, \chaoticPad,
|
||||||
|
\dur, 2,
|
||||||
|
\amp, 0.1,
|
||||||
|
\pan, Pwhite(-0.3, 0.3),
|
||||||
|
\freq, Pfunc {
|
||||||
|
var progression = ~makeProgression.(~musicalParams[\progressionSeed]);
|
||||||
|
var chord = progression.choose;
|
||||||
|
|
||||||
|
// Generate frequencies for each note in the chord
|
||||||
|
chord.collect { |deg|
|
||||||
|
~musicalParams[\scale].degreeToFreq(deg + 1, ~musicalParams[\key].midicps, 4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// PLAYBACK
|
||||||
|
~player = ~pattern.play(TempoClock.new(~musicalParams[\bpm] / 60));
|
||||||
|
)
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
MIDIClient.init;
|
||||||
|
MIDIIn.connectAll;
|
||||||
|
|
||||||
|
|
||||||
|
(
|
||||||
|
MIDIdef.noteOn(\noteOnTest, {
|
||||||
|
arg vel, nn, chan, src;
|
||||||
|
[vel, nn].postln;
|
||||||
|
|
||||||
|
{
|
||||||
|
var sig, env;
|
||||||
|
sig = LFTri.ar(nn.midicps)!2;
|
||||||
|
env = EnvGen.kr(Env.perc, doneAction:2);
|
||||||
|
sig = sig * env * vel.linexp(1,127,0.01,0.3);
|
||||||
|
}.play;
|
||||||
|
});
|
||||||
|
)
|
||||||
|
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
~structBus = Bus.audio(s, 5); // Bus with 5 channels
|
||||||
|
|
||||||
|
(
|
||||||
|
SynthDef(\layer0_struct0, { |in, out, fftSize=2048|
|
||||||
|
var sig = PlayBuf.ar(1, in, loop: 1);
|
||||||
|
var chain = FFT(LocalBuf(fftSize), sig);
|
||||||
|
chain = PV_RandComb(chain, 0.5, Impulse.kr(2));
|
||||||
|
chain = PV_BrickWall(chain);
|
||||||
|
Out.ar(out, IFFT(chain));
|
||||||
|
}).add;
|
||||||
|
)
|
||||||
|
|
||||||
|
(
|
||||||
|
~structSynths = Array.fill(5, { |i|
|
||||||
|
var synthName = ("layer0_struct" ++ i).asSymbol;
|
||||||
|
Synth(synthName, [
|
||||||
|
\in, b.bufnum, // your sample buffer
|
||||||
|
\out, ~structBus.index + i
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
(
|
||||||
|
SynthDef(\structMixer, { |out=0, mixIndex=2.0, amp=0.3|
|
||||||
|
var ins, mix;
|
||||||
|
|
||||||
|
// Read 5 mono inputs
|
||||||
|
ins = Array.fill(5, { |i| In.ar(~structBus.index + i, 1) });
|
||||||
|
|
||||||
|
// Use SelectX to interpolate between adjacent channels
|
||||||
|
mix = SelectX.ar(mixIndex.clip(0, 4), ins);
|
||||||
|
|
||||||
|
Out.ar(out, mix * amp ! 2); // stereo
|
||||||
|
}).add;
|
||||||
|
)
|
||||||
|
|
||||||
|
// Start the mixer
|
||||||
|
~mixer = Synth(\structMixer);
|
||||||
|
|
||||||
|
(
|
||||||
|
// MIDI CC Volume
|
||||||
|
MIDIdef.cc(\structVol, { |val, num, chan|
|
||||||
|
~mixer.set(\amp, val.linlin(0, 127, 0.0, 1.0));
|
||||||
|
}, ccNum: 0, chan: 2);
|
||||||
|
|
||||||
|
// MIDI CC Blend
|
||||||
|
MIDIdef.cc(\structMix, { |val, num, chan|
|
||||||
|
~mixer.set(\mixIndex, val.linlin(0, 127, 0.0, 4.0));
|
||||||
|
}, ccNum: 1, chan: 2);
|
||||||
|
)
|
||||||
|
|
||||||
|
MIDIClient.init;
|
||||||
|
MIDIIn.connectAll;
|
||||||
@ -0,0 +1,84 @@
|
|||||||
|
b = Buffer.read(s, "/home/lcoogan/snd/samples/scarlett/textural_nightmare.wav");
|
||||||
|
|
||||||
|
c = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/Cantorial/Cantor_Samuel_Malavsky_Zechor.wav");
|
||||||
|
b.free;
|
||||||
|
|
||||||
|
(
|
||||||
|
SynthDef(\pvVocalPlay, {
|
||||||
|
arg bufnum, fftSize = 1024, amp = 1;
|
||||||
|
var in, chain, out;
|
||||||
|
var shiftLFO;
|
||||||
|
|
||||||
|
// LFOs
|
||||||
|
var brickLFO = SinOsc.kr(0.1).range(0.02, 0.2); // slowly shift the BrickWall limit
|
||||||
|
var smearLFO = LFNoise1.kr(0.3).range(5, 20); // jittery smear amount
|
||||||
|
var randRate = LFNoise1.kr(0.2).range(2, 12); // random impulse rate
|
||||||
|
|
||||||
|
in = PlayBuf.ar(1, bufnum, BufRateScale.kr(bufnum), loop: 0, doneAction: 2);
|
||||||
|
chain = FFT(LocalBuf(fftSize), in);
|
||||||
|
|
||||||
|
// Modulated PV processing
|
||||||
|
// chain = PV_BrickWall(chain, 0.05);
|
||||||
|
chain = PV_MagFreeze(chain);
|
||||||
|
chain = PV_RandComb(chain, 0.1, Impulse.kr(randRate));
|
||||||
|
chain = PV_MagSmear(chain, smearLFO);
|
||||||
|
chain = PV_SpectralEnhance(chain, 1, 1, 0.1);
|
||||||
|
chain = PV_BinScramble(chain, 0.5 0.8, 0);
|
||||||
|
// Uncomment to experiment
|
||||||
|
/* shiftLFO = SinOsc.kr(0.0005).range(0.5, 2.0);
|
||||||
|
chain = PV_BinShift(chain, shiftLFO, 1);*/
|
||||||
|
|
||||||
|
out = IFFT(chain);
|
||||||
|
Out.ar(0, out ! 2 * amp);
|
||||||
|
}).add;
|
||||||
|
)
|
||||||
|
|
||||||
|
x = Synth(\pvVocalPlay, [\bufnum, c]);
|
||||||
|
|
||||||
|
|
||||||
|
(
|
||||||
|
Pbind(
|
||||||
|
\instrument, \pvVocalPlay,
|
||||||
|
\bufnum, c, // assuming you've preloaded your buffer
|
||||||
|
\dur, 5, // repeat every 5 seconds
|
||||||
|
\fftSize, Pseq([1024, 2048, 512], inf), // modulate fftSize across events
|
||||||
|
// \amp, 4;
|
||||||
|
).play;
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Create a multidimensional modulation map
|
||||||
|
~modMap = Array.fill([4, 4], { |i, j|
|
||||||
|
SinOsc.kr(0.05 * (i + 1) * (j + 1)).range(0.1, 0.9)
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(
|
||||||
|
~numVoices = 6;
|
||||||
|
|
||||||
|
~loopVoices = Routine({
|
||||||
|
inf.do {
|
||||||
|
// Free old voices if they exist
|
||||||
|
if(~voices.notNil) {
|
||||||
|
~voices.do(_.free);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Spawn new voices with varied modulation
|
||||||
|
~voices = Array.fill(~numVoices, { |i|
|
||||||
|
var baseRate = i.linlin(0, ~numVoices-1, 0.05, 0.2);
|
||||||
|
var smearVar = i.linlin(0, ~numVoices-1, 0.1, 0.5);
|
||||||
|
Synth(\pvVocalPlay, [
|
||||||
|
\bufnum, c,
|
||||||
|
\brickRate, baseRate,
|
||||||
|
\smearRate, smearVar,
|
||||||
|
\randRate, 0.15 + 0.03.rand
|
||||||
|
])
|
||||||
|
});
|
||||||
|
|
||||||
|
8.wait; // wait before refreshing voices
|
||||||
|
}
|
||||||
|
}).play;
|
||||||
|
)
|
||||||
@ -0,0 +1,125 @@
|
|||||||
|
// TODO
|
||||||
|
|
||||||
|
|
||||||
|
(
|
||||||
|
5.do { |i|
|
||||||
|
SynthDef(("layer0_struct" ++ i).asSymbol, {
|
||||||
|
arg buf, out, fftSize = 1024, amp = 0.3;
|
||||||
|
|
||||||
|
var in, chain, sig, wipe, trig, interp, stretch, shift, threshold, factor, freeze, lfo;
|
||||||
|
var wipeFreq = 0.2;
|
||||||
|
var wipeDepth = 1;
|
||||||
|
|
||||||
|
// Sample playback
|
||||||
|
in = PlayBuf.ar(1, buf, BufRateScale.kr(buf), loop: 1);
|
||||||
|
|
||||||
|
// FFT
|
||||||
|
chain = FFT(LocalBuf(fftSize), in);
|
||||||
|
|
||||||
|
// Unique spectral processing per struct
|
||||||
|
switch(i,
|
||||||
|
0, {
|
||||||
|
wipe = SinOsc.kr(wipeFreq).range(wipeDepth, 0.85);
|
||||||
|
trig = Impulse.kr(SinOsc.kr(0.1).range(1, 10));
|
||||||
|
|
||||||
|
chain = PV_RandComb(chain, wipe, trig);
|
||||||
|
chain = PV_BrickWall(chain, wipe);
|
||||||
|
},
|
||||||
|
1, {
|
||||||
|
wipe = SinOsc.kr(wipeFreq).range(wipeDepth, 0.85);
|
||||||
|
trig = 0.0;
|
||||||
|
|
||||||
|
stretch = 1.0;
|
||||||
|
shift = 0.0;
|
||||||
|
interp = 0;
|
||||||
|
|
||||||
|
chain = PV_RandComb(chain, wipe, trig);
|
||||||
|
chain = PV_BinShift(chain, stretch, interp);
|
||||||
|
|
||||||
|
},
|
||||||
|
2, {
|
||||||
|
freeze = 0.0;
|
||||||
|
wipe = 0.0;
|
||||||
|
|
||||||
|
chain = PV_MagFreeze(chain, freeze);
|
||||||
|
chain = PV_BrickWall(chain, wipe);
|
||||||
|
},
|
||||||
|
3, {
|
||||||
|
threshold = 0.0;
|
||||||
|
factor = 0.1;
|
||||||
|
|
||||||
|
chain = PV_MagAbove(chain, threshold);
|
||||||
|
chain = PV_MagSmooth(chain, factor);
|
||||||
|
},
|
||||||
|
4, {
|
||||||
|
trig = 0.0;
|
||||||
|
|
||||||
|
chain = PV_PhaseShift90(chain);
|
||||||
|
chain = PV_Diffuser(chain, trig);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
sig = IFFT(chain);
|
||||||
|
|
||||||
|
Out.ar(out, sig.dup * amp);
|
||||||
|
}).play;
|
||||||
|
};
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(
|
||||||
|
5.do { |i|
|
||||||
|
SynthDef(("layer0_textu" ++ i).asSymbol, {
|
||||||
|
arg buf, out, fftSize = 1024, amp = 0.3;
|
||||||
|
|
||||||
|
var in, chain, sig, wipe, trig;
|
||||||
|
|
||||||
|
// Sample playback
|
||||||
|
in = PlayBuf.ar(1, buf, BufRateScale.kr(buf), loop: 1);
|
||||||
|
|
||||||
|
// FFT
|
||||||
|
chain = FFT(LocalBuf(fftSize), in);
|
||||||
|
|
||||||
|
// Unique spectral processing per struct
|
||||||
|
switch(i,
|
||||||
|
0, {
|
||||||
|
chain = PV_RandComb(chain);
|
||||||
|
chain = PV_BinScramble(chain);
|
||||||
|
chain = PV_BinWipe(chain, chain);
|
||||||
|
},
|
||||||
|
1, {
|
||||||
|
chain = PV_RandComb(chain);
|
||||||
|
chain = PV_BinShift(chain);
|
||||||
|
chain = PV_Diffuser(chain);
|
||||||
|
},
|
||||||
|
2, {
|
||||||
|
chain = PV_MagSquared(chain);
|
||||||
|
chain = PV_RectComb(chain);
|
||||||
|
},
|
||||||
|
3, {
|
||||||
|
chain = PV_MagFreeze(chain);
|
||||||
|
chain = PV_BinWipe(chain, chain);
|
||||||
|
},
|
||||||
|
4, {
|
||||||
|
chain = PV_BrickWall(chain);
|
||||||
|
chain = PV_MagSmooth(chain);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
sig = IFFT(chain);
|
||||||
|
Out.ar(out, sig.dup * amp);
|
||||||
|
}).play;
|
||||||
|
};
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*# Effects
|
||||||
|
Verb CC12 convolution reverb
|
||||||
|
Comb CC13 comb filter
|
||||||
|
Fold CC14 wave folding
|
||||||
|
Sply CC15 splay*/
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
(
|
||||||
|
// Load single buffer (user switches manually)
|
||||||
|
b = Buffer.read(s,
|
||||||
|
"/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/Cantorial/old/Ribono_Shel_Olom.wav");
|
||||||
|
)
|
||||||
|
|
||||||
|
(
|
||||||
|
// SynthDef without the combo switch functionality
|
||||||
|
SynthDef(\pv16knob, {
|
||||||
|
|out=0,
|
||||||
|
bufnum=0,
|
||||||
|
l1CC=0, l2CC=0, // CC values (no combo switching)
|
||||||
|
l1Amp=1, l2Amp=1,
|
||||||
|
pvAmp=1, pvMix=1,
|
||||||
|
fil1Type=0, res1=0.3, fil2Type=0, res2=0.3,
|
||||||
|
verb=0, comb=0, fold=0, sply=0,
|
||||||
|
mast=1
|
||||||
|
|
|
||||||
|
|
||||||
|
var sig, chain, base, fftSize = 2048;
|
||||||
|
|
||||||
|
base = PlayBuf.ar(1, bufnum, loop: 1);
|
||||||
|
sig = base;
|
||||||
|
|
||||||
|
chain = FFT(LocalBuf(fftSize), sig);
|
||||||
|
|
||||||
|
// IFFT and effects applied directly to the signal
|
||||||
|
sig = IFFT(chain) * l1Amp + IFFT(chain) * l2Amp;
|
||||||
|
sig = SelectX.ar(pvMix, [base, sig]) * pvAmp;
|
||||||
|
|
||||||
|
// Filters
|
||||||
|
sig = Select.ar(fil1Type, [
|
||||||
|
RLPF.ar(sig, 1200, res1),
|
||||||
|
LPF.ar(sig, 1200),
|
||||||
|
HPF.ar(sig, 1200),
|
||||||
|
BPF.ar(sig, 1200),
|
||||||
|
Formlet.ar(sig, 1000, 0.05, 0.005)
|
||||||
|
]);
|
||||||
|
|
||||||
|
sig = BLowShelf.ar(sig, 500, 1, res2) + BHiPass.ar(sig, 1500, res2);
|
||||||
|
|
||||||
|
// Effects
|
||||||
|
sig = FreeVerb.ar(sig, mix: verb);
|
||||||
|
sig = CombC.ar(sig, 0.3, 0.2, comb * 0.5);
|
||||||
|
sig = Fold.ar(sig, 1 + fold);
|
||||||
|
sig = Splay.ar(sig) * sply;
|
||||||
|
|
||||||
|
Out.ar(out, sig * mast);
|
||||||
|
}).play;
|
||||||
|
)
|
||||||
|
|
||||||
|
(
|
||||||
|
// Instantiate the synth
|
||||||
|
~pvSynth = Synth(\pv16knob, [\bufnum, b.bufnum]);
|
||||||
|
)
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
(
|
||||||
|
// ========== Spectral SynthDef with PV_Control and expanded modulation ==========
|
||||||
|
SynthDef(\pv16knob, {
|
||||||
|
arg bufnum, fftSize = 1024,
|
||||||
|
amp = 0.3, smearAmt = 5, randRate = 6, binScrambleAmt = 0.5,
|
||||||
|
pvRouting = 0, grainSize = 0.1,
|
||||||
|
delTime = 0.3, delFeedback = 0.4, verbMix = 0.2,
|
||||||
|
lfoFreq = 0.2, bitcrushAmt = 0.0, distAmt = 1.0,
|
||||||
|
ringFreq = 200, freezeAmt = 0.5,
|
||||||
|
transpose = 1.0, filterCutoff = 8000;
|
||||||
|
|
||||||
|
var in, chain, dry, fx, delay, verb;
|
||||||
|
var chain0, chain1, chain2, chain3, chain4, chain5;
|
||||||
|
var lfo = SinOsc.kr(lfoFreq).range(0.1, 1.0);
|
||||||
|
var controlBuf = LocalBuf(fftSize); // for PV_Control output
|
||||||
|
|
||||||
|
// Audio input and bitcrushing
|
||||||
|
in = PlayBuf.ar(1, bufnum, BufRateScale.kr(bufnum) * transpose, loop: 1);
|
||||||
|
in = Decimator.ar(in, (1 - bitcrushAmt).linexp(0, 1, 44100, 1000), 8 - (bitcrushAmt * 7));
|
||||||
|
|
||||||
|
// FFT and spectral freeze
|
||||||
|
chain = FFT(LocalBuf(fftSize), in);
|
||||||
|
chain = PV_MagFreeze(chain, freezeAmt);
|
||||||
|
|
||||||
|
// Spectral processing chains
|
||||||
|
chain0 = PV_BinScramble(PV_MagSmear(PV_RandComb(chain, 0.1, Impulse.kr(randRate)), smearAmt + lfo), binScrambleAmt, 0);
|
||||||
|
chain1 = PV_BrickWall(chain, lfo.range(0.05, 0.2));
|
||||||
|
chain2 = PV_BinShift(chain, lfo * 20, 0.5);
|
||||||
|
chain3 = PV_BinWipe(chain, lfo);
|
||||||
|
chain4 = PV_SpectralEnhance(chain, 0.8, 1.5, 0.2);
|
||||||
|
|
||||||
|
// PV_Control dynamic bin suppression
|
||||||
|
PV_Control.new(chain, controlBuf,
|
||||||
|
thresh: 0.5,
|
||||||
|
mulFactor: 0.8,
|
||||||
|
limiter: 10,
|
||||||
|
attackReleaseFrames: 50,
|
||||||
|
sustainZeroFrames: 100,
|
||||||
|
waitGoFrames: 50,
|
||||||
|
tripCount: 2,
|
||||||
|
tripBlockFrames: 500,
|
||||||
|
highestBin: 400
|
||||||
|
);
|
||||||
|
chain5 = PV_MagMul(chain, controlBuf);
|
||||||
|
|
||||||
|
// Select branch
|
||||||
|
chain = SelectX.kr(pvRouting.clip(0, 5), [chain0, chain1, chain2, chain3, chain4, chain5]);
|
||||||
|
dry = IFFT(chain);
|
||||||
|
|
||||||
|
// Post-PV grain, distortion, filter
|
||||||
|
dry = TGrains.ar(2, Impulse.ar(20), bufnum, 1, Phasor.ar(0, 1, 0, BufFrames.ir(bufnum)), grainSize, 0, 0.1, 1);
|
||||||
|
dry = Ringz.ar(dry, ringFreq, 0.2);
|
||||||
|
dry = (dry * distAmt).tanh;
|
||||||
|
dry = LPF.ar(dry, filterCutoff);
|
||||||
|
|
||||||
|
// Delay and reverb
|
||||||
|
delay = CombC.ar(dry, 1, delTime, delFeedback);
|
||||||
|
verb = FreeVerb.ar(dry, verbMix, 0.8, 0.3);
|
||||||
|
|
||||||
|
// Output
|
||||||
|
fx = Mix([dry, delay, verb]);
|
||||||
|
Out.ar(0, fx.dup * amp);
|
||||||
|
}).add;
|
||||||
|
)
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
b = Buffer.read(s, "/home/lcoogan/snd/samples/scarlett/textural_nightmare.wav");
|
||||||
|
|
||||||
|
c = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/Cantorial/Cantor_Samuel_Malavsky_Zechor.wav");
|
||||||
|
b.free;
|
||||||
|
|
||||||
|
(
|
||||||
|
SynthDef(\pvVocalPlay, {
|
||||||
|
arg bufnum, fftSize = 1024, amp = 1;
|
||||||
|
var in, chain, out;
|
||||||
|
var shiftLFO;
|
||||||
|
|
||||||
|
// LFOs
|
||||||
|
var brickLFO = SinOsc.kr(0.1).range(0.02, 0.2); // slowly shift the BrickWall limit
|
||||||
|
var smearLFO = LFNoise1.kr(0.3).range(5, 20); // jittery smear amount
|
||||||
|
var randRate = LFNoise1.kr(0.2).range(2, 12); // random impulse rate
|
||||||
|
|
||||||
|
in = PlayBuf.ar(1, bufnum, BufRateScale.kr(bufnum), loop: 0, doneAction: 2);
|
||||||
|
chain = FFT(LocalBuf(fftSize), in);
|
||||||
|
|
||||||
|
// Modulated PV processing
|
||||||
|
// chain = PV_BrickWall(chain, 0.05);
|
||||||
|
chain = PV_MagFreeze(chain);
|
||||||
|
chain = PV_RandComb(chain, 0.1, Impulse.kr(randRate));
|
||||||
|
chain = PV_MagSmear(chain, smearLFO);
|
||||||
|
chain = PV_SpectralEnhance(chain, 1, 1, 0.1);
|
||||||
|
chain = PV_BinScramble(chain, 0.5 0.8, 0);
|
||||||
|
// Uncomment to experiment
|
||||||
|
/* shiftLFO = SinOsc.kr(0.0005).range(0.5, 2.0);
|
||||||
|
chain = PV_BinShift(chain, shiftLFO, 1);*/
|
||||||
|
|
||||||
|
out = IFFT(chain);
|
||||||
|
Out.ar(0, out ! 2 * amp);
|
||||||
|
}).add;
|
||||||
|
)
|
||||||
|
|
||||||
|
x = Synth(\pvVocalPlay, [\bufnum, c]);
|
||||||
|
|
||||||
|
|
||||||
|
(
|
||||||
|
Pbind(
|
||||||
|
\instrument, \pvVocalPlay,
|
||||||
|
\bufnum, c, // assuming you've preloaded your buffer
|
||||||
|
\dur, 5, // repeat every 5 seconds
|
||||||
|
\fftSize, Pseq([1024, 2048, 512], inf), // modulate fftSize across events
|
||||||
|
// \amp, 4;
|
||||||
|
).play;
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
(
|
||||||
|
// Create a multidimensional modulation map
|
||||||
|
~modMap = Array.fill([4, 4], { |i, j|
|
||||||
|
Pulse.kr(1 * (i + 1) * (j + 1)).range(0.01, 0.9)
|
||||||
|
});
|
||||||
|
)
|
||||||
Loading…
Reference in New Issue