diff --git a/neo-hasidic_brainsex/better_spectral.scd b/better_spectral.scd similarity index 100% rename from neo-hasidic_brainsex/better_spectral.scd rename to better_spectral.scd diff --git a/granular reverb with cc.scd b/granular reverb with cc.scd new file mode 100644 index 0000000..bfa5d15 --- /dev/null +++ b/granular reverb with cc.scd @@ -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); +) diff --git a/granular_reverb.scd b/granular_reverb.scd new file mode 100644 index 0000000..a4b491e --- /dev/null +++ b/granular_reverb.scd @@ -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 +) + + + \ No newline at end of file diff --git a/microtonality.scd b/microtonality.scd new file mode 100644 index 0000000..77b16b4 --- /dev/null +++ b/microtonality.scd @@ -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; +) + diff --git a/midi for weeping.scd b/midi for weeping.scd new file mode 100644 index 0000000..326b5ea --- /dev/null +++ b/midi for weeping.scd @@ -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; + }); +}); + +) \ No newline at end of file diff --git a/neo-hasidic_brainsex/01-Acheinu_Kol_Beit_Israel.scd b/neo-hasidic_brainsex/01-Acheinu_Kol_Beit_Israel.scd new file mode 100644 index 0000000..b571f05 --- /dev/null +++ b/neo-hasidic_brainsex/01-Acheinu_Kol_Beit_Israel.scd @@ -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); +}; +) diff --git a/neo-hasidic_brainsex/02-Cantor_Mordechai_Hershman_Baruch_Hashem_Bayom.scd b/neo-hasidic_brainsex/02-Cantor_Mordechai_Hershman_Baruch_Hashem_Bayom.scd new file mode 100644 index 0000000..abafa30 --- /dev/null +++ b/neo-hasidic_brainsex/02-Cantor_Mordechai_Hershman_Baruch_Hashem_Bayom.scd @@ -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); +}; +) diff --git a/neo-hasidic_brainsex/03-Cantor_Samual_Malavsky_Shomea_Kol_Bichios.scd b/neo-hasidic_brainsex/03-Cantor_Samual_Malavsky_Shomea_Kol_Bichios.scd new file mode 100644 index 0000000..8ed768f --- /dev/null +++ b/neo-hasidic_brainsex/03-Cantor_Samual_Malavsky_Shomea_Kol_Bichios.scd @@ -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); +}; +) diff --git a/neo-hasidic_brainsex/04-Cantor_Samuel_Malavsky_Zechor.scd b/neo-hasidic_brainsex/04-Cantor_Samuel_Malavsky_Zechor.scd new file mode 100644 index 0000000..b6cfe47 --- /dev/null +++ b/neo-hasidic_brainsex/04-Cantor_Samuel_Malavsky_Zechor.scd @@ -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); +}; +) diff --git a/neo-hasidic_brainsex/05-Cantor_Zavel_Kwartin_Ribono_Shel_Olam.scd b/neo-hasidic_brainsex/05-Cantor_Zavel_Kwartin_Ribono_Shel_Olam.scd new file mode 100644 index 0000000..1c23a7f --- /dev/null +++ b/neo-hasidic_brainsex/05-Cantor_Zavel_Kwartin_Ribono_Shel_Olam.scd @@ -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"); diff --git a/neo-hasidic_brainsex/06-Cantor_Zevulun_Zavel_Kwartin_sings_Tiher.scd b/neo-hasidic_brainsex/06-Cantor_Zevulun_Zavel_Kwartin_sings_Tiher.scd new file mode 100644 index 0000000..e69914c --- /dev/null +++ b/neo-hasidic_brainsex/06-Cantor_Zevulun_Zavel_Kwartin_sings_Tiher.scd @@ -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"); diff --git a/neo-hasidic_brainsex/07-Izak_Algazi_Efendi_Kamti_Be_ashmoret.scd b/neo-hasidic_brainsex/07-Izak_Algazi_Efendi_Kamti_Be_ashmoret.scd new file mode 100644 index 0000000..e9b9f10 --- /dev/null +++ b/neo-hasidic_brainsex/07-Izak_Algazi_Efendi_Kamti_Be_ashmoret.scd @@ -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"); diff --git a/neo-hasidic_brainsex/808.scd b/neo-hasidic_brainsex/808.scd index 9cd9e46..7c5855e 100644 --- a/neo-hasidic_brainsex/808.scd +++ b/neo-hasidic_brainsex/808.scd @@ -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); \ No newline at end of file diff --git a/neo-hasidic_brainsex/revised spectral.scd b/neo-hasidic_brainsex/revised spectral.scd index 20ff5b5..de11ae9 100644 --- a/neo-hasidic_brainsex/revised spectral.scd +++ b/neo-hasidic_brainsex/revised spectral.scd @@ -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; diff --git a/neo-hasidic_brainsex/spectral n.scd b/neo-hasidic_brainsex/spectral n.scd deleted file mode 100644 index c3e969b..0000000 --- a/neo-hasidic_brainsex/spectral n.scd +++ /dev/null @@ -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); -}; -) diff --git a/pads/mel.scd b/pads/mel.scd index 6138f13..25a9397 100644 --- a/pads/mel.scd +++ b/pads/mel.scd @@ -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([ +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]); - lpfMod = SinOsc.kr(lpfLfoRate).range(lpfFreq - lpfLfoDepth, lpfFreq + lpfLfoDepth); + 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; ) - diff --git a/sine_eikosany.scd b/sine_eikosany.scd new file mode 100644 index 0000000..b1f63fe --- /dev/null +++ b/sine_eikosany.scd @@ -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; +)