Advertisement
Guest User

Untitled

a guest
Oct 31st, 2014
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2.  *  twitter: @potasmic - dubstep dawn (i ported this from wavepot.com :) )
  3. **/
  4. var sampleRate= 44100;
  5. var bpm = 148;
  6. var tuning = 440;
  7. var transpose = 0;
  8.  
  9. // constants
  10. var tau = 2 * Math.PI;
  11.  
  12. // time coefficients
  13. var t, tt;
  14.  
  15. function Osc(type, octave, size, alias){
  16.   if (!(this instanceof Osc)) return new Osc(type, size, alias);
  17.   this.pos = 0;
  18.   this.octave = Math.pow(2,octave) || 1;
  19.   this.size = size || sampleRate;
  20.   this.coeff = this.size / sampleRate;
  21.   this.table = new Float32Array(this.size);
  22.   this.alias = alias === false ? false : true;
  23.   this.build(type);
  24. }
  25.  
  26. Osc.prototype.build = function(type){
  27.   switch (type) {
  28.     case 'sin':
  29.       var scale = 2 * Math.PI / this.size;
  30.       for (var i = 0; i < this.size; i++) {
  31.         this.table[i] = Math.sin(i * scale);
  32.       }
  33.       break;
  34.  
  35.     case 'saw':
  36.       for (var i = 0; i < this.size; i++) {
  37.         var x = (i / this.size);
  38.         this.table[i] = +2.0 * (x - Math.round(x));
  39.       }
  40.       break;
  41.  
  42.     case 'ramp':
  43.       for (var i = 0; i < this.size; i++) {
  44.         var x = (i / this.size);
  45.         this.table[i] = -2.0 * (x - Math.round(x));
  46.       }
  47.       break;
  48.  
  49.     case 'tri':
  50.       for (var i = 0; i < this.size; i++) {
  51.         var x = (i / this.size) - 0.25;
  52.         this.table[i] = 1.0 - 4.0 * Math.abs(Math.round(x) - x);
  53.       }
  54.       break;
  55.  
  56.     case 'sqr':
  57.       var half = this.size / 2;
  58.       for (var i = 0; i < this.size; i++) {
  59.         this.table[i] = i < half ? +1 : -1;
  60.       }
  61.       break;
  62.   }
  63. };
  64.  
  65. Osc.prototype.play = function(freq,oct){
  66.   var octa = Math.pow(2,oct) || this.octave;
  67.   this.pos += freq * this.coeff * octa;
  68.   if (this.pos >= this.size) this.pos -= this.size;
  69.   this.index = this.pos | 0;
  70.   if (!this.alias) return this.table[this.index];
  71.   this.alpha = this.pos - this.index;
  72.   this.next = this.table[this.index == this.size - 1 ? 0 : this.index + 1];
  73.   this.curr = this.table[this.index];
  74.   return this.curr + (this.next - this.curr) * this.alpha;
  75. };
  76.  
  77.  
  78. function Syn(oscs, octs) {
  79.   if(!(this instanceof Syn)) return new Syn(oscs);
  80.   this.oscs = oscs;
  81.   this.octs = octs;
  82. }
  83.  
  84. Syn.prototype.setOcts = function(arr) {
  85.   this.octs = arr;
  86. }
  87.  
  88. Syn.prototype.mix = function(freq) {
  89.   var sum = 0;
  90.   var all = this.oscs.length;
  91.   for(i=0; i< all; i++ ) {
  92.     var oct = this.octs[i];
  93.     sum += this.oscs[i].play(freq,oct) * 1/all;
  94.   }
  95.   return sum;
  96. }
  97.  
  98. function clock(_t){
  99.   t = _t;
  100.   t *= bpm / 120;
  101.   tt = tau * t;
  102. }
  103.  
  104.  
  105. function sequence(measure, seq){
  106.   return seq[(t / measure / 2 | 0) % seq.length];
  107. }
  108.  
  109. function ms2freq(ms) {
  110.   return (ms)*60/bpm;
  111. }
  112.  
  113. function arp(measure, x, y, z){
  114.   var ts = t / 2 % measure;
  115.   return Math.sin(x * (Math.exp(-ts * y))) * Math.exp(-ts * z);
  116. }
  117.  
  118. function sin(freq, phase){
  119.   return Math.sin((t * freq + (2 - (phase || 0) / 2)) * tau);
  120. }
  121.  
  122. function saw(freq){
  123.   return 1-2 * (t % (1 / freq)) * freq;
  124. }
  125.  
  126. function tri(freq){
  127.   return Math.abs(1 - (2 * t * freq) % 2) * 2 - 1;
  128. }
  129.  
  130. function sqr(freq){
  131.   return sin(freq, t) > 0 ? 1 : -1;
  132. }
  133.  
  134. function Noise(){
  135.   return Math.random() * 2 - 1;
  136. }
  137.  
  138. function note(n, octave){
  139.   return Math.pow(2, (
  140.     n + transpose - 33 + (12 * (octave || 0))
  141.   ) / 12) * tuning; // A4 tuning
  142. }
  143.  
  144. function clip(x){
  145.   return x / (1 + Math.abs(x));
  146. }
  147.  
  148. function DiodeFilter(){
  149.   this.k = 0;
  150.   this.A = 0;
  151.   this.z = [0,0,0,0,0];
  152.   this.ah;
  153.   this.bh;
  154.   this.fc;
  155.   this.set_q(0);
  156.   this.set_hpf(0.5);
  157.   this.set_fc(.5);
  158. }
  159.  
  160. DiodeFilter.prototype.set_hpf = function(fc){
  161.   var K = fc * Math.PI;
  162.   this.ah = (K - 2) / (K + 2);
  163.   this.bh = 2 / (K + 2);
  164. };
  165.  
  166. DiodeFilter.prototype.reset = function(){
  167.   if (this.k < 17) this.z = [0,0,0,0,0];
  168. };
  169.  
  170. DiodeFilter.prototype.set_q = function(q){
  171.   this.k = 20 * q;
  172.   this.A = 1 + 0.5 * this.k;
  173. };
  174.  
  175. DiodeFilter.prototype.set_fc = function(cutoff){
  176.   cutoff = (cutoff * cutoff);
  177.   this.fc = cutoff <= 0
  178.     ? .02
  179.     : (cutoff >= 1.0 ? .999 : cutoff);
  180. };
  181.  
  182. DiodeFilter.prototype.run = function(x){
  183.   var a = Math.PI * this.fc;
  184.   a = 2 * Math.tan(0.5*a); // dewarping, not required with 2x oversampling
  185.   var ainv = 1 / a;
  186.   var a2 = a*a;
  187.   var b = 2*a + 1;
  188.   var b2 = b*b;
  189.   var c = 1 / (2*a2*a2 - 4*a2*b2 + b2*b2);
  190.   var g0 = 2*a2*a2*c;
  191.   var g = g0 * this.bh;
  192.  
  193.   // current state
  194.   var s0 = (a2*a*this.z[0] + a2*b*this.z[1] + this.z[2]*(b2 - 2*a2)*a + this.z[3]*(b2 - 3*a2)*b) * c;
  195.   var s = this.bh*s0 - this.z[4];
  196.  
  197.   // solve feedback loop (linear)
  198.   var y5 = (g*x + s) / (1 + g*this.k);
  199.  
  200.   // input clipping
  201.   var y0 = clip(x - this.k*y5);
  202.   y5 = g*y0 + s;
  203.  
  204.   // compute integrator outputs
  205.   var y4 = g0*y0 + s0;
  206.   var y3 = (b*y4 - this.z[3]) * ainv;
  207.   var y2 = (b*y3 - a*y4 - this.z[2]) * ainv;
  208.   var y1 = (b*y2 - a*y3 - this.z[1]) * ainv;
  209.  
  210.   // update filter state
  211.   this.z[0] += 4*a*(y0 - y1 + y2);
  212.   this.z[1] += 2*a*(y1 - 2*y2 + y3);
  213.   this.z[2] += 2*a*(y2 - 2*y3 + y4);
  214.   this.z[3] += 2*a*(y3 - 2*y4);
  215.   this.z[4] = this.bh*y4 + this.ah*y5;
  216.  
  217.   return this.A*y4;
  218. };
  219.  
  220. // -----------------------------------------------------------
  221. var snare_patt = [
  222.   0,0,0,0,0,0,0,0,
  223.   .3,0,0,0,0,0,0,0,//-
  224.   0,0,0,0,0,0,0,0,
  225.   .3,0,0,0,0,0,0,0,//-
  226.   0,0,0,0,0,0,0,0,
  227.   .3,0,0,0,0,0,0,0,//-
  228.   0,0,0,0,0,0,0,0,
  229.   .3,0,0,.3,0,0,.3,0//-
  230.   ];
  231. var kick_patt = [
  232.   1,0,0,0,0,0,0,0,
  233.   1,0,0,0,0,0,0,0,//-
  234.   1,0,0,1,0,0,1,0,
  235.   1,0,0,0,0,0,0,0,//-
  236.   1,0,0,0,0,0,0,0,
  237.   1,0,0,0,0,0,0,0,//-
  238.   1,0,0,1,0,0,1,0,
  239.   1,0,1,1,0,0,1,0//-
  240.   ];
  241. var hat_patt = [
  242.   0.01,0.1,0.5,0.01
  243.   ];
  244.  
  245. var wob_state_init = [
  246.   0,0,0,0,0,0,0,0,
  247.   0,0,0.25,0.5,1,1,1,1,//-
  248.   0,0,0,0,0,0,0,0,
  249.   0.25,0.5,1,0.5,1,0.5,1,0.5,//-
  250.   0,0,0,0,0,0,0,0,
  251.   0,0,0.25,0.5,1,1,1,1,//-
  252.   0,0,0,0,0,0,0,0,
  253.   1,1,1,1,1,1,1,1//-
  254.   ];
  255. var wob_lfo = [
  256.   8,8,8,8,16,16,16,16,8,8,8,8,4,4,16,8
  257.   ].map( function(n) { return ms2freq(n);} );
  258. var wob_note_init = [
  259.  0,0,0,0,5,5,5,5,3,3,3,3,1,1,5,-2
  260.  ].map( function(n) { return note(n,1) });
  261. var wob_note_drop = [
  262.  0,0,0,0,5,5,5,5,3,3,3,3,1,1,5,-2,
  263.  0,0,0,0,-2,-2,-2,-2,-3,-3,-3,-3,-4,-4,-2,-2,
  264.  0,0,0,0,-2,-2,-2,-2,3,3,3,3,2,2,3,2,
  265.  0,0,0,0,-2,-2,-2,-2,7,7,7,7,5,5,2,2
  266.  ].map( function(n) { return note(n,1) });
  267.  
  268. var pling_note = [
  269.   0,3,7,12,0,3,7,12,0,3,7,12,0,3,7,12,
  270.   5,9,12,17,5,9,12,17,5,9,12,17,5,9,12,17,
  271.   3,7,10,15,3,7,10,15,3,7,10,15,3,7,10,15,
  272.   1,5,8,13,1,5,8,13,1,5,8,13,1,5,8,13
  273.   ].map( function(n) {return note(n,1) });
  274.  
  275. var fr8_note = [
  276.   0,0,5,5,3,3,1,5
  277.   ].map( function(n) {return note(n,1) });
  278. var fr8_on = [
  279.   0,0,1,0
  280.   ];
  281. var build_kick = [
  282.   1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
  283.   1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,
  284.   1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,
  285.   1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  286.   ];
  287.  
  288.  
  289. // -------------------------------------------------------------
  290. //wobble setup
  291. var osc1 = Osc('sqr');
  292. var osc2 = Osc('saw');
  293. var osc3 = Osc('saw');
  294. var fil = new DiodeFilter();
  295. fil.set_hpf(0.0);
  296. fil.set_q(0.07);
  297. var wobble = new Syn([osc1,osc2,osc3],[-1,0,-1]);
  298.  
  299. //hat setup
  300. var hat_note = note(21,6);
  301. var hat_osc = Osc('ramp');
  302.  
  303. //pingplong setup
  304. var arp1 = Osc('sqr');
  305. var arp2 = Osc('sin');
  306. var arp3 = Osc('saw');
  307. var pling = new Syn([arp1,arp2,arp3],[3,5,1]);
  308.  
  309. //skwear
  310. var skw = Osc('saw',2);
  311.  
  312.  
  313.  
  314. return function (t) {
  315.   clock(t);
  316.   var beat = Math.floor(t/(60/bpm))%336;
  317.  
  318.   var noise = Noise();
  319.  
  320.   //ending
  321.   var end_muter = beat >= 256? 0:1;
  322.  
  323.   //wibble wobble
  324.   var wob_on = (beat >= 16 && beat < 320)? 1 : 0;
  325.   var wob_vol = 1;
  326.   fil.set_q(0.13 + sin(0.5)*0.13);
  327.   fil.set_fc(0.29 + tri(sequence(1/4,wob_lfo))*0.289);
  328.   if(beat > 95) {
  329.     wob_state=[1];
  330.     wob_note = wob_note_drop;
  331.     wob_vol = 0.75;
  332.     wobble.setOcts([-1,3,2]);
  333.   } else { // else clause prevent variables being sticky if you want to play it again
  334.     wob_state = wob_state_init;
  335.     wob_note = wob_note_init;
  336.     wob_vol = 1;
  337.     wobble.setOcts([-1,0,-1]);
  338.   }
  339.   var wob =  fil.run(wobble.mix( sequence(1/4,wob_note) )) * sequence(1/16,wob_state) * wob_on;
  340.  
  341.   //spacey plingplongs
  342.   var plings = pling.mix( sequence(1/16, pling_note )) * sqr(ms2freq(16));
  343.  
  344.   //4-8/16-skwr
  345.   var fr8 = skw.play(sequence(1/2, fr8_note), (2 + Math.floor(beat/16)%2)) * sequence(1/8,fr8_on);
  346.   fr8 = (fr8 > 0.85)? 1:0;
  347.  
  348.   //all le drums
  349.   var drums_on = (beat >= 80 && beat < 96)? 0:1;
  350.   var drums = arp(1/16,60,40,20) * sequence(1/16,kick_patt) + arp(1/16,60,80,3) * noise * sequence(1/16,snare_patt);
  351.   var drums_build = arp(1/16,60,40 + (beat - 80)*2,20) * sequence(1/16,build_kick) * ( 1 - drums_on);
  352.   var hats_on = beat >= 32? 1: 0;
  353.   var hat = arp(1/16, hat_osc.play(hat_note) + noise * 1.4, 18, 70) * sequence(1/16,hat_patt) * hats_on;
  354.  
  355.   return (
  356.      wob * wob_vol
  357.     + drums * 0.9 * drums_on
  358.     + drums_build * 0.9
  359.     + hat * 0.9 * drums_on * end_muter
  360.     + plings * 0.09 * end_muter
  361.     + fr8 * 0.2 * drums_on* end_muter
  362.     );
  363. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement