mirror of
https://github.com/Tonejs/Tone.js
synced 2024-11-17 00:58:09 +00:00
153 lines
No EOL
3.9 KiB
JavaScript
153 lines
No EOL
3.9 KiB
JavaScript
define(["Tone/core/Tone", "Tone/core/Transport", "Tone/signal/Signal", "Tone/source/Source"],
|
|
function(Tone){
|
|
|
|
/**
|
|
* Oscillator
|
|
*
|
|
* Oscilator with start, pause, stop and sync to Transport
|
|
*
|
|
* @constructor
|
|
* @extends {Tone.Source}
|
|
* @param {number|string=} freq starting frequency
|
|
* @param {string=} type type of oscillator (sine|square|triangle|sawtooth)
|
|
*/
|
|
Tone.Oscillator = function(freq, type){
|
|
Tone.Source.call(this);
|
|
|
|
/**
|
|
* the main oscillator
|
|
* @type {OscillatorNode}
|
|
*/
|
|
this.oscillator = this.context.createOscillator();
|
|
/**
|
|
* the frequency control signal
|
|
* @type {Tone.Signal}
|
|
*/
|
|
this.frequency = new Tone.Signal(this.defaultArg(this.toFrequency(freq), 440));
|
|
|
|
/**
|
|
* @type {function()}
|
|
*/
|
|
this.onended = function(){};
|
|
|
|
//connections
|
|
this.oscillator.connect(this.output);
|
|
//setup
|
|
this.oscillator.type = this.defaultArg(type, "sine");
|
|
};
|
|
|
|
Tone.extend(Tone.Oscillator, Tone.Source);
|
|
|
|
/**
|
|
* start the oscillator
|
|
*
|
|
* @param {Tone.Time} time
|
|
*/
|
|
Tone.Oscillator.prototype.start = function(time){
|
|
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;
|
|
//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));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* 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(){
|
|
if (this.state !== Tone.Source.State.SYNCED){
|
|
this.state = Tone.Source.State.SYNCED;
|
|
Tone.Transport.sync(this);
|
|
Tone.Transport.syncSignal(this.frequency);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* unsync the oscillator from the Transport
|
|
*/
|
|
Tone.Oscillator.prototype.unsync = function(){
|
|
if (this.state === Tone.Source.State.SYNCED){
|
|
Tone.Transport.unsync(this);
|
|
this.frequency.unsync();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* exponentially ramp the frequency of the oscillator over the rampTime
|
|
*
|
|
* @param {Tone.Time} val
|
|
* @param {Tone.Time=} rampTime when the oscillator will arrive at the frequency
|
|
*/
|
|
Tone.Oscillator.prototype.setFrequency = function(val, rampTime){
|
|
if (rampTime){
|
|
this.frequency.exponentialRampToValueAtTime(this.toFrequency(val), this.toSeconds(rampTime));
|
|
} else {
|
|
this.frequency.setValue(this.toFrequency(val));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* set the oscillator type
|
|
*
|
|
* @param {string} type (sine|square|triangle|sawtooth)
|
|
*/
|
|
Tone.Oscillator.prototype.setType = function(type){
|
|
this.oscillator.type = type;
|
|
};
|
|
|
|
/**
|
|
* 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(){
|
|
if (this.oscillator !== null){
|
|
this.oscillator.disconnect();
|
|
this.oscillator = null;
|
|
}
|
|
this.frequency.dispose();
|
|
this.frequency = null;
|
|
this.output.disconnect();
|
|
this.output = null;
|
|
};
|
|
|
|
return Tone.Oscillator;
|
|
}); |