master
Leo Coogan 8 months ago
parent 81927955be
commit 8a7853a108
Signed by: lcoogan
SSH Key Fingerprint: SHA256:vnrR5ilHkdr6L4t2yOMUMINFPpxEh+53N3nMel66mCw

@ -0,0 +1,80 @@
b = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/04-Cantor_Samuel_Malavsky_Zechor.wav");
b.play;
b = Buffer.read(s, "/home/lcoogan/Music/Musicians/My Bloody Valentine/Loveless/02 Loomer.wav");
b = Buffer.read(s, "/home/lcoogan/Misc/my_grave.wav");
b = Buffer.read(s, "/home/lcoogan/Misc/loomer.wav");
b = Buffer.read(s, "/home/lcoogan/snd/releases/desolation-mountain/out.wav");
b = Buffer.read(s, "/home/lcoogan/snd/releases/2025.05.10-Mothers_Day/rem.wav");
(
SynthDef(\brickwall, {
arg out=0, bufnum, fftSize=4096;
var source, chain, sig, noise;
//
source = PlayBuf.ar(1, b, loop: 1, doneAction: 2);
// source = XFade2.ar(source, WhiteNoise.ar(1));
//
chain = FFT(LocalBuf(fftSize), source);
chain = PV_BrickWall(chain, Line.kr(SinOsc.kr(-0.95), -0.80, 1));
chain = PV_BrickWall(chain, Line.kr(0.012, 0.003, 4));
// chain= PV_BrickWall(chain, Line.kr(-1,0,10));
// chain = PV_BinDelay(chain, 0.1, 0.01, chain, chain, 0.5);
// chain = PV_BinDelay(b,);
// chain = PV_BinScramble(chain, 0.1, 0.2, SinOsc.kr(1));
// chain = PV_BrickWall(chain, -0.99);
// chain = PV_ConformalMap(chain, 0.1, Phasor.kr(8));
// chain = PV_Conj(chain);
// chain = PV_Whiten(chain, b, 0.01, 0.5, Dust.kr(1), Dust.kr(0.5));
// chain = PV_MagAbove(chain, Line.kr(30, 40, 1));
//
/* chain= chain.pvcollect(b.numFrames,{|mag, phase, index|
// noise= LFNoise1.kr(rrand(0.5,1.1));
noise = WhiteNoise.kr(2);
[noise*mag,noise.range(-pi,pi)]
},
//
frombin:80, tobin:100,zeroothers:0);*/
// chain = PV_MagBelow(chain, 10);
chain = PV_LocalMax(chain, SinOsc.kr(440, SinOsc.kr(1)));
// chain = PV_MagSmear(chain, Line.kr(0, 100, 1, SinOsc.kr(440)));
sig = IFFT(chain);
// sig = BPF.ar(sig, 4000, 0.1);
// sig = Resonz.ar(sig, 200, 1);
// sig = BHiShelf.ar(sig, 10000, 1);
/*sig = BHiShelf.ar(
sig,
18000,
1,
6, // db
3); // mul*/
// sig = RLPF.ar(sig, 2000, 1, -1);
sig = GVerb.ar(sig, 299, 4, 1, 0.5, 30, 1, 0.1, 0.5);
sig = Splay.ar(sig, 4);
sig = PitchShift.ar(sig, Line.kr(0.5, 1.0, 0.65, Line.kr(0, 3, 4)), 2.0, 0.0, 0.0, 1.0, 0 );
sig = LPF.ar(sig, 800);
// sig = PitchShift.ar(sig, 0.1, 0.4, 0.2, 3);
Out.ar(out, sig.dup);
}).play;
)

@ -0,0 +1,48 @@
{CA1x.ar(100 + LFNoise0.kr(2), 40 + SinOsc.kr(40), 2, mul:2)}.play;
(
SynthDef(\ca, {
arg freq=180, amp = 2;
var sig, env;
sig = CA1.ar(freq + LFNoise0.kr(20), freq + SinOsc.kr(40), 2, mul:2) + CA2.ar();
// sig = SinOsc.ar(freq);
env = EnvGen.kr(Env.adsr(0, 0.1, 0.2), doneAction:2);
Out.ar(0, sig.dup, amp * env);
}).add;
)
Synth(\ca, [\freq, 120]);
{CA1.ar(440, 60, 18, ).dup}.play;
(
SynthDef(\ca2, {
arg freq=440, amp=1;
var sig, env, r;
r = Pca.r2;
sig = CA2.ar(freq, 50, r[10], trig:Impulse.kr(4 + SinOsc.kr(0.2)));
env = EnvGen.kr(Env.adsr(0, 0.1, 0.2), doneAction:2);
// sig = LPF.ar(sig, 800);
Out.ar(0, sig.dup * env * amp);
}).add;
)
{CA2.ar(2).dup}.play;
(
Pbind(
\instrument, \ca,
\dur, 0.25,
\freq, Pseq([60, 63, 65], inf),
\amp, 0.1,
\rel, 0.8,
).play;
)

@ -0,0 +1,55 @@
(
Ndef(\algo22bass, {
var freq = \freq.kr(55);
var amp = \amp.kr(0.5);
var gate = \gate.kr(1);
var pan = \pan.kr(0);
var lfo, fb, op1, op2, op3, op4, op5, op6;
var env1, env2, env3, env4, env5, env6;
var sig;
lfo = LFSaw.kr(8).range(0.1, 1.5);
// Feedback loop
fb = LocalIn.ar(1);
// Operator 6
env6 = EnvGen.kr(Env.new([0, 1, 1, 1, 0], [0.01, 0.1, 0.1, 0.1], \lin, 3), gate);
op6 = SinOsc.ar((freq * 8) + (fb * 7), 0, env6 * lfo * 0.6);
LocalOut.ar(op6);
// Operator 5
env5 = EnvGen.kr(Env.new([0, 1, 1, 1, 0], [0.01, 0.2, 0.2, 0.2], \lin, 3), gate);
op5 = SinOsc.ar((freq * 0.5) + (op6 * 200), 0, env5);
// Operator 4
env4 = EnvGen.kr(Env.new([0, 1, 1, 1, 0], [0.01, 0.3, 0.3, 0.3], \lin, 3), gate);
op4 = SinOsc.ar((freq * 1.0) + (op5 * 200), 0, env4);
// Operator 1
env1 = EnvGen.kr(Env.new([\op1_env1_atk.kr(0);, 1, 1, 1, 0], [0.01, 0.2, 0.4, 0.2], \lin, 3), gate, doneAction:2);
op1 = SinOsc.ar(freq * 3.0, 0, env1 * 0.6);
// Operator 2
env2 = EnvGen.kr(Env.new([0, 1, 1, 1, 0], [0.01, 0.2, 0.2, 0.2], \lin, 3), gate);
op2 = SinOsc.ar(freq * 5.91, 0, env2 * 0.4);
// Operator 3
env3 = EnvGen.kr(Env.new([0, 1, 1, 1, 0], [0.01, 0.3, 0.2, 0.2], \lin, 3), gate);
op3 = SinOsc.ar(freq * 2.0, 0, env3 * 0.5);
sig = (op1 + op2 + op3 + op4) * amp;
sig = RLPF.ar(sig, 1200, 0.4);
sig = sig.tanh * 1.5;
sig = CombL.ar(sig, 0.3, 0.15, 1.5, mul: 0.7);
Pan2.ar(sig, pan)
});
)
(
Ndef(\algo22bass).addSpec(
\freq,
\amp,
\op1_env1_atk, [0.0, 0.01],
).edit;
)

@ -0,0 +1,55 @@
// Algorithmic
(
Pbind(
\instrument, \fm_pulsar_terrain,
\dur, 0.25,
\midinote, Pseq([60, 63, 65], inf) + Prand([0, 5, 8], inf),
\amp, 0.1,
\rel, 0.8,
).play;
)
// J-Style pattern
~base = [0, 3, 5];
~transpose = [0, 5, 8];
(
Pbind(
\instrument, \fm_pulsar_terrain,
\dur, 0.25,
\midinote, Pseq(~base.collect(_ + 60), inf) + Prand(~transpose, inf),
\amp, 0.1,
\rel, 0.8
).play;
)
~scale = [0, 3, 5];
(
Pbind(
\instrument, \fm_pulsar_terrain,
\dur, 0.25,
\midinote, Pfunc { ~scale.choose + 60 + [0, 5, 8].choose },
\amp, 0.1,
\rel, 0.8
).play;
)
~durs = [1, 0.5, 0.25].rotate(1).mirror1;
(
Pbind(
\instrument, \fm_pulsar_terrain,
\dur, Pseq(~durs, inf),
\midinote, Pseq(~base.collect(_ + 60), inf) + Prand(~transpose, inf),
\amp, 0.1,
\rel, 0.8
).play;
)

@ -0,0 +1,361 @@
( // run once to convert and resample wavetable files
var paths, file, data, n, newData, outFile;
paths = "/home/lcoogan/snd/wtables/AKWF/AKWF_0002/*.wav".pathMatch;
Routine({
paths.do { |it i|
// 'protect' guarantees the file objects will be closed in case of error
protect {
// Read original size of data
file = SoundFile.openRead(paths[i]);
data = Signal.newClear(file.numFrames);
file.readData(data);
0.1.wait;
// Convert to n = some power of 2 samples.
// n = data.size.nextPowerOfTwo;
n = 4096;
newData = data.resamp1(n);
0.1.wait;
// Convert the resampled signal into a Wavetable.
// resamp1 outputs an Array, so we have to reconvert to Signal
newData = newData.as(Signal).asWavetable;
0.1.wait;
// save to disk.
outFile = SoundFile(paths[i] ++ "_4096.wtable")
.headerFormat_("WAV")
.sampleFormat_("float")
.numChannels_(1)
.sampleRate_(44100);
if(outFile.openWrite.notNil) {
outFile.writeData(newData);
0.1.wait;
} {
"Couldn't write output file".warn;
};
} {
file.close;
if(outFile.notNil) { outFile.close };
};
}
}).play
)
( // to be put to Platform.userConfigDir +/+ "startup.scd"
~serverBootFunc = { |server|
var wtsize, wtpaths, wtbuffers;
"-----------wavetables begin-----------".postln;
wtsize = 4096;
wtpaths = "/home/lcoogan/snd/wtables/AKWF/AKWF_0002/*.wav_4096.wtable".pathMatch;
[wtpaths].postln;
wtbuffers = Buffer.allocConsecutive(wtpaths.size, s, wtsize * 2, 1, );
wtpaths.do { |it i| wtbuffers[i].read(wtpaths[i])};
~wtbufnums = List[];
~wavetables = ();
wtpaths.do { |it i|
var name = wtbuffers[i].path.basename.findRegexp(".*\.wav")[0][1].splitext[0];
var buffer = wtbuffers[i].bufnum;
~wavetables[name.asSymbol] = buffer;
~wtbufnums.add(buffer);
};
"-----------wavetables end-----------".postln;
};
ServerBoot.add(~serverBootFunc, \default);
)
(
Spec.add(\bufn, ControlSpec(~wtbufnums.minItem, ~wtbufnums.maxItem, 'linear', 1, 0, ""));
Spec.add(\wtmodbufn, \bufn);
Spec.add(\wtmodfreq,\widefreq);
Spec.add(\wtmodamp, [0,5]);
Spec.add(\fmod, \bipolar);
Spec.add(\fmodbufn, \bufn);
Spec.add(\fltRange, \freq);
Spec.add(\res, \unipolar);
Spec.add(\driveDB, [-40,40,\lin,0,0.01,"dB"]);
)
Ndef(\wtable_vosc_dual_t).edit
~wtbufnums.postln;
(
Ndef(\wtable_vosc_dual_t, {
var env, freq;
var wtbufnumRange = [ ~wtbufnums.minItem, ~wtbufnums.maxItem ];
var sig;
// var trg = Dust.kr(2);
var trg = Impulse.kr(0.5);
// trg = trg.lag(TRand.kr(0.0,0.2,trg));
env = EnvGen.ar(Env.perc(
TRand.kr(0.2,1,trg),
TRand.kr(0.2,2,trg)
), gate:trg).lag(0.1);
// env = XFade2.ar(env,env * LFDNoise3.ar(env * 20 + 1).range(0,1), env*2-1);
freq = TExpRand.kr(80,500,trg);
sig = VOsc.ar(
(
VOsc.ar(\wtmodbufn.kr( rrand( wtbufnumRange[0],wtbufnumRange[1] ) ).lag(0.3), \wtmodfreq.kr(2), Rand(0,2pi), \wtmodamp.kr(1))
+
env.pow(1.4)
+
\bufn.ar( rrand( wtbufnumRange[0],wtbufnumRange[1] ) )
) .lag(1.8) .mod( wtbufnumRange[1] - wtbufnumRange[0] ) + wtbufnumRange[0],
freq
) * env;
sig!2 * 0.2
}).play
)
(// low pass filtering the env
{
[
EnvGen.kr(Env.perc(0.02, 0.02)),
EnvGen.kr(Env.perc(0.02, 0.02)).lag(0.1)
]
}.plot(0.1)
)
({ // modulo plot
var a = Line.ar(8,150);
[
a,
a.mod(107-8) +8
]
}.plot(1))
Ndef(\wtable_vosc_dual_t_0).edit.nameView
(
Ndef(\wtable_vosc_dual_t_0, {| vel=1|
var env, freq;
var wtbufnumRange = [ ~wtbufnums.minItem, ~wtbufnums.maxItem ];
var sig;
var fenv;
var driveDB = \driveDB.kr(0);
var direct = \direct.kr(0.5);
// var trg = \trg.kr(1);
// var trg = Dust.kr(2);
var trg = Impulse.kr(1);
env = EnvGen.ar(
Env.adsr(
TExpRand.kr(0.001, 0.1, trg),
TExpRand.kr(0.001, 0.1, trg),
TExpRand.kr(0.1, 0.6, trg),
TExpRand.kr(1.5,4,trg),
curve: TRand.kr(-5.0,4,trg)
),
gate:trg,
doneAction:0
).lag(0.1) * vel;
env = XFade2.ar(env,LFDNoise3.ar(env * 20 + 1).range(0,1), env*2-1);
// env = env * WhiteNoise.ar(MouseX.kr(0,1)!2).range(0,1.0);
// fenv = env * LFNoise0.kr(TRand.kr(1,21, trg)).range(0.5,1.4).lag(TRand.kr(0.0001,0.1, trg));
fenv = env * VOsc.ar(
\fmodbufn.kr( rrand( wtbufnumRange[0],wtbufnumRange[1] ) ).lag(0.4),
\fmodFreq.kr(11)
).range(0.5,1.4)
.lag(TRand.kr(0.0001,0.01, trg));
// freq = \freq.kr(111).lag(0.1);
// freq = LFNoise0.kr(1).exprange(80,1000).lag(0.1);
freq = TExpRand.kr(80,1000,trg);
sig = VOsc.ar(
(
VOsc.ar(\wtmodbufn.kr( rrand( wtbufnumRange[0],wtbufnumRange[1] ) ).lag(0.3), \wtmodfreq.kr(2), Rand(0,2pi), \wtmodamp.kr(1))
+
( env * [ Rand(0.5,1.5), Rand(0.5,1.5) ])
// ( env.pow(1.4) * [ LFNoise1.kr(3).range(1.5,9), LFNoise1.kr(3).range(1.5,9)] + 0.1)
+
\bufn.ar( rrand( wtbufnumRange[0],wtbufnumRange[1] ) )
).lag(0.1).mod( wtbufnumRange[1] - wtbufnumRange[0] ) + wtbufnumRange[0],
freq
) * env;
sig = MoogVCF.ar(
sig * driveDB.dbamp,
XFade2.ar( env.pow(1.4), fenv.pow(1.4), \fmod.kr(0)) * \fltRange.kr(10000) + 50 ,
\res.kr(0)
);
sig = sig * driveDB.neg.dbamp * 0.4; // compensate drive
sig * direct;
}).play
)
(
SynthDef(\wtable_vosc_dual_t, {| vel=0.8|
var env, freq;
var wtbufnumRange = [ ~wtbufnums.minItem, ~wtbufnums.maxItem ];
var sig;
var fenv;
var driveDB = \driveDB.kr(0);
var direct = \direct.kr(0.5).lag(0.2);
// var trg = \trg.kr(1);
var trg = Dust.kr(1);
// var trg = Impulse.kr(2);
env = EnvGen.ar(
Env.adsr(
TExpRand.kr(0.001, 0.1, trg),
TExpRand.kr(0.001, 0.1, trg),
TExpRand.kr(0.1, 0.6, trg),
TExpRand.kr(0.5,4,trg),
curve: TRand.kr(-5.0,4,trg)),
gate:trg,
doneAction:0
).lag(0.1) * vel;
env = XFade2.ar(env,env * LFDNoise3.ar(env * 20 + 1).range(0,1), env*2-1);
// env = env * WhiteNoise.ar(MouseX.kr(0,1)!2).range(0,1.0);
// fenv = env * LFNoise0.kr(TRand.kr(1,21, trg)).range(0.5,1.4).lag(TRand.kr(0.0001,0.1, trg));
fenv = env * VOsc.ar(
\fmodbufn.kr( rrand( wtbufnumRange[0],wtbufnumRange[1] ) ).lag(0.4),
// TRand.kr(1,21, trg)
\fmodFreq.kr(11)
).range(0.5,1.4)
.lag(TRand.kr(0.0001,0.01, trg));
freq = \freq.kr(111).lag(0.1);
// freq = LFNoise0.kr(1).exprange(80,1000).lag(0.1);
// freq = TExpRand.kr(80,1000,trg);
sig = VOsc.ar(
(
VOsc.ar(\wtmodbufn.kr( rrand( wtbufnumRange[0],wtbufnumRange[1] ) ).lag(0.3), \wtmodfreq.kr(2), Rand(0,2pi), \wtmodamp.kr(1))
+
// ( env * [ Rand(1.5,2), Rand(1.5,2) ])
( env.pow(1.4) * [ LFNoise1.kr(3).range(1.5,3), LFNoise1.kr(3).range(1.5,3)])
+
\bufn.ar( rrand( wtbufnumRange[0],wtbufnumRange[1] ) )
).lag(0.1).mod( wtbufnumRange[1] - wtbufnumRange[0] ) + wtbufnumRange[0],
freq
) * env;
sig = MoogVCF.ar(
sig * driveDB.dbamp,
XFade2.ar( env.pow(1.4), fenv.pow(1.4), \fmod.kr(0)) * \fltRange.kr(10000) + 50 ,
\res.kr(0)
);
sig = sig * driveDB.neg.dbamp * 0.4; // compensate drive
Out.ar(\outBus.kr, sig * direct);
Out.ar(\effBus.kr, sig * (1-direct))
// }).play
}).add
)
~reverbBus = Bus.audio(s,2);
(
{
var a;
Ndef(\verb, {var a, n;
a = In.ar(~reverbBus, 2);
n = 8;
n.collect { |i|
a = AllpassC.ar(
a,
delaytime: LFNoise1.kr(0.03!2).range(0.01 , 0.02 * (i+1)),
// decaytime: n-i
decaytime: (i+1)
// decaytime: (n / 2 -i).abs + 0.1
).tanh
}.mean;
a
}).play;
a = [
Synth(\wtable_vosc_dual_t, [\outBus, 0, \effBus, ~reverbBus, \bufn, ~wtbufnums.choose]),
Synth(\wtable_vosc_dual_t, [\outBus, 0, \effBus, ~reverbBus, \bufn, ~wtbufnums.choose]),
Synth(\wtable_vosc_dual_t, [\outBus, 0, \effBus, ~reverbBus, \bufn, ~wtbufnums.choose]),
// Synth(\wtable_vosc_dual_t, [\outBus, 0, \effBus, ~reverbBus, \bufn, ~wtbufnums.choose]),
];
loop{
a.choose.set(
\freq, ([0, 1, 2, 4, 5, 8, 11].choose + 60).midicps * 2.pow((-2..2).choose),
\wtmodfreq, exprand(1, 20),
// \wtmodamp, exprand(0.1,4).postln,
\fmod, rrand(-1.0,1),
// \fmodbufn, ~wtbufnums.choose,
\fmodFreq, exprand(2,20),
// \fltRange, rrand(1000,10000),
\vel, rrand(0.1,0.9),
\direct, rrand(0.1,0.6),
);
2.pow((-2..1).choose).wait;
}
}.fork
)

@ -0,0 +1,119 @@
~ir = Buffer.read(s, "/home/lcoogan/snd/ir/ForestScaleModel/ForestScaleModel/IR_ScaleModel/S1R1_ScaleModel.wav");
~ir = Buffer.read(s, "/home/lcoogan/snd/ir/r1-nuclear-reactor-hall/stereo/r1_ortf-48k.wav");
b = Buffer.read(s, "/home/lcoogan/snd/samples/scarlett/scarlett singing.wav");
b.play;
{Convolution.ar(b, ~ir)}.play;
s.options.memSize = 8192;
(
SynthDef(\bellFM, {
|freq = 440, amp = 0.1, gate = 1, ratioIndex = 0, out = 0, irBuf = 0, wet = 0.5, lfoRate = 20, lfoDepth = 1|
var car, mod, env, mFreq, mIndex, tunedFreq, tuning, dry, reverb, sig, lfo;
tuning = [13/12, 55/48, 5/4, 65/48, 11/8, 143/96, 13/8, 5/3, 11/6, 2/1];
tunedFreq = freq * Select.kr(ratioIndex.clip(0, tuning.size - 1), tuning);
env = EnvGen.kr(Env.perc(0.01, 1.0, 1, 4), gate, doneAction: 2);
mFreq = tunedFreq * 6.7;
mIndex = env * 5;
mod = Pulse.ar(mFreq) * (tunedFreq * mIndex);
dry = SinOsc.ar(tunedFreq + mod) * env * amp;
// Initialize sig with the dry signal
// sig = dry;
sig =
// Create LFO and modulate
lfo = SinOsc.kr(lfoRate, 0, lfoDepth); // Low-frequency oscillator
lfo = LFNoise0.kr(lfoRate * lfoDepth);
sig = sig + lfo; // Add LFO to the signal
// Convolve and scale
reverb = Convolution2.ar(dry, ~ir, 512);
// Mix dry and wet signals
sig = XFade2.ar(dry, reverb, (wet * 2) + lfo); // -1 = all dry, +1 = all wet
Out.ar(out, sig.dup);
}).add;
)
(
SynthDef(\pluckedSine, {
|out=0, freq=220, amp=0.4, decay=3, coef=0.5|
var trig, burst, pluck;
trig = Impulse.kr(0); // trigger manually
burst = SinOsc.ar(freq) * EnvGen.kr(Env.perc(0.001, 0.05), trig);
pluck = Pluck.ar(
burst,
trig,
0.2, // max delay time
1 / freq, // delay time = 1 / freq
decay,
coef
);
Out.ar(out, pluck.dup * amp);
}).add;
)
Synth(\bellFM, [\irBuf, ~ir.bufnum]);
Synth(\bellFM, [\freq, 440]);
Synth(\bellFM, [\freq, 660]);
Synth(\bellFM, [\freq, 550]);
(
SynthDef(\pluckedSine, {
|out = 0, freq = 220, amp = 0.4, decay = 3, coef = 0.5, wet = 0.5, lfoRate = 3, lfoDepth = 1, irBuf = 0|
var trig, burst, pluck, reverb, lfo, sig;
trig = Impulse.kr(0); // trigger manually
burst = LFSaw.ar(freq) * EnvGen.kr(Env.perc(0.001, 0.05), trig);
pluck = Pluck.ar(
burst,
trig,
0.2, // max delay time
1 / freq, // delay time = 1 / freq
decay,
coef
);
// Initialize sig with the pluck signal
sig = pluck;
// LFO modulation (Low-frequency noise oscillator)
lfo = LFNoise0.kr(lfoRate); // Low-frequency noise oscillator
sig = sig + lfo * lfoDepth; // Apply LFO to the signal
// Convolve and scale
// reverb = Convolution2.ar(sig, irBuf, 512); // Apply convolution reverb
sig = XFade2.ar(sig, reverb, (wet * 2) + 0.1); // Mix dry and wet signals
// sig = GVerb.ar(sig);
// Output the signal
Out.ar(out, sig.dup);
}).add;
)

@ -1,17 +1,61 @@
b = Buffer.read(s, "/Users/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/04-Cantor_Samuel_Malavsky_Zechor.wav");
b = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/04-Cantor_Samuel_Malavsky_Zechor.wav");
b.play;
b = Buffer.read(s, "/home/lcoogan/Music/Musicians/My Bloody Valentine/Loveless/02 Loomer.wav");
b = Buffer.read(s, "/home/lcoogan/Misc/my_grave.wav");
c = Buffer.read(s, "/home/lcoogan/Misc/loomer.wav");
b = Buffer.read(s, "/home/lcoogan/snd/releases/desolation-mountain/out.wav");
(
SynthDef(\brickwall, {
arg out=0, bufnum, fftSize=4096;
var source, chain, sig;
var source, chain, sig, noise;
//
source = PlayBuf.ar(1, b, loop: 0, doneAction: 2);
//
chain = FFT(LocalBuf(fftSize), source);
chain = PV_BrickWall(chain, -0.95);
chain = PV_BrickWall(chain, 0.035);
// chain= PV_BrickWall(chain, Line.kr(-1,0,10));
// chain = PV_BinDelay(chain, 0.01, 0.01, chain, chain, 0.5);
// chain = PV_BinScramble(chain, 0.1, 0.2, SinOsc.kr(1));
// chain = PV_BrickWall(chain, -0.99);
// chain = PV_ConformalMap(chain, 0.1, Phasor.kr(8));
// chain = PV_Conj(chain);
// chain = PV_Whiten(chain, b, 0.01, 0.5, Dust.kr(1), Dust.kr(0.5));
chain = PV_MagAbove(chain, 10);
// chain= chain.pvcollect(b.numFrames,{|mag, phase, index|
// noise= LFNoise1.kr(rrand(0.5,1.1));
// [noise*mag,noise.range(-pi,pi)]
//
// },
//
// frombin:0, tobin:10,zeroothers:1);
source = PlayBuf.ar(1, bufnum, loop: 0, doneAction: 2);
chain = FFT(LocalBuf(fftSize), source);
chain = PV_BrickWall(chain, -0.992);
// chain = PV_MagBelow(chain, 40);
// chain = PV_LocalMax(chain, 4);
// chain = PV_MagSmear(chain, 4);
sig = IFFT(chain);
// sig = BPF.ar(sig, 4000, 0.1);
/*sig = GVerb.ar(sig, 299, 4, 1, 0.5, 30, 1, 0.1, 0.5);
sig = Splay.ar(sig, 4);*/
Out.ar(out, sig.dup);
}).play;
)
)

@ -88,33 +88,26 @@ MIDIdef.noteOff(\noteOffTest, {
});
[
[\freq, 0, 50, 4000],
[\amp, 1, 0.0, 1.5],
[\cf, 2, 0.1, 4.0],
[\mf, 3, 0.1, 4.0],
[\tblIndex, 4, 0.0, 1.0],
[\gain, 5, 0.01, 1.0],
[\att, 6, 0.001, 0.2],
[\dec, 7, 0.001, 0.2],
[\rel, 8, 0.1, 8.0],
[\susl, 9, 0.0, 1.0],
[\curve, 10, -8.0, 8.0],
[\kel, 11, 0.0, 1.0]
[\f0ratio, 0, 1],
[\f1ratio, 0, 1],
[\f2ratio, 0, 1],
[\modInd0, 0, 1],
[\modInd1, 0, 1],
[\modInd2, 0, 1],
].do { |spec|
var param, cc, min, max;
#param, cc, min, max = spec;
MIDIdef.cc(param.asSymbol, { |val, num, chan, src|
if (chan == 2) {
if (chan == 0) {
var mapped = val.linlin(0, 127, min, max);
~pulsar.set(param, mapped);
\fm3mc_perc.set(param, mapped);
}
}, cc);
};
)
(
MIDIClient.init;
MIDIIn.connectAll;
)

@ -4,7 +4,7 @@
SynthDef("sine_wave_non_et", {
arg freq, amp, tuningRatio, outBus;
// Set up tuning - Just Intonation scale (can use different tuning ratios)
// Set up tuning - ET scale (can use different tuning ratios)
var tuning = [ 33/32, 21/20, 11/10, 9/8, 7/6, 99/80, 77/60, 21/16,
11/8, 7/5, 231/160, 3/2, 63/40, 77/48, 33/20, 7/4,
9/5, 11/6, 77/40, 2/1]; // Example ratios for the 8-note scale

@ -0,0 +1,74 @@
MIDIIn.connectAll;
~pulsar = 8388608;
~mellotron = 8388611;
(
~notes = Array.newClear(128); // Initialize the array to store synths
// Handle noteOn for MIDI device 8454149 (first device)
MIDIdef.noteOn(\noteOnTest_device1, {
arg vel, nn, chan, src;
[vel, nn, src].postln; // Post the velocity, note number, and source to thethe console
// Only respond to MIDI input from source 8454149 (device 1)
if (src == ~pulsar, {
// Create a new synth for device 1
~notes[nn] = Synth.new(
\wtable_vosc_dual_clean, [
\freq, nn.midicps,
\amp, vel.linexp(1,127,0.01,0.3),
]
);
});
});
// Handle noteOff for MIDI device 8454149 (first device)
MIDIdef.noteOff(\noteOffTest_device1, {
arg vel, nn, chan, src;
[vel, nn, src].postln;
// Only respond to MIDI input from source 8454149 (device 1)
if (src == ~pulsar, {
// Turn off the synth and free the memory for device 1
~notes[nn].set(\gate, 0);
~notes[nn] = nil;
});
});
// Handle noteOn for MIDI device 8454145 (second device)
MIDIdef.noteOn(\noteOnTest_device2, {
arg vel, nn, chan, src;
[vel, nn, src].postln; // Post the velocity, note number, and source to the console
// Only respond to MIDI input from source 8454145 (device 2)
if (src == ~mellotron, {
// Create a new synth for device 2
~notes[nn] = Synth.new(
\mellotron,
[
\freq, nn.midicps,
\amp, vel.linexp(1,127,0.01,0.3),
]
);
});
});
// Handle noteOff for MIDI device 8454145 (second device)
MIDIdef.noteOff(\noteOffTest_device2, {
arg vel, nn, chan, src;
[vel, nn, src].postln;
// Only respond to MIDI input from source 8454145 (dev
if (src == ~mellotron, {
// Turn off the synth and free the memory for device 2
~notes[nn].set(\gate, 0);
~notes[nn] = nil;
});
});
)
MIDIIn.free;

@ -1,17 +1,23 @@
MIDIIn.connectAll;
~pulsar = 8388610;
~mellotron = 8388611;
(
~notes = Array.newClear(128); // Initialize the array to store synths
// Handle noteOn for MIDI device 8454149 (first device)
MIDIdef.noteOn(\noteOnTest_device1, {
arg vel, nn, chan, src;
[vel, nn, src].postln; // Post the velocity, note number, and source to the console
[vel, nn, src].postln; // Post the velocity, note number, and source to thethe console
// Only respond to MIDI input from source 8454149 (device 1)
if (src == 8454147, {
if (src == ~pulsar, {
// Create a new synth for device 1
~notes[nn] = Synth.new(
\mellotron,
[
\fm_pulsar_terrain, [
\freq, nn.midicps,
\amp, vel.linexp(1,127,0.01,0.3),
]
@ -25,10 +31,10 @@ MIDIdef.noteOff(\noteOffTest_device1, {
[vel, nn, src].postln;
// Only respond to MIDI input from source 8454149 (device 1)
if (src == 8454147, {
if (src == ~pulsar, {
// Turn off the synth and free the memory for device 1
~notes[nn].set(\gate, 0);
~notes[nn] = nil;
~notes[nn].set(\gate, 0);
~notes[nn] = nil;
});
});
@ -38,10 +44,10 @@ MIDIdef.noteOn(\noteOnTest_device2, {
[vel, nn, src].postln; // Post the velocity, note number, and source to the console
// Only respond to MIDI input from source 8454145 (device 2)
if (src == 8454146, {
if (src == ~mellotron, {
// Create a new synth for device 2
~notes[nn] = Synth.new(
\fm_pulsar_terrain,
\mellotron,
[
\freq, nn.midicps,
\amp, vel.linexp(1,127,0.01,0.3),
@ -55,12 +61,14 @@ MIDIdef.noteOff(\noteOffTest_device2, {
arg vel, nn, chan, src;
[vel, nn, src].postln;
// Only respond to MIDI input from source 8454145 (device 2)
if (src == 8454146, {
// Only respond to MIDI input from source 8454145 (dev
if (src == ~mellotron, {
// Turn off the synth and free the memory for device 2
~notes[nn].set(\gate, 0);
~notes[nn] = nil;
});
});
)
)
MIDIIn.free;

@ -0,0 +1,51 @@
~setupMidiForNdef = { |ndefName, midiChan = 0, ccMap|
var ndef = Ndef(ndefName);
// Remove old defs if they exist
MIDIdef.noteOn((ndefName ++ "_On").asSymbol).clear;
MIDIdef.noteOff((ndefName ++ "_Off").asSymbol).clear;
MIDIdef.cc((ndefName ++ "_CC").asSymbol).clear;
// Note on/off
MIDIdef.noteOn(
(ndefName ++ "_On").asSymbol,
{ |vel, note, chan|
ndef.put(
note,
ndef.source,
0,
[\freq, note.midicps, \gt, 1, \lev, vel / 127]
);
},
chan: midiChan
).fix;
MIDIdef.noteOff(
(ndefName ++ "_Off").asSymbol,
{ |vel, note, chan| ndef.removeAt(note) },
chan: midiChan
).fix;
// MIDI CC mapping
MIDIdef.cc(
(ndefName ++ "_CC").asSymbol,
{ |val, num|
var param = ccMap[num];
if (param.notNil) {
var spec = ndef.getSpec(param) ?? ControlSpec(0, 1);
ndef.set(param, spec.map(val / 127));
};
},
ccNum: ccMap.keys,
chan: midiChan
).fix;
};
~setupMidiForNdef.(
\,
0,
(
0: \freq, 60;
)
);

@ -102,7 +102,8 @@ Pbind(
\instrument, \mellotron,
\freq, Pseq([
// [65, 69, 71], // F Major (F, A, C)
[65, 69, 71], // F Major (F, A, C)
[80, 75,],
[90, 70],
[90, 70],

@ -0,0 +1,15 @@
{max(SinOsc.ar(220), 0) !2}.play
(
SynthDef(\pm, {
var sig;
sig = PMOsc.ar(\freq.ar(440), \modfreq.kr(0), \pmindex.kr(0), SinOsc.kr(\modphase.kr(1.0)));
Out.ar(0, sig.dup);
}).add;
x = Synth(\pm, [\freq, 240, \modfreq, 20, \pmindex, 5, \modphase, 1]);
)

@ -0,0 +1,90 @@
(
{
var freq = 220;
var trig = Impulse.kr(1); // re-pluck every second
var burst = SinOsc.ar(freq) * EnvGen.kr(Env.perc(0.001, 0.05), trig); // short sine burst
Pluck.ar(
burst,
trig,
0.2, // max delay time
1/freq, // delay time = 1 / frequency
3, // decay
0.5 // damping
) * 0.4;
}.play;
)
(
SynthDef(\envPluckSine, {
|out=0, freq=220, amp=0.4, sustain=1.5|
var trig, env, sig;
trig = Impulse.kr(1); // triggers every second
env = EnvGen.kr(Env.perc(0.001, sustain), trig);
sig = SinOsc.ar(freq) * env * amp;
Out.ar(out, sig.dup); // stereo
}).add;
)
(
SynthDef(\pluckedSine, {
|out=0, freq=220, amp=0.4, decay=3, coef=0.5|
var trig, burst, pluck;
trig = Impulse.kr(0); // trigger manually
burst = SinOsc.ar(freq) * EnvGen.kr(Env.perc(0.001, 0.05), trig);
pluck = Pluck.ar(
burst,
trig,
0.2, // max delay time
1 / freq, // delay time = 1 / freq
decay,
coef
);
Out.ar(out, pluck.dup * amp);
}).add;
)
(
~notes = Array.newClear(128);
MIDIdef.noteOn(\noteOnTest, {
arg vel, nn, chan, src;
[vel, nn].postln;
if (chan == 0, {
~notes[nn] = Synth.new(
\prophet5style,
[
\freq, nn.midicps,
\amp, vel.linexp(1,127,0.01,0.3),
// \gate, 1,
]
);
});
});
MIDIdef.noteOff(\noteOffTest, {
arg vel, nn, chan;
[vel, nn].postln;
if (chan == 0, {
~notes[nn].set(\gate, 0);
~notes[nn] = nil;
});
});
)

@ -0,0 +1,73 @@
(
SynthDef(\prophet5style, {
|out=0, freq=440, amp=0.5, detune=0, osc1Wave=0, osc2Wave=1, filterCutoff=600, filterResonance=0.5,
attack=0.1, decay=1, sustain=0.7, release=0.3, lfoRate=0.5, lfoDepth=0.5,
lfoFreq=1, lfoWave=1, filterModDepth=0.3|
// Oscillators
var osc1, osc2, lfo, env, filter, filteredSignal, drySignal;
// Oscillator 1 & 2: Waveforms and detuning
osc1 = Select.ar(osc1Wave, [SinOsc.ar(freq), Saw.ar(freq), Pulse.ar(freq, 0.5)]);
osc2 = Select.ar(osc2Wave, [SinOsc.ar(freq + detune), Saw.ar(freq + detune), Pulse.ar(freq + detune, 0.5)]);
// Envelope
env = EnvGen.kr(Env.perc(attack, decay, sustain, release), doneAction: 2);
// LFO for modulation (filter or other params)
lfo = SinOsc.kr(lfoRate, 0, lfoDepth);
// Filter
// filter = osc1 + osc2;
filter = BPF.ar(osc1 + osc2, filterCutoff, filterResonance);
filteredSignal = filter * env;
// Modulate filter with LFO
filteredSignal = filteredSignal * (1 + lfo * filterModDepth);
// Dry signal (unfiltered)
drySignal = (osc1 + osc2) * env;
// Output mixed signal
Out.ar(out, (filteredSignal + drySignal).dup * amp);
}).add;
)
MIDIClient.init;
MIDIIn.connectAll;
x = Synth(\prophet5style);
// Mapping MIDI CCs to synth parameters
(
~midiMap = {
|num, val|
var osc1Wave, osc2Wave, release, cutoff, resonance;
// Conditional mappings for parameters
osc1Wave = num == 1 ifTrue: { val.linlin(0, 127, 0, 2).round } ifFalse: { 0 };
osc2Wave = num == 2 ifTrue: { val.linlin(0, 127, 0, 2).round } ifFalse: { 0 };
release = num == 8 ifTrue: { val.linlin(0, 127, 0.01, 3) } ifFalse: { 0.3 };
cutoff = num == 74 ifTrue: { val.linlin(0, 127, 20, 2000) } ifFalse: { 1000 };
resonance = num == 71 ifTrue: { val.linlin(0, 127, 0, 1) } ifFalse: { 0.5 };
// Return a dictionary with mapped parameters
^(
\osc1Wave -> osc1Wave,
\osc2Wave -> osc2Wave,
\release -> release,
\cutoff -> cutoff,
\resonance -> resonance
);
};
)
// Use the midi map to update synth parameters
MIDIIn.control = { |num, val|
var mappedParams = ~midiMap.(num, val);
Synth(\prophet5styleModular, mappedParams);
};

@ -1,22 +1,17 @@
b = Buffer.read(s, "/Users/lcoogan/snd/installation/zeitlin-six_lines.wav");
b = Buffer.read(s, "/home/lcoogan/snd/installation/zeitlin-six_lines.wav");
(
SynthDef(\voiceObscured, {
arg out=0, bufnum, rate=1, shift=0, cutoff=1200, amp = 40;
var sig;
sig = PlayBuf.ar(1, bufnum, BufRateScale.kr(bufnum) * rate, doneAction: 2);
sig = NoiseRepellent.ar(sig, learner:NRAverage(\isLearning.kr(0)));
sig = PitchShift.ar(sig, 0.2, 2.pow(shift / 12), 0.01, 0.01);
sig = LPF.ar(sig, cutoff); // soften sibilance
// sig = BPF.ar(sig, 60, 0.001).neg + sig; // cancels 60Hz hum
// sig = BPF.ar(sig, 120, 0.001).neg + sig; // cancels 2nd harmonic
// sig = NoiseRepellent.ar(sig, learner:NRAverage(\isLearning.kr(0)), reductionAmount:40);
sig = HPF.ar(sig, cutoff); // soften sibilance
sig = sig * amp ;
Out.ar(out, sig.dup);
}).add;
)
Synth(\voiceObscured, [\bufnum, b, \shift, -7, \cutoff, 1000, \amp, 40]);
Synth(\voiceObscured, [\isLearning, 1]); // capture some noise
Synth(\voiceObscured, [\isLearning, 0]); // start the script
x = Synth(\voiceObscured, [\bufnum, b, \amp, 60]);
x.set(\isLearning, 1); // capture some noise
x.set(\isLearning, 0); // start the script

@ -0,0 +1,123 @@
(
// Run once to convert and resample wavetable files
var paths, file, data, n, newData, outFile;
paths = PathName("/home/lcoogan/snd/wtables/AKWF").deepFiles.select { |f|
f.extension == "wav"
};
Routine({
paths.do { |path, i|
var outputPath;
// 'protect' ensures file cleanup on error
protect {
// Read original data
file = SoundFile.openRead(path.fullPath);
data = Signal.newClear(file.numFrames);
file.readData(data);
0.1.wait;
// Resample to n = 4096 samples (power of 2)
n = 4096;
newData = data.resamp1(n).as(Signal).asWavetable;
0.1.wait;
// Generate output file path
outputPath = path.fullPath ++ "_4096.wtable";
// Write to disk
outFile = SoundFile(outputPath)
.headerFormat_("WAV")
.sampleFormat_("float")
.numChannels_(1)
.sampleRate_(44100);
if(outFile.openWrite.notNil) {
outFile.writeData(newData);
0.1.wait;
} {
"Couldn't write output file: %".format(outputPath).warn;
};
} {
file.close;
if(outFile.notNil) { outFile.close };
};
};
}).play;
)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
(
SynthDef(\wtable_vosc_dual_t_0, {| vel=1|
var env, freq;
var wtbufnumRange = [ ~wtbufnums.minItem, ~wtbufnums.maxItem ];
var sig;
var fenv;
var driveDB = \driveDB.kr(0);
var direct = \direct.kr(0.5);
// var trg = \trg.kr(1);
// var trg = Dust.kr(2);
var trg = Impulse.kr(1);
env = EnvGen.ar(
Env.adsr(
TExpRand.kr(0.001, 0.1, trg),
TExpRand.kr(0.001, 0.1, trg),
TExpRand.kr(0.1, 0.6, trg),
TExpRand.kr(1.5,4,trg),
curve: TRand.kr(-5.0,4,trg)
),
gate:trg,
doneAction:0
).lag(0.1) * vel;
env = XFade2.ar(env,LFDNoise3.ar(env * 20 + 1).range(0,1), env*2-1);
// env = env * WhiteNoise.ar(MouseX.kr(0,1)!2).range(0,1.0);
// fenv = env * LFNoise0.kr(TRand.kr(1,21, trg)).range(0.5,1.4).lag(TRand.kr(0.0001,0.1, trg));
fenv = env * VOsc.ar(
\fmodbufn.kr( rrand( wtbufnumRange[0],wtbufnumRange[1] ) ).lag(0.4),
\fmodFreq.kr(11)
).range(0.5,1.4)
.lag(TRand.kr(0.0001,0.01, trg));
freq = \freq.kr(111).lag(0.1);
// freq = LFNoise0.kr(1).exprange(80,1000).lag(0.1);
// freq = TExpRand.kr(80,1000,trg);
sig = VOsc.ar(
(
VOsc.ar(\wtmodbufn.kr( rrand( wtbufnumRange[0],wtbufnumRange[1] ) ).lag(0.3), \wtmodfreq.kr(2), Rand(0,2pi), \wtmodamp.kr(1))
+
( env * [ Rand(0.5,1.5), Rand(0.5,1.5) ])
// ( env.pow(1.4) * [ LFNoise1.kr(3).range(1.5,9), LFNoise1.kr(3).range(1.5,9)] + 0.1)
+
\bufn.ar( rrand( wtbufnumRange[0],wtbufnumRange[1] ) )
).lag(0.1).mod( wtbufnumRange[1] - wtbufnumRange[0] ) + wtbufnumRange[0],
freq
) * env;
sig = MoogVCF.ar(
sig * driveDB.dbamp,
XFade2.ar( env.pow(1.4), fenv.pow(1.4), \fmod.kr(0)) * \fltRange.kr(10000) + 50 ,
\res.kr(0)
);
sig = sig * driveDB.neg.dbamp * 0.4; // compensate drive
sig * direct;
Out.ar(0, sig);
}).add;
)

@ -0,0 +1,55 @@
(
SynthDef(\wtable_vosc_dual_clean, { |freq = 440, vel = 1, gate = 1, amp = 0.5, driveDB = 0, fmod = 0, res = 0.6, fltRange = 6000, direct = 1|
var env, sig, wtbufnum, wtbufnMod, osc, modOsc, fenv;
var wtbufnumRange = [ ~wtbufnums.minItem, ~wtbufnums.maxItem ];
// Standard ADSR Envelope
env = EnvGen.kr(
Env.adsr(0.1, 0.5, 0.6, 1, peakLevel:1.0, curve:-1.0, bias:0.0),
gate,
doneAction: 2
) * vel;
// Select a wavetable buffer in range
wtbufnum = \bufn.kr(wtbufnumRange[0]);
// Optional modulation oscillator (wavetable-based)
modOsc = VOsc.ar(
\wtmodbufn.kr(wtbufnumRange[0]),
\wtmodfreq.kr(2),
\modPhase.kr(0),
\wtmodamp.kr(1)
);
// Main oscillator using VOsc
osc = VOsc.ar(
wtbufnum,
freq
);
// Optional filtered modulation of the filter cutoff
fenv = VOsc.ar(
\fmodbufn.kr(wtbufnumRange[0]),
\fmodFreq.kr(0)
).range(0.5, 1.5);
// Apply envelope and optional distortion/filtering
sig = osc * env;
sig = RLPF.ar(
sig * driveDB.dbamp,
(freq * fenv).clip(40, fltRange),
res
);
sig = Resonz.ar(sig, Line.kr(200, 840), bwr:Line.kr(0.5, 0.1), mul:1.0, add:0.0);
sig = CombL.ar(sig, maxdelaytime:0.8, delaytime:0.5, decaytime:0.5, mul:1.0, add:0.0);
// Final level and output
sig = sig * amp * direct;
Out.ar(0, sig.dup);
}).add;
)

@ -0,0 +1,195 @@
(
SynthDef(\wtable_vosc_dual, {
var env, sig, freq, buf, wtmod, wtpos;
var wtbufnumRange = [ ~wtbufnums.minItem, ~wtbufnums.maxItem ];
// Main controls
var gate = \gate.kr(1);
freq = \freq.kr(120) / 2;
buf = \bufn.kr(wtbufnumRange[2]);
wtmod = \wtmodbufn.kr(wtbufnumRange[2]);
// Envelope
env = EnvGen.kr(
Env.adsr(
\attack.kr(0.1),
\decay.kr(0.2),
\sustain.kr(3.0),
\release.kr(1.0)
),
gate,
doneAction: 2
).lag(\envLag.kr(0.1));
wtpos = (
VOsc.ar(wtmod, \wtmodfreq.kr(0), \phase.kr(0), \wtmodamp.kr(1)
)
+ env.pow(1.4)
+ buf
).lag(1.8)
.mod(wtbufnumRange[1] - wtbufnumRange[0])
+ wtbufnumRange[0];
sig = VOsc.ar(wtpos, freq, \phase.kr(0), 1) * env * \amp.kr(0.2);
// sig = BPF.ar(sig, \lpf.ar(800), \q.ar(1.0));
sig = BLowShelf.ar(sig, \lpf.ar(800), \q.ar(1.0));
sig = AllpassN.ar(sig, 1, 1, 1);
Out.ar(\out.kr(0), sig ! 2);
}).add;
)
x = Synth(\wtable_vosc_dual, [\freq, 70.midicps]);
(
Pbind(
\instrument, \wtable_vosc_dual, // Choose SynthDef
\amp, Pwhite(0.2, 0.8, inf), // Random amplitude (0.2 to 0.8)
/* \mod1, Pwhite(5, 40, inf), // Random mod1 value (5 to 40)
\mod2, Pwhite(0.01, 0.3, inf), // Random mod2 value (0.01 to 0.3)
\mod3, Pwhite(1, 10, inf), // Random mod3 value (1 to 10)
\mod4, Pwhite(0.1, 0.8, inf), // Random mod4 value (0.1 to 0.8)
\mod5, Pwhite(0.01, 0.4, inf), // Random mod5 value (0.01 to 0.4)*/
\freq, Pwhite(40, 70, inf),
\dur, Pseq([1], inf) // Sequence of durations
).play;
)
(
~chords = (
"Csus4": [0, 5, 7], // Root, fourth, fifth
"Cmaj7": [0, 4, 7, 11],
"Cmin7": [0, 3, 7, 10],
"C5": [0, 7], // Power chord
"C": [0, 4, 7]
);
)
(
~chords = (
\Csus4: [0, 5, 7],
\Cmaj7: [0, 4, 7, 11],
\Cmin7: [0, 3, 7, 10],
\C5: [0, 7],
\C: [0, 4, 7]
);
)
(
Pbind(
\instrument, \wtable_vosc_dual,
\amp, 0.5,
\dur, 1,
\midinote, Pseq([
~chords["Csus4"] + 60, // Transpose to MIDI note 60 (C4)
].flat, inf)
).play;
)
x = Synth(\wtable_vosc_dual [\freq, Pseq((~chords["Csus4"] + 60).midicps, inf)]);
(
~chords = (
\Csus4: [[2, 4]],
\Cmaj7: [[0, 4, 7, 11]],
\Cmin7: [[0, 3, 7, 10]],
\C5: [[0, 7]],
\C: [[0, 4, 7]]
);
Pbind(
\instrument, \wtable_vosc_dual,
\amp, 0.4,
\dur, Pwhite(0.4, 0.8),
// add freq ratio
\midinote, Pwhite(40, 80),
// \midinote, Pseq((~chords[\Cmin7, ~chords[\Cmaj7]] + 60), inf)
).play;
)
(
~chords = (
/*\Csus4: [[ 3, 5]],
// \Cmaj7: [0, 1, 3, 7],
\Cmin7: [[3, 7]],
\whatever: [3, 5],
\whateer: [12, 15],*/
\Fm: [[0, 3, 7]],
\Bbm: [[-1, 2, 6]], // Relative to C
\F: [[0, 4, 7]],
\Eb: [[-4, 0, 3]],
\Ebm: [[-4, -1, 3]]
/* \C5: [0, 7],
\C: [0, 4, 7],*/
);
~chordKeys = ~chords.keys;
Pbind(
\instrument, \wtable_vosc_dual,
\amp, 0.4,
\dur, Pwhite(0.1, 1),
\midinote, Pfunc({
var chordName = ~chordKeys.choose; // Randomly pick a chord
var chord = ~chords[chordName]; // Get its intervals
var note = chord.choose + 60; // Pick one and transpose
note;
}),
\attack, Pwhite(0.01, 0.1),
\decay, Pwhite(0.1, 0.3),
\sustain, Pwhite(0.2, 0.8),
\release, Pwhite(0.1, 2.0),
\lpf, Pwhite(800, 2000),
\q, Pwhite(0.3, 1.0),
).play;
)
(
~freygish = [0, 1, 4, 5, 7, 8, 10]; // Freygish scale in C
~root = 60; // Middle C
Pbind(
\instrument, \wtable_vosc_dual,
\amp, 0.4,
\dur, Pwhite(1, 2),
\midinote, Pfunc({
~root + ~freygish.choose;
})
).play;
)
(
~chords = (
\Csus4: [0, 5, 7],
\Cmaj7: [0, 4, 7, 11],
\Cmin7: [0, 3, 7, 10],
\C5: [0, 7],
\C: [0, 4, 7]
);
Pbind(
\instrument, \wtable_vosc_dual,
\amp, 0.4,
\dur, 1,
\midinote, Pcollect(
Pseq([\Cmin7, \Cmaj7, \C5], inf), // sequence of chord names
{ |chordName| ~chords[chordName] + 60 } // map to MIDI notes
)
).play;
)

@ -0,0 +1,41 @@
(
SynthDef(\wtable_vosc_dual, {
var env, sig, freq, buf, wtmod, wtpos;
var wtbufnumRange = [ ~wtbufnums.minItem, ~wtbufnums.maxItem ];
// Main controls
var gate = \gate.kr(1);
freq = \freq.kr(220);
buf = \bufn.kr(wtbufnumRange[0]);
wtmod = \wtmodbufn.kr(wtbufnumRange[1]);
// Envelope
env = EnvGen.kr(
Env.perc(
\attack.kr(0.1),
\release.kr(1.0)
),
gate,
doneAction: 2
).lag(\envLag.kr(0.1));
// Wavetable oscillator modulation
wtpos = VOsc.ar(
wtmod,
\wtmodfreq.kr(2),
\phase.kr(0),
\wtmodamp.kr(1)
)
+ env.pow(1.4)
+ buf;
wtpos = wtpos.lag(1.8).mod(wtbufnumRange[1] - wtbufnumRange[0]) + wtbufnumRange[0];
// Final signal
sig = VOsc.ar(wtpos, freq, \phase.kr(0), 1) * env * \amp.kr(0.2);
// Output
Out.ar(\out.kr(0), sig ! 2);
}).add;
)
Loading…
Cancel
Save