/* Sébastien Clara - Septempbre 2012 - https://sebastienclara.wordpress.com/ An instrument for granular synthesis v201306. You need to install the numeral preset patch before !! */ //////////////////////////////////////////////////////////////////////////// s.boot; //////////////////////////////////////////////////////////////////////////// // Synthétiseur //////////////////////////////////////////////////////////////////////////// ( SynthDef(\granul, {arg bus=0, gate=1, densite=10, dureeGrain=0.05, freq=440, rangPartiel=1, amp = 1, textureSpectral=1, jitter=0; var signal, env, jit; env = EnvGen.kr(Env.asr, gate ); jit = LFBrownNoise2.kr.range(1-jitter,1+jitter); signal = SinGrain.ar(Impulse.kr(densite*jit), dureeGrain, (rangPartiel**textureSpectral) * freq * jit, amp); // signal = SinGrain.ar(Impulse.kr(densite), dureeGrain, (rangPartiel**textureSpectral) * freq, amp); Out.ar(bus, signal*env); }).add; ) //////////////////////////////////////////////////////////////////////////// // guiApp //////////////////////////////////////////////////////////////////////////// ( var window, densiteTxt, densiteNum, densiteSlider, dureeGrainTxt, dureeGrainSlider, dureeGrainNum, fondamentaleTxt, fondamentaleSlider, fondamentaleNum, nombrePartielTxt, nombrePartielSlider, nombrePartielNum, ampTxt, ampSlider, ampNum, textureSpectreTxt, textureSpectreSlider, textureSpectreNum, jitterTxt, jitterSlider, jitterNum, onOffTxt, onOffButton, statusBox; var densiteControl, dureeGrainControl, fondamentaleControl, nombrePartielControl, textureSpectreControl, ampControl; var scale = 0.2, g = Group.new, maxPartiels = 100, partiels = Array.fill(maxPartiels, {nil}), nombrePartielTmoins1; var numeralPreset, objet2presetTab; var fichierSauvegarde = (PathName(thisProcess.nowExecutingPath).pathOnly ++ "preset.sctxar").standardizePath; /////////////////////////////////////////////////////////////// // guiObjects window = Window("Synthèse granulaire", Rect(430, 60, 400, 650)); densiteTxt = StaticText(window).align_(\center).string_("Densité granumaire"); densiteNum = NumberBox(window).align_(\center).clipLo_(0.1).clipHi_(250).step_(0.1).scroll_step_(5).value_(10); densiteSlider = Slider(window).orientation_(\horizontal); dureeGrainTxt = StaticText(window).align_(\center).string_("Durée du grain"); dureeGrainNum = NumberBox(window).align_(\center).clipLo_(0.001).clipHi_(0.3).step_(0.001).scroll_step_(0.002).minDecimals_(3).value_(0.05); dureeGrainSlider = Slider(window).orientation_(\horizontal); fondamentaleTxt = StaticText(window).align_(\center).string_("Fondamentale"); fondamentaleNum = NumberBox(window).align_(\center).clipLo_(50).clipHi_(4000).step_(10).scroll_step_(10).value_(440); fondamentaleSlider = Slider(window).orientation_(\horizontal); nombrePartielTxt = StaticText(window).align_(\center).string_("Nombre de partiel"); nombrePartielNum = NumberBox(window).align_(\center).clipLo_(1).clipHi_(maxPartiels-1).step_(1).scroll_step_(1).value_(10); nombrePartielSlider = Slider(window).orientation_(\horizontal); textureSpectreTxt = StaticText(window).align_(\center).string_("Texture spectral"); textureSpectreNum = NumberBox(window).align_(\center).clipLo_(0.1).clipHi_(2).step_(0.1).scroll_step_(0.1).value_(1); textureSpectreSlider = Slider(window).orientation_(\horizontal); jitterTxt = StaticText(window).align_(\center).string_("Jitter"); jitterNum = NumberBox(window).align_(\center).clipLo_(0).clipHi_(1).step_(0.01).scroll_step_(0.01).value_(0); jitterSlider = Slider(window).orientation_(\horizontal); ampTxt = StaticText(window).align_(\center).string_("Amplitude"); ampNum = NumberBox(window).align_(\center).clipLo_(0.05).clipHi_(2).step_(0.05).scroll_step_(0.05).value_(1); ampSlider = Slider(window).orientation_(\horizontal); onOffTxt = StaticText(window).align_(\center).string_("On / Off"); onOffButton = Button(window).states_([["Off"], ["On"]]); objet2presetTab = [densiteSlider, dureeGrainSlider, fondamentaleSlider, nombrePartielSlider, textureSpectreSlider, jitterSlider, ampSlider]; numeralPreset = ViewNumeralPreset(window, fichierSauvegarde); /////////////////////////////////////////////////////////////// // Window window.layout_( VLayout( [HLayout([densiteTxt], [densiteNum])], densiteSlider, [HLayout([dureeGrainTxt], [dureeGrainNum])], dureeGrainSlider, [HLayout([fondamentaleTxt], [fondamentaleNum])], fondamentaleSlider, [HLayout([nombrePartielTxt], [nombrePartielNum])], nombrePartielSlider, [HLayout([textureSpectreTxt], [textureSpectreNum])], textureSpectreSlider, [HLayout([jitterTxt], [jitterNum])], jitterSlider, [HLayout([ampTxt], [ampNum])], ampSlider, [HLayout([onOffTxt], [onOffButton]), align:\center], numeralPreset.build ) ).front; statusBox = StatusBox2(window); numeralPreset.start(objet2presetTab); /////////////////////////////////////////////////////////////// // Action onOffButton.action = { if (onOffButton.value == 0, { partiels.do(_.free ); partiels = Array.fill(maxPartiels, {nil}); }, { nombrePartielNum.value.do({arg i; partiels[i] = Synth(\granul, [\freq,fondamentaleNum.value, \rangPartiel,i+1, \amp, nombrePartielNum.value.reciprocal * scale * ampNum.value, \textureSpectral, textureSpectreNum.value, \densite, densiteNum.value, \dureeGrain, dureeGrainNum.value, \jitter, jitterNum.value], g ); }); }); }; densiteNum.action = { densiteNum.value = (densiteControl.map(densiteSlider.value)); }; densiteSlider.action = { densiteNum.value = (densiteControl.map(densiteSlider.value)); if (onOffButton.value != 0, { (nombrePartielNum.value-1).do({|i| partiels[i].set(\densite, densiteNum.value)}); }); }; dureeGrainNum.action = { dureeGrainNum.value = (dureeGrainControl.map(dureeGrainSlider.value)); }; dureeGrainSlider.action = { dureeGrainNum.value = (dureeGrainControl.map(dureeGrainSlider.value)); if (onOffButton.value != 0, { (nombrePartielNum.value-1).do({|i| partiels[i].set(\dureeGrain, dureeGrainNum.value)}); }); }; fondamentaleNum.action = { fondamentaleNum.value = (fondamentaleControl.map(fondamentaleSlider.value)); }; fondamentaleSlider.action = { fondamentaleNum.value = (fondamentaleControl.map(fondamentaleSlider.value)); if (onOffButton.value != 0, { (nombrePartielNum.value-1).do({|i| partiels[i].set(\freq, fondamentaleNum.value)}); }); }; nombrePartielNum.action = { nombrePartielNum.value = (nombrePartielControl.map(nombrePartielSlider.value)); }; nombrePartielSlider.action = { nombrePartielNum.value = (nombrePartielControl.map(nombrePartielSlider.value)); if( (onOffButton.value != 0) && (nombrePartielNum.value < (maxPartiels) ) && (nombrePartielNum.value != nombrePartielTmoins1), { if( nombrePartielTmoins1 < nombrePartielNum.value, { (nombrePartielTmoins1 .. nombrePartielNum.value-1).do({|i| partiels[i] = Synth(\granul, [\freq,fondamentaleNum.value, \rangPartiel,i+1, \amp, nombrePartielNum.value.reciprocal * scale * ampNum.value, \textureSpectral, textureSpectreNum.value, \densite, densiteNum.value, \dureeGrain, dureeGrainNum.value, \jitter, jitterNum.value], g ); }); ampSlider.action.value; }, { (nombrePartielNum.value .. nombrePartielTmoins1-1).do({|i| partiels[i].free; partiels[i]=nil;}); ampSlider.action.value; }); }); nombrePartielTmoins1 = nombrePartielNum.value; }; textureSpectreNum.action = { textureSpectreNum.value = (textureSpectreControl.map(textureSpectreSlider.value)); }; textureSpectreSlider.action = { textureSpectreNum.value = (textureSpectreControl.map(textureSpectreSlider.value)); if (onOffButton.value != 0, { (nombrePartielNum.value-1).do({|i| partiels[i].set(\textureSpectral, textureSpectreNum.value)}); }); }; jitterNum.action = { jitterNum.value = jitterSlider.value; }; jitterSlider.action = { jitterNum.value = jitterSlider.value; if (onOffButton.value != 0, { (nombrePartielNum.value-1).do({|i| partiels[i].set(\jitter, jitterNum.value)}); }); }; ampNum.action = { ampNum.value = (ampControl.map(ampSlider.value)); }; ampSlider.action = { ampNum.value = (ampControl.map(ampSlider.value)); if (onOffButton.value != 0, { (nombrePartielNum.value-1).do({|i| partiels[i].set(\amp,nombrePartielNum.value.reciprocal * scale * ampNum.value) }); }); }; /////////////////////////////////////////////////////////////// // Contrôle densiteControl = ControlSpec(minval: 0.1, maxval: 250, warp:\lin, step: 0.1, default:10); densiteSlider.value = (densiteControl.unmap(densiteNum.value)); dureeGrainControl = ControlSpec(minval: 0.001, maxval: 0.3, warp:\lin, step: 0.001, default:0.05); dureeGrainSlider.value = (dureeGrainControl.unmap(dureeGrainNum.value)); fondamentaleControl = ControlSpec(minval: 50, maxval: 4000, warp:\lin, step: 10, default:440); fondamentaleSlider.value = (fondamentaleControl.unmap(fondamentaleNum.value)); nombrePartielControl = ControlSpec(minval: 1, maxval: maxPartiels-1, warp:\lin, step: 1, default:10); nombrePartielSlider.value = (nombrePartielControl.unmap(nombrePartielNum.value)); textureSpectreControl = ControlSpec(minval: 0.1, maxval: 2, warp:\lin, step: 0.05, default:1); textureSpectreSlider.value = (textureSpectreControl.unmap(textureSpectreNum.value)); ampControl = ControlSpec(minval: 0.1, maxval: 2, warp:\lin, step: 0.1, default:1); ampSlider.value = (ampControl.unmap(ampNum.value)); nombrePartielTmoins1 = nombrePartielNum.value; window.onClose = { g.free; }; // Contrôle par clavier d'ordi window.view.keyDownAction = { arg view, char, modifiers, unicode, keycode; switch (unicode, 27, { onOffButton.valueAction = 0; } // ); }; "Start" )