From 5b646677c424a9b5a3aac7afb994dade00d229d7 Mon Sep 17 00:00:00 2001 From: Mike Lynch Date: Mon, 23 Oct 2023 11:52:15 +1100 Subject: [PATCH 1/5] Added all the changes made in Looptober 2023 so far --- control.scd | 29 ++--------------------------- effects.scd | 32 ++++++++++++++++++++++++++++++-- granulator.scd | 3 ++- interface.scd | 4 ++-- main.scd | 9 +++++---- synths.scd | 4 ++-- 6 files changed, 43 insertions(+), 38 deletions(-) diff --git a/control.scd b/control.scd index b0a62af..09647b0 100644 --- a/control.scd +++ b/control.scd @@ -3,7 +3,7 @@ //input mixing, effects and lfos -~inputb = Bus.audio(s, 1); +~inputb = Bus.audio(s, 1); // bypassing this one for now ~infxb = Bus.audio(s, 1); ~inmixer = SynthDef( @@ -12,7 +12,7 @@ arg in1 = 2, in2 = 3, out = 4; Out.ar(out, In.ar(in1) + In.ar(in2)); } -).play(s, [\in1, ~usbinput1, \in2, ~usbinput2, \out, ~inputb]); +).play(s, [\in1, ~usbinput1, \in2, ~usbinput2, \out, ~infxb]); // LFO buses and synths @@ -27,31 +27,6 @@ "LFOs running".postln; -// filter is now before grains - -~filtermodb = Bus.control(s, 1); - -~filtermod = SynthDef( - \filtermod, { - arg out, a = 1.0, b = 0.0, c = 0.0; - var siga, sigb, sigc; - siga = In.kr(~lfoab) * a; - sigb = In.kr(~lfobb) * b; - sigc = In.kr(~lfocb) * c; - Out.kr(out, Wrap.kr(siga + sigb + sigc, -1, 1)); - } -).play(s, [\out, ~filtermodb, \a, 1, \b, 0, \c, 0 ]); - - -~filter = SynthDef( - \filter, { - arg in, out, mod, freq=10000, res=0.3, amp=1.0; - var filt, lfo; - lfo = LinExp.kr(In.kr(mod, 1), -1, 1, freq * 0.5, freq * 2); - filt = RLPF.ar(In.ar(in, 2) * amp, lfo, res); - Out.ar(out, filt); - } -).play(s, [ \in, ~inputb, \out, ~infxb, \mod, ~filtermodb, \amp, 0.5], \addToTail); ) diff --git a/effects.scd b/effects.scd index 9ddcfed..fc9e4b6 100644 --- a/effects.scd +++ b/effects.scd @@ -5,6 +5,7 @@ ~outfxb = Bus.audio(s, 2); +~filterb = Bus.audio(s, 2); ~delayb = Bus.audio(s, 2); ~reverbb = Bus.audio(s, 2); @@ -20,6 +21,34 @@ +// filter is after grains again + +~filtermodb = Bus.control(s, 1); + +~filtermod = SynthDef( + \filtermod, { + arg out, a = 1.0, b = 0.0, c = 0.0; + var siga, sigb, sigc; + siga = In.kr(~lfoab) * a; + sigb = In.kr(~lfobb) * b; + sigc = In.kr(~lfocb) * c; + Out.kr(out, Wrap.kr(siga + sigb + sigc, -1, 1)); + } +).play(s, [\out, ~filtermodb, \a, 1, \b, 0, \c, 0 ]); + + +~filter = SynthDef( + \filter, { + arg in, out, mod, freq=10000, res=0.3, amp=1.0; + var filt, lfo; + lfo = LinExp.kr(In.kr(mod, 1), -1, 1, freq * 0.5, freq * 2); + filt = RLPF.ar(In.ar(in, 2) * amp, lfo, res); + Out.ar(out, filt); + } +).play(s, [ \in, ~outfxb, \out, ~filterb, \mod, ~filtermodb, \amp, 0.5], \addToTail); + + + // delay always passes through 100% of its input + amp % of the delay @@ -31,9 +60,8 @@ del = CombC.ar(sig, maxdelay, delaytime, decaytime, amp); Out.ar(out, sig + del); } - ).play(s, [ \in, ~outfxb, \out, ~delayb ], \addToTail); + ).play(s, [ \in, ~filterb, \out, ~delayb ], \addToTail); -// try taking out the reverb because I think it causes noises ~reverb = SynthDef( \reverb, { diff --git a/granulator.scd b/granulator.scd index 017fabb..fac91ac 100644 --- a/granulator.scd +++ b/granulator.scd @@ -41,7 +41,7 @@ (0..3).do({ |i| var pb = ~posb[i], rtb = ~rectriggerb[i]; ~possynths.add(Synth(\pos_saw, [ \out, pb, \speed, 1 / ~buflen ])); - ~triggersynths.add(Synth(\trigger, [ \out, rtb ])); + ~triggersynths.add(Synth(\trigger, [ \out, rtb, \freq, 1 / ~buflen ])); }); // TODO - retrigger the buffer records when changing the length etc @@ -65,3 +65,4 @@ }); } ) + diff --git a/interface.scd b/interface.scd index 279e862..79205e3 100644 --- a/interface.scd +++ b/interface.scd @@ -120,12 +120,12 @@ OSCdef.freeAll; // Page 2: track -~to.xy('/track/triggersize', [ 100, 0.125 ], TouchOSCScale(0, 400), TouchOSCScale(0, 1.5), { |v| +~to.xy('/track/triggersize', [ 100, 0.125 ], TouchOSCScale(0, 200), TouchOSCScale(0, 1), { |v| ~granulator.trigger_(v[0]); ~granulator.size_(v[1]); }); -~to.slider('/track/blur', 0, TouchOSCScale(0, 0.25), { |v| ~granulator.blur_(v) }); +~to.slider('/track/blur', 0, TouchOSCScale(0, 1.0), { |v| ~granulator.blur_(v) }); ~to.button('/track/dust', 0, { |v| ~granulator.dust_(v) }); ~to.button('/track/back', 0, { |v| ~granulator.back_(v)}); diff --git a/main.scd b/main.scd index 8564112..7035ed9 100644 --- a/main.scd +++ b/main.scd @@ -15,9 +15,9 @@ Routine.run({ ~usbinput1 = 2; ~usbinput2 = 3; - ~bpm = 55; + ~bpm = 80; ~bps = ~bpm / 60; - ~beatsperbar = 4; + ~beatsperbar = 8; ~buflen = ~beatsperbar / ~bps; [ "bpm", ~bpm ].postln; @@ -43,5 +43,6 @@ Routine.run({ }); ) - - +~granulators[0].grainamp_(0.75); +g +~dumpbuffers.value("looptober14") \ No newline at end of file diff --git a/synths.scd b/synths.scd index 594ace5..66862db 100644 --- a/synths.scd +++ b/synths.scd @@ -32,8 +32,8 @@ SynthDef(\lfo, { }).add; SynthDef(\trigger, { - arg out=1; - Out.kr(out, Impulse.kr(0)) + arg out=1, freq=1; + Out.kr(out, Impulse.kr(freq)) }).add; ) -- 2.47.0 From 58117762a66473a21d7278853413669219e9f3d4 Mon Sep 17 00:00:00 2001 From: Mike Lynch Date: Wed, 25 Oct 2023 12:54:05 +1100 Subject: [PATCH 2/5] First working version of position buffers as envelopes triggered from a Pattern so that they are guaranteed to be in sync with the tempoclock --- interface.scd | 46 +++++++++++++++++++++++----------------------- main.scd | 21 ++++++++++++++------- synths.scd | 51 ++++++++++++++++++++++++++++----------------------- 3 files changed, 65 insertions(+), 53 deletions(-) diff --git a/interface.scd b/interface.scd index 79205e3..eb6bd3b 100644 --- a/interface.scd +++ b/interface.scd @@ -40,20 +40,20 @@ OSCdef.freeAll; -~setspeed = { | track, v | - var speed, qv = if(~speedquant > 0, { ~quantspeed.value(v) }, { v }); - speed = qv / ~buflen; - if(~speedlock > 0, { - (0..3).do({|n| - ~possynths[n].set(\speed, speed); - if( n != track, { - var url = ("/grains/speed" ++ n).asSymbol; - ~to.s_(url, v); - }); - }); - }, - { ~possynths[track].set(\speed, speed) }); -}; +// ~setspeed = { | track, v | +// var speed, qv = if(~speedquant > 0, { ~quantspeed.value(v) }, { v }); +// speed = qv / ~buflen; +// if(~speedlock > 0, { +// (0..3).do({|n| +// ~possynths[n].set(\speed, speed); +// if( n != track, { +// var url = ("/grains/speed" ++ n).asSymbol; +// ~to.s_(url, v); +// }); +// }); +// }, +// { ~possynths[track].set(\speed, speed) }); +// }; // setrecord: toggles record on (1) or off (0) for a track, and also sets the // track's input mix to 0 so that it doesn't start fadeing out. If the track @@ -85,15 +85,15 @@ OSCdef.freeAll; ~to.slider('/grains/buflen', ~buflen, TouchOSCScale(0.1, 10.0), {}); -~to.button('/grains/mode0', 0, { |v| ~granulators[0].mode_(v); ~setmode.value(0, v) }); -~to.button('/grains/mode1', 0, { |v| ~granulators[1].mode_(v); ~setmode.value(1, v) }); -~to.button('/grains/mode2', 0, { |v| ~granulators[2].mode_(v); ~setmode.value(2, v) }); -~to.button('/grains/mode3', 0, { |v| ~granulators[3].mode_(v); ~setmode.value(3, v) }); - -~to.slider('/grains/speed0', 1, TouchOSCScale(0, 2), { |v| ~setspeed.value(0, v) }); -~to.slider('/grains/speed1', 1, TouchOSCScale(0, 2), { |v| ~setspeed.value(1, v) }); -~to.slider('/grains/speed2', 1, TouchOSCScale(0, 2), { |v| ~setspeed.value(2, v) }); -~to.slider('/grains/speed3', 1, TouchOSCScale(0, 2), { |v| ~setspeed.value(3, v) }); +// ~to.button('/grains/mode0', 0, { |v| ~granulators[0].mode_(v); ~setmode.value(0, v) }); +// ~to.button('/grains/mode1', 0, { |v| ~granulators[1].mode_(v); ~setmode.value(1, v) }); +// ~to.button('/grains/mode2', 0, { |v| ~granulators[2].mode_(v); ~setmode.value(2, v) }); +// ~to.button('/grains/mode3', 0, { |v| ~granulators[3].mode_(v); ~setmode.value(3, v) }); +// +// ~to.slider('/grains/speed0', 1, TouchOSCScale(0, 2), { |v| ~setspeed.value(0, v) }); +// ~to.slider('/grains/speed1', 1, TouchOSCScale(0, 2), { |v| ~setspeed.value(1, v) }); +// ~to.slider('/grains/speed2', 1, TouchOSCScale(0, 2), { |v| ~setspeed.value(2, v) }); +// ~to.slider('/grains/speed3', 1, TouchOSCScale(0, 2), { |v| ~setspeed.value(3, v) }); ~to.slider('/grains/passthrough', 0.75, TouchOSCScale(0, 1), { |v| ~grainmixer.set(\passthrough, v) }); diff --git a/main.scd b/main.scd index 7035ed9..ce9453e 100644 --- a/main.scd +++ b/main.scd @@ -15,9 +15,9 @@ Routine.run({ ~usbinput1 = 2; ~usbinput2 = 3; - ~bpm = 80; + ~bpm = 85; ~bps = ~bpm / 60; - ~beatsperbar = 8; + ~beatsperbar = 4; ~buflen = ~beatsperbar / ~bps; [ "bpm", ~bpm ].postln; @@ -25,7 +25,6 @@ Routine.run({ ~tc = TempoClock.new(~bps); - ~touchosc_ip = "192.168.0.209"; ("./synths.scd").loadRelative; @@ -33,8 +32,15 @@ Routine.run({ s.sync; ("./control.scd").loadRelative; s.sync; + +}); +) + ("./granulator.scd").loadRelative; - s.sync; + + +( +Routine.run({ ("./effects.scd").loadRelative; s.sync; ("./sequencer.scd").loadRelative; @@ -43,6 +49,7 @@ Routine.run({ }); ) -~granulators[0].grainamp_(0.75); -g -~dumpbuffers.value("looptober14") \ No newline at end of file +~posb[0].scope +~granulators[0].grainamp_(0); +~granulators[0].loopsynth +~dumpbuffers.value("looptober23") \ No newline at end of file diff --git a/synths.scd b/synths.scd index 66862db..707bff5 100644 --- a/synths.scd +++ b/synths.scd @@ -1,30 +1,25 @@ ( -SynthDef(\pos_sine, { - arg out, speed=1; - Out.kr(out, 0.5 + SinOsc.kr(speed * 0.5, -0.5pi, 0.5)); -}).add; - SynthDef(\pos_saw, { - arg out, speed=1; - Out.kr(out, 0.5 + LFSaw.kr(speed, 1, 0.5, 0)); -}).add; + arg out, dur=1; + Out.kr(out, EnvGen.kr(Env([0, 1], dur), doneAction: Done.freeSelf)) +}).add(); + +SynthDef(\pos_sin, { + arg out, dur=1; + Out.kr(out, EnvGen.kr(Env.sine(dur, 1), doneAction: Done.freeSelf)) +}).add(); SynthDef(\pos_reverse, { - arg out, speed=1; - Out.kr(out, 0.5 - LFSaw.kr(speed, 1, 0.5, 0)); -}).add; + arg out, dur=1; + Out.kr(out, EnvGen.kr(Env([1, 0], dur), doneAction: Done.freeSelf)) +}).add(); -SynthDef(\pos_step, { - arg out, speed=1, steps=8; - var stepwise = LFSaw.kr(speed, 1, 0.5 * steps, 0.5 * steps).floor; - Out.kr(out, stepwise / steps); -}).add; - -SynthDef(\pos_random, { - arg out=5, speed=1; - Out.kr(out, 0.5 + WhiteNoise.kr(0.5)); -}).add; +// SynthDef(\pos_step, { +// arg out, speed=1, steps=8; +// var stepwise = LFSaw.kr(speed, 1, 0.5 * steps, 0.5 * steps).floor; +// Out.kr(out, stepwise / steps); +// }).add; SynthDef(\lfo, { arg out, freq=1, amp=0; @@ -32,8 +27,18 @@ SynthDef(\lfo, { }).add; SynthDef(\trigger, { - arg out=1, freq=1; - Out.kr(out, Impulse.kr(freq)) + arg out=1; + Out.kr(out, EnvGen.kr(Env.perc(0.001, 0.2, 2), levelScale:2.0, levelBias:-1,doneAction:Done.freeSelf)); }).add; + +SynthDef(\metronome, { + arg out=0, amp=1, pan=0, filter=1000, atk=0.01, rel=0.1; + var sig, env; + env = EnvGen.kr(Env.perc(atk, rel, amp), doneAction: Done.freeSelf); + sig = HPF.ar(WhiteNoise.ar(), filter); + Out.ar(out, Pan2.ar(sig * env, pan)); +} +).add; + ) -- 2.47.0 From 4f4132fdcc4e20bf1a479fb55529fd6b7102d3b8 Mon Sep 17 00:00:00 2001 From: Mike Lynch Date: Wed, 25 Oct 2023 14:34:23 +1100 Subject: [PATCH 3/5] Fixed playback issues --- granulator.scd | 57 +++++++++++++++++++++++++++++++++----------------- interface.scd | 8 +++---- main.scd | 15 +++---------- sequencer.scd | 10 +-------- synths.scd | 15 ++++++------- 5 files changed, 54 insertions(+), 51 deletions(-) diff --git a/granulator.scd b/granulator.scd index fac91ac..3763f76 100644 --- a/granulator.scd +++ b/granulator.scd @@ -4,9 +4,7 @@ ~modes = [ [ "saw", \pos_saw ], [ "reverse", \pos_reverse ], - [ "sine", \pos_sine ], - [ "step", \pos_step ], - [ "random", \pos_random ] + [ "sine", \pos_sine ] ]; ~outputDir = Platform.recordingsDir +/+ "GrainBuffers"; @@ -15,15 +13,16 @@ ~grainsb = Bus.audio(s, 2); ~granulators = Array.new(4); +~grainmodes = [ 0, 0, 0, 0 ]; // keep track of mode so don't swap if not needed ~posb = Array.new(4); ~rectriggerb = Array.new(4); -~possynths = Array.new(4); -~triggersynths = Array.new(4); +~patterns = Array.new(4); +~players = Array.new(4); +~loopsynths = Array.new(4); // create the control busses (0..3).do({ - var ps; ~posb.add(Bus.control(s, 1)); ~rectriggerb.add(Bus.control(s, 1)); }); @@ -35,29 +34,49 @@ ~granulators.add(Granulator.new(~buflen, ~infxb, ~grainsb, pb, rtb)); }); - -// launch the pos synths and triggers to sync the buffer recorders +// set up the Patterns which drive the position synths (0..3).do({ |i| - var pb = ~posb[i], rtb = ~rectriggerb[i]; - ~possynths.add(Synth(\pos_saw, [ \out, pb, \speed, 1 / ~buflen ])); - ~triggersynths.add(Synth(\trigger, [ \out, rtb, \freq, 1 / ~buflen ])); + ~patterns.add(~makePattern.value(i, 0)); }); -// TODO - retrigger the buffer records when changing the length etc +// play the four patterns +// to-do - will these need separate tempoclocks? + +(0..3).do({|i| + ~players.add(~patterns[i].play(~tc, quant: ~beatsperbar)) +}); ~setmode = { arg track, mode; - var synth = ~modes[mode][1]; - ~possynths[track].get(\speed, { | speed | - ~possynths[track].free; - ~triggersynths[track].free; - ~possynths[track] = Synth(synth, [\out, ~posb[track], \speed, speed]); - ~triggersynths[track] = Synth(\trigger, [ \out, ~rectriggerb[track] ]); + if( ~grainmodes[track] != mode, { + ~grainmodes[track] = mode; + ~players[track].stop; + ~patterns[track].free; + ~patterns[track] = ~makePattern.value(track, mode); + ~players[track] = ~patterns[track].play(~tc, quant: ~beatsperbar); }); - ~granulators[track].mode_(mode); }; +~makePattern = { + arg track, mode; + var ptrig, ppos, synth = ~modes[mode][1]; + [ "makePattern", ~track, ~buflen ].postln; + ptrig = Pbind( + \instrument, \trigger, + \dur, ~beatsperbar, + \out, ~rectriggerb[track] + ); + ppos = Pbind( + \instrument, synth, + \dur, ~beatsperbar, + \length, ~buflen, + \out, ~posb[track] + ); + Ppar([ptrig, ppos]); +}; + + ~dumpbuffers = { |prefix| (0..3).do({|i| var filename = ~outputDir +/+ prefix ++ 'buffer' ++ i.asString ++ '.aiff'; diff --git a/interface.scd b/interface.scd index eb6bd3b..dba2364 100644 --- a/interface.scd +++ b/interface.scd @@ -85,10 +85,10 @@ OSCdef.freeAll; ~to.slider('/grains/buflen', ~buflen, TouchOSCScale(0.1, 10.0), {}); -// ~to.button('/grains/mode0', 0, { |v| ~granulators[0].mode_(v); ~setmode.value(0, v) }); -// ~to.button('/grains/mode1', 0, { |v| ~granulators[1].mode_(v); ~setmode.value(1, v) }); -// ~to.button('/grains/mode2', 0, { |v| ~granulators[2].mode_(v); ~setmode.value(2, v) }); -// ~to.button('/grains/mode3', 0, { |v| ~granulators[3].mode_(v); ~setmode.value(3, v) }); +~to.button('/grains/mode0', 0, { |v| ~setmode.value(0, v) }); +~to.button('/grains/mode1', 0, { |v| ~setmode.value(1, v) }); +~to.button('/grains/mode2', 0, { |v| ~setmode.value(2, v) }); +~to.button('/grains/mode3', 0, { |v| ~setmode.value(3, v) }); // // ~to.slider('/grains/speed0', 1, TouchOSCScale(0, 2), { |v| ~setspeed.value(0, v) }); // ~to.slider('/grains/speed1', 1, TouchOSCScale(0, 2), { |v| ~setspeed.value(1, v) }); diff --git a/main.scd b/main.scd index ce9453e..d7cd723 100644 --- a/main.scd +++ b/main.scd @@ -32,24 +32,15 @@ Routine.run({ s.sync; ("./control.scd").loadRelative; s.sync; - -}); -) - ("./granulator.scd").loadRelative; - - -( -Routine.run({ + s.sync; ("./effects.scd").loadRelative; s.sync; ("./sequencer.scd").loadRelative; s.sync; + ~buflen.sleep; + "loading interface".postln; ("./interface.scd").loadRelative; }); ) -~posb[0].scope -~granulators[0].grainamp_(0); -~granulators[0].loopsynth -~dumpbuffers.value("looptober23") \ No newline at end of file diff --git a/sequencer.scd b/sequencer.scd index ce93b85..da45d47 100644 --- a/sequencer.scd +++ b/sequencer.scd @@ -2,14 +2,6 @@ ( -SynthDef(\metronome, { - arg out=0, amp=1, pan=0, filter=1000, atk=0.01, rel=0.1; - var sig, env; - env = EnvGen.kr(Env.perc(atk, rel, amp), doneAction: Done.freeSelf); - sig = HPF.ar(WhiteNoise.ar(), filter); - Out.ar(out, Pan2.ar(sig * env, pan)); -} -).add; ~metrob = Bus.audio(s, 2); @@ -21,7 +13,7 @@ SynthDef(\metronome, { ~metronome = Pbind( \instrument, \metronome, - \dur, 1, + \dur, ~beatsperbar, \amp, 0.5, \pan, 0, \out, ~metrob diff --git a/synths.scd b/synths.scd index 707bff5..7e04845 100644 --- a/synths.scd +++ b/synths.scd @@ -1,18 +1,18 @@ ( SynthDef(\pos_saw, { - arg out, dur=1; - Out.kr(out, EnvGen.kr(Env([0, 1], dur), doneAction: Done.freeSelf)) + arg out, length=1; + Out.kr(out, EnvGen.kr(Env([0, 1], length), doneAction: Done.freeSelf)) }).add(); -SynthDef(\pos_sin, { - arg out, dur=1; - Out.kr(out, EnvGen.kr(Env.sine(dur, 1), doneAction: Done.freeSelf)) +SynthDef(\pos_sine, { + arg out, length=1; + Out.kr(out, EnvGen.kr(Env.sine(length, 1), doneAction: Done.freeSelf)) }).add(); SynthDef(\pos_reverse, { - arg out, dur=1; - Out.kr(out, EnvGen.kr(Env([1, 0], dur), doneAction: Done.freeSelf)) + arg out, length=1; + Out.kr(out, EnvGen.kr(Env([1, 0], length), doneAction: Done.freeSelf)) }).add(); // SynthDef(\pos_step, { @@ -42,3 +42,4 @@ SynthDef(\metronome, { ).add; ) + -- 2.47.0 From 9f7b83a44eb68a56be3a7f95cbeef2651853d0a4 Mon Sep 17 00:00:00 2001 From: Mike Lynch Date: Wed, 25 Oct 2023 15:19:31 +1100 Subject: [PATCH 4/5] Quantised speed controls are back --- granulator.scd | 31 +++++++++++++++++++++---------- interface.scd | 33 ++++++++------------------------- 2 files changed, 29 insertions(+), 35 deletions(-) diff --git a/granulator.scd b/granulator.scd index 3763f76..a06c831 100644 --- a/granulator.scd +++ b/granulator.scd @@ -14,6 +14,7 @@ ~granulators = Array.new(4); ~grainmodes = [ 0, 0, 0, 0 ]; // keep track of mode so don't swap if not needed +~speeds = [ 1, 1, 1, 1 ]; // hacky speed quantisation ~posb = Array.new(4); ~rectriggerb = Array.new(4); ~patterns = Array.new(4); @@ -35,14 +36,10 @@ }); // set up the Patterns which drive the position synths - (0..3).do({ |i| - ~patterns.add(~makePattern.value(i, 0)); + ~patterns.add(~makePattern.value(i, 0, ~speeds[i])); }); -// play the four patterns -// to-do - will these need separate tempoclocks? - (0..3).do({|i| ~players.add(~patterns[i].play(~tc, quant: ~beatsperbar)) }); @@ -53,15 +50,29 @@ ~grainmodes[track] = mode; ~players[track].stop; ~patterns[track].free; - ~patterns[track] = ~makePattern.value(track, mode); + ~patterns[track] = ~makePattern.value(track, mode, ~speeds[track]); ~players[track] = ~patterns[track].play(~tc, quant: ~beatsperbar); }); }; +~setspeed = { + arg track, speed; + [ "setspeed", track, speed ].postln; + if( ~speeds[track] != speed, { + ~speeds[track] = speed; + ~players[track].stop; + ~patterns[track].free; + ~patterns[track] = ~makePattern.value(track, ~grainmodes[track], ~speeds[track]); + ~players[track] = ~patterns[track].play(~tc, quant: ~beatsperbar); + }); +}; + + ~makePattern = { - arg track, mode; + arg track, mode, speed; var ptrig, ppos, synth = ~modes[mode][1]; - [ "makePattern", ~track, ~buflen ].postln; + // note: trigger is going off the base tempoclock, not the playback speed - I think this is + // the right thing to do but I'm not sure yet ptrig = Pbind( \instrument, \trigger, \dur, ~beatsperbar, @@ -69,8 +80,8 @@ ); ppos = Pbind( \instrument, synth, - \dur, ~beatsperbar, - \length, ~buflen, + \dur, ~beatsperbar / speed, + \length, ~buflen / speed, \out, ~posb[track] ); Ppar([ptrig, ppos]); diff --git a/interface.scd b/interface.scd index dba2364..9c5a0b2 100644 --- a/interface.scd +++ b/interface.scd @@ -36,25 +36,6 @@ OSCdef.freeAll; }; -// control ganging is hella laggy, do it in TouchOSC - - - -// ~setspeed = { | track, v | -// var speed, qv = if(~speedquant > 0, { ~quantspeed.value(v) }, { v }); -// speed = qv / ~buflen; -// if(~speedlock > 0, { -// (0..3).do({|n| -// ~possynths[n].set(\speed, speed); -// if( n != track, { -// var url = ("/grains/speed" ++ n).asSymbol; -// ~to.s_(url, v); -// }); -// }); -// }, -// { ~possynths[track].set(\speed, speed) }); -// }; - // setrecord: toggles record on (1) or off (0) for a track, and also sets the // track's input mix to 0 so that it doesn't start fadeing out. If the track // is the currently selected track, set its touchosc control to 0. @@ -89,11 +70,13 @@ OSCdef.freeAll; ~to.button('/grains/mode1', 0, { |v| ~setmode.value(1, v) }); ~to.button('/grains/mode2', 0, { |v| ~setmode.value(2, v) }); ~to.button('/grains/mode3', 0, { |v| ~setmode.value(3, v) }); -// -// ~to.slider('/grains/speed0', 1, TouchOSCScale(0, 2), { |v| ~setspeed.value(0, v) }); -// ~to.slider('/grains/speed1', 1, TouchOSCScale(0, 2), { |v| ~setspeed.value(1, v) }); -// ~to.slider('/grains/speed2', 1, TouchOSCScale(0, 2), { |v| ~setspeed.value(2, v) }); -// ~to.slider('/grains/speed3', 1, TouchOSCScale(0, 2), { |v| ~setspeed.value(3, v) }); + +// needs work + +~to.slider('/grains/speed0', 1, TouchOSCScale(0, 2), { |v| ~setspeed.value(0, ~quantspeed.value(v)) }); +~to.slider('/grains/speed1', 1, TouchOSCScale(0, 2), { |v| ~setspeed.value(1, ~quantspeed.value(v)) }); +~to.slider('/grains/speed2', 1, TouchOSCScale(0, 2), { |v| ~setspeed.value(2, ~quantspeed.value(v)) }); +~to.slider('/grains/speed3', 1, TouchOSCScale(0, 2), { |v| ~setspeed.value(3, ~quantspeed.value(v)) }); ~to.slider('/grains/passthrough', 0.75, TouchOSCScale(0, 1), { |v| ~grainmixer.set(\passthrough, v) }); @@ -105,7 +88,7 @@ OSCdef.freeAll; ~to.button('/grains/lock', 0, { |v| ~speedlock = v }); -~to.button('/grains/quant', 0, { |v| ~speedquant = v }); +~to.button('/grains/quant', 1, { |v| ~speedquant = v }); ~to.button('/grains/metronome', 0, { |v| if( v == 1, { -- 2.47.0 From 5e0e9df5f4abf60f10d20e9c70fc9614c3b81933 Mon Sep 17 00:00:00 2001 From: Mike Lynch Date: Thu, 26 Oct 2023 10:44:21 +1100 Subject: [PATCH 5/5] reinstated step playback --- granulator.scd | 32 ++++++++++++++++---------------- interface.scd | 2 +- main.scd | 6 +++--- synths.scd | 12 ++++++------ 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/granulator.scd b/granulator.scd index a06c831..1151a31 100644 --- a/granulator.scd +++ b/granulator.scd @@ -4,7 +4,8 @@ ~modes = [ [ "saw", \pos_saw ], [ "reverse", \pos_reverse ], - [ "sine", \pos_sine ] + [ "sine", \pos_sine ], + [ "step", \pos_step ], ]; ~outputDir = Platform.recordingsDir +/+ "GrainBuffers"; @@ -17,9 +18,9 @@ ~speeds = [ 1, 1, 1, 1 ]; // hacky speed quantisation ~posb = Array.new(4); ~rectriggerb = Array.new(4); -~patterns = Array.new(4); -~players = Array.new(4); -~loopsynths = Array.new(4); +~patterns = [ nil, nil, nil, nil ]; +~players = [ nil, nil, nil, nil ]; +~loopsynths = [ nil, nil, nil, nil ]; // create the control busses @@ -36,28 +37,28 @@ }); // set up the Patterns which drive the position synths -(0..3).do({ |i| - ~patterns.add(~makePattern.value(i, 0, ~speeds[i])); -}); -(0..3).do({|i| - ~players.add(~patterns[i].play(~tc, quant: ~beatsperbar)) -}); +// (0..3).do({ |i| +// ~patterns.add(~makePattern.value(i, 0, ~speeds[i])); +// }); +// +// (0..3).do({|i| +// ~players.add(~patterns[i].play(~tc, quant: ~beatsperbar)) +// }); ~setmode = { arg track, mode; - if( ~grainmodes[track] != mode, { - ~grainmodes[track] = mode; + ~grainmodes[track] = mode; + if(~players[track].isNil.not,{ ~players[track].stop; ~patterns[track].free; - ~patterns[track] = ~makePattern.value(track, mode, ~speeds[track]); - ~players[track] = ~patterns[track].play(~tc, quant: ~beatsperbar); }); + ~patterns[track] = ~makePattern.value(track, mode, ~speeds[track]); + ~players[track] = ~patterns[track].play(~tc, quant: ~beatsperbar); }; ~setspeed = { arg track, speed; - [ "setspeed", track, speed ].postln; if( ~speeds[track] != speed, { ~speeds[track] = speed; ~players[track].stop; @@ -95,4 +96,3 @@ }); } ) - diff --git a/interface.scd b/interface.scd index 9c5a0b2..e5295a0 100644 --- a/interface.scd +++ b/interface.scd @@ -112,7 +112,7 @@ OSCdef.freeAll; ~to.button('/track/dust', 0, { |v| ~granulator.dust_(v) }); ~to.button('/track/back', 0, { |v| ~granulator.back_(v)}); -~to.button('/track/slope', 0, { |v| ~granulator.slope_(v) }); +~to.button('/track/slope', 1, { |v| ~granulator.slope_(v) }); ~to.button('/track/chorus', 0, { |v| ~granulator.chorus_(v) }); ~to.slider('/track/harmonics', 2, TouchOSCScale(0.5, 3), { |v| diff --git a/main.scd b/main.scd index d7cd723..89bb301 100644 --- a/main.scd +++ b/main.scd @@ -15,7 +15,7 @@ Routine.run({ ~usbinput1 = 2; ~usbinput2 = 3; - ~bpm = 85; + ~bpm = 90; ~bps = ~bpm / 60; ~beatsperbar = 4; ~buflen = ~beatsperbar / ~bps; @@ -38,9 +38,9 @@ Routine.run({ s.sync; ("./sequencer.scd").loadRelative; s.sync; + "please wait for the interface to load...".postln; ~buflen.sleep; - "loading interface".postln; ("./interface.scd").loadRelative; + "ok go!".postln; }); ) - diff --git a/synths.scd b/synths.scd index 7e04845..d573fde 100644 --- a/synths.scd +++ b/synths.scd @@ -15,11 +15,12 @@ SynthDef(\pos_reverse, { Out.kr(out, EnvGen.kr(Env([1, 0], length), doneAction: Done.freeSelf)) }).add(); -// SynthDef(\pos_step, { -// arg out, speed=1, steps=8; -// var stepwise = LFSaw.kr(speed, 1, 0.5 * steps, 0.5 * steps).floor; -// Out.kr(out, stepwise / steps); -// }).add; +SynthDef(\pos_step, { + arg out, length=1; + var levels = (0..8) / 8, times = (length / 8) ! 7; + Out.kr(out, EnvGen.kr(Env(levels: levels, times: times, curve: \hold), doneAction: Done.freeSelf)); +}).add(); + SynthDef(\lfo, { arg out, freq=1, amp=0; @@ -42,4 +43,3 @@ SynthDef(\metronome, { ).add; ) - -- 2.47.0