Tone.js/Tone/source/OmniOscillator.js

242 lines
6.8 KiB
JavaScript
Raw Normal View History

2014-09-30 03:44:59 +00:00
define(["Tone/core/Tone", "Tone/source/Source", "Tone/source/Oscillator", "Tone/source/PulseOscillator", "Tone/source/PWMOscillator"],
function(Tone){
"use strict";
/**
* @class An OmniOscillator can be a sine|square|triangle|sawtooth|pulse|pwm
*
* @extends {Tone.Source}
* @constructor
* @param {frequency} frequency frequency of the oscillator (meaningless for noise types)
* @param {string} type the type of the oscillator
*/
Tone.OmniOscillator = function(){
var options = this.optionsObject(arguments, ["frequency", "type"], Tone.OmniOscillator.defaults);
Tone.Source.call(this);
/**
* the frequency control
* (doesn't do anything for noises)
* @type {Tone.Signal}
*/
this.frequency = new Tone.Signal(options.frequency);
/**
* the detune control
* (doesn't do anything for noises)
* @type {Tone.Signal}
*/
this.detune = new Tone.Signal(options.detune);
/**
* the type of the oscillator source
* @type {string}
* @private
*/
this._sourceType = undefined;
/**
* the oscillator
* @type {Tone.Oscillator|Tone.PWMOscillator|Tone.PulseOscillator}
* @private
*/
this._oscillator = null;
/**
* callback which is invoked when the oscillator is stoped
* @type {function()}
*/
this.onended = options.onended;
//set the oscillator
this.setType(options.type);
};
Tone.extend(Tone.OmniOscillator, Tone.Source);
/**
* default values
* @static
* @type {Object}
* @const
*/
Tone.OmniOscillator.defaults = {
"frequency" : 440,
"detune" : 0,
"type" : "sine",
"width" : 0.4, //only applies if the oscillator is set to "pulse",
"modulationFrequency" : 0.4, //only applies if the oscillator is set to "pwm",
"onended" : function(){}
};
/**
* start the oscillator
* @param {Tone.Time} [time=now] the time to start the oscillator
*/
Tone.OmniOscillator.prototype.start = function(time){
if (this.state === Tone.Source.State.STOPPED){
this.state = Tone.Source.State.STARTED;
this._oscillator.start(time);
}
};
/**
* start the oscillator
* @param {Tone.Time} [time=now] the time to start the oscillator
*/
Tone.OmniOscillator.prototype.stop = function(time){
if (this.state === Tone.Source.State.STARTED){
if (!time){
this.state = Tone.Source.State.STOPPED;
}
this._oscillator.stop(time);
}
};
/**
* internal on end call
* @private
*/
Tone.OmniOscillator.prototype._onended = function(){
this.state = Tone.Source.State.STOPPED;
this.onended();
};
/**
* exponentially ramp the frequency of the oscillator over the rampTime
* borrows the method from {@link Tone.Oscillator}
2014-09-30 03:44:59 +00:00
*
* @param {Tone.Time} val
* @param {Tone.Time=} rampTime when the oscillator will arrive at the frequency
* @function
2014-09-30 03:44:59 +00:00
*/
Tone.OmniOscillator.prototype.setFrequency = Tone.Oscillator.prototype.setFrequency;
2014-09-30 03:44:59 +00:00
/**
* set the type of the oscillator
* @param {string} type sine|square|triangle|sawtooth|pulse|pwm
*/
Tone.OmniOscillator.prototype.setType = function(type){
if (type === "sine" || type === "square" || type === "triangle" || type === "sawtooth"){
2014-10-01 02:48:21 +00:00
if (this._sourceType !== OmniOscType.Oscillator){
this._sourceType = OmniOscType.Oscillator;
2014-10-03 05:00:37 +00:00
this._createNewOscillator(Tone.Oscillator);
2014-09-30 03:44:59 +00:00
}
this._oscillator.setType(type);
} else if (type === "pwm"){
2014-10-01 02:48:21 +00:00
if (this._sourceType !== OmniOscType.PWMOscillator){
this._sourceType = OmniOscType.PWMOscillator;
2014-10-03 05:00:37 +00:00
this._createNewOscillator(Tone.PWMOscillator);
2014-09-30 03:44:59 +00:00
}
} else if (type === "pulse"){
2014-10-01 02:48:21 +00:00
if (this._sourceType !== OmniOscType.PulseOscillator){
this._sourceType = OmniOscType.PulseOscillator;
2014-10-03 05:00:37 +00:00
this._createNewOscillator(Tone.PulseOscillator);
2014-09-30 03:44:59 +00:00
}
} else {
throw new TypeError("Tone.OmniOscillator does not support type "+type);
}
};
2014-10-01 02:48:21 +00:00
/**
* @returns {string} the type of oscillator
*/
Tone.OmniOscillator.prototype.getType = function(){
if (this._sourceType === OmniOscType.PulseOscillator){
return "pulse";
} else if (this._sourceType === OmniOscType.PWMOscillator){
return "pwm";
} else if (this._sourceType === OmniOscType.Oscillator){
return this._oscillator.getType();
}
};
2014-09-30 03:44:59 +00:00
/**
* connect the oscillator to the frequency and detune signals
* @private
*/
2014-10-03 05:00:37 +00:00
Tone.OmniOscillator.prototype._createNewOscillator = function(OscillatorConstructor){
if (this._oscillator !== null){
var oldOsc = this._oscillator;
oldOsc.stop();
oldOsc.onended = function(){
oldOsc.dispose();
oldOsc = null;
};
}
this._oscillator = new OscillatorConstructor();
2014-09-30 03:44:59 +00:00
this.frequency.connect(this._oscillator.frequency);
this.detune.connect(this._oscillator.detune);
this._oscillator.connect(this.output);
if (this.state === Tone.Source.State.STARTED){
this._oscillator.start();
}
this._oscillator.onended = this._onended.bind(this);
};
/**
* set the width of the PulseOscillator
* @throws {Error} If the type of oscillator is not "pulse"
* @param {number} width the width of the pulse oscillator
*/
Tone.OmniOscillator.prototype.setWidth = function(width){
2014-10-01 02:48:21 +00:00
if (this._sourceType === OmniOscType.PulseOscillator){
2014-09-30 03:44:59 +00:00
this._oscillator.setWidth(width);
} else {
throw new Error("Invalid call to 'setWidth'. OmniOscillator type must be set to type 'pulse'.");
}
};
/**
* set the modulation frequency of the PWMOscillator
* @throws {Error} If the type of oscillator is not "pwm"
* @param {Tone.Time} freq the modulation frequency of the pwm
*/
Tone.OmniOscillator.prototype.setModulationFrequency = function(freq){
2014-10-01 02:48:21 +00:00
if (this._sourceType === OmniOscType.PWMOscillator){
2014-09-30 03:44:59 +00:00
this._oscillator.setModulationFrequency(freq);
} else {
throw new Error("Invalid call to 'setModulationFrequency'. OmniOscillator type must be set to type 'pwm'.");
}
};
/**
* bulk setter
* @param {Object} params
*/
Tone.OmniOscillator.prototype.set = function(params){
2014-10-01 02:48:21 +00:00
if (!this.isUndef(params.type)) this.setType(params.type);
if (!this.isUndef(params.onended)) this.onended = params.onended;
2014-09-30 03:44:59 +00:00
if (!this.isUndef(params.frequency)) this.setFrequency(params.frequency);
if (!this.isUndef(params.detune)) this.detune.setValue(params.detune);
2014-10-01 02:48:21 +00:00
if (!this.isUndef(params.width)) this.setWidth(params.width);
2014-09-30 03:44:59 +00:00
if (!this.isUndef(params.modulationFrequency)) this.setModulationFrequency(params.modulationFrequency);
Tone.Source.prototype.set.call(this, params);
2014-09-30 03:44:59 +00:00
};
/**
* clean up
*/
Tone.OmniOscillator.prototype.dispose = function(){
Tone.Source.prototype.dispose.call(this);
this.detune.dispose();
this.frequency.dispose();
this._oscillator.dispose();
this.detune = null;
this.frequency = null;
this._oscillator = null;
this._sourceType = null;
};
2014-10-01 02:48:21 +00:00
/**
* @enum {string}
*/
var OmniOscType = {
PulseOscillator : "PulseOscillator",
PWMOscillator : "PWMOscillator",
Oscillator : "Oscillator"
};
2014-09-30 03:44:59 +00:00
return Tone.OmniOscillator;
});