Browse files

Move oscillators from using LUT to using pure maths, cause lookups ar…

…e sloooow.
  • Loading branch information...
1 parent 77ce7be commit 06af428781f6720475ec7c2799e4b57323bf547f @oampo committed Feb 15, 2012
Showing with 184 additions and 221 deletions.
  1. +84 −101 src/audiolet/Audiolet.js
  2. +7 −11 src/audiolet/Audiolet.min.js
  3. +22 −12 src/dsp/Saw.js
  4. +24 −13 src/dsp/Sine.js
  5. +24 −14 src/dsp/Square.js
  6. +0 −57 src/dsp/TableLookupOscillator.js
  7. +23 −13 src/dsp/Triangle.js
View
185 src/audiolet/Audiolet.js
@@ -2470,87 +2470,48 @@ CombFilter.prototype.toString = function() {
*/
/**
- * Oscillator which reads waveform values from a look-up table
+ * Sine wave oscillator
*
* **Inputs**
*
* - Frequency
*
* **Outputs**
*
- * - Waveform
+ * - Sine wave
*
* **Parameters**
*
- * - frequency The oscillator frequency. Linked to input 0.
+ * - frequency The frequency of the oscillator. Linked to input 0.
*
* @constructor
* @extends AudioletNode
* @param {Audiolet} audiolet The audiolet object.
- * @param {Number} [frequency=440] The initial frequency.
+ * @param {Number} [frequency=440] Initial frequency.
*/
-var TableLookupOscillator = function(audiolet, table, frequency) {
+var Sine = function(audiolet, frequency) {
AudioletNode.call(this, audiolet, 1, 1);
- this.table = table;
this.frequency = new AudioletParameter(this, 0, frequency || 440);
this.phase = 0;
};
-extend(TableLookupOscillator, AudioletNode);
+extend(Sine, AudioletNode);
/**
- * Process a block of samples
+ * Process samples
*/
-TableLookupOscillator.prototype.generate = function() {
- this.outputs[0].samples[0] = this.table[Math.floor(this.phase)];
+Sine.prototype.generate = function() {
+ var output = this.outputs[0];
- var sampleRate = this.audiolet.device.sampleRate;
var frequency = this.frequency.getValue();
- var tableSize = this.table.length;
-
- this.phase += frequency * tableSize / sampleRate;
- if (this.phase > tableSize) {
- this.phase %= tableSize;
- }
-};
-
-/**
- * toString
- *
- * @return {String} String representation.
- */
-TableLookupOscillator.prototype.toString = function() {
- return 'Table Lookup Oscillator';
-};
+ var sampleRate = this.audiolet.device.sampleRate;
+ output.samples[0] = Math.sin(this.phase);
-/*!
- * @depends TableLookupOscillator.js
- */
-
-/**
- * Sine wave oscillator using a lookup table
- *
- * **Inputs**
- *
- * - Frequency
- *
- * **Outputs**
- *
- * - Sine wave
- *
- * **Parameters**
- *
- * - frequency The frequency of the oscillator. Linked to input 0.
- *
- * @constructor
- * @extends TableLookupOscillator
- * @param {Audiolet} audiolet The audiolet object.
- * @param {Number} [frequency=440] Initial frequency.
- */
-var Sine = function(audiolet, frequency) {
- TableLookupOscillator.call(this, audiolet, Sine.TABLE, frequency);
+ this.phase += 2 * Math.PI * frequency / sampleRate;
+ if (this.phase > 2 * Math.PI) {
+ this.phase %= 2 * Math.PI;
+ }
};
-extend(Sine, TableLookupOscillator);
/**
* toString
@@ -2561,14 +2522,6 @@ Sine.prototype.toString = function() {
return 'Sine';
};
-/**
- * Sine table
- */
-Sine.TABLE = [];
-for (var i = 0; i < 8192; i++) {
- Sine.TABLE.push(Math.sin(i * 2 * Math.PI / 8192));
-}
-
/*!
* @depends ../core/AudioletNode.js
@@ -4327,7 +4280,7 @@ Reverb.prototype.toString = function() {
/*!
- * @depends TableLookupOscillator.js
+ * @depends ../core/AudioletNode.js
*/
/**
@@ -4346,14 +4299,32 @@ Reverb.prototype.toString = function() {
* - frequency The frequency of the oscillator. Linked to input 0.
*
* @constructor
- * @extends TableLookupOscillator
+ * @extends AudioletNode
* @param {Audiolet} audiolet The audiolet object.
* @param {Number} [frequency=440] Initial frequency.
*/
var Saw = function(audiolet, frequency) {
- TableLookupOscillator.call(this, audiolet, Saw.TABLE, frequency);
+ AudioletNode.call(this, audiolet, 1, 1);
+ this.frequency = new AudioletParameter(this, 0, frequency || 440);
+ this.phase = 0;
+};
+extend(Saw, AudioletNode);
+
+/**
+ * Process samples
+ */
+Saw.prototype.generate = function() {
+ var output = this.outputs[0];
+ var frequency = this.frequency.getValue();
+ var sampleRate = this.audiolet.device.sampleRate;
+
+ output.samples[0] = ((this.phase / 2 + 0.25) % 0.5 - 0.25) * 4;
+ this.phase += frequency / sampleRate;
+
+ if (this.phase > 1) {
+ this.phase %= 1;
+ }
};
-extend(Saw, TableLookupOscillator);
/**
* toString
@@ -4364,14 +4335,6 @@ Saw.prototype.toString = function() {
return 'Saw';
};
-/**
- * Saw table
- */
-Saw.TABLE = [];
-for (var i = 0; i < 8192; i++) {
- Saw.TABLE.push(((((i - 4096) / 8192) % 1) + 1) % 1 * 2 - 1);
-}
-
/*!
* @depends ../core/AudioletNode.js
@@ -4429,11 +4392,11 @@ SoftClip.prototype.toString = function() {
/*!
- * @depends TableLookupOscillator.js
+ * @depends ../core/AudioletNode.js
*/
/**
- * Square wave oscillator using a lookup table
+ * Square wave oscillator
*
* **Inputs**
*
@@ -4448,14 +4411,33 @@ SoftClip.prototype.toString = function() {
* - frequency The frequency of the oscillator. Linked to input 0.
*
* @constructor
- * @extends TableLookupOscillator
+ * @extends AudioletNode
* @param {Audiolet} audiolet The audiolet object.
* @param {Number} [frequency=440] Initial frequency.
*/
var Square = function(audiolet, frequency) {
- TableLookupOscillator.call(this, audiolet, Square.TABLE, frequency);
+ AudioletNode.call(this, audiolet, 1, 1);
+ this.frequency = new AudioletParameter(this, 0, frequency || 440);
+ this.phase = 0;
+};
+extend(Square, AudioletNode);
+
+/**
+ * Process samples
+ */
+Square.prototype.generate = function() {
+ var output = this.outputs[0];
+
+ var frequency = this.frequency.getValue();
+ var sampleRate = this.audiolet.device.sampleRate;
+
+ output.samples[0] = this.phase > 0.5 ? 1 : -1;
+
+ this.phase += frequency / sampleRate;
+ if (this.phase > 1) {
+ this.phase %= 1;
+ }
};
-extend(Square, TableLookupOscillator);
/**
* toString
@@ -4466,18 +4448,9 @@ Square.prototype.toString = function() {
return 'Square';
};
-/**
- * Square wave table
- */
-Square.TABLE = [];
-for (var i = 0; i < 8192; i++) {
- Square.TABLE.push(((i - 4096) / 8192) < 0 ? 1 : -1);
-}
-
-
/*!
- * @depends TableLookupOscillator.js
+ * @depends ../core/AudioletNode.js
*/
/**
@@ -4496,14 +4469,33 @@ for (var i = 0; i < 8192; i++) {
* - frequency The frequency of the oscillator. Linked to input 0.
*
* @constructor
- * @extends TableLookupOscillator
+ * @extends AudioletNode
* @param {Audiolet} audiolet The audiolet object.
* @param {Number} [frequency=440] Initial frequency.
*/
var Triangle = function(audiolet, frequency) {
- TableLookupOscillator.call(this, audiolet, Triangle.TABLE, frequency);
+ AudioletNode.call(this, audiolet, 1, 1);
+ this.frequency = new AudioletParameter(this, 0, frequency || 440);
+ this.phase = 0;
+};
+extend(Triangle, AudioletNode);
+
+/**
+ * Process samples
+ */
+Triangle.prototype.generate = function() {
+ var output = this.outputs[0];
+
+ var frequency = this.frequency.getValue();
+ var sampleRate = this.audiolet.device.sampleRate;
+
+ output.samples[0] = 1 - 4 * Math.abs((this.phase + 0.25) % 1 - 0.5);
+
+ this.phase += frequency / sampleRate;
+ if (this.phase > 1) {
+ this.phase %= 1;
+ }
};
-extend(Triangle, TableLookupOscillator);
/**
* toString
@@ -4514,15 +4506,6 @@ Triangle.prototype.toString = function() {
return 'Triangle';
};
-/**
- * Triangle table
- */
-Triangle.TABLE = [];
-for (var i = 0; i < 8192; i++) {
- // Smelly, but looks right...
- Triangle.TABLE.push(Math.abs(((((i - 2048) / 8192) % 1) + 1) % 1 * 2 - 1) * 2 - 1);
-}
-
/*!
* @depends ../core/AudioletNode.js
View
18 src/audiolet/Audiolet.min.js
@@ -103,11 +103,7 @@ var CombFilter=function(a,d,c,b){AudioletNode.call(this,a,3,1);this.linkNumberOf
/*!
* @depends ../core/AudioletNode.js
*/
-var TableLookupOscillator=function(a,b,c){AudioletNode.call(this,a,1,1);this.table=b;this.frequency=new AudioletParameter(this,0,c||440);this.phase=0};extend(TableLookupOscillator,AudioletNode);TableLookupOscillator.prototype.generate=function(){this.outputs[0].samples[0]=this.table[Math.floor(this.phase)];var b=this.audiolet.device.sampleRate;var c=this.frequency.getValue();var a=this.table.length;this.phase+=c*a/b;if(this.phase>a){this.phase%=a}};TableLookupOscillator.prototype.toString=function(){return"Table Lookup Oscillator"};
-/*!
- * @depends TableLookupOscillator.js
- */
-var Sine=function(a,b){TableLookupOscillator.call(this,a,Sine.TABLE,b)};extend(Sine,TableLookupOscillator);Sine.prototype.toString=function(){return"Sine"};Sine.TABLE=[];for(var i=0;i<8192;i++){Sine.TABLE.push(Math.sin(i*2*Math.PI/8192))}
+var Sine=function(a,b){AudioletNode.call(this,a,1,1);this.frequency=new AudioletParameter(this,0,b||440);this.phase=0};extend(Sine,AudioletNode);Sine.prototype.generate=function(){var a=this.outputs[0];var c=this.frequency.getValue();var b=this.audiolet.device.sampleRate;a.samples[0]=Math.sin(this.phase);this.phase+=2*Math.PI*c/b;if(this.phase>2*Math.PI){this.phase%=2*Math.PI}};Sine.prototype.toString=function(){return"Sine"};
/*!
* @depends ../core/AudioletNode.js
* @depends Sine.js
@@ -188,21 +184,21 @@ var ReverbB=function(c,f,a,b){AudioletGroup.call(this,c,4,1);this.initialMix=0.3
*/
var Reverb=function(d,g,a,c){AudioletNode.call(this,d,4,1);this.initialMix=0.33;this.fixedGain=0.015;this.initialDamping=0.5;this.scaleDamping=0.4;this.initialRoomSize=0.5;this.scaleRoom=0.28;this.offsetRoom=0.7;this.combTuning=[1116,1188,1277,1356,1422,1491,1557,1617];this.allPassTuning=[556,441,341,225];var g=g||this.initialMix;this.mix=new AudioletParameter(this,1,g);var a=a||this.initialRoomSize;this.roomSize=new AudioletParameter(this,2,a);var c=c||this.initialDamping;this.damping=new AudioletParameter(this,3,c);this.combBuffers=[];this.combIndices=[];this.filterStores=[];var b=this.combTuning.length;for(var f=0;f<b;f++){this.combBuffers.push(new Float32Array(this.combTuning[f]));this.combIndices.push(0);this.filterStores.push(0)}this.allPassBuffers=[];this.allPassIndices=[];var e=this.allPassTuning.length;for(var f=0;f<e;f++){this.allPassBuffers.push(new Float32Array(this.allPassTuning[f]));this.allPassIndices.push(0)}};extend(Reverb,AudioletNode);Reverb.prototype.generate=function(){var k=this.mix.getValue();var m=this.roomSize.getValue();var d=this.damping.getValue();var a=this.combTuning.length;var s=this.allPassTuning.length;var q=this.inputs[0].samples[0]||0;var j=q;q*=this.fixedGain;var c=q;var d=d*this.scaleDamping;var e=m*this.scaleRoom+this.offsetRoom;for(var r=0;r<a;r++){var o=this.combIndices[r];var p=this.combBuffers[r];var n=this.filterStores[r];var h=p[o];n=(h*(1-d))+(n*d);q+=h;p[o]=c+e*n;o+=1;if(o>=p.length){o=0}this.combIndices[r]=o;this.filterStores[r]=n}for(var r=0;r<s;r++){var b=this.allPassBuffers[r];var g=this.allPassIndices[r];var l=q;var f=b[g];q=-q+f;b[g]=l+(f*0.5);g+=1;if(g>=b.length){g=0}this.allPassIndices[r]=g}this.outputs[0].samples[0]=k*q+(1-k)*j};Reverb.prototype.toString=function(){return"Reverb"};
/*!
- * @depends TableLookupOscillator.js
+ * @depends ../core/AudioletNode.js
*/
-var Saw=function(a,b){TableLookupOscillator.call(this,a,Saw.TABLE,b)};extend(Saw,TableLookupOscillator);Saw.prototype.toString=function(){return"Saw"};Saw.TABLE=[];for(var i=0;i<8192;i++){Saw.TABLE.push(((((i-4096)/8192)%1)+1)%1*2-1)}
+var Saw=function(a,b){AudioletNode.call(this,a,1,1);this.frequency=new AudioletParameter(this,0,b||440);this.phase=0};extend(Saw,AudioletNode);Saw.prototype.generate=function(){var a=this.outputs[0];var c=this.frequency.getValue();var b=this.audiolet.device.sampleRate;a.samples[0]=((this.phase/2+0.25)%0.5-0.25)*4;this.phase+=c/b;if(this.phase>1){this.phase%=1}};Saw.prototype.toString=function(){return"Saw"};
/*!
* @depends ../core/AudioletNode.js
*/
var SoftClip=function(a){AudioletNode.call(this,a,1,1);this.linkNumberOfOutputChannels(0,0)};extend(SoftClip,AudioletNode);SoftClip.prototype.generate=function(){var b=this.inputs[0];var a=this.outputs[0];var c=b.samples.length;for(var d=0;d<c;d++){var e=b.samples[d];if(e>0.5||e<-0.5){a.samples[d]=(Math.abs(e)-0.25)/e}else{a.samples[d]=e}}};SoftClip.prototype.toString=function(){return("SoftClip")};
/*!
- * @depends TableLookupOscillator.js
+ * @depends ../core/AudioletNode.js
*/
-var Square=function(a,b){TableLookupOscillator.call(this,a,Square.TABLE,b)};extend(Square,TableLookupOscillator);Square.prototype.toString=function(){return"Square"};Square.TABLE=[];for(var i=0;i<8192;i++){Square.TABLE.push(((i-4096)/8192)<0?1:-1)}
+var Square=function(a,b){AudioletNode.call(this,a,1,1);this.frequency=new AudioletParameter(this,0,b||440);this.phase=0};extend(Square,AudioletNode);Square.prototype.generate=function(){var a=this.outputs[0];var c=this.frequency.getValue();var b=this.audiolet.device.sampleRate;a.samples[0]=this.phase>0.5?1:-1;this.phase+=c/b;if(this.phase>1){this.phase%=1}};Square.prototype.toString=function(){return"Square"};
/*!
- * @depends TableLookupOscillator.js
+ * @depends ../core/AudioletNode.js
*/
-var Triangle=function(a,b){TableLookupOscillator.call(this,a,Triangle.TABLE,b)};extend(Triangle,TableLookupOscillator);Triangle.prototype.toString=function(){return"Triangle"};Triangle.TABLE=[];for(var i=0;i<8192;i++){Triangle.TABLE.push(Math.abs(((((i-2048)/8192)%1)+1)%1*2-1)*2-1)}
+var Triangle=function(a,b){AudioletNode.call(this,a,1,1);this.frequency=new AudioletParameter(this,0,b||440);this.phase=0};extend(Triangle,AudioletNode);Triangle.prototype.generate=function(){var a=this.outputs[0];var c=this.frequency.getValue();var b=this.audiolet.device.sampleRate;a.samples[0]=1-4*Math.abs((this.phase+0.25)%1-0.5);this.phase+=c/b;if(this.phase>1){this.phase%=1}};Triangle.prototype.toString=function(){return"Triangle"};
/*!
* @depends ../core/AudioletNode.js
*/
View
34 src/dsp/Saw.js
@@ -1,5 +1,5 @@
/*!
- * @depends TableLookupOscillator.js
+ * @depends ../core/AudioletNode.js
*/
/**
@@ -18,14 +18,32 @@
* - frequency The frequency of the oscillator. Linked to input 0.
*
* @constructor
- * @extends TableLookupOscillator
+ * @extends AudioletNode
* @param {Audiolet} audiolet The audiolet object.
* @param {Number} [frequency=440] Initial frequency.
*/
var Saw = function(audiolet, frequency) {
- TableLookupOscillator.call(this, audiolet, Saw.TABLE, frequency);
+ AudioletNode.call(this, audiolet, 1, 1);
+ this.frequency = new AudioletParameter(this, 0, frequency || 440);
+ this.phase = 0;
+};
+extend(Saw, AudioletNode);
+
+/**
+ * Process samples
+ */
+Saw.prototype.generate = function() {
+ var output = this.outputs[0];
+ var frequency = this.frequency.getValue();
+ var sampleRate = this.audiolet.device.sampleRate;
+
+ output.samples[0] = ((this.phase / 2 + 0.25) % 0.5 - 0.25) * 4;
+ this.phase += frequency / sampleRate;
+
+ if (this.phase > 1) {
+ this.phase %= 1;
+ }
};
-extend(Saw, TableLookupOscillator);
/**
* toString
@@ -36,11 +54,3 @@ Saw.prototype.toString = function() {
return 'Saw';
};
-/**
- * Saw table
- */
-Saw.TABLE = [];
-for (var i = 0; i < 8192; i++) {
- Saw.TABLE.push(((((i - 4096) / 8192) % 1) + 1) % 1 * 2 - 1);
-}
-
View
37 src/dsp/Sine.js
@@ -1,9 +1,9 @@
/*!
- * @depends TableLookupOscillator.js
+ * @depends ../core/AudioletNode.js
*/
/**
- * Sine wave oscillator using a lookup table
+ * Sine wave oscillator
*
* **Inputs**
*
@@ -18,14 +18,33 @@
* - frequency The frequency of the oscillator. Linked to input 0.
*
* @constructor
- * @extends TableLookupOscillator
+ * @extends AudioletNode
* @param {Audiolet} audiolet The audiolet object.
* @param {Number} [frequency=440] Initial frequency.
*/
var Sine = function(audiolet, frequency) {
- TableLookupOscillator.call(this, audiolet, Sine.TABLE, frequency);
+ AudioletNode.call(this, audiolet, 1, 1);
+ this.frequency = new AudioletParameter(this, 0, frequency || 440);
+ this.phase = 0;
+};
+extend(Sine, AudioletNode);
+
+/**
+ * Process samples
+ */
+Sine.prototype.generate = function() {
+ var output = this.outputs[0];
+
+ var frequency = this.frequency.getValue();
+ var sampleRate = this.audiolet.device.sampleRate;
+
+ output.samples[0] = Math.sin(this.phase);
+
+ this.phase += 2 * Math.PI * frequency / sampleRate;
+ if (this.phase > 2 * Math.PI) {
+ this.phase %= 2 * Math.PI;
+ }
};
-extend(Sine, TableLookupOscillator);
/**
* toString
@@ -36,11 +55,3 @@ Sine.prototype.toString = function() {
return 'Sine';
};
-/**
- * Sine table
- */
-Sine.TABLE = [];
-for (var i = 0; i < 8192; i++) {
- Sine.TABLE.push(Math.sin(i * 2 * Math.PI / 8192));
-}
-
View
38 src/dsp/Square.js
@@ -1,9 +1,9 @@
/*!
- * @depends TableLookupOscillator.js
+ * @depends ../core/AudioletNode.js
*/
/**
- * Square wave oscillator using a lookup table
+ * Square wave oscillator
*
* **Inputs**
*
@@ -18,14 +18,33 @@
* - frequency The frequency of the oscillator. Linked to input 0.
*
* @constructor
- * @extends TableLookupOscillator
+ * @extends AudioletNode
* @param {Audiolet} audiolet The audiolet object.
* @param {Number} [frequency=440] Initial frequency.
*/
var Square = function(audiolet, frequency) {
- TableLookupOscillator.call(this, audiolet, Square.TABLE, frequency);
+ AudioletNode.call(this, audiolet, 1, 1);
+ this.frequency = new AudioletParameter(this, 0, frequency || 440);
+ this.phase = 0;
+};
+extend(Square, AudioletNode);
+
+/**
+ * Process samples
+ */
+Square.prototype.generate = function() {
+ var output = this.outputs[0];
+
+ var frequency = this.frequency.getValue();
+ var sampleRate = this.audiolet.device.sampleRate;
+
+ output.samples[0] = this.phase > 0.5 ? 1 : -1;
+
+ this.phase += frequency / sampleRate;
+ if (this.phase > 1) {
+ this.phase %= 1;
+ }
};
-extend(Square, TableLookupOscillator);
/**
* toString
@@ -36,12 +55,3 @@ Square.prototype.toString = function() {
return 'Square';
};
-/**
- * Square wave table
- */
-Square.TABLE = [];
-for (var i = 0; i < 8192; i++) {
- Square.TABLE.push(((i - 4096) / 8192) < 0 ? 1 : -1);
-}
-
-
View
57 src/dsp/TableLookupOscillator.js
@@ -1,57 +0,0 @@
-/*!
- * @depends ../core/AudioletNode.js
- */
-
-/**
- * Oscillator which reads waveform values from a look-up table
- *
- * **Inputs**
- *
- * - Frequency
- *
- * **Outputs**
- *
- * - Waveform
- *
- * **Parameters**
- *
- * - frequency The oscillator frequency. Linked to input 0.
- *
- * @constructor
- * @extends AudioletNode
- * @param {Audiolet} audiolet The audiolet object.
- * @param {Number} [frequency=440] The initial frequency.
- */
-var TableLookupOscillator = function(audiolet, table, frequency) {
- AudioletNode.call(this, audiolet, 1, 1);
- this.table = table;
- this.frequency = new AudioletParameter(this, 0, frequency || 440);
- this.phase = 0;
-};
-extend(TableLookupOscillator, AudioletNode);
-
-/**
- * Process a block of samples
- */
-TableLookupOscillator.prototype.generate = function() {
- this.outputs[0].samples[0] = this.table[Math.floor(this.phase)];
-
- var sampleRate = this.audiolet.device.sampleRate;
- var frequency = this.frequency.getValue();
- var tableSize = this.table.length;
-
- this.phase += frequency * tableSize / sampleRate;
- if (this.phase > tableSize) {
- this.phase %= tableSize;
- }
-};
-
-/**
- * toString
- *
- * @return {String} String representation.
- */
-TableLookupOscillator.prototype.toString = function() {
- return 'Table Lookup Oscillator';
-};
-
View
36 src/dsp/Triangle.js
@@ -1,5 +1,5 @@
/*!
- * @depends TableLookupOscillator.js
+ * @depends ../core/AudioletNode.js
*/
/**
@@ -18,14 +18,33 @@
* - frequency The frequency of the oscillator. Linked to input 0.
*
* @constructor
- * @extends TableLookupOscillator
+ * @extends AudioletNode
* @param {Audiolet} audiolet The audiolet object.
* @param {Number} [frequency=440] Initial frequency.
*/
var Triangle = function(audiolet, frequency) {
- TableLookupOscillator.call(this, audiolet, Triangle.TABLE, frequency);
+ AudioletNode.call(this, audiolet, 1, 1);
+ this.frequency = new AudioletParameter(this, 0, frequency || 440);
+ this.phase = 0;
+};
+extend(Triangle, AudioletNode);
+
+/**
+ * Process samples
+ */
+Triangle.prototype.generate = function() {
+ var output = this.outputs[0];
+
+ var frequency = this.frequency.getValue();
+ var sampleRate = this.audiolet.device.sampleRate;
+
+ output.samples[0] = 1 - 4 * Math.abs((this.phase + 0.25) % 1 - 0.5);
+
+ this.phase += frequency / sampleRate;
+ if (this.phase > 1) {
+ this.phase %= 1;
+ }
};
-extend(Triangle, TableLookupOscillator);
/**
* toString
@@ -36,12 +55,3 @@ Triangle.prototype.toString = function() {
return 'Triangle';
};
-/**
- * Triangle table
- */
-Triangle.TABLE = [];
-for (var i = 0; i < 8192; i++) {
- // Smelly, but looks right...
- Triangle.TABLE.push(Math.abs(((((i - 2048) / 8192) % 1) + 1) % 1 * 2 - 1) * 2 - 1);
-}
-

0 comments on commit 06af428

Please sign in to comment.