2015-08-18 20:28:55 +00:00
|
|
|
define(["Tone/core/Tone", "Tone/signal/Signal", "Tone/core/Timeline"], function (Tone) {
|
2015-08-16 19:15:54 +00:00
|
|
|
|
2015-10-21 16:12:17 +00:00
|
|
|
"use strict";
|
|
|
|
|
2015-08-16 19:15:54 +00:00
|
|
|
/**
|
2017-08-31 16:41:15 +00:00
|
|
|
* @class A signal which adds the method getValueAtTime.
|
2015-08-16 19:15:54 +00:00
|
|
|
* Code and inspiration from https://github.com/jsantell/web-audio-automation-timeline
|
2017-04-26 03:45:37 +00:00
|
|
|
* @extends {Tone.Signal}
|
2015-11-03 01:09:19 +00:00
|
|
|
* @param {Number=} value The initial value of the signal
|
|
|
|
* @param {String=} units The conversion units of the signal.
|
2015-08-16 19:15:54 +00:00
|
|
|
*/
|
2015-08-18 20:28:55 +00:00
|
|
|
Tone.TimelineSignal = function(){
|
2015-08-16 19:15:54 +00:00
|
|
|
|
2017-04-26 03:45:37 +00:00
|
|
|
var options = Tone.defaults(arguments, ["value", "units"], Tone.Signal);
|
|
|
|
Tone.Signal.call(this, options);
|
2017-08-31 16:41:15 +00:00
|
|
|
|
2015-08-16 19:15:54 +00:00
|
|
|
/**
|
2015-08-17 05:01:04 +00:00
|
|
|
* The scheduled events
|
2015-08-18 20:28:55 +00:00
|
|
|
* @type {Tone.Timeline}
|
2015-08-16 19:15:54 +00:00
|
|
|
* @private
|
|
|
|
*/
|
2017-08-02 21:49:15 +00:00
|
|
|
this._events = new Tone.Timeline(100);
|
2015-08-16 19:15:54 +00:00
|
|
|
|
2015-08-17 05:01:04 +00:00
|
|
|
/**
|
|
|
|
* The initial scheduled value
|
|
|
|
* @type {Number}
|
|
|
|
* @private
|
|
|
|
*/
|
2015-10-21 14:53:43 +00:00
|
|
|
this._initial = this._fromUnits(this._param.value);
|
2017-04-26 03:45:37 +00:00
|
|
|
this.value = options.value;
|
2017-05-26 21:17:32 +00:00
|
|
|
|
2017-05-26 21:39:45 +00:00
|
|
|
//delete the input node so that nothing can overwrite the signal value
|
|
|
|
delete this.input;
|
2015-08-16 19:15:54 +00:00
|
|
|
};
|
|
|
|
|
2017-04-26 03:45:37 +00:00
|
|
|
Tone.extend(Tone.TimelineSignal, Tone.Signal);
|
2015-08-16 19:15:54 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The event types of a schedulable signal.
|
|
|
|
* @enum {String}
|
2016-03-05 15:44:03 +00:00
|
|
|
* @private
|
2015-08-16 19:15:54 +00:00
|
|
|
*/
|
2015-08-18 20:28:55 +00:00
|
|
|
Tone.TimelineSignal.Type = {
|
2015-08-16 19:15:54 +00:00
|
|
|
Linear : "linear",
|
|
|
|
Exponential : "exponential",
|
|
|
|
Target : "target",
|
|
|
|
Set : "set"
|
|
|
|
};
|
|
|
|
|
2015-08-18 20:28:55 +00:00
|
|
|
/**
|
2017-08-31 16:41:15 +00:00
|
|
|
* The current value of the signal.
|
2015-08-18 20:28:55 +00:00
|
|
|
* @memberOf Tone.TimelineSignal#
|
|
|
|
* @type {Number}
|
|
|
|
* @name value
|
|
|
|
*/
|
|
|
|
Object.defineProperty(Tone.TimelineSignal.prototype, "value", {
|
|
|
|
get : function(){
|
2016-03-03 18:04:02 +00:00
|
|
|
var now = this.now();
|
|
|
|
var val = this.getValueAtTime(now);
|
|
|
|
return this._toUnits(val);
|
2015-08-18 20:28:55 +00:00
|
|
|
},
|
|
|
|
set : function(value){
|
2017-04-26 03:45:37 +00:00
|
|
|
if (this._events){
|
|
|
|
var convertedVal = this._fromUnits(value);
|
|
|
|
this._initial = convertedVal;
|
|
|
|
this.cancelScheduledValues();
|
|
|
|
this._param.value = convertedVal;
|
|
|
|
}
|
2015-08-18 20:28:55 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2015-08-17 05:01:04 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// SCHEDULING
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Schedules a parameter value change at the given time.
|
|
|
|
* @param {*} value The value to set the signal.
|
|
|
|
* @param {Time} time The time when the change should occur.
|
2015-08-18 20:28:55 +00:00
|
|
|
* @returns {Tone.TimelineSignal} this
|
2015-08-17 05:01:04 +00:00
|
|
|
* @example
|
2017-08-31 16:41:15 +00:00
|
|
|
* //set the frequency to "G4" in exactly 1 second from now.
|
2015-08-17 05:01:04 +00:00
|
|
|
* freq.setValueAtTime("G4", "+1");
|
|
|
|
*/
|
2015-08-18 20:28:55 +00:00
|
|
|
Tone.TimelineSignal.prototype.setValueAtTime = function (value, startTime) {
|
2015-10-21 14:53:43 +00:00
|
|
|
value = this._fromUnits(value);
|
2015-08-16 19:15:54 +00:00
|
|
|
startTime = this.toSeconds(startTime);
|
2016-12-19 02:56:22 +00:00
|
|
|
this._events.add({
|
2015-08-18 20:28:55 +00:00
|
|
|
"type" : Tone.TimelineSignal.Type.Set,
|
2015-10-21 14:53:43 +00:00
|
|
|
"value" : value,
|
2015-08-16 19:15:54 +00:00
|
|
|
"time" : startTime
|
|
|
|
});
|
|
|
|
//invoke the original event
|
2015-10-21 14:53:43 +00:00
|
|
|
this._param.setValueAtTime(value, startTime);
|
2015-08-17 05:01:04 +00:00
|
|
|
return this;
|
2015-08-16 19:15:54 +00:00
|
|
|
};
|
|
|
|
|
2015-08-17 05:01:04 +00:00
|
|
|
/**
|
2017-08-31 16:41:15 +00:00
|
|
|
* Schedules a linear continuous change in parameter value from the
|
2015-08-17 05:01:04 +00:00
|
|
|
* previous scheduled parameter value to the given value.
|
2017-08-31 16:41:15 +00:00
|
|
|
*
|
|
|
|
* @param {number} value
|
|
|
|
* @param {Time} endTime
|
2015-08-18 20:28:55 +00:00
|
|
|
* @returns {Tone.TimelineSignal} this
|
2015-08-17 05:01:04 +00:00
|
|
|
*/
|
2015-08-18 20:28:55 +00:00
|
|
|
Tone.TimelineSignal.prototype.linearRampToValueAtTime = function (value, endTime) {
|
2015-10-21 14:53:43 +00:00
|
|
|
value = this._fromUnits(value);
|
2015-08-16 19:15:54 +00:00
|
|
|
endTime = this.toSeconds(endTime);
|
2016-12-19 02:56:22 +00:00
|
|
|
this._events.add({
|
2015-08-18 20:28:55 +00:00
|
|
|
"type" : Tone.TimelineSignal.Type.Linear,
|
2015-10-21 14:53:43 +00:00
|
|
|
"value" : value,
|
2015-08-16 19:15:54 +00:00
|
|
|
"time" : endTime
|
|
|
|
});
|
2015-10-21 14:53:43 +00:00
|
|
|
this._param.linearRampToValueAtTime(value, endTime);
|
2015-08-17 05:01:04 +00:00
|
|
|
return this;
|
2015-08-16 19:15:54 +00:00
|
|
|
};
|
|
|
|
|
2015-08-17 05:01:04 +00:00
|
|
|
/**
|
2017-08-31 16:41:15 +00:00
|
|
|
* Schedules an exponential continuous change in parameter value from
|
2015-08-17 05:01:04 +00:00
|
|
|
* the previous scheduled parameter value to the given value.
|
2017-08-31 16:41:15 +00:00
|
|
|
*
|
|
|
|
* @param {number} value
|
|
|
|
* @param {Time} endTime
|
2015-08-18 20:28:55 +00:00
|
|
|
* @returns {Tone.TimelineSignal} this
|
2015-08-17 05:01:04 +00:00
|
|
|
*/
|
2015-08-18 20:28:55 +00:00
|
|
|
Tone.TimelineSignal.prototype.exponentialRampToValueAtTime = function (value, endTime) {
|
2016-02-01 04:33:36 +00:00
|
|
|
//get the previous event and make sure it's not starting from 0
|
2016-09-20 23:35:07 +00:00
|
|
|
endTime = this.toSeconds(endTime);
|
2016-02-01 04:33:36 +00:00
|
|
|
var beforeEvent = this._searchBefore(endTime);
|
|
|
|
if (beforeEvent && beforeEvent.value === 0){
|
|
|
|
//reschedule that event
|
|
|
|
this.setValueAtTime(this._minOutput, beforeEvent.time);
|
|
|
|
}
|
2015-10-21 14:53:43 +00:00
|
|
|
value = this._fromUnits(value);
|
2016-02-01 04:33:36 +00:00
|
|
|
var setValue = Math.max(value, this._minOutput);
|
2016-12-19 02:56:22 +00:00
|
|
|
this._events.add({
|
2015-08-18 20:28:55 +00:00
|
|
|
"type" : Tone.TimelineSignal.Type.Exponential,
|
2016-02-01 04:33:36 +00:00
|
|
|
"value" : setValue,
|
2015-08-16 19:15:54 +00:00
|
|
|
"time" : endTime
|
|
|
|
});
|
2016-02-01 04:33:36 +00:00
|
|
|
//if the ramped to value is 0, make it go to the min output, and then set to 0.
|
|
|
|
if (value < this._minOutput){
|
2017-07-27 21:54:57 +00:00
|
|
|
this._param.exponentialRampToValueAtTime(this._minOutput, endTime - this.sampleTime);
|
2016-02-01 04:33:36 +00:00
|
|
|
this.setValueAtTime(0, endTime);
|
|
|
|
} else {
|
|
|
|
this._param.exponentialRampToValueAtTime(value, endTime);
|
|
|
|
}
|
2015-08-17 05:01:04 +00:00
|
|
|
return this;
|
2015-08-16 19:15:54 +00:00
|
|
|
};
|
|
|
|
|
2015-08-17 05:01:04 +00:00
|
|
|
/**
|
|
|
|
* Start exponentially approaching the target value at the given time with
|
|
|
|
* a rate having the given time constant.
|
2017-08-31 16:41:15 +00:00
|
|
|
* @param {number} value
|
|
|
|
* @param {Time} startTime
|
|
|
|
* @param {number} timeConstant
|
|
|
|
* @returns {Tone.TimelineSignal} this
|
2015-08-17 05:01:04 +00:00
|
|
|
*/
|
2015-08-18 20:28:55 +00:00
|
|
|
Tone.TimelineSignal.prototype.setTargetAtTime = function (value, startTime, timeConstant) {
|
2015-10-21 14:53:43 +00:00
|
|
|
value = this._fromUnits(value);
|
|
|
|
value = Math.max(this._minOutput, value);
|
2015-12-06 00:11:20 +00:00
|
|
|
timeConstant = Math.max(this._minOutput, timeConstant);
|
2015-08-16 19:15:54 +00:00
|
|
|
startTime = this.toSeconds(startTime);
|
2016-12-19 02:56:22 +00:00
|
|
|
this._events.add({
|
2015-08-18 20:28:55 +00:00
|
|
|
"type" : Tone.TimelineSignal.Type.Target,
|
2015-10-21 14:53:43 +00:00
|
|
|
"value" : value,
|
2015-08-16 19:15:54 +00:00
|
|
|
"time" : startTime,
|
|
|
|
"constant" : timeConstant
|
|
|
|
});
|
2015-10-21 14:53:43 +00:00
|
|
|
this._param.setTargetAtTime(value, startTime, timeConstant);
|
2015-08-17 05:01:04 +00:00
|
|
|
return this;
|
2015-08-16 19:15:54 +00:00
|
|
|
};
|
|
|
|
|
2016-03-05 15:44:03 +00:00
|
|
|
/**
|
|
|
|
* Set an array of arbitrary values starting at the given time for the given duration.
|
2017-08-31 16:41:15 +00:00
|
|
|
* @param {Float32Array} values
|
|
|
|
* @param {Time} startTime
|
2016-03-05 15:44:03 +00:00
|
|
|
* @param {Time} duration
|
|
|
|
* @param {NormalRange} [scaling=1] If the values in the curve should be scaled by some value
|
2017-08-31 16:41:15 +00:00
|
|
|
* @returns {Tone.TimelineSignal} this
|
2016-03-05 15:44:03 +00:00
|
|
|
*/
|
|
|
|
Tone.TimelineSignal.prototype.setValueCurveAtTime = function (values, startTime, duration, scaling) {
|
2017-04-30 19:03:49 +00:00
|
|
|
scaling = Tone.defaultArg(scaling, 1);
|
2016-03-05 15:44:03 +00:00
|
|
|
duration = this.toSeconds(duration);
|
2017-08-02 21:49:15 +00:00
|
|
|
startTime = this.toSeconds(startTime);
|
|
|
|
var segTime = duration / (values.length - 1);
|
|
|
|
this.setValueAtTime(values[0] * scaling, startTime);
|
|
|
|
for (var i = 1; i < values.length; i++){
|
|
|
|
this.linearRampToValueAtTime(values[i] * scaling, startTime + i * segTime);
|
2016-03-20 22:36:59 +00:00
|
|
|
}
|
2016-05-23 23:19:06 +00:00
|
|
|
return this;
|
2016-03-20 22:36:59 +00:00
|
|
|
};
|
|
|
|
|
2015-08-16 19:15:54 +00:00
|
|
|
/**
|
2017-08-31 16:41:15 +00:00
|
|
|
* Cancels all scheduled parameter changes with times greater than or
|
2015-08-17 05:01:04 +00:00
|
|
|
* equal to startTime.
|
|
|
|
* @param {Time} startTime
|
2015-08-18 20:28:55 +00:00
|
|
|
* @returns {Tone.TimelineSignal} this
|
2015-08-16 19:15:54 +00:00
|
|
|
*/
|
2015-08-18 20:28:55 +00:00
|
|
|
Tone.TimelineSignal.prototype.cancelScheduledValues = function (after) {
|
2016-09-20 23:35:07 +00:00
|
|
|
after = this.toSeconds(after);
|
2015-11-16 16:11:01 +00:00
|
|
|
this._events.cancel(after);
|
2016-09-20 23:35:07 +00:00
|
|
|
this._param.cancelScheduledValues(after);
|
2015-08-17 05:01:04 +00:00
|
|
|
return this;
|
2015-08-16 19:15:54 +00:00
|
|
|
};
|
|
|
|
|
2017-08-31 16:41:15 +00:00
|
|
|
/**
|
|
|
|
* Cancels all scheduled parameter changes with times greater than or
|
|
|
|
* equal to cancelTime and sets the output of the signal to be the value
|
2017-08-31 22:24:18 +00:00
|
|
|
* at cancelTime. Similar to (cancelScheduledValues)[#cancelscheduledvalues].
|
2017-08-31 16:41:15 +00:00
|
|
|
* @param {Time} cancelTime
|
|
|
|
* @returns {Tone.TimelineSignal} this
|
|
|
|
*/
|
|
|
|
Tone.TimelineSignal.prototype.cancelAndHoldAtTime = function (cancelTime) {
|
|
|
|
this.setRampPoint(this.toSeconds(cancelTime));
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
2015-08-16 19:15:54 +00:00
|
|
|
/**
|
2015-08-17 05:01:04 +00:00
|
|
|
* Sets the computed value at the given time. This provides
|
|
|
|
* a point from which a linear or exponential curve
|
2017-08-31 16:41:15 +00:00
|
|
|
* can be scheduled after. Will cancel events after
|
2015-11-16 16:11:01 +00:00
|
|
|
* the given time and shorten the currently scheduled
|
|
|
|
* linear or exponential ramp so that it ends at `time` .
|
2017-08-31 16:41:15 +00:00
|
|
|
* This is to avoid discontinuities and clicks in envelopes.
|
2015-08-16 19:15:54 +00:00
|
|
|
* @param {Time} time When to set the ramp point
|
2015-08-18 20:28:55 +00:00
|
|
|
* @returns {Tone.TimelineSignal} this
|
2015-08-16 19:15:54 +00:00
|
|
|
*/
|
2015-08-18 20:28:55 +00:00
|
|
|
Tone.TimelineSignal.prototype.setRampPoint = function (time) {
|
2015-08-16 19:15:54 +00:00
|
|
|
time = this.toSeconds(time);
|
|
|
|
//get the value at the given time
|
2016-07-07 03:00:07 +00:00
|
|
|
var val = this._toUnits(this.getValueAtTime(time));
|
2016-02-01 04:33:36 +00:00
|
|
|
//if there is an event at the given time
|
|
|
|
//and that even is not a "set"
|
|
|
|
var before = this._searchBefore(time);
|
|
|
|
if (before && before.time === time){
|
|
|
|
//remove everything after
|
2017-07-27 21:54:57 +00:00
|
|
|
this.cancelScheduledValues(time + this.sampleTime);
|
2016-02-01 04:33:36 +00:00
|
|
|
} else {
|
|
|
|
//reschedule the next event to end at the given time
|
|
|
|
var after = this._searchAfter(time);
|
|
|
|
if (after){
|
|
|
|
//cancel the next event(s)
|
|
|
|
this.cancelScheduledValues(time);
|
|
|
|
if (after.type === Tone.TimelineSignal.Type.Linear){
|
|
|
|
this.linearRampToValueAtTime(val, time);
|
|
|
|
} else if (after.type === Tone.TimelineSignal.Type.Exponential){
|
|
|
|
this.exponentialRampToValueAtTime(val, time);
|
2016-05-23 23:19:06 +00:00
|
|
|
}
|
|
|
|
}
|
2016-02-01 04:33:36 +00:00
|
|
|
}
|
2017-09-13 15:02:17 +00:00
|
|
|
this.setValueAtTime(val, time);
|
2015-08-17 05:01:04 +00:00
|
|
|
return this;
|
2015-08-16 19:15:54 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2015-08-17 05:01:04 +00:00
|
|
|
* Do a linear ramp to the given value between the start and finish times.
|
|
|
|
* @param {Number} value The value to ramp to.
|
|
|
|
* @param {Time} start The beginning anchor point to do the linear ramp
|
|
|
|
* @param {Time} finish The ending anchor point by which the value of
|
|
|
|
* the signal will equal the given value.
|
2015-10-21 14:53:43 +00:00
|
|
|
* @returns {Tone.TimelineSignal} this
|
2015-08-16 19:15:54 +00:00
|
|
|
*/
|
2015-08-18 20:28:55 +00:00
|
|
|
Tone.TimelineSignal.prototype.linearRampToValueBetween = function (value, start, finish) {
|
2015-08-16 19:15:54 +00:00
|
|
|
this.setRampPoint(start);
|
|
|
|
this.linearRampToValueAtTime(value, finish);
|
2015-08-17 05:01:04 +00:00
|
|
|
return this;
|
2015-08-16 19:15:54 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2015-08-17 05:01:04 +00:00
|
|
|
* Do a exponential ramp to the given value between the start and finish times.
|
|
|
|
* @param {Number} value The value to ramp to.
|
|
|
|
* @param {Time} start The beginning anchor point to do the exponential ramp
|
|
|
|
* @param {Time} finish The ending anchor point by which the value of
|
|
|
|
* the signal will equal the given value.
|
2015-10-21 14:53:43 +00:00
|
|
|
* @returns {Tone.TimelineSignal} this
|
2015-08-16 19:15:54 +00:00
|
|
|
*/
|
2015-08-18 20:28:55 +00:00
|
|
|
Tone.TimelineSignal.prototype.exponentialRampToValueBetween = function (value, start, finish) {
|
2015-08-16 19:15:54 +00:00
|
|
|
this.setRampPoint(start);
|
|
|
|
this.exponentialRampToValueAtTime(value, finish);
|
2015-08-17 05:01:04 +00:00
|
|
|
return this;
|
2015-08-16 19:15:54 +00:00
|
|
|
};
|
|
|
|
|
2015-08-17 05:01:04 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// GETTING SCHEDULED VALUES
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2015-08-16 19:15:54 +00:00
|
|
|
/**
|
2015-08-17 05:01:04 +00:00
|
|
|
* Returns the value before or equal to the given time
|
|
|
|
* @param {Number} time The time to query
|
|
|
|
* @return {Object} The event at or before the given time.
|
|
|
|
* @private
|
2015-08-16 19:15:54 +00:00
|
|
|
*/
|
2015-08-18 20:28:55 +00:00
|
|
|
Tone.TimelineSignal.prototype._searchBefore = function(time){
|
2016-12-19 02:56:22 +00:00
|
|
|
return this._events.get(time);
|
2015-08-16 19:15:54 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2015-08-17 05:01:04 +00:00
|
|
|
* The event after the given time
|
|
|
|
* @param {Number} time The time to query.
|
|
|
|
* @return {Object} The next event after the given time
|
2015-10-11 20:02:10 +00:00
|
|
|
* @private
|
2015-08-16 19:15:54 +00:00
|
|
|
*/
|
2015-08-18 20:28:55 +00:00
|
|
|
Tone.TimelineSignal.prototype._searchAfter = function(time){
|
2016-12-19 02:56:22 +00:00
|
|
|
return this._events.getAfter(time);
|
2015-08-16 19:15:54 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2015-11-26 06:24:34 +00:00
|
|
|
* Get the scheduled value at the given time. This will
|
|
|
|
* return the unconverted (raw) value.
|
2015-08-16 19:15:54 +00:00
|
|
|
* @param {Number} time The time in seconds.
|
|
|
|
* @return {Number} The scheduled value at the given time.
|
|
|
|
*/
|
2015-08-18 20:28:55 +00:00
|
|
|
Tone.TimelineSignal.prototype.getValueAtTime = function(time){
|
2016-09-20 23:35:07 +00:00
|
|
|
time = this.toSeconds(time);
|
2015-08-16 19:15:54 +00:00
|
|
|
var after = this._searchAfter(time);
|
|
|
|
var before = this._searchBefore(time);
|
2015-11-24 04:49:54 +00:00
|
|
|
var value = this._initial;
|
2015-08-17 05:01:04 +00:00
|
|
|
//if it was set by
|
|
|
|
if (before === null){
|
2015-11-24 04:49:54 +00:00
|
|
|
value = this._initial;
|
2015-08-18 20:28:55 +00:00
|
|
|
} else if (before.type === Tone.TimelineSignal.Type.Target){
|
2016-12-19 02:56:22 +00:00
|
|
|
var previous = this._events.getBefore(before.time);
|
2017-09-13 14:02:01 +00:00
|
|
|
var previousVal;
|
2015-08-17 05:01:04 +00:00
|
|
|
if (previous === null){
|
2017-09-13 14:02:01 +00:00
|
|
|
previousVal = this._initial;
|
2015-08-16 19:15:54 +00:00
|
|
|
} else {
|
2017-09-13 14:02:01 +00:00
|
|
|
previousVal = previous.value;
|
2015-08-16 19:15:54 +00:00
|
|
|
}
|
2017-09-13 14:02:01 +00:00
|
|
|
value = this._exponentialApproach(before.time, previousVal, before.value, before.constant, time);
|
2015-08-17 05:01:04 +00:00
|
|
|
} else if (after === null){
|
2015-11-24 04:49:54 +00:00
|
|
|
value = before.value;
|
2015-08-18 20:28:55 +00:00
|
|
|
} else if (after.type === Tone.TimelineSignal.Type.Linear){
|
2015-11-24 04:49:54 +00:00
|
|
|
value = this._linearInterpolate(before.time, before.value, after.time, after.value, time);
|
2015-08-18 20:28:55 +00:00
|
|
|
} else if (after.type === Tone.TimelineSignal.Type.Exponential){
|
2015-11-24 04:49:54 +00:00
|
|
|
value = this._exponentialInterpolate(before.time, before.value, after.time, after.value, time);
|
2015-08-16 19:15:54 +00:00
|
|
|
} else {
|
2015-11-24 04:49:54 +00:00
|
|
|
value = before.value;
|
2015-08-16 19:15:54 +00:00
|
|
|
}
|
2015-11-26 06:24:34 +00:00
|
|
|
return value;
|
2015-08-16 19:15:54 +00:00
|
|
|
};
|
|
|
|
|
2015-10-21 14:53:43 +00:00
|
|
|
/**
|
2017-08-31 16:41:15 +00:00
|
|
|
* When signals connect to other signals or AudioParams,
|
|
|
|
* they take over the output value of that signal or AudioParam.
|
|
|
|
* For all other nodes, the behavior is the same as a default <code>connect</code>.
|
2015-10-21 14:53:43 +00:00
|
|
|
*
|
|
|
|
* @override
|
2017-08-31 16:41:15 +00:00
|
|
|
* @param {AudioParam|AudioNode|Tone.Signal|Tone} node
|
2015-10-21 14:53:43 +00:00
|
|
|
* @param {number} [outputNumber=0] The output number to connect from.
|
|
|
|
* @param {number} [inputNumber=0] The input number to connect to.
|
|
|
|
* @returns {Tone.TimelineSignal} this
|
|
|
|
* @method
|
|
|
|
*/
|
2015-10-21 16:12:17 +00:00
|
|
|
Tone.TimelineSignal.prototype.connect = Tone.SignalBase.prototype.connect;
|
2015-10-21 14:53:43 +00:00
|
|
|
|
2015-08-16 19:15:54 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// AUTOMATION CURVE CALCULATIONS
|
|
|
|
// MIT License, copyright (c) 2014 Jordan Santell
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Calculates the the value along the curve produced by setTargetAtTime
|
|
|
|
* @private
|
|
|
|
*/
|
2015-08-18 20:28:55 +00:00
|
|
|
Tone.TimelineSignal.prototype._exponentialApproach = function (t0, v0, v1, timeConstant, t) {
|
2015-08-16 19:15:54 +00:00
|
|
|
return v1 + (v0 - v1) * Math.exp(-(t - t0) / timeConstant);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Calculates the the value along the curve produced by linearRampToValueAtTime
|
|
|
|
* @private
|
|
|
|
*/
|
2015-08-18 20:28:55 +00:00
|
|
|
Tone.TimelineSignal.prototype._linearInterpolate = function (t0, v0, t1, v1, t) {
|
2015-08-16 19:15:54 +00:00
|
|
|
return v0 + (v1 - v0) * ((t - t0) / (t1 - t0));
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Calculates the the value along the curve produced by exponentialRampToValueAtTime
|
|
|
|
* @private
|
|
|
|
*/
|
2015-08-18 20:28:55 +00:00
|
|
|
Tone.TimelineSignal.prototype._exponentialInterpolate = function (t0, v0, t1, v1, t) {
|
2015-08-16 19:15:54 +00:00
|
|
|
v0 = Math.max(this._minOutput, v0);
|
|
|
|
return v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0));
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Clean up.
|
2015-08-18 20:28:55 +00:00
|
|
|
* @return {Tone.TimelineSignal} this
|
2015-08-16 19:15:54 +00:00
|
|
|
*/
|
2015-08-18 20:28:55 +00:00
|
|
|
Tone.TimelineSignal.prototype.dispose = function(){
|
2015-08-16 19:15:54 +00:00
|
|
|
Tone.Signal.prototype.dispose.call(this);
|
2015-08-17 05:01:04 +00:00
|
|
|
this._events.dispose();
|
|
|
|
this._events = null;
|
2015-08-16 19:15:54 +00:00
|
|
|
};
|
|
|
|
|
2015-08-18 20:28:55 +00:00
|
|
|
return Tone.TimelineSignal;
|
2017-08-31 16:41:15 +00:00
|
|
|
});
|