// title: A QuNeo's Sampler melodic and expressive with different scales // author: sebastienclara // description: // code: /* Sébastien Clara - octobre 2013 // QuNeoSamplerMelodic v201310 You NEED to install and configure the QuNeo library on Quarks. A QuNeo's Sampler melodic and expressive with different scales. Usage : Horizontal pad => second for heptatonic scale. Vertical pad => third for heptatonic scale. For change the configuration, see variable padsDegree. pad X => frequency of the vibrato. pad Y => amplitude of the vibrato. circles[0] => change the scale. If you have a problem with the 15 pad, see http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/QuNeo-Quark-tp7598479p7603927.html */ ( s.waitForBoot({ //////////////////////////////////////////////////////////////////////// // Initialisation var window, scalePopUp, scalesIndexTxt, selectSampleButton; var scale, padsDegree = [0,1,2,3, 2,3,4,5, 4,5,6,7, 6,7,8,9]; var scalesIndex = 51, locMoinsUn = 1; var sampler = Array.fill(padsDegree.size, {nil}); var buffer = Buffer.read(s, Platform.resourceDir +/+ "sounds/a11wlk01.wav"); SynthDef(\looper, { arg out=0, buffer, rate=1, amp=0.5, vibFreq=7, vibAmp=0; var signal; signal = PlayBuf.ar(1, buffer, BufRateScale.kr(buffer)*rate, loop:1); signal = signal * SinOsc.kr(vibFreq*15, mul:vibAmp, add:1); signal = signal * amp * EnvGate.new(curve:\welch); Out.ar(out, signal.dup); }).add; // QuNeo's functions padsDegree.size.do({ |i| ~quNeo.pads[i].note.onFunc = { sampler[i] = Synth(\looper, [\buffer,buffer, \rate, scale.degreeToRatio(padsDegree[i], 0), \amp, ~quNeo.pads[i].press.map, \vibFreq, ~quNeo.pads[i].x.map, \vibAmp, ~quNeo.pads[i].y.map ]) }; ~quNeo.pads[i].note.offFunc = { sampler[i].set(\fadeTime,0.02, \gate,0); }; }); ~quNeo.circles[0].loc.func = { case {((~quNeo.circles[0].loc.value*10).round > locMoinsUn).and(scalesIndex < (scalePopUp.items.size-1))} {scalesIndex = scalesIndex + 1} {((~quNeo.circles[0].loc.value*10).round < locMoinsUn).and(scalesIndex > 0)} {scalesIndex = scalesIndex - 1}; if (locMoinsUn != (~quNeo.circles[0].loc.value*10).round, { locMoinsUn = (~quNeo.circles[0].loc.value*10).round; {scalePopUp.valueAction = (scalesIndex)}.defer; }); // postf("scalesIndex = % -- loc = % -- loc-1 = %\n", scalesIndex, (~quNeo.circles[0].loc.value*10).round, locMoinsUn ); }; //////////////////////////////////////////////////////////////////////// // Gui window = Window("A QuNeo's Sampler", Rect(500, 700, 250, 50)); selectSampleButton = Button(window).states_([["Select a sample"]]); scalePopUp = PopUpMenu(window).items_(ScaleInfo.scales.keys.asArray.sort); scalesIndexTxt = StaticText(window).align_(\center); window.layout_( VLayout( selectSampleButton, HLayout(scalePopUp, scalesIndexTxt) ) ).front; //////////////////////////////////////////////////////////////////////// // Actions scalePopUp.action = { arg menu; scale = ScaleInfo.at(menu.item); // postf("\t*** Using scale: ---> %\n", menu.item.asString); scalesIndex = menu.value; scalesIndexTxt.string = menu.value.asString; }; scalePopUp.valueAction = (scalesIndex); selectSampleButton.action = { Dialog.openPanel({ arg pathFile; ("sample =>" + pathFile).postln; buffer = Buffer.read(s, pathFile); }); }; window.onClose = { padsDegree.size.do({ |i| ~quNeo.pads[i].note.onFunc = nil; ~quNeo.pads[i].note.offFunc = nil; }); ~quNeo.circles[0].loc.func = nil; // "Clear QuNeo's functions.\n".postln; }; }) )