SHARE
TWEET

Untitled

a guest Jul 6th, 2018 116 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (
  2. var microtonal_organ = {arg basefreq=50, padStates=4, sendOSCData = true;
  3.    
  4.     (
  5.    
  6.     init: {|self|
  7.         self.setupBusses;
  8.         self.prepareForSynths;
  9.         self.setupController;
  10.     },
  11.  
  12.     prepareForSynths: {|self|
  13.         self.synths = Array.fill2D(8,8); // Note, this has different behaviour from Array2D.new
  14.  
  15.         // This is the mastergroup that will hold all synths from each pad and
  16.         // run them through the output synth and other master effects
  17.         self.masterGroup = Group.new;
  18.  
  19.             Synth.tail(self.masterGroup,
  20.                 'out',
  21.                 [
  22.                     \amp, self.controlBusses.sliders.at(8).asMap
  23.                 ]
  24.             );
  25.  
  26.     },
  27.  
  28.     makeSynth: {|self, state, row, col|
  29.  
  30.         var synthgroup = Group.head(self.masterGroup);
  31.  
  32.         var r = row + 1;
  33.         var c = col + 1 ;
  34.         var freq = basefreq * c * r;
  35.  
  36.         s.makeBundle(nil, {
  37.  
  38.             (state < 3).if({
  39.  
  40.                 // Source
  41.                 Synth.head(synthgroup,
  42.                    'organVoice',
  43.                    [
  44.                         \freq, freq,
  45.                         \freqdiff, state,
  46.                         \detune, self.controlBusses.sliders.at(col).asMap,
  47.                         \pan,exprand(-1,1) ,
  48.                         \amp, r.pow(2).reciprocal
  49.                    ]
  50.                 );
  51.  
  52.             }, {
  53.  
  54.                 // Source
  55.                 Synth.head(synthgroup,
  56.                    'grainsin',
  57.                    [
  58.                         \freq, freq,
  59.                         \freqdiff, state,
  60.                         \detune, self.controlBusses.sliders.at(col).asMap,
  61.                         \amp, r.pow(2).reciprocal
  62.                    ]
  63.                 );
  64.             });
  65.            
  66.         });
  67.  
  68.         // Place the synth in a 2d matrix array equivalent to the pad matrix on
  69.         // the controller
  70.         // When the synth needs to be freed it's done from here as well
  71.         self.synths[row][col] = synthgroup;
  72.  
  73.     },
  74.    
  75.     // FUNCTION FOR PADS
  76.     padFunc: {|self, row, col, state|
  77.  
  78.         // Update bus
  79.         self.controlBusses.pads[row][col].set(state);
  80.  
  81.         // If a synth is already playing in this pads memory, free it
  82.         self.synths[row][col].notNil.if({ self.synths[row][col].free; });
  83.        
  84.         // If the state of the pad isn't 0, play a synth
  85.         (state == 0).if(
  86.             {self.synths[row][col].free},
  87.             {self.makeSynth(state, row, col).value}
  88.         );
  89.    
  90.         // Send data off via OSC
  91.         self.oscSender("/padRow%Col%".format(row,col), state);
  92.     },
  93.  
  94.     // FUNCTION FOR BUTTONS
  95.     btnFunc: {|self, type, btnNo, state|
  96.  
  97.         // Do this if it's a horizontal button
  98.         (type == \hor).if({
  99.             self.controlBusses.horBtns.at(btnNo).set(state)
  100.         });
  101.  
  102.         // Do this if it's a vertical button
  103.         (type == \ver).if({
  104.             self.controlBusses.verBtns.at(btnNo).set(state)
  105.         });
  106.  
  107.         self.oscSender("/%Btn%".format(type, btnNo), state);
  108.     },
  109.  
  110.    
  111.     // BUS SETUP
  112.     setupBusses: {|self|
  113.         var sliderdefault = 0.5;
  114.  
  115.         self.controlBusses = ();
  116.  
  117.         // Slider busses
  118.         self.controlBusses.sliders = Array.fill(9, { Bus.control(s,1).set(sliderdefault)});
  119.  
  120.         // Pad busses
  121.         self.controlBusses.pads = Array.fill2D(8, 8, {Bus.control(s,1)});
  122.  
  123.         // Horizontal button busses
  124.         self.controlBusses.horBtns = Array.fill(8, {Bus.control(s,1)});
  125.  
  126.         // Vertical button busses
  127.         self.controlBusses.verBtns = Array.fill(8, {Bus.control(s,1)});
  128.  
  129.         },
  130.  
  131.     // CONTROLLER SETUP
  132.     setupController: {|self|
  133.  
  134.         // Instantiate script
  135.         self.controller = APCmini.new;
  136.  
  137.         // Number of states for the pads
  138.         self.controller.setNumStatesAll(padStates);
  139.  
  140.         // Set sliders
  141.         9.do{|sliderNum|
  142.             self.controller.setSliderFunction(sliderNum, {| sliderIndex, value|
  143.                 var v = value.linlin(0,127,0.0,1.0);
  144.                 self.controlBusses.sliders.at(sliderIndex).set(v);
  145.                 self.oscSender("/slider" ++ sliderNum, v);
  146.             })
  147.         };
  148.  
  149.         // Set pads (there are 8 x 8 and for each there are 4 states)
  150.         8.do{|row|
  151.             8.do{|col|
  152.                 padStates.do{|state|
  153.                     self.controller.setPadFunction(row, col, state, {
  154.                         self.padFunc(row, col, state);
  155.                         }
  156.                     );
  157.                 }
  158.             }
  159.         };
  160.  
  161.         // The horizontal and vertical buttons on the side of the controller
  162.         // only have two modes: On or off
  163.         8.do{|btnNo| 
  164.             2.do{|state|
  165.                 2.do{|typeNo|
  166.                     var types = [\hor, \ver];
  167.                     self.controller.setButtonFunction(types[typeNo], btnNo, state, {
  168.                         self.btnFunc(types[typeNo], btnNo, state);
  169.                         }
  170.                     );
  171.                 }
  172.             }
  173.         }
  174.     },
  175.            
  176.     // OSC FUNCTIONS
  177.     oscTarget: {|self, targetAddress="127.0.0.1", targetPort=7000|
  178.         NetAddr.new(targetAddress, targetPort);
  179.     }, 
  180.  
  181.     oscSender: {|self, message, parameter, base="/apcmini_HELLO"|
  182.         if (sendOSCData, {
  183.             self.oscTarget.sendMsg(base ++ message, parameter);  
  184.         },
  185.         {"Not sending OSC data"})
  186.     }
  187. )};
  188.  
  189. microtonal_organ.value(basefreq:80).init;
  190.  
  191. /************
  192.  
  193.     SYNTHS
  194.  
  195. ************/
  196.  
  197. SynthDef(\organVoice, {
  198.     arg out=0, amp=1, freq, freqdiff=0, detune=0, effectBus, pan=0;
  199.     var d = 1 + (detune / 10);
  200.     var env, sig;
  201.  
  202.     sig = SinOsc.ar(d * [freq, freq-freqdiff]);
  203.     sig = Pan2.ar(sig, pan);
  204.  
  205.     sig = sig * amp * 0.01;
  206.  
  207.     Out.ar(out, sig )
  208. }).add;
  209.  
  210. SynthDef(\grainsin, {
  211.     arg out=0, amp=1, freq, freqdiff=0, detune=0;
  212.     var d = 1 + (detune / 10);
  213.     var env, sig;
  214.  
  215.     sig = GrainSin.ar(2,
  216.         Dust.ar(d * freq.log2),
  217.         freq.log2.reciprocal * 2 ,
  218.         d * freq,
  219.         0,
  220.         -1,
  221.         512
  222.     );
  223.  
  224.     sig = sig * amp * 0.01;
  225.  
  226.     Out.ar(out, sig )
  227. }).add;
  228.  
  229. /* --- SYNTH: out --- */
  230. SynthDef(\out, {
  231.     arg in, out=0, fadetime=2, amp=1.0, gate=1;
  232.     var env, sig;
  233.  
  234.     sig = In.ar(in, 2);
  235.  
  236.     ReplaceOut.ar(out, sig * amp )
  237. }).add;
  238.  
  239. s.plotTree;
  240. s.meter;
  241. )
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top