Tone.js/Tone/source/Oscillator.js

153 lines
3.9 KiB
JavaScript
Raw Normal View History

2014-06-16 01:00:22 +00:00
define(["Tone/core/Tone", "Tone/core/Transport", "Tone/signal/Signal", "Tone/source/Source"],
2014-06-15 21:36:52 +00:00
function(Tone){
2014-06-15 21:36:52 +00:00
/**
* Oscillator
*
* Oscilator with start, pause, stop and sync to Transport
*
* @constructor
2014-06-16 01:00:22 +00:00
* @extends {Tone.Source}
2014-06-18 05:36:40 +00:00
* @param {number|string=} freq starting frequency
2014-06-15 21:36:52 +00:00
* @param {string=} type type of oscillator (sine|square|triangle|sawtooth)
*/
Tone.Oscillator = function(freq, type){
2014-06-16 23:38:46 +00:00
Tone.Source.call(this);
2014-06-17 16:15:10 +00:00
/**
* the main oscillator
* @type {OscillatorNode}
*/
this.oscillator = this.context.createOscillator();
2014-06-17 16:15:10 +00:00
/**
* the frequency control signal
* @type {Tone.Signal}
*/
this.frequency = new Tone.Signal(this.defaultArg(this.toFrequency(freq), 440));
2014-06-15 21:36:52 +00:00
2014-06-19 05:40:16 +00:00
/**
* @type {function()}
*/
this.onended = function(){};
//connections
2014-06-15 21:36:52 +00:00
this.oscillator.connect(this.output);
2014-06-17 16:15:10 +00:00
//setup
2014-06-15 21:36:52 +00:00
this.oscillator.type = this.defaultArg(type, "sine");
};
2014-06-16 01:00:22 +00:00
Tone.extend(Tone.Oscillator, Tone.Source);
2014-06-15 21:36:52 +00:00
/**
* start the oscillator
*
* @param {Tone.Time} time
*/
Tone.Oscillator.prototype.start = function(time){
2014-06-19 05:40:16 +00:00
if (this.state === Tone.Source.State.STOPPED){
this.state = Tone.Source.State.STARTED;
//get previous values
var type = this.oscillator.type;
var detune = this.oscillator.detune.value;
2014-06-19 05:40:16 +00:00
//new oscillator with previous values
this.oscillator = this.context.createOscillator();
this.oscillator.type = type;
this.oscillator.detune.value = detune;
//connect the control signal to the oscillator frequency
this.oscillator.connect(this.output);
this.frequency.connect(this.oscillator.frequency);
this.oscillator.frequency.value = 0;
//start the oscillator
this.oscillator.start(this.toSeconds(time));
this.oscillator.onended = this._onended.bind(this);
}
};
/**
* stop the oscillator
* @param {Tone.Time=} time (optional) timing parameter
*/
Tone.Oscillator.prototype.stop = function(time){
if (this.state === Tone.Source.State.STARTED){
if (!time){
this.state = Tone.Source.State.STOPPED;
}
this.oscillator.stop(this.toSeconds(time));
}
2014-06-15 21:36:52 +00:00
};
/**
* Sync the oscillator to the transport
*
* the current ratio between the oscillator and the Transport BPM
* is fixed and any change to the Transport BPM will change this
* oscillator in that same ratio
*
* Transport start/pause/stop will also start/pause/stop the oscillator
*/
Tone.Oscillator.prototype.sync = function(){
2014-06-19 05:40:16 +00:00
if (this.state !== Tone.Source.State.SYNCED){
this.state = Tone.Source.State.SYNCED;
Tone.Transport.sync(this);
Tone.Transport.syncSignal(this.frequency);
}
2014-06-15 21:36:52 +00:00
};
/**
* unsync the oscillator from the Transport
*/
Tone.Oscillator.prototype.unsync = function(){
2014-06-19 05:40:16 +00:00
if (this.state === Tone.Source.State.SYNCED){
Tone.Transport.unsync(this);
this.frequency.unsync();
}
2014-06-15 21:36:52 +00:00
};
2014-06-15 21:36:52 +00:00
/**
* exponentially ramp the frequency of the oscillator over the rampTime
*
2014-06-16 23:38:46 +00:00
* @param {Tone.Time} val
* @param {Tone.Time=} rampTime when the oscillator will arrive at the frequency
2014-06-15 21:36:52 +00:00
*/
Tone.Oscillator.prototype.setFrequency = function(val, rampTime){
2014-06-19 05:40:16 +00:00
if (rampTime){
this.frequency.exponentialRampToValueAtTime(this.toFrequency(val), this.toSeconds(rampTime));
} else {
this.frequency.setValue(this.toFrequency(val));
}
2014-06-15 21:36:52 +00:00
};
2014-06-15 21:36:52 +00:00
/**
* set the oscillator type
2014-06-16 01:00:22 +00:00
*
2014-06-15 21:36:52 +00:00
* @param {string} type (sine|square|triangle|sawtooth)
*/
Tone.Oscillator.prototype.setType = function(type){
this.oscillator.type = type;
2014-06-15 21:36:52 +00:00
};
2014-06-19 05:40:16 +00:00
/**
* internal on end call
* @private
*/
Tone.Oscillator.prototype._onended = function(){
this.state = Tone.Source.State.STOPPED;
this.onended();
};
/**
* dispose and disconnect
*/
Tone.Oscillator.prototype.dispose = function(){
2014-06-20 01:48:16 +00:00
if (this.oscillator !== null){
2014-06-19 05:40:16 +00:00
this.oscillator.disconnect();
this.oscillator = null;
}
this.frequency.dispose();
2014-06-20 01:48:16 +00:00
this.frequency = null;
2014-06-20 04:25:10 +00:00
this.output.disconnect();
this.output = null;
2014-06-19 05:40:16 +00:00
};
return Tone.Oscillator;
});