2016-09-20 03:53:07 +00:00
|
|
|
define(["Tone/core/Tone", "Tone/source/Source", "Tone/source/Oscillator",
|
|
|
|
"Tone/signal/Signal", "Tone/signal/WaveShaper", "Tone/core/Gain"],
|
2014-08-31 20:29:56 +00:00
|
|
|
function(Tone){
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
/**
|
2015-07-04 16:43:21 +00:00
|
|
|
* @class Tone.PulseOscillator is a pulse oscillator with control over pulse width,
|
|
|
|
* also known as the duty cycle. At 50% duty cycle (width = 0.5) the wave is
|
|
|
|
* a square and only odd-numbered harmonics are present. At all other widths
|
|
|
|
* even-numbered harmonics are present. Read more
|
2015-07-04 19:25:37 +00:00
|
|
|
* [here](https://wigglewave.wordpress.com/2014/08/16/pulse-waveforms-and-harmonics/).
|
2014-08-31 20:29:56 +00:00
|
|
|
*
|
|
|
|
* @constructor
|
2014-10-03 20:07:30 +00:00
|
|
|
* @extends {Tone.Oscillator}
|
2015-06-20 19:50:57 +00:00
|
|
|
* @param {Frequency} [frequency] The frequency of the oscillator
|
|
|
|
* @param {NormalRange} [width] The width of the pulse
|
2015-02-27 16:19:45 +00:00
|
|
|
* @example
|
2015-06-20 19:50:57 +00:00
|
|
|
* var pulse = new Tone.PulseOscillator("E5", 0.4).toMaster().start();
|
2014-08-31 20:29:56 +00:00
|
|
|
*/
|
2014-09-30 03:44:35 +00:00
|
|
|
Tone.PulseOscillator = function(){
|
2014-08-31 20:29:56 +00:00
|
|
|
|
2014-09-30 03:44:35 +00:00
|
|
|
var options = this.optionsObject(arguments, ["frequency", "width"], Tone.Oscillator.defaults);
|
2015-02-02 01:38:06 +00:00
|
|
|
Tone.Source.call(this, options);
|
2014-08-31 20:29:56 +00:00
|
|
|
|
|
|
|
/**
|
2015-06-14 02:30:33 +00:00
|
|
|
* The width of the pulse.
|
2015-06-13 23:50:39 +00:00
|
|
|
* @type {NormalRange}
|
|
|
|
* @signal
|
2014-08-31 20:29:56 +00:00
|
|
|
*/
|
2015-05-24 13:45:15 +00:00
|
|
|
this.width = new Tone.Signal(options.width, Tone.Type.NormalRange);
|
2015-02-20 05:53:03 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* gate the width amount
|
2016-09-20 03:53:07 +00:00
|
|
|
* @type {Tone.Gain}
|
2015-02-27 16:19:45 +00:00
|
|
|
* @private
|
2015-02-20 05:53:03 +00:00
|
|
|
*/
|
2016-09-20 03:53:07 +00:00
|
|
|
this._widthGate = new Tone.Gain();
|
2014-08-31 20:29:56 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* the sawtooth oscillator
|
|
|
|
* @type {Tone.Oscillator}
|
2014-09-06 19:56:41 +00:00
|
|
|
* @private
|
2014-08-31 20:29:56 +00:00
|
|
|
*/
|
2014-09-30 03:44:35 +00:00
|
|
|
this._sawtooth = new Tone.Oscillator({
|
|
|
|
frequency : options.frequency,
|
|
|
|
detune : options.detune,
|
|
|
|
type : "sawtooth",
|
|
|
|
phase : options.phase
|
|
|
|
});
|
2014-08-31 20:29:56 +00:00
|
|
|
|
|
|
|
/**
|
2015-06-20 19:50:57 +00:00
|
|
|
* The frequency control.
|
2015-06-13 23:50:39 +00:00
|
|
|
* @type {Frequency}
|
|
|
|
* @signal
|
2014-08-31 20:29:56 +00:00
|
|
|
*/
|
|
|
|
this.frequency = this._sawtooth.frequency;
|
|
|
|
|
|
|
|
/**
|
2015-02-27 16:19:45 +00:00
|
|
|
* The detune in cents.
|
2015-06-13 23:50:39 +00:00
|
|
|
* @type {Cents}
|
|
|
|
* @signal
|
2014-08-31 20:29:56 +00:00
|
|
|
*/
|
|
|
|
this.detune = this._sawtooth.detune;
|
|
|
|
|
|
|
|
/**
|
2015-02-27 16:19:45 +00:00
|
|
|
* Threshold the signal to turn it into a square
|
2014-11-30 18:20:35 +00:00
|
|
|
* @type {Tone.WaveShaper}
|
2014-08-31 20:29:56 +00:00
|
|
|
* @private
|
|
|
|
*/
|
2014-11-30 18:20:35 +00:00
|
|
|
this._thresh = new Tone.WaveShaper(function(val){
|
|
|
|
if (val < 0){
|
|
|
|
return -1;
|
|
|
|
} else {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
});
|
2014-08-31 20:29:56 +00:00
|
|
|
|
2014-09-30 03:44:35 +00:00
|
|
|
//connections
|
2014-12-01 02:32:09 +00:00
|
|
|
this._sawtooth.chain(this._thresh, this.output);
|
2015-02-20 05:53:03 +00:00
|
|
|
this.width.chain(this._widthGate, this._thresh);
|
2015-04-05 18:53:27 +00:00
|
|
|
this._readOnly(["width", "frequency", "detune"]);
|
2014-08-31 20:29:56 +00:00
|
|
|
};
|
|
|
|
|
2014-10-03 20:07:30 +00:00
|
|
|
Tone.extend(Tone.PulseOscillator, Tone.Oscillator);
|
2014-08-31 20:29:56 +00:00
|
|
|
|
2014-09-30 03:44:35 +00:00
|
|
|
/**
|
2015-02-27 16:19:45 +00:00
|
|
|
* The default parameters.
|
2014-09-30 03:44:35 +00:00
|
|
|
* @static
|
|
|
|
* @const
|
|
|
|
* @type {Object}
|
|
|
|
*/
|
|
|
|
Tone.PulseOscillator.defaults = {
|
|
|
|
"frequency" : 440,
|
|
|
|
"detune" : 0,
|
|
|
|
"phase" : 0,
|
2014-10-01 02:48:00 +00:00
|
|
|
"width" : 0.2,
|
2014-09-30 03:44:35 +00:00
|
|
|
};
|
|
|
|
|
2014-08-31 20:29:56 +00:00
|
|
|
/**
|
|
|
|
* start the oscillator
|
2015-06-14 00:20:36 +00:00
|
|
|
* @param {Time} time
|
2015-02-02 02:32:07 +00:00
|
|
|
* @private
|
2014-08-31 20:29:56 +00:00
|
|
|
*/
|
2015-02-02 02:32:07 +00:00
|
|
|
Tone.PulseOscillator.prototype._start = function(time){
|
|
|
|
time = this.toSeconds(time);
|
|
|
|
this._sawtooth.start(time);
|
2015-02-20 05:53:03 +00:00
|
|
|
this._widthGate.gain.setValueAtTime(1, time);
|
2014-08-31 20:29:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* stop the oscillator
|
2015-06-14 00:20:36 +00:00
|
|
|
* @param {Time} time
|
2015-02-27 16:19:45 +00:00
|
|
|
* @private
|
2014-08-31 20:29:56 +00:00
|
|
|
*/
|
2015-02-02 02:32:07 +00:00
|
|
|
Tone.PulseOscillator.prototype._stop = function(time){
|
|
|
|
time = this.toSeconds(time);
|
|
|
|
this._sawtooth.stop(time);
|
|
|
|
//the width is still connected to the output.
|
|
|
|
//that needs to be stopped also
|
2015-02-20 05:53:03 +00:00
|
|
|
this._widthGate.gain.setValueAtTime(0, time);
|
2014-08-31 20:29:56 +00:00
|
|
|
};
|
|
|
|
|
2015-02-04 04:48:47 +00:00
|
|
|
/**
|
2015-02-27 16:19:45 +00:00
|
|
|
* The phase of the oscillator in degrees.
|
2015-02-04 04:48:47 +00:00
|
|
|
* @memberOf Tone.PulseOscillator#
|
2015-06-14 02:30:33 +00:00
|
|
|
* @type {Degrees}
|
2015-02-04 04:48:47 +00:00
|
|
|
* @name phase
|
|
|
|
*/
|
|
|
|
Object.defineProperty(Tone.PulseOscillator.prototype, "phase", {
|
|
|
|
get : function(){
|
|
|
|
return this._sawtooth.phase;
|
|
|
|
},
|
|
|
|
set : function(phase){
|
|
|
|
this._sawtooth.phase = phase;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
/**
|
2015-02-27 16:19:45 +00:00
|
|
|
* The type of the oscillator. Always returns "pulse".
|
|
|
|
* @readOnly
|
2015-02-04 04:48:47 +00:00
|
|
|
* @memberOf Tone.PulseOscillator#
|
|
|
|
* @type {string}
|
|
|
|
* @name type
|
|
|
|
*/
|
|
|
|
Object.defineProperty(Tone.PulseOscillator.prototype, "type", {
|
|
|
|
get : function(){
|
|
|
|
return "pulse";
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2015-11-18 03:51:10 +00:00
|
|
|
/**
|
|
|
|
* The partials of the waveform. Cannot set partials for this waveform type
|
|
|
|
* @memberOf Tone.PulseOscillator#
|
|
|
|
* @type {Array}
|
|
|
|
* @name partials
|
|
|
|
* @private
|
|
|
|
*/
|
2015-11-24 04:51:36 +00:00
|
|
|
Object.defineProperty(Tone.PulseOscillator.prototype, "partials", {
|
2015-11-18 03:51:10 +00:00
|
|
|
get : function(){
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2014-08-31 20:29:56 +00:00
|
|
|
/**
|
2015-06-14 02:30:33 +00:00
|
|
|
* Clean up method.
|
2015-06-14 00:54:29 +00:00
|
|
|
* @return {Tone.PulseOscillator} this
|
2014-08-31 20:29:56 +00:00
|
|
|
*/
|
2015-02-02 03:05:24 +00:00
|
|
|
Tone.PulseOscillator.prototype.dispose = function(){
|
|
|
|
Tone.Source.prototype.dispose.call(this);
|
2014-08-31 20:29:56 +00:00
|
|
|
this._sawtooth.dispose();
|
2015-04-05 18:41:43 +00:00
|
|
|
this._sawtooth = null;
|
2015-04-05 18:53:27 +00:00
|
|
|
this._writable(["width", "frequency", "detune"]);
|
2014-08-31 20:29:56 +00:00
|
|
|
this.width.dispose();
|
2015-04-05 18:41:43 +00:00
|
|
|
this.width = null;
|
2016-09-20 03:53:07 +00:00
|
|
|
this._widthGate.dispose();
|
2015-02-20 05:53:03 +00:00
|
|
|
this._widthGate = null;
|
2016-09-20 03:53:07 +00:00
|
|
|
this._thresh.dispose();
|
2015-02-02 01:02:13 +00:00
|
|
|
this._thresh = null;
|
2015-04-05 18:41:43 +00:00
|
|
|
this.frequency = null;
|
|
|
|
this.detune = null;
|
2015-02-02 03:05:24 +00:00
|
|
|
return this;
|
2014-08-31 20:29:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
return Tone.PulseOscillator;
|
|
|
|
});
|