random stuff

master
Leo Coogan 8 months ago
parent 53018120f4
commit f4aabcc61f
Signed by: lcoogan
SSH Key Fingerprint: SHA256:vnrR5ilHkdr6L4t2yOMUMINFPpxEh+53N3nMel66mCw

@ -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,127 @@
(
// Generate a terrain table
~terrain = Buffer.alloc(s, 1024, 1);
~terrain.sine1([1, 0.5, 0.3, 0.2, 0.1], true); // You can sculpt this more chaotically
SynthDef("fm_pulsar_terrain", {
arg a, e, f, d;
var t, overlap, carfreq, modfreq, mInd, vel, vel_, tblPos, sig;
f = \freq.kr(100);
vel = \kel.kr(0.5);
vel_ = vel.clip(0,1.0).linlin( 0, 1, 2, 0.7);
e = EnvGen.kr(
Env.adsr(
\att.kr(0.025) * vel_,
\dec.kr(0.02) * vel_,
\susl.kr(0.7),
\rel.kr(4),
curve: \curve.kr(-4)
),
gate: \gate.kr(1),
doneAction:2
) * vel;
carfreq = f * \cf.kr(2) + LFNoise1.kr(3).range(0,50);
modfreq = carfreq * \mf.kr(2) + LFNoise1.kr(3).range(0,100);
t = Impulse.ar(f);
mInd = e.pow(3.3); // use envelope shape to shift table pos
overlap = 1.1 - e.pow(0.5);
d = overlap / f;
// convert modfreq to index between 0 and 1 for VOsc
tblPos = modfreq.linlin(0, 8000, 0, 1).wrap(0, 1); // safer than clip for edge cases
a = Mix([
SinOsc.ar(f),
GrainBuf.ar(1, t, d, ~terrain, tblPos, carfreq, 0, 2)
]);
a = LeakDC.ar(a * e);
a = FreeVerb.ar(a, 0.33, 1);
Out.ar(\outBus.kr(0), a.dup * \gain.kr(0.1));
}).add;
)
(
// MIDI
~notes = Array.newClear(128);
~ccVals = Array.fill(128, { 0.0 }); // NEW: store CC values
// Map CC knobs 015 on MIDI channel 2
(0..15).do { |ccNum|
MIDIdef.cc(\cc_ ++ ccNum, { |val, num, chan, src|
if (chan == 1) { // channel 2
~ccVals[num] = val.linlin(0, 127, 0.0, 1.0);
};
}, ccNum);
};
MIDIdef.noteOn(\noteOnTest, {
arg vel, nn, chan, src;
[vel, nn].postln;
if (chan == 0, {
~notes[nn] = Synth.new(
\fm_pulsar_terrain,
[
\amp, vel.linexp(1,127,0.01,0.3),
\freq, nn.midicps,
// NEW: use CC knob values
\att, ~ccVals[0].linlin(0, 1, 0.01, 0.2),
\dec, ~ccVals[1].linlin(0, 1, 0.01, 0.2),
\susl, ~ccVals[2].linlin(0, 1, 0.1, 1.0),
\rel, ~ccVals[3].linlin(0, 1, 0.2, 8.0),
\cf, ~ccVals[4].linlin(0, 1, 0.5, 4.0),
\mf, ~ccVals[5].linlin(0, 1, 0.5, 4.0),
\curve, ~ccVals[6].linlin(0, 1, -8, 8),
\gain, ~ccVals[7].linlin(0, 1, 0.01, 0.5),
\kel, ~ccVals[8].linlin(0, 1, 0.1, 1.0)
// Knobs 915 are unused for now
]
);
});
});
MIDIdef.noteOff(\noteOffTest, {
arg vel, nn, chan;
[vel, nn].postln;
if (chan == 0, {
~notes[nn].set(\gate, 0);
~notes[nn] = nil;
});
});
)
(
// MIDI setup
MIDIClient.init;
MIDIIn.connectAll;
)
(
~notes[60] = Synth(\fm_pulsar_terrain, [
\freq, 60.midicps,
\amp, 0.2,
\att, ~ccVals[0].linlin(0,1, 0.001, 0.2),
\dec, ~ccVals[1].linlin(0,1, 0.001, 0.2),
\susl, ~ccVals[2].linlin(0,1, 0.1, 1.0),
\rel, ~ccVals[3].linlin(0,1, 0.1, 8.0),
\cf, ~ccVals[4].linlin(0,1, 0.5, 5.0),
\mf, ~ccVals[5].linlin(0,1, 0.5, 5.0),
\curve, ~ccVals[6].linlin(0,1, -8, 8),
\gain, ~ccVals[7].linlin(0,1, 0.01, 0.5),
\kel, ~ccVals[8].linlin(0,1, 0.1, 1.0)
]);
)

@ -42,6 +42,9 @@ SynthDef("fm_pulsar_terrain", {
]); ]);
a = LeakDC.ar(a * e); a = LeakDC.ar(a * e);
a = FreeVerb.ar(a, 0.33, 1);
Out.ar(\outBus.kr(0), a.dup * \gain.kr(0.1)); Out.ar(\outBus.kr(0), a.dup * \gain.kr(0.1));
}).add; }).add;

@ -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));
)

@ -1,3 +1,14 @@
b = Buffer.read(s, "/home/lcoogan/snd/demos/desolation.wav");
(
{
PlayBuf.ar(2, b, 1, loop: 1) * 0.3
}.play;
)
/*add springverb and dubecho
split break and pad*/
( (
SynthDef(\grainFMPad, { SynthDef(\grainFMPad, {
|out=0, bufnum=0, rate=1, centerFreq=200, dur=6, amp=0.3, pan=0| |out=0, bufnum=0, rate=1, centerFreq=200, dur=6, amp=0.3, pan=0|
@ -33,3 +44,185 @@ x = Synth(\grainFMPad, [
\amp, 0.3 \amp, 0.3
]); ]);
) )
(
~midiToFreq = { |note| note.midicps };
)
(
t = TempoClock(86/60);
Pbind(
\instrument, \grainFMPad,
\bufnum, b, // your loaded buffer
\dur, 2, // time between notes (longer since your grains are pad-like)
\centerFreq, Pseq([60, 62, 65, 67, 69, 72].collect(~midiToFreq), inf),
\amp, 0.05,
\rate,1,
\pan, 0,
).play(t);
)
(
SynthDef(\grainFMPad, {
|out=0, bufnum=0, rate=1, centerFreq=200, dur=6, amp=0.3, pan=0|
var trigRate = 20;
var grainDur = 0.1;
var snd;
// Subtle detuning of carrier freq (optional)
var carfreq = centerFreq * LFNoise1.kr(0.1).range(0.98, 1.02);
snd = GrainFM.ar(
numChannels: 2,
trigger: Impulse.kr(trigRate),
dur: grainDur,
carfreq: carfreq, // More stable, but still a little alive
modfreq: LFNoise1.kr(0.1).range(100, 300),
index: LFNoise1.kr(0.05).range(1, 10),
pan: LFNoise1.kr(0.5),
envbufnum: -1,
sndbuf: bufnum,
rate: rate
);
snd = snd * EnvGen.kr(Env.linen(2, dur - 4, 2), doneAction: 2) * amp;
Out.ar(out, snd);
}).add;
)
(
SynthDef(\grainFMPadBlended, {
|out=0, bufnum=0, rate=1, centerFreq=500, dur=6, amp=0.3, pan=0, toneMix=1|
var trigRate = 20;
var grainDur = 0.1;
var snd, tone, blend;
// GrainFM layer
snd = GrainFM.ar(
numChannels: 2,
trigger: Impulse.kr(trigRate),
dur: grainDur,
carfreq: centerFreq,
modfreq: centerFreq * 2,
index: 1.0,
pan: pan,
envbufnum: -1,
sndbuf: bufnum,
rate: rate
);
// Clean tone layer (can also try Saw or Pulse for edge)
tone = SinOsc.ar(centerFreq ! 2); // stereo
// Blend between grainy texture and clean tone
blend = XFade2.ar(snd, tone, (toneMix * 2 - 1)); // toneMix: 0 = all grains, 1 = all tone
// Envelope
blend = blend * EnvGen.kr(Env.linen(2, dur - 4, 2), doneAction: 2) * amp;
Out.ar(out, blend);
}).add;
)
(
SynthDef(\grainFMPadShifted, {
|out=0, bufnum=0, rate=1, centerFreq=200, dur=6, amp=0.3, pan=0, pitchRatio=20.0|
var trigRate = 20;
var grainDur = 0.1;
var snd, shifted;
snd = GrainFM.ar(
numChannels: 2,
trigger: Impulse.kr(trigRate),
dur: grainDur,
carfreq: centerFreq,
modfreq: centerFreq * 2,
index: 1.0,
pan: pan,
envbufnum: -1,
sndbuf: bufnum,
rate: rate
);
// Pitch shift output toward stable tone
shifted = PitchShift.ar(snd, windowSize: 0.2, pitchRatio: pitchRatio, pitchDisp: 0.0);
shifted = shifted * EnvGen.kr(Env.linen(2, dur - 4, 2), doneAction: 2) * amp;
Out.ar(out, shifted);
}).add;
)
(
SynthDef(\grainFMPadPV, {
|out=0, bufnum=0, rate=1, centerFreq=1, dur=1, amp=0.3, pan=0, shiftBins=20, gate 1, env|
var trigRate = 20;
var grainDur = 0.1;
var snd, chain, shifted;
snd = GrainFM.ar(
numChannels: 1, // FFT works on mono
trigger: Impulse.kr(trigRate),
dur: grainDur,
carfreq: centerFreq,
modfreq: centerFreq * 1,
index: 1.0,
pan: 0,
envbufnum: -1,
sndbuf: b,
rate: rate
);
env = EnvGen.kr(Env.asr(0.1, 1.0, 0.1, -4), gate, doneAction:2);
// FFT and PV shift
chain = FFT(LocalBuf(2048), snd);
// chain = PV_MagShift(chain, shiftBins, 0); // shifts bins upward
chain = PV_BinScramble(chain, 1, 1, 0);
chain = PV_BinDelay(chain, 1, 1, 1, 0.5);
chain = PV_PitchShift(chain, -2000);
chain = PV_BrickWall(chain, -20000);
chain = PV_NoiseSynthF(chain, 80, 2, 0);
shifted = IFFT(chain);
shifted = Pan2.ar(shifted, pan); // stereo output
shifted = RLPF.ar(shifted, 800, 0.1);
shifted = CombL.ar(shifted);
// shifted = shifted * EnvGen.kr(Env.linen(2, dur - 4, 2), doneAction: 2) * amp;
shifted = shifted * amp;
Out.ar(out, shifted);
}).add;
)
(
~midiToFreq = { |note| note.midicps };
)
(
t = TempoClock(86/60);
Pbind(
\instrument, \grainFMPad,
\bufnum, b, // your loaded buffer
\dur, 2, // time between notes (longer since your grains are pad-like)
\centerFreq, Pseq([60].collect(~midiToFreq), inf),
\amp, 0.05,
\rate,1,
\pan, 0,
).play(t);
)

@ -1,7 +1,7 @@
MIDIClient.init; MIDIClient.init;
MIDIIn.connectAll; MIDIIn.connectAll;
MIDIdef.noteOn(\noteOnTest, {"key down".postln}); MIDIdef.noteOn(\noteOnTest, {"key down".postln});P
// Print MIDI debug info // Print MIDI debug info
@ -23,7 +23,7 @@ MIDIdef.cc(\ccTest, {
// Load samples // Load samples
( (
~sampleDir = PathName("/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/01-borrowed flesh/seq/808").fullPath; ~sampleDir = PathName("/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/seq/borrowed_flesh/808").fullPath;
~samples = Dictionary.newFrom( ~samples = Dictionary.newFrom(
( (
@ -46,7 +46,7 @@ MIDIdef.cc(\ccTest, {
~samples[39].class ~samples[39].class
( (
~sampleDir = PathName("/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/01-borrowed flesh/seq/808"); ~sampleDir = PathName("/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/seq/borrowed_flesh/808");
~sample = (); ~sample = ();
~sampleDir.entries.do({ |pn| ~sampleDir.entries.do({ |pn|
var sym; var sym;
@ -62,7 +62,7 @@ SynthDef(\sampleTrigger, { |buf, ampin = 0|
amp = In.kr(ampin, 1); amp = In.kr(ampin, 1);
sound = PlayBuf.ar(1, buf, BufRateScale.ir(buf), doneAction: 2); // doneAction: 2 will free the synth when it's done sound = PlayBuf.ar(1, buf, BufRateScale.ir(buf), doneAction: 2); // doneAction: 2 will free the synth when it's done
sound = sound * amp; sound = sound * amp;
Out.ar(0, sound!2); // Send to audio output Out.ar(0, sound.dup);
}).add; }).add;
) )

@ -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…
Cancel
Save