2015-02-02 01:38:06 +00:00
|
|
|
define(["Tone/core/Tone", "Tone/source/Source", "Tone/source/Oscillator",
|
|
|
|
"Tone/source/PulseOscillator", "Tone/source/PWMOscillator"],
|
2014-09-30 03:44:59 +00:00
|
|
|
function(Tone){
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
/**
|
2014-12-04 02:38:24 +00:00
|
|
|
* @class OmniOscillator aggregates Tone.Oscillator, Tone.PulseOscillator,
|
|
|
|
* and Tone.PWMOscillator which allows it to have the types:
|
|
|
|
* sine, square, triangle, sawtooth, pulse or pwm.
|
2014-09-30 03:44:59 +00:00
|
|
|
*
|
2014-10-03 20:07:30 +00:00
|
|
|
* @extends {Tone.Oscillator}
|
2014-09-30 03:44:59 +00:00
|
|
|
* @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);
|
2015-02-02 01:38:06 +00:00
|
|
|
Tone.Source.call(this, options);
|
2014-09-30 03:44:59 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* the frequency control
|
|
|
|
* @type {Tone.Signal}
|
|
|
|
*/
|
|
|
|
this.frequency = new Tone.Signal(options.frequency);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* the detune control
|
|
|
|
* @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;
|
|
|
|
|
|
|
|
//set the oscillator
|
|
|
|
this.setType(options.type);
|
|
|
|
};
|
|
|
|
|
2014-10-03 20:07:30 +00:00
|
|
|
Tone.extend(Tone.OmniOscillator, Tone.Oscillator);
|
2014-09-30 03:44:59 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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",
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* start the oscillator
|
|
|
|
* @param {Tone.Time} [time=now] the time to start the oscillator
|
2015-02-02 02:32:07 +00:00
|
|
|
* @private
|
2014-09-30 03:44:59 +00:00
|
|
|
*/
|
2015-02-02 02:32:07 +00:00
|
|
|
Tone.OmniOscillator.prototype._start = function(time){
|
|
|
|
this._oscillator.start(time);
|
2014-09-30 03:44:59 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* start the oscillator
|
|
|
|
* @param {Tone.Time} [time=now] the time to start the oscillator
|
2015-02-02 02:32:07 +00:00
|
|
|
* @private
|
2014-09-30 03:44:59 +00:00
|
|
|
*/
|
2015-02-02 02:32:07 +00:00
|
|
|
Tone.OmniOscillator.prototype._stop = function(time){
|
|
|
|
this._oscillator.stop(time);
|
2014-09-30 03:44:59 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* set the type of the oscillator
|
|
|
|
* @param {string} type sine|square|triangle|sawtooth|pulse|pwm
|
2015-02-01 19:40:47 +00:00
|
|
|
* @returns {Tone.OmniOscillator} `this`
|
2014-09-30 03:44:59 +00:00
|
|
|
*/
|
|
|
|
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);
|
|
|
|
}
|
2015-02-01 19:40:47 +00:00
|
|
|
return this;
|
2014-09-30 03:44:59 +00:00
|
|
|
};
|
|
|
|
|
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){
|
2014-10-16 18:52:08 +00:00
|
|
|
//short delay to avoid clicks on the change
|
|
|
|
var now = this.now() + this.bufferTime;
|
2014-10-03 05:00:37 +00:00
|
|
|
if (this._oscillator !== null){
|
|
|
|
var oldOsc = this._oscillator;
|
2014-10-16 18:52:08 +00:00
|
|
|
oldOsc.stop(now);
|
2014-10-03 05:00:37 +00:00
|
|
|
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){
|
2014-10-16 18:52:08 +00:00
|
|
|
this._oscillator.start(now);
|
2014-09-30 03:44:59 +00:00
|
|
|
}
|
|
|
|
this._oscillator.onended = this._onended.bind(this);
|
|
|
|
};
|
|
|
|
|
2015-02-01 20:47:31 +00:00
|
|
|
/**
|
|
|
|
* set the phase of the oscillator
|
|
|
|
* @param {number} phase
|
|
|
|
* @returns {Tone.PulseOscillator} `this`
|
|
|
|
*/
|
|
|
|
Tone.OmniOscillator.prototype.setPhase = function(phase){
|
|
|
|
this._oscillator.setPhase(phase);
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* returns the phase in degrees
|
|
|
|
* @returns {number} the phase
|
|
|
|
*/
|
|
|
|
Tone.OmniOscillator.prototype.getPhase = function(){
|
|
|
|
return this._oscillator.getPhase();
|
|
|
|
};
|
|
|
|
|
2014-09-30 03:44:59 +00:00
|
|
|
/**
|
|
|
|
* 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
|
2015-02-01 19:40:47 +00:00
|
|
|
* @returns {Tone.OmniOscillator} `this`
|
2014-09-30 03:44:59 +00:00
|
|
|
*/
|
|
|
|
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'.");
|
|
|
|
}
|
2015-02-01 19:40:47 +00:00
|
|
|
return this;
|
2014-09-30 03:44:59 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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
|
2015-02-01 19:40:47 +00:00
|
|
|
* @returns {Tone.OmniOscillator} `this`
|
2014-09-30 03:44:59 +00:00
|
|
|
*/
|
|
|
|
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'.");
|
|
|
|
}
|
2015-02-01 19:40:47 +00:00
|
|
|
return this;
|
2014-09-30 03:44:59 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* bulk setter
|
|
|
|
* @param {Object} params
|
2015-02-01 19:40:47 +00:00
|
|
|
* @returns {Tone.OmniOscillator} `this`
|
2014-09-30 03:44:59 +00:00
|
|
|
*/
|
|
|
|
Tone.OmniOscillator.prototype.set = function(params){
|
2015-02-02 02:32:07 +00:00
|
|
|
Tone.Source.prototype.set.call(this, params);
|
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);
|
2015-02-01 19:40:47 +00:00
|
|
|
return this;
|
2014-09-30 03:44:59 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* clean up
|
2015-02-02 01:02:13 +00:00
|
|
|
* @private
|
2015-02-02 03:05:24 +00:00
|
|
|
* @return {Tone.OmniOscillator} `this`
|
2014-09-30 03:44:59 +00:00
|
|
|
*/
|
2015-02-02 03:05:24 +00:00
|
|
|
Tone.OmniOscillator.prototype.dispose = function(){
|
|
|
|
Tone.Source.prototype.dispose.call(this);
|
2014-09-30 03:44:59 +00:00
|
|
|
this.detune.dispose();
|
|
|
|
this.detune = null;
|
2014-12-04 02:38:24 +00:00
|
|
|
this.frequency.dispose();
|
2014-09-30 03:44:59 +00:00
|
|
|
this.frequency = null;
|
2014-12-04 02:38:24 +00:00
|
|
|
this._oscillator.dispose();
|
2014-09-30 03:44:59 +00:00
|
|
|
this._oscillator = null;
|
|
|
|
this._sourceType = null;
|
2015-02-01 19:40:47 +00:00
|
|
|
return this;
|
2014-09-30 03:44:59 +00:00
|
|
|
};
|
|
|
|
|
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;
|
|
|
|
});
|