experiments

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

@ -0,0 +1,111 @@
(
// Load buffers
Buffer.readChannel(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/crawling-stems/lead.wav", channels:[0], bufnum: 0);
Buffer.readChannel(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/crawling-stems/perc mel solo.wav", channels:[0], bufnum: 1);
Buffer.readChannel(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/crawling-stems/bass.wav", channels:[0], bufnum: 2);
Buffer.readChannel(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/crawling-stems/drums.wav", channels:[0], bufnum: 3);
Buffer.readChannel(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/crawling-stems/break.wav", channels:[0], bufnum: 4);
)
(
// Granulator
Ndef(\granulator, { |bufnum=0, tFreq=20, overlap=2, rate=1, posStart=0.0,
tFreqMF=0, tFreqMD=0, rateMF=0, rateMD=0,
posRateMF=0, posRateMD=0, granDur=4|
var samplePhasor, phasor, gran, env, bufrd;
var bufFrames = BufFrames.ir(bufnum);
var t;
var tFreqMod = SinOsc.ar(tFreqMF, Rand(0.0, 2pi)) * tFreqMD;
var rateMod = SinOsc.ar(rateMF, Rand(0.0, 2pi)) * rateMD;
var posRateMod = SinOsc.ar(posRateMF, Rand(0.0, 2pi)) * posRateMD;
var playTrig = Impulse.ar(\playTrFr.kr(0.5));
tFreq = tFreq + tFreqMod.dup;
rate = rate + rateMod.dup;
t = Impulse.ar(tFreq);
samplePhasor = EnvGen.ar(Env([0, 0, bufFrames], [0, bufFrames / SampleRate.ir], curve: 0), gate: playTrig);
phasor = EnvGen.ar(Env([posStart, posStart, 1], [0, granDur], curve: 0), gate: playTrig);
bufrd = BufRd.ar(1, bufnum, samplePhasor, interpolation: 4);
bufrd = LeakDC.ar(bufrd);
gran = GrainBufJ.ar(
numChannels: 1,
trigger: t,
dur: tFreq.reciprocal * overlap,
sndbuf: bufnum,
rate: rate,
pos: phasor + posRateMod.dup,
interp: 2,
pan: 0,
envbufnum: -1,
maxGrains: 512,
loop: 0
) * EnvGen.ar(Env.perc(0.001, granDur * \grainGate.kr(1), curve: \granCurve.kr(-4)), gate: playTrig);
Mix([
bufrd * \dry.kr(1.0),
gran * \wet.kr(0.5)
])
});
Ndef(\granulator).addSpec(
\overlap, [0.001, 40, \exp],
\rate, [-2, 2],
\posStart, [0.0, 1.0],
\tFreq, \widefreq,
\tFreqMF, [0.0,80],
\tFreqMD, [0.0,20],
\rateMF, [0.0,80],
\rateMD, [0.0,2],
\posRateMF, [0.0,80],
\posRateMD, [0.0,2],
\dry, [0.0,1],
\wet, [0.0,1],
\playTrFr, [0.0,1],
\granDur, [0.0,8],
\granCurve, [-10,10],
\grainGate, [0,1],
\bufnum, [0, 4, \lin, 1]
).edit;
)
(
// MIDI Mappings for Channel 2 (MIDI channels are zero-indexed)
MIDIdef.cc(\gran_bufnum, { |val, num, chan|
if(chan == 1, { Ndef(\granulator).set(\bufnum, val.linlin(0,127,0,4).round(1)) });
}, ccnum: 1);
MIDIdef.cc(\gran_posStart, { |val, num, chan|
if(chan == 1, { Ndef(\granulator).set(\posStart, val.linlin(0,127,0,1)) });
}, ccnum: 2);
MIDIdef.cc(\gran_tf, { |val, num, chan|
if(chan == 1, { Ndef(\granulator).set(1\tFreq, val.linexp(0,127,0.1,100)) });
}, ccnum: 3);
MIDIdef.cc(\gran_overlap, { |val, num, chan|
if(chan == 1, { Ndef(\granulator).set(\overlap, val.linexp(0,127,0.01,20)) });
}, ccnum: 4);
MIDIdef.cc(\gran_rate, { |val, num, chan|
if(chan == 1, { Ndef(\granulator).set(\rate, val.linlin(0,127,-2,2)) });
}, ccnum: 5);
MIDIdef.cc(\gran_posRateMD, { |val, num, chan|
if(chan == 1, { Ndef(\granulator).set(\posRateMD, val.linlin(0,127,0,2)) });
}, ccnum: 6);
MIDIdef.cc(\gran_dry, { |val, num, chan|
if(chan == 1, { Ndef(\granulator).set(\dry, val.linlin(0,127,0,1)) });
}, ccnum: 7);
MIDIdef.cc(\gran_wet, { |val, num, chan|
if(chan == 1, { Ndef(\granulator).set(\wet, val.linlin(0,127,0,1)) });
}, ccnum: 8);
)

@ -0,0 +1,664 @@
// Author: Alik Rustamoff
// Repo: https://github.com/alikthename/Musical-Design-in-Supercollider
// Video: https://www.youtube.com/watch?v=c5wM-Pgxf70&list=PLXCUkMwOEWQsjiAVWdMzvmsGWEIvyu2KG&index=5
// =====================================================================
// SuperCollider Workspace
// =====================================================================
b = Buffer.readChannel(s, "non-oneshot-sample-path", channels:[0]);
b = Buffer.readChannel(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/01-Acheinu_Kol_Beit_Israel.wav", channels:[0]);
(
b = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/01-Acheinu_Kol_Beit_Israel.wav");
b = Buffer.readChannel(s, "/home/lcoogan/snd/ardour/hebrewian_rue/export/hebrewian_rue_r1_lead.wav", channels:[0]);
b = Buffer.readChannel(s, "/home/lcoogan/snd/ardour/hebrewian_rue/export/hebrewian_rue_r1_harm.wav", channels:[0]);
b = Buffer.readChannel(s, "/home/lcoogan/snd/ardour/hebrewian_rue/export/hebrewian_rue_r1_drums.wav", channels:[0]);
)
(
Buffer.readChannel(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/crawling-stems/lead.wav", channels:[0], bufnum: 0);
Buffer.readChannel(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/crawling-stems/perc mel solo.wav", channels:[0], bufnum: 1);
Buffer.readChannel(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/crawling-stems/bass.wav", channels:[0], bufnum: 2);
Buffer.readChannel(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/crawling-stems/drums.wav", channels:[0], bufnum: 3);
Buffer.readChannel(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/crawling-stems/break.wav", channels:[0], bufnum: 4);
)
b.play
Ndef(\granulator).clear;
Ndef(\granulator).ar(2);
Ndef(\granulator).set(\bufnum, b.bufnum);
( // one-shot reverb
Ndef(\granulator, { |bufnum, tFreq=20, overlap=2, rate=1, tFreqMF=0, tFreqMD=0,
rateMF=0, rateMD=0, posRateMD=0, posRateMF=0, granDur=4|
var samplePhasor, phasor, gran, env, bufrd;
var bufFrames = BufFrames.ir(bufnum);
var t;
var tFreqMod = {
SinOsc.ar(tFreqMF, Rand(0.0,2pi)) * tFreqMD;
};
var rateMod = {
SinOsc.ar(rateMF, Rand(0.0,2pi)) * rateMD;
};
var posRateMod = {
SinOsc.ar(posRateMF, Rand(0.0,2pi)) * posRateMD;
};
var playTrig = Impulse.ar(\playTrFr.kr(0.5));
tFreq = tFreq + tFreqMod.dup;
rate = rate + rateMod.dup;
t = Impulse.ar(tFreq);
// t = In.ar(somebus);
samplePhasor = EnvGen.ar(Env([0, 0, bufFrames], [0, bufFrames / SampleRate.ir], curve: 0), gate: playTrig);
phasor = EnvGen.ar(Env([0, 0, 1], [0, granDur], curve: 0), gate: playTrig);
bufrd = BufRd.ar(
numChannels: 1,
bufnum: bufnum,
phase: samplePhasor,
interpolation: 4
);
bufrd = LeakDC.ar(bufrd);
gran = GrainBufJ.ar(
numChannels: 1,
trigger: t,
dur: tFreq.reciprocal * overlap,
sndbuf: bufnum,
rate: rate,
// pos: phasor + WhiteNoise.ar(posRateMD!2),
pos: phasor + posRateMod.dup,
interp: 2,
pan: 0,
envbufnum: -1,
maxGrains: 512,
loop: 0
) * EnvGen.ar(Env.perc(0.001, granDur * \grainGate.kr(1), curve: \granCurve.kr(-4)), gate: playTrig);
Mix([
bufrd * \dry.kr(1.0),
gran * \wet.kr(0.5)
])
// DetectSilence.ar(gran, doneAction: 2); // in case we lauch it without trigger Ugens (with Synth etc)
});
Ndef(\granulator).addSpec(
\overlap, [0.001, 40, \exp],
\rate, [-2, 2],
\posRate, [0, 4],
\tFreq, \widefreq,
\tFreqMF, [0.0,80],
\tFreqMD, [0.0,20],
\rateMF, [0.0,80],
\rateMD, [0.0,2],
\posRateMF, [0.0,80],
\posRateMD, [0.0,2],
\dry, [0.0,1],
\wet, [0.0,1],
\playTrFr, [0.0,1],
\granDur, [0.0,8],
\granCurve, [-10,10],
\grainGate, [0,1],
).edit;
)
// tFreq modulation + little rate mod
Ndef('granulator').set('wet', 0.20634920634921, 'tFreq', 68.049596318246, 'posRateMF', 0.0, 'posRateMD', 0.0, 'rateMF', 40.21164021164, 'tFreqMF', 22.857142857143, 'tFreqMD', 18.835978835979, 'playTrFr', 0.24867724867725, 'granDur', 6.3915343915344, 'rateMD', 0.031746031746032, 'overlap', 27.015519604492, 'bufnum', b.bufnum, 'dry', 0.8994708994709, 'posRate', 1.0);
// rate modulation only
Ndef('granulator').set('wet', 0.49206349206349, 'tFreq', 68.049596318246, 'posRateMF', 0.0, 'posRateMD', 0.0, 'rateMF', 29.62962962963, 'tFreqMF', 0.0, 'tFreqMD', 0.0, 'playTrFr', 0.24867724867725, 'granDur', 6.8994708994709, 'rateMD', 0.052910052910053, 'overlap', 27.015519604492, 'bufnum', b.bufnum, 'dry', 0.82010582010582, 'posRate', 1.0);
// posRate mod only
Ndef('granulator').set('wet', 0.49, 'tFreq', 82.597877312021, 'posRateMF', 21.164021164021, 'posRateMD', 0.1481481486212, 'rateMF', 0.0, 'tFreqMF', 0.0, 'tFreqMD', 0.0, 'granDur', 1.1428571428571, 'playTrFr', 0.53439153439153, 'rateMD', 0.0, 'overlap', 14.580370622763, 'bufnum', b.bufnum, 'dry', 0.8);
// all parameters at once
Ndef('granulator').set('wet', 0.53968253968254, 'tFreq', 56.063759866166, 'posRateMF', 0.0, 'rateMF', 20.31746031746, 'tFreqMF', 42.328042328042, 'tFreqMD', 7.6190476190476, 'playTrFr', 0.24867724867725, 'granDur', 0.8042328042328, 'rateMD', 0.031746031746032, 'overlap', 7.4400230051039, 'posRate', 1.0, 'bufnum', b.bufnum, 'dry', 0.77777777777778);
// unnatural
Ndef('granulator').set('wet', 0.85714285714286, 'tFreq', 56.063759866166, 'posRateMF', 0.0, 'rateMF', 20.31746031746, 'tFreqMF', 42.328042328042, 'tFreqMD', 7.6190476190476, 'playTrFr', 0.24867724867725, 'granDur', 2.3703703703704, 'rateMD', 0.031746031746032, 'overlap', 21.58814020418, 'posRate', 1.0, 'bufnum', b.bufnum, 'dry', 0.77777777777778);
// on musical phrase sample
Ndef('granulator').set('wet', 0.1957671957672, 'rate', 1.0, 'tFreq', 82.597877312021, 'posRateMF', 0.0, 'posRateMD', 0.0, 'rateMF', 20.31746031746, 'tFreqMF', 0.0, 'tFreqMD', 0.0, 'playTrFr', 0.24867724867725, 'granDur', 5.4603174603175, 'rateMD', 0.0042328039805094, 'overlap', 12.323100555167, 'posRate', 1.0, 'bufnum', b.bufnum, 'dry', 0.84126984126984);
Ndef('granulator').set('granCurve', -0.79365079365079, 'wet', 0.48148148148148, 'rate', 1.0, 'tFreq', 82.597877312021, 'posRateMF', 7.1957671957672, 'posRateMD', 0.010582010582011, 'rateMF', 20.31746031746, 'tFreqMF', 53.333333333333, 'tFreqMD', 10.05291005291, 'playTrFr', 0.24867724867725, 'granDur', 5.4603174603175, 'rateMD', 0.010582010582011, 'overlap', 12.323100555167, 'grainGate', 1.0, 'bufnum', b.bufnum, 'dry', 0.84126984126984, 'posRate', 1.0);
( // triggered Env.new
{
[
EnvGen.kr(Env(levels: [0, 0.1, 0.2, 0.3], times: [0.1, 0.1, 0.1], curve: 8), gate: Impulse.kr(3)),
EnvGen.kr(Env(levels: [0, 0.0, 0.2, 0.3], times: [0.0, 0.1, 0.1], curve: 8), gate: Impulse.kr(3))
]
}.plot(duration: 1);
)
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
////////////////////// GrainBuf as effect //////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
b.play;
(
Ndef('alik_input_granulate_0').addSpec(
// \recLevel, [0,1],
// \preLevel, [0,1],
\feedback, [-2.0,2],
\inAmp, \inAmp,
\wet, \bipolar,
\inputAmp, [0,30],
\tFreqMF, [0,200],
\tFreqMD, [0,200],
\offsetMF, \widefreq,
\offsetMD, [0.0,1],
\rateMF, \widefreq,
\rateMD, [0.0,1],
\offset, [0.0,1],
\rate, \bipolar,
\tFreq, [1,22050, \exp],
\overlap, [0.01,512.0, \exp],
\grHpf, \freq,
\grLpf, \freq,
\wet, [0.0,1],
\dry, [0.0,1],
\outAmp, [0.0,4],
)
)
Ndef('alik_input_granulate_0').clear
Ndef('alik_input_granulate_0').ar(2)
Ndef('alik_input_granulate_0').edit
(
Ndef('alik_input_granulate_0', {|
inAmp=1, outAmp=1, overlap=2, tFreq=20, tFreqMF=0, tFreqMD=0,
rate=1, rateMF=0, rateMD=0,
offset = 0, offsetMF=0, offsetMD=0
|
var input;
var gDur, readPos, signal, writePos, grained, balance;
var t, bufFrames, bufRateScale;
var buf, bufdur;
var tFreqMod = {
SinOsc.ar(tFreqMF, Rand(0.0,2pi)) * tFreqMD;
};
var rateMod = {
SinOsc.ar(rateMF, Rand(0.0,2pi)).range(rateMD.neg, rateMD);
// SinOsc.ar(rateMF, Rand(0.0,2pi)).range(0, rateMD);
};
var offsetMod = {
SinOsc.ar(offsetMF, Rand(0.0,2pi)).range(0, offsetMD);
// LFDNoise3.ar(offsetMF).range(0,offsetMD(0.0))
};
tFreq = tFreq + tFreqMod.dup;
rate = rate - rateMod.dup;
bufFrames = 2**16;
buf = {LocalBuf(bufFrames).clear}!2;
bufdur = BufDur.ir(buf);
writePos = Phasor.ar( end: bufFrames );
t = Impulse.ar(tFreq);
readPos =
writePos
- 64 // looks like a controlblocksize ------ why?
/ bufFrames
- offset
- offsetMod.dup;
// readPos = readPos.clip( 0, bufFrames - 64 / bufFrames );
readPos = Wrap.ar(readPos, 0, 1);
(
offset * bufFrames + 64 / SampleRate.ir
).poll(10, \delaytime);
grained = GrainBufJ.ar(
numChannels:1,
loop: 1,
trigger:t,
dur: overlap / tFreq,
sndbuf: buf,
rate: rate,
pos: readPos,
interp: 4,
pan: 0,
envbufnum:-1
);
grained = HPF.ar( grained, \grHpf.kr(40) );
grained = LPF.ar( grained, \grLpf.kr(15000) );
input = SoundIn.ar([0,1]) * inAmp;
// writing granulated + input back to grain buffer
buf.do { |b i|
BufWr.ar(grained[i] * \feedback.kr(0.3) + input[i], b, writePos)
// RecordBuf has an option to overdub, might be of any use for big mess
// RecordBuf.ar(
// grained[i] * \feedback.kr(0.3) + input[i],
// b,
// recLevel: \recLevel.kr(1),
// preLevel: \preLevel.kr(0),
// );
};
signal = Mix([
grained * \wet.kr(1),
input * \dry.kr(1)
]) * outAmp;
// signal.tanh
signal
}).play
)
// good on piano (and cheap)
Ndef('alik_input_granulate_0').set('offset', 0.031746031746032, 'tFreqMD', 0.0, 'wet', 0.4973544973545, 'rateMF', 19.782824080247, 'outAmp', 1, 'rate', 1.0, 'grLpf', 14393.713460023, 'offsetMF', 93.986276007881, 'inAmp', 1, 'tFreqMF', 25.092540737125, 'grHpf', 92.831776672256, 'tFreq', 26.59633942062, 'overlap', 5.304141781977, 'rateMD', 0.0, 'offsetMD', 0.10582010582011, 'dry', 1.0, 'feedback', 0.44444444444445);
// flies around piano
Ndef('alik_input_granulate_0').set('offset', 0.042328042328042, 'tFreqMD', 0.0, 'wet', 0.079365079365079, 'rateMF', 19.782824080247, 'outAmp', 1, 'rate', 1.0, 'grLpf', 8319.1243261437, 'offsetMF', 8.0769777651696, 'inAmp', 1, 'tFreqMF', 0.21943273553761, 'grHpf', 92.831776672256, 'tFreq', 395.23259800231, 'overlap', 102.70706933049, 'rateMD', 0.0, 'offsetMD', 0.5978835978836, 'dry', 1.0, 'feedback', 0.084656084656086);
// drum room
Ndef('alik_input_granulate_0').set('offset', 0.031746031746032, 'wet', 0.15343915343915, 'rate', 1.0, 'tFreq', 58.821600133219, 'grLpf', 11144.529591014, 'inAmp', 1, 'offsetMF', 4245.0550792034, 'offsetMD', 0.037037037037037, 'rateMF', 0.0, 'tFreqMF', 20.10582010582, 'grHpf', 89.385349076664, 'tFreqMD', 0.0, 'outAmp', 1, 'overlap', 9.7726573922977, 'dry', 1.0, 'feedback', 0.13756613756614);
// cheap
Ndef('alik_input_granulate_0').set('offset', 0.031746031746032, 'wet', 0.16402116402116, 'rate', 1.0, 'tFreq', 337.21723538924, 'grLpf', 11144.529591014, 'inAmp', 1, 'offsetMF', 100.25642627688, 'offsetMD', 0.083068783439341, 'rateMF', 0.0, 'tFreqMF', 83.597883597884, 'grHpf', 89.385349076664, 'tFreqMD', 93.121693121693, 'outAmp', 1, 'overlap', 9.7726573922977, 'dry', 1.0, 'feedback', 0.43386243386244);
Ndef('alik_input_granulate_0').set('offset', 0.010582010582011, 'wet', 0.10582010582011, 'rate', 1.0, 'tFreq', 120.0, 'grLpf', 11144.529591014, 'inAmp', 1, 'offsetMF', 43.300320303739, 'offsetMD', 0.22063492100548, 'rateMF', 0.37037037037037, 'tFreqMF', 105.82010582011, 'grHpf', 89.385349076664, 'tFreqMD', 0.0, 'rateMD', 0.0063492061284487, 'outAmp', 1, 'overlap', 15.46489059164, 'dry', 1.0, 'feedback', 0.30687830687831);
Ndef('alik_input_granulate_0').set('offset', 0.026455026455026, 'wet', 0.16402116402116, 'offsetMD', 0.037037037037037, 'rate', 1.0, 'grLpf', 11144.529591014, 'tFreq', 123.38739758059, 'inAmp', 1, 'rateMF', 0.14732846585601, 'tFreqMF', 83.597883597884, 'tFreqMD', 93.121693121693, 'grHpf', 89.385349076664, 'rateMD', 0.48148148148148, 'outAmp', 1, 'overlap', 9.7726573922977, 'offsetMF', 100.25642627688, 'dry', 1.0, 'feedback', 0.43386243386244);
// expensive
Ndef('alik_input_granulate_0').set('outAmp', 1, 'inAmp', 1, 'offset', 0.0052910052910053, 'offsetMF', 8637.9141790185, 'tFreq', 2799.9461420941, 'offsetMD', 0.22751322751323, 'feedback', 0.052910052910052, 'rate', 1.0, 'overlap', 136.83090472716, 'grHpf', 89.385349076664, 'grLpf', 11144.529591014, 'dry', 1.0, 'wet', 0.042328042328042);
(
g = SynthDef('alik_input_granulate_0', {|
inAmp=1, outAmp=1, overlap=2, tFreq=20, tFreqMF=0, tFreqMD=0,
rate=1, rateMF=0, rateMD=0,
offset = 0, offsetMF=0, offsetMD=0
|
var input;
var gDur, readPos, signal, writePos, grained, balance;
var t, bufFrames, bufRateScale;
var buf, bufdur;
var tFreqMod = {
SinOsc.ar(tFreqMF, Rand(0.0,2pi)) * tFreqMD;
};
var rateMod = {
SinOsc.ar(rateMF, Rand(0.0,2pi)).range(0, rateMD);
};
var offsetMod = {
SinOsc.ar(offsetMF, Rand(0.0,2pi)).range(0, offsetMD);
};
tFreq = tFreq + tFreqMod.dup;
rate = rate - rateMod.dup;
bufFrames = 2**16;
buf = {LocalBuf(bufFrames).clear}!2;
bufdur = BufDur.ir(buf);
writePos = Phasor.ar( end: bufFrames );
t = Impulse.ar(tFreq);
readPos =
writePos
- 64 // looks like a controlblocksize ------ why?
/ bufFrames
- offset
- offsetMod.dup;
// readPos = readPos.clip( 0, bufFrames - 64 / bufFrames );
readPos = Wrap.ar(readPos, 0, 1);
(
offset * bufFrames + 64 / SampleRate.ir
).poll(1, \delaytime);
grained = GrainBufJ.ar(
numChannels:1,
loop: 1,
trigger:t,
dur: overlap.lag(5) / tFreq,
sndbuf: buf,
rate: rate,
pos: readPos,
interp: 4,
pan: 0,
envbufnum:-1
);
grained = HPF.ar( grained, \grHpf.kr(40) );
grained = LPF.ar( grained, \grLpf.kr(15000) );
input = In.ar(\inBus.kr,2) * inAmp;
// writing granulated + input back to grain buffer
buf.do { |b i|
BufWr.ar(grained[i] * \feedback.kr(0.3) + input[i], b, writePos)
};
signal = Mix([
grained * \wet.kr(1).lag(3),
input * \dry.kr(1)
]) * outAmp;
Out.ar(0,
signal.tanh
)
}).add;
SynthDef(\sin_pulsar, { |out=0|
var a,b,c,d,e,f, f_ ,t,lev, formantA, formantB, overlapA, overlapB;
lev = \lev.kr(0.3);
f = \freq.kr(440);
f_ = f.clip(50, 1500);
formantA = \formantA.kr(2);
formantB = \formantB.kr(6);
overlapA = \overlapA.ar(2);
overlapB = \overlapB.kr(2);
e = EnvGen.kr(
Env.perc(
attackTime: ( f_.linlin( 50, 1500, 0.1, 0.02) ),
releaseTime: Rand(1,7)
),
gate: \gate.kr(1)
);
e = e * PinkNoise.ar(1!2).range( 0.1, 1 ).lag(0.02) ;
a = GrainSin.ar(
numChannels: 1,
trigger: Impulse.ar(f),
// dur: overlapA * ( 1.05 - e.pow(0.5) )
dur: overlapA * ( 0.05 + e.pow(0.5) )
* SinOsc.ar(e * 2, {Rand(0, 6.28)}.dup).range(0.87,1.15)
/ f,
freq: f *
( formantA * SinOsc.ar(3 * e, {Rand(0, 6.28)}.dup).range(0.9,1.1) ),
pan: PinkNoise.ar(0.5!2),
);
b = GrainSin.ar(
numChannels: 1,
trigger: Impulse.ar(f) + Rand(-1,1),
// dur: overlapB * ( 1.05 - e.pow(0.5) )
dur: overlapB * ( 0.05 + e.pow(0.5) )
*SinOsc.ar(e * 1, {Rand(0, 6.28)}.dup).range(0.87,1.15)
/ f,
freq: f *
( formantB * SinOsc.ar(e * 3, {Rand(0, 6.28)}.dup).range(0.9,Rand(1,1.5)) ),
pan: PinkNoise.ar(0.5!2),
);
c = GrainSin.ar(
numChannels: 1,
trigger: Impulse.ar(f),
// dur: Rand(0.5,2) * ( 0.05 + e.pow(0.5) )
dur: 1.5 * ( 0.05 + e.pow(0.5) )
*SinOsc.ar(e * 1.5, {Rand(0, 6.28)}.dup).range(0.87,1.15)
/ f,
freq: f
* SinOsc.ar(e * 2, {Rand(0, 6.28)}.dup).range(0.9,Rand(1,1.5))
,
pan: PinkNoise.ar(0.5!2),
);
c = Mix([
a * ( lev * e ).pow(f_.linlin( 50, 1500, 1.1, 2.5)),
b * ( lev * 0.8 * e ).pow(f_.linlin( 50, 1500, 0.85, 4.5)),
c * ( lev * e ).pow(0.7)
]);
c = LeakDC.ar(c);
DetectSilence.ar(c, doneAction: 2);
Out.ar(out, c )
}).add;
)
~reverbBus = Bus.audio(s, 2);
(
Routine({
thisThread.randSeed = 1234;
// thisThread.randSeed = 2341567;
// thisThread.randSeed = 4315627;
// thisThread.randSeed = 1716434;
// thisThread.randSeed = 2205318;
Pbind(
\instrument, \sin_pulsar,
\dur, Pseq( 2.pow((-4..1).scramble), inf ),
\legato, Pfunc({rrand(0.01,1)}),
\degree, Pseq([0,2,5,6,8,11].scramble, inf),
\octave, Pstutter(3, Pseq([3,4,5], inf) ),
// \lev, Pstutter(6, Pseq([ 0.2, 1, 1.2 ].scramble, inf)),
\lev, Pshuf(( 1..10 ) * 0.01, inf),
\overlapA, Pseq(2.pow([-1,0,1,2]), inf),
\overlapB, Pseq(2.pow([-1,0,1].scramble), inf),
\formantA, Pseq([1,2,3], inf),
// \formantA, 4,
\formantB, Pseq([3,4,5,6,7].scramble, inf),
// \formantB, 16,
\out, ~reverbBus
// \outBus, 0
).play;
x = Synth( 'alik_input_granulate_0',
addAction: \addToTail,
args: [
\inBus, ~reverbBus,
'offset', 0.042328042328042, 'tFreqMD', 0.0, 'wet', 0, 'rateMF', 19.782824080247, 'outAmp', 1, 'rate', 1.0, 'grLpf', 8319.1243261437, 'offsetMF', 8.0769777651696, 'inAmp', 1, 'tFreqMF', 0.21943273553761, 'grHpf', 92.831776672256, 'tFreq', 395.23259800231, 'overlap', 102.70706933049, 'rateMD', 0.0, 'offsetMD', 0.5978835978836, 'dry', 1.0, 'feedback', 0.084656084656086
]);
8.wait;
10.do { |i|
i.postln;
x.set(
'overlap', 5,
'tFreq', 26.59633942062,
'tFreqMD', exprand(1.0,55),
'tFreqMF', 25.092540737125,
'rate', 1.0,
'rateMF', exprand(3,55),
'rateMD', rand(0.005),
'offset', exprand(0.05,0.7),
'offsetMF', 93.986276007881,
'offsetMD', exprand(0.01,0.4),
'grHpf', 92.831776672256,
'grLpf', 14393.713460023,
'feedback', 0.4,
'dry', 1 - exprand(0.1,0.6),
'wet', 0.7,
);
8.wait;
};
x.set('offset', 0.026455026455026, 'wet', 0.16402116402116, 'offsetMD', 0.037037037037037, 'rate', 1.0, 'grLpf', 11144.529591014, 'tFreq', 123.38739758059, 'inAmp', 1, 'rateMF', 0.14732846585601, 'tFreqMF', 83.597883597884, 'tFreqMD', 93.121693121693, 'grHpf', 89.385349076664, 'rateMD', 0.48148148148148, 'outAmp', 1, 'overlap', 9.7726573922977, 'offsetMF', 100.25642627688, 'dry', 1.0, 'feedback', 0.43386243386244);
}).play
)

@ -0,0 +1,42 @@
// Define the sine wave synth with non-ET tuning (just intonation)
// Define the sine wave synth with non-ET tuning and an envelope (Just Intonation)
(
SynthDef("sine_wave_non_et", {
arg freq, amp, tuningRatio, outBus;
// Set up tuning - Just Intonation 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
// Calculate frequency based on tuning ratio
var tunedFreq = freq * tuning * tuningRatio;
// Calculate frequency based on tuning ratio
/*var scaleIndex = freq % tuning.size; // Wrap the frequency to the scale size
var tunedFreq = freq * tuning[scaleIndex]; // Apply the tuning ratio*/
// Create an envelope (ADSR)
var env = EnvGen.kr(Env.perc(0.01, 0.2), gate: 1); // Short attack and release times
// Generate a sine wave oscillator with the tuned frequency and apply the envelope to the amplitude
var sig = SinOsc.ar(tunedFreq, 0, amp * env); // Sine wave at tuned frequency with envelope
// Send output to the specified bus
Out.ar(outBus, sig);
}).add;
)
(
// Use Pbind to bind parameters with patterns
Pbind(
\instrument, "sine_wave_non_et", // Synth name
\freq, Pseq([60, 61, 62, 63].midicps), // Sequence of frequencies (A4, E5, A5)
\amp, 0.3, //Constant amplitude
\tuningRatio, -4, // Tuning ratio for each frequency
\outBus, 0 // Output bus
).play;
)

@ -0,0 +1,66 @@
(
~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
// Only respond to MIDI input from source 8454149 (device 1)
if (src == 8454147, {
// Create a new synth for device 1
~notes[nn] = Synth.new(
\mellotron,
[
\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 == 8454147, {
// 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 == 8454146, {
// Create a new synth for device 2
~notes[nn] = Synth.new(
\fm_pulsar_terrain,
[
\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 (device 2)
if (src == 8454146, {
// Turn off the synth and free the memory for device 2
~notes[nn].set(\gate, 0);
~notes[nn] = nil;
});
});
)

@ -0,0 +1,136 @@
b = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/01-Cantor_Samual_Malavsky_Shomea_Kol_Bichios.wav");
b = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/06-Cantor_Zevulun_Zavel_Kwartin_sings_Tiher.wav");
(
SynthDef(\layer0_struct0, {
arg bufnum, fftSize = 1024, amp = 2,
wipeFreq = 0.1, wipeDepth = 0.4,
trigFreq = 2.0, threshold = 0.3, smoothAmt = 0.2,
mix = 1.0, crf_1, rs_1, crf_2, rs_2, foldLo = -0.8, foldHi = 0.8,
combDelay = 0.2, combDecay = 2.0,
verbMix = 0.5, verbSize = 1.0,
splayWidth = 1.0;
var in, dry, sig, chain;
var wipe, trig;
var ir = Buffer.read(s, "/home/lcoogan/snd/ir/ForestScaleModel/ForestScaleModel/IR_ScaleModel/S1R1_ScaleModel.wav"); // Load an impulse response file
in = PlayBuf.ar(1, bufnum, BufRateScale.kr(bufnum), loop: 1);
dry = in;
// FFT
chain = FFT(LocalBuf(fftSize), in);
// Modulated parameters
wipe = LFSaw.kr(wipeFreq).range(wipeDepth, 0.9);
trig = Impulse.kr(trigFreq);
// Processing chain
/*chain = PV_RandComb(chain, wipe, trig);
chain = PV_MagAbove(chain, threshold);
chain = PV_MagSmooth(chain, smoothAmt);
chain = PV_BrickWall(chain);*/
chain = PV_RandComb(chain, wipe, trig);
chain = PV_BinShift(chain);
sig = IFFT(chain);
// Filtering
// sig = RLPF.ar(sig, crf, res);
sig = RHPF.ar(sig, crf_1, rs_1);
sig = BLowShelf.ar(sig, crf_2, rs_2);
sig = GlitchBPF.ar(sig, 440);
// Effects
// Inside signal chain
sig = Fold.ar(sig, foldLo, foldHi);
sig = CombL.ar(sig, combDelay, combDelay, combDecay);
sig = Splay.ar(sig, spread: splayWidth);
sig = XFade2.ar(sig, Convolution2.ar(sig, ir, 512), verbMix); // Mix dry and wet
// Mix dry/wet
sig = XFade2.ar(dry, sig, mix.linlin(0, 1, -1, 1));
Out.ar(0, sig.dup * amp);
}).add;
)
(
~midiControlMap = (
// Group 1
// Mixing
00: \amp,
01: \mix,
// Filtering
04: \crf_1,
05: \rs_1,
06: \crf_2,
07: \rs_2,
// Modulation
08: \wipeFreq,
09: \wipeDepth,
10: \trigFreq,
11: \threshold,
// Modulation ext
12: \smoothAmt,
// Group 2 — FX Modulation
// Fold
16: \fold, // enable/fade
17: \foldLo, // lower bound
18: \foldHi, // upper bound
// 19:
// Comb
20: \comb, // enable/fade
21: \combDelay, // delay time
22: \combDecay, // decay time4
// 23:
// Verb
24: \verb, // enable/fade
25: \verbMix, // wet/dry
26: \verbSize, // scale IR/dry level
// 27
// Splay
28: \splay, // enable/fade
29: \splayWidth // stereo spread
);
// Replace this with your actual Synth instance
~layer0 = Synth(\layer0_struct0, [\bufnum, b]);
// Connect MIDI CCs on channel 2
~midiControlMap.keysValuesDo { |cc, param|
MIDIFunc.cc({ |val, num, chan, src|
if (chan == 2) { // Channel 2 (zero-indexed)
var mappedVal = val.linlin(0, 127, 0.0, 1.0);
~layer0.set(param, mappedVal);
("CC" ++ cc ++ " (" ++ param ++ ") → " ++ mappedVal).postln;
}
}, cc);
};
)

@ -0,0 +1,146 @@
b = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/02-Cantor_Mordechai_Hershman_Baruch_Hashem_Bayom.wav");
(
SynthDef(\layer0_struct0, {
arg bufnum, fftSize = 1024, amp = 2,
wipeFreq = 0.1, wipeDepth = 0.4,
trigFreq = 2.0, threshold = 0.3, smoothAmt = 0.2,
mix = 1.0, crf_1, rs_1, crf_2, rs_2, foldLo = -0.8, foldHi = 0.8,
combDelay = 0.2, combDecay = 2.0,
verbMix = 0.5, verbSize = 1.0,
splayWidth = 1.0;
var in, dry, sig, chain;
var wipe, trig;
var ir = Buffer.read(s, "/home/lcoogan/snd/ir/ForestScaleModel/ForestScaleModel/IR_ScaleModel/S1R1_ScaleModel.wav"); // Load an impulse response file
var beatFreq, stepGate;
in = PlayBuf.ar(1, bufnum, BufRateScale.kr(bufnum), loop: 0);
dry = in;
// FFT
chain = FFT(LocalBuf(fftSize), in);
// Modulated parameters
wipe = LFSaw.kr(wipeFreq).range(wipeDepth, 0.9);
trig = Impulse.kr(trigFreq);
// Processing chain
/*chain = PV_RandComb(chain, wipe, trig);
chain = PV_MagAbove(chain, threshold);
chain = PV_MagSmooth(chain, smoothAmt);
chain = PV_BrickWall(chain);*/
// inside your SynthDef, after `chain = FFT(...)`:
beatFreq = 2; // pulses per second, can be MIDI-controlled
stepGate = LFPulse.kr(beatFreq, 0, 0.5).lag(0.01); // square wave gate, adds groove
// Rhythmic spectral chain
chain = PV_RandWipe(chain, stepGate); // wipe out sections of the spectrum rhythmically
chain = PV_MagAbove(chain, 0.2); // keep only strong partials
chain = PV_MagSmear(chain, 5); // smear partials slightly for continuity
chain = PV_BinScramble(chain, stepGate); // shuffle bins during gate
chain = PV_BrickWall(chain); // hard gate remaining partials
sig = IFFT(chain);
// Filtering -- needs adjustment
// sig = RLPF.ar(sig, crf, res);
// sig = RLPF.ar(sig, crf_1, rs_1);
// sig = BLowShelf.ar(sig, crf_2, rs_2);
// sig = GlitchBPF.ar(sig, 440);
// Effects
// Inside signal chain
sig = Fold.ar(sig, foldLo, foldHi);
sig = CombL.ar(sig, combDelay, combDelay, combDecay);
sig = Splay.ar(sig, spread: splayWidth);
sig = XFade2.ar(sig, Convolution2.ar(sig, ir, 512), verbMix); // Mix dry and wet
// Mix dry/wet
sig = XFade2.ar(dry, sig, mix.linlin(0, 1, -1, 1));
Out.ar(0, sig.dup * amp);
}).add;
)
(
~midiControlMap = (
// Group 1
// Mixing
00: \amp,
01: \mix,
// Filtering
04: \crf_1,
05: \rs_1,
06: \crf_2, // maybe make lfo rate for filter
07: \rs_2, // maybe make lfo depth for filter
// Modulation
08: \wipeFreq,
09: \wipeDepth,
10: \trigFreq,
11: \threshold,
// Modulation ext
12: \smoothAmt,
// Group 2 — FX Modulation
// Fold
16: \fold, // enable/fade
17: \foldLo, // lower bound
18: \foldHi, // upper bound
// 19:
// Comb
20: \comb, // enable/fade
21: \combDelay, // delay time
22: \combDecay, // decay time
// 23:
// Verb
24: \verbMix, // wet/dry
25: \verbSize, // scale IR/dry level
// 27
// Splay
28: \splay, // enable/fade
29: \splayWidth // stereo spread
);
// Replace this with your actual Synth instance
~layer0 = Synth(\layer0_struct0, [\bufnum, b]);
// Connect MIDI CCs on channel 2
~midiControlMap.keysValuesDo { |cc, param|
MIDIFunc.cc({ |val, num, chan, src|
if (chan == 2) { // Channel 2 (zero-indexed)
var mappedVal = val.linlin(0, 127, 0.0, 1.0);
~layer0.set(param, mappedVal);
("CC" ++ cc ++ " (" ++ param ++ ") → " ++ mappedVal).postln;
}
}, cc);
};
)

@ -0,0 +1,130 @@
b = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/01-Cantor_Samual_Malavsky_Shomea_Kol_Bichios.wav");
(
SynthDef(\layer0_struct0, {
arg bufnum, fftSize = 1024, amp = 2,
wipeFreq = 0.1, wipeDepth = 0.4,
trigFreq = 2.0, threshold = 0.3, smoothAmt = 0.2,
mix = 1.0, crf_1, rs_1, crf_2, rs_2, foldLo = -0.8, foldHi = 0.8,
combDelay = 0.2, combDecay = 2.0,
verbMix = 0.5, verbSize = 1.0,
splayWidth = 1.0;
var in, dry, sig, chain;
var wipe, trig;
var ir = Buffer.read(s, "/home/lcoogan/snd/ir/ForestScaleModel/ForestScaleModel/IR_ScaleModel/S1R1_ScaleModel.wav"); // Load an impulse response file
in = PlayBuf.ar(1, bufnum, BufRateScale.kr(bufnum), loop: 1);
dry = in;
// FFT
chain = FFT(LocalBuf(fftSize), in);
// Modulated parameters
wipe = LFSaw.kr(wipeFreq).range(wipeDepth, 0.9);
trig = Impulse.kr(trigFreq);
// Needs adjustment
chain = PV_MagFreeze(chain);
chain = PV_BrickWall(chain);
sig = IFFT(chain);
// Filtering -- needs adjustment
// sig = RLPF.ar(sig, crf, rs_);
sig = RHPF.ar(sig, crf_1, rs_1);
sig = BLowShelf.ar(sig, crf_2, rs_2);
sig = GlitchBPF.ar(sig, 440);
// Effects
// Inside signal chain
sig = Fold.ar(sig, foldLo, foldHi);
sig = CombL.ar(sig, combDelay, combDelay, combDecay);
sig = Splay.ar(sig, spread: splayWidth);
sig = XFade2.ar(sig, Convolution2.ar(sig, ir, 512), verbMix); // Mix dry and wet
// Mix dry/wet
sig = XFade2.ar(dry, sig, mix.linlin(0, 1, -1, 1));
Out.ar(0, sig.dup * amp);
}).add;
)
(
~midiControlMap = (
// Group 1
// Mixing
00: \amp,
01: \mix,
// Filtering
04: \crf_1,
05: \rs_1,
06: \crf_2,
07: \rs_2,
// Modulation
08: \wipeFreq,
09: \wipeDepth,
10: \trigFreq,
11: \threshold,
// Modulation ext
12: \smoothAmt,
// Group 2 — FX Modulation
// Fold
16: \fold, // enable/fade
17: \foldLo, // lower bound
18: \foldHi, // upper bound
// 19:
// Comb
20: \comb, // enable/fade
21: \combDelay, // delay time
22: \combDecay, // decay time4
// 23:
// Verb
24: \verb, // enable/fade
25: \verbMix, // wet/dry
26: \verbSize, // scale IR/dry level
// 27
// Splay
28: \splay, // enable/fade
29: \splayWidth // stereo spread
);
// Replace this with your actual Synth instance
~layer0 = Synth(\layer0_struct0, [\bufnum, b]);
// Connect MIDI CCs on channel 2
~midiControlMap.keysValuesDo { |cc, param|
MIDIFunc.cc({ |val, num, chan, src|
if (chan == 2) { // Channel 2 (zero-indexed)
var mappedVal = val.linlin(0, 127, 0.0, 1.0);
~layer0.set(param, mappedVal);
("CC" ++ cc ++ " (" ++ param ++ ") → " ++ mappedVal).postln;
}
}, cc);
};
)

@ -0,0 +1,130 @@
b = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/04-Cantor_Samuel_Malavsky_Zechor.wav");
(
SynthDef(\layer0_struct0, {
arg bufnum, fftSize = 1024, amp = 2,
wipeFreq = 0.1, wipeDepth = 0.4,
trigFreq = 2.0, threshold = 0.3, smoothAmt = 0.2,
mix = 1.0, crf_1, rs_1, crf_2, rs_2, foldLo = -0.8, foldHi = 0.8,
combDelay = 0.2, combDecay = 2.0,
verbMix = 0.5, verbSize = 1.0,
splayWidth = 1.0;
var in, dry, sig, chain;
var wipe, trig;
var ir = Buffer.read(s, "/home/lcoogan/snd/ir/ForestScaleModel/ForestScaleModel/IR_ScaleModel/S1R1_ScaleModel.wav"); // Load an impulse response file
in = PlayBuf.ar(1, bufnum, BufRateScale.kr(bufnum), loop: 1);
dry = in;
// FFT
chain = FFT(LocalBuf(fftSize), in);
// Modulated parameters
wipe = LFSaw.kr(wipeFreq).range(wipeDepth, 0.9);
trig = Impulse.kr(trigFreq);
// Needs adjustment
chain = PV_RandComb(chain, wipe, trig);
chain = PV_BrickWall(chain);
sig = IFFT(chain);
// Filtering -- needs adjustment
sig = RLPF.ar(sig, crf, res);
sig = RHPF.ar(sig, crf_1, rs_1);
sig = BLowShelf.ar(sig, crf_2, rs_2);
sig = GlitchBPF.ar(sig, 440);
// Effects
// Inside signal chain
sig = Fold.ar(sig, foldLo, foldHi);
sig = CombL.ar(sig, combDelay, combDelay, combDecay);
sig = Splay.ar(sig, spread: splayWidth);
sig = XFade2.ar(sig, Convolution2.ar(sig, ir, 512), verbMix); // Mix dry and wet
// Mix dry/wet
sig = XFade2.ar(dry, sig, mix.linlin(0, 1, -1, 1));
Out.ar(0, sig.dup * amp);
}).add;
)
(
~midiControlMap = (
// Group 1
// Mixing
00: \amp,
01: \mix,
// Filtering
04: \crf_1,
05: \rs_1,
06: \crf_2,
07: \rs_2,
// Modulation
08: \wipeFreq,
09: \wipeDepth,
10: \trigFreq,
11: \threshold,
// Modulation ext
12: \smoothAmt,
// Group 2 — FX Modulation
// Fold
16: \fold, // enable/fade
17: \foldLo, // lower bound
18: \foldHi, // upper bound
// 19:
// Comb
20: \comb, // enable/fade
21: \combDelay, // delay time
22: \combDecay, // decay time4
// 23:
// Verb
24: \verb, // enable/fade
25: \verbMix, // wet/dry
26: \verbSize, // scale IR/dry level
// 27
// Splay
28: \splay, // enable/fade
29: \splayWidth // stereo spread
);
// Replace this with your actual Synth instance
~layer0 = Synth(\layer0_struct0, [\bufnum, b]);
// Connect MIDI CCs on channel 2
~midiControlMap.keysValuesDo { |cc, param|
MIDIFunc.cc({ |val, num, chan, src|
if (chan == 2) { // Channel 2 (zero-indexed)
var mappedVal = val.linlin(0, 127, 0.0, 1.0);
~layer0.set(param, mappedVal);
("CC" ++ cc ++ " (" ++ param ++ ") → " ++ mappedVal).postln;
}
}, cc);
};
)

@ -0,0 +1 @@
b = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/05-Cantor_Zavel_Kwartin_Ribono_Shel_Olam.wav");

@ -0,0 +1 @@
b = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/06-Cantor_Zevulun_Zavel_Kwartin_sings_Tiher.wav");

@ -0,0 +1 @@
b = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/07-Izak_Algazi_Efendi_Kamti_Be_ashmoret.wav");

@ -18,7 +18,7 @@ MIDIdef.cc(\ccTest, {
// Load samples
(
~sampleDir = PathName("/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/seq/borrowed_flesh/808").fullPath;
~sampleDir = PathName("/home/lcoogan/snd/samples/seq/@808").fullPath;
~samples = Dictionary.newFrom(
(
@ -38,7 +38,7 @@ MIDIdef.cc(\ccTest, {
~samples[39].class;
(
~sampleDir = PathName("/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/seq/borrowed_flesh/808");
~sampleDir = PathName("/home/lcoogan/snd/samples/seq/@808");
~sample = ();
~sampleDir.entries.do({ |pn|
var sym;
@ -48,11 +48,11 @@ MIDIdef.cc(\ccTest, {
)
// Define the Synth for sample triggering with amp bus and drum bus
(
("/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/05-Cantor_Zavel_Kwartin_Ribono_Shel_Olam.wav""/home/lcoogan/snd/live/20"/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/02-Cantor_Mordechai_Hershman_Baruch_Hashem_Bayom.wav"25"/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/05-Cantor_Zavel_Kwartin_Ribono_Shel_Olam.wav"-04-26.Basic_City_Brewery/trax/05-Cantor_Zavel_Kwartin_Ribono_Shel_Olam.wav"
SynthDef(\sampleTrigger, { |buf, ampin = 0, outbus = 0|
var sound, amp;
amp = In.kr(ampin, 1);
sound = PlayBuf.ar(1, buf, BufRateScale.ir(buf), doneAction: 2);
sound = PlayBuf.ar(1, buf, BufRateScale.ir(buf), doneAction: 2);"/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/05-Cantor_Zavel_Kwartin_Ribono_Shel_Olam.wav"
sound = sound * amp;
Out.ar(outbus, sound.dup);
}).add;
@ -120,6 +120,6 @@ MIDIdef.cc('808amp', { |val, num|
MIDIdef.cc('drumBusAmp', { |val|
~drumAmpBus.set(val / 127)
}, ccNum: 3, chan: 2);
}, ccNum: 2, chan: 2);
)
MIDIFunc.trace(true);

@ -1,5 +1,7 @@
// TODO: add modulation to chain params
// 02
(
SynthDef(\layer0_struct0, {
arg bufnum, fftSize = 1024, amp = 0.3;
@ -32,13 +34,14 @@ SynthDef(\layer0_struct0, {
}).add;
)
x = Synth(\layer0_textur0, [\bufnum, b, \amp, 0.3]);
x = Synth(\layer0_struct0, [\bufnum, b, \amp, 0.3]);
x.free;
// Acheinu
(
SynthDef(\layer0_struct1, {
arg bufnum, fftSize = 1024, amp = 0.3;

@ -1,60 +0,0 @@
(
SynthDef(\layer0_struct0, {
arg bufnum, fftSize = 1024, amp = 0.3,
wipeFreq = 0.1, wipeDepth = 0.4,
trigFreq = 2.0, threshold = 0.3, smoothAmt = 0.2,
mix = 1.0;
var in, dry, sig, chain;
var wipe, trig;
in = PlayBuf.ar(1, bufnum, BufRateScale.kr(bufnum), loop: 1);
dry = in;
// FFT
chain = FFT(LocalBuf(fftSize), in);
// Modulated parameters
wipe = SinOsc.kr(wipeFreq).range(wipeDepth, 0.9);
trig = Impulse.kr(trigFreq);
// Processing chain
chain = PV_RandComb(chain, wipe, trig);
chain = PV_MagAbove(chain, threshold);
chain = PV_MagSmooth(chain, smoothAmt);
chain = PV_BrickWall(chain);
sig = IFFT(chain);
// Mix dry/wet
sig = XFade2.ar(dry, sig, mix.linlin(0, 1, -1, 1));
Out.ar(0, sig.dup * amp);
}).add;
)
(
~midiControlMap = (
16: \wipeFreq, // CC16
17: \wipeDepth, // CC17
18: \trigFreq, // CC18
19: \threshold, // CC19
20: \smoothAmt, // CC20
21: \mix // CC21
);
// Replace this with your actual Synth instance
~layer0 = Synth(\layer0_struct0, [\bufnum, b]);
// Connect MIDI CCs on channel 2
~midiControlMap.keysValuesDo { |cc, param|
MIDIFunc.cc({ |val, num, chan, src|
if (chan == 2) { // Channel 2 (zero-indexed)
var mappedVal = val.linlin(0, 127, 0.0, 1.0);
~layer0.set(param, mappedVal);
("CC" ++ cc ++ " (" ++ param ++ ") → " ++ mappedVal).postln;
}
}, cc);
};
)

@ -1,40 +1,97 @@
(
SynthDef(\mellotron, {
arg freq = 440, amp = 0.8, gate = 1, pan = 0, vibratoRate = 1, vibratoDepth = 0.15,
noiseLevel = 0.2, ringModFreq = 3, lpfFreq = 2000, res = 0.8, lpfLfoRate = 1, lpfLfoDepth = 100,
detune = 0.005;
arg freq = 440, amp =0.3, gate = 1, pan = 0, vibratoRate = 1, vibratoDepth = 0.15,
noiseLevel = 0.2, ringModFreq = 3, lpfFreq = 1e3, res = 1, lpfLfoRate = 1, lpfLfoDepth = 100,
detune = 0.005, fineDetune1, fineDetune2;
var sig, osc1, osc2, vibrato, noise, env, lpfMod, freq1, freq2;
var tuning = [
38.70968,
116.12903,
154.83871,
232.25806,
309.67742,
348.38710,
425.80645,
503.22581,
541.93548,
619.35484,
658.06452,
735.48387,
812.90323,
851.61290,
929.03226,
1006.45161,
1045.16129,
1122.58065,
2/1
];
var tuningRatios = tuning * freq / 8; // Scale the whole array once
freq1 = tuningRatios[0];
freq2 = tuningRatios[1];
vibrato = SinOsc.kr(vibratoRate, 0, vibratoDepth).range(0.98, 1.02);
freq1 = (freq * (0.99))/4;
freq2 = (freq * (1.01))/2;
freq1 = (freq * (0.99))/8 * tuning ;
freq2 = (freq * (1.0))/3 * tuning ;
// Apply the tuning ratios directly to each frequency
osc1 = Mix([
LFTri.ar(freq1 * vibrato),
LFTri.ar(freq2 * vibrato)
/* osc1 = Mix([
Saw.ar(freq1 * vibrato),
Saw.ar(freq2 * vibrato)
]) * 0.5;
noise = WhiteNoise.ar(noiseLevel);
osc1 = Mix([osc1, noise * 0.5]);
// noise = WhiteNoise.ar(noiseLevel);
osc1 = Mix([osc1 * 0.5]);
osc2 = Mix([
Saw.ar(freq1 * ringModFreq),
SinOscFB.ar(freq2 * ringModFreq)
]) * 0.5 * osc1;
Saw.ar(freq2 * ringModFreq)
]) * 0.5;*/
// // Directly combine the oscillators instead of using Mix
osc1 = LFTri.ar(freq1 * vibrato);
osc2 = Saw.ar(freq1 * ringModFreq) + Saw.ar(freq2 * ringModFreq);
// Apply the final mix
sig = osc1 + osc2 * 0.5;
// sig = Fold.ar(sig, -20, 20); // EMF: wavefolding only happens if the input signal amplitude exceeds the bounds provided. osc has a pretty normal range and won't ever exceed ±20. You can see in the previous line (LFDNoise3) I'm only amplifying it by a maximum factor of 1.5. It's actually small boundary values with Fold that cause audible results (change to the folding min/max to -0.1, +0.1 and you'll notice the sound changes significantly)
sig = Mix([ osc1, osc2 * 0.5]);
sig = Mix([osc1 + osc2]);
lpfMod = SinOsc.kr(lpfLfoRate).range(lpfFreq - lpfLfoDepth, lpfFreq + lpfLfoDepth);
sig = RLPF.ar(sig, lpfMod, res);
sig = BPF.ar(sig, 200);
env = EnvGen.kr(Env.adsr(0.2, 3, 1, 2), gate, doneAction: 2);
sig = sig * env * amp;
sig = sig.tanh(8);
sig = BLowShelf.ar(sig, 200, 0.5, 9);
// sig = sig.tanh(8);
sig = BLowShelf.ar(sig, 300, 1);
// sig = Splay.ar(sig, 0.1, );
sig = LeakDC.ar(sig);
// sig = FreeVerb.ar(sig, 0.33, 2);
// sig = GVerb.ar(sig, 40, 3, 0.5, 0.5, 20, 0, 1, 1);
// sig = CombL.ar(sig, 0.01, 0.2, 1.0);
Out.ar(0, Pan2.ar(sig, pan));
}).add;
@ -62,4 +119,3 @@ Pbind(
\pan, Pseq([0.5, -0.5], inf), // Panning left and right for stereo spread
).play;
)

@ -0,0 +1,37 @@
// Define the sine wave synth with Eikosany tuning and an envelope (Just Intonation)
(
SynthDef("sine_wave_eikosany", {
arg freq, amp, tuningRatio, outBus;
// Eikosany tuning ratios from the .scl file
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
];
// Calculate frequency based on tuning ratio
var scaleIndex = freq % tuning.size; // Wrap the frequency to the scale size
var tunedFreq = freq * tuning[scaleIndex]; // Apply the tuning ratio
// Create an envelope (ADSR)
var env = EnvGen.kr(Env.perc(0.01, 0.2), gate: 1); // Short attack and release times
// Generate a sine wave oscillator with the tuned frequency and apply the envelope to the amplitude
var sig = SinOsc.ar(tunedFreq, 0, amp * env); // Sine wave at tuned frequency with envelope
// Send output to the specified bus
Out.ar(outBus, sig);
}).add;
)
(
// Use Pbind to bind parameters with patterns
Pbind(
\instrument, "sine_wave_eikosany", // Synth name
\freq, Pseq([60, 61, 62, 63].midicps), // Sequence of frequencies (e.g., A4, E5, A5)
\amp, 0.3, // Constant amplitude
\tuningRatio, 1, // Tuning ratio for each frequency
\outBus, 0 // Output bus
).play;
)
Loading…
Cancel
Save