mirror of
https://github.com/Tonejs/Tone.js
synced 2024-11-16 16:48:00 +00:00
Tone.Loop provides a simple, schedulable looped callback.
This commit is contained in:
parent
03c580db3e
commit
a51ed921bf
1 changed files with 239 additions and 0 deletions
239
Tone/event/Loop.js
Normal file
239
Tone/event/Loop.js
Normal file
|
@ -0,0 +1,239 @@
|
|||
define(["Tone/core/Tone", "Tone/event/Event"], function (Tone) {
|
||||
|
||||
/**
|
||||
* @class Tone.Loop creates a looped callback at the
|
||||
* specified interval. The callback can be
|
||||
* started, stopped and scheduled along
|
||||
* the Transport's timeline.
|
||||
* @example
|
||||
* var loop = new Tone.Loop(function(time){
|
||||
* //triggered every eighth note.
|
||||
* console.log(time);
|
||||
* }, "8n").start(0);
|
||||
* Tone.Transport.start();
|
||||
* @extends {Tone}
|
||||
* @param {Function} callback The callback to invoke with the
|
||||
* event.
|
||||
* @param {Array} events The events to arpeggiate over.
|
||||
*/
|
||||
Tone.Loop = function(){
|
||||
|
||||
var options = this.optionsObject(arguments, ["callback", "interval"], Tone.Loop.defaults);
|
||||
|
||||
/**
|
||||
* The event which produces the callbacks
|
||||
*/
|
||||
this._event = new Tone.Event({
|
||||
"callback" : this._tick.bind(this),
|
||||
"loop" : true,
|
||||
"loopEnd" : options.interval,
|
||||
"playbackRate" : options.playbackRate,
|
||||
"probability" : options.probability
|
||||
});
|
||||
|
||||
/**
|
||||
* The callback to invoke with the next event in the pattern
|
||||
* @type {Function}
|
||||
*/
|
||||
this.callback = options.callback;
|
||||
|
||||
//set the iterations
|
||||
this.iterations = options.iterations;
|
||||
};
|
||||
|
||||
Tone.extend(Tone.Loop);
|
||||
|
||||
/**
|
||||
* The defaults
|
||||
* @const
|
||||
* @type {Object}
|
||||
*/
|
||||
Tone.Loop.defaults = {
|
||||
"interval" : "4n",
|
||||
"callback" : Tone.noOp,
|
||||
"playbackRate" : 1,
|
||||
"iterations" : Infinity,
|
||||
"probability" : true,
|
||||
"mute" : false
|
||||
};
|
||||
|
||||
/**
|
||||
* Start the loop at the specified time along the Transport's
|
||||
* timeline.
|
||||
* @param {Time=} time When to start the Loop.
|
||||
* @return {Tone.Loop} this
|
||||
*/
|
||||
Tone.Loop.prototype.start = function(time){
|
||||
this._event.start(time);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Stop the arpeggio at the given time.
|
||||
* @param {Time=} time When to stop the Arpeggio
|
||||
* @return {Tone.Loop} this
|
||||
*/
|
||||
Tone.Loop.prototype.stop = function(time){
|
||||
this._event.stop(time);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Cancel all scheduled events greater than or equal to the given time
|
||||
* @param {Time} [time=0] The time after which events will be cancel.
|
||||
* @return {Tone.Loop} this
|
||||
*/
|
||||
Tone.Loop.prototype.cancel = function(time){
|
||||
this._event.cancel(time);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal function called when the notes should be called
|
||||
* @param {Number} time The time the event occurs
|
||||
* @private
|
||||
*/
|
||||
Tone.Loop.prototype._tick = function(time){
|
||||
this.callback(time);
|
||||
};
|
||||
|
||||
/**
|
||||
* The state of the Loop, either started or stopped.
|
||||
* @memberOf Tone.Loop#
|
||||
* @type {String}
|
||||
* @name state
|
||||
* @readOnly
|
||||
*/
|
||||
Object.defineProperty(Tone.Loop.prototype, "state", {
|
||||
get : function(){
|
||||
return this._event.state;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* The progress of the loop as a value between 0-1. 0, when
|
||||
* the loop is stopped or done iterating.
|
||||
* @memberOf Tone.Loop#
|
||||
* @type {NormalRange}
|
||||
* @name progress
|
||||
* @readOnly
|
||||
*/
|
||||
Object.defineProperty(Tone.Loop.prototype, "progress", {
|
||||
get : function(){
|
||||
return this._event.progress;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* The repeat interval
|
||||
* @memberOf Tone.Loop#
|
||||
* @type {Time}
|
||||
* @name interval
|
||||
*/
|
||||
Object.defineProperty(Tone.Loop.prototype, "interval", {
|
||||
get : function(){
|
||||
return this._event.loopEnd;
|
||||
},
|
||||
set : function(interval){
|
||||
this._event.loopEnd = interval;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* The playback rate of the pattern.
|
||||
* @memberOf Tone.Loop#
|
||||
* @type {Time}
|
||||
* @name playbackRate
|
||||
*/
|
||||
Object.defineProperty(Tone.Loop.prototype, "playbackRate", {
|
||||
get : function(){
|
||||
return this._event.playbackRate;
|
||||
},
|
||||
set : function(rate){
|
||||
this._event.playbackRate = rate;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Random variation +/-0.01s to the scheduled time.
|
||||
* Or give it a time value which it will randomize by.
|
||||
* @type {Boolean|Time}
|
||||
* @memberOf Tone.Loop#
|
||||
* @name humanize
|
||||
*/
|
||||
Object.defineProperty(Tone.Loop.prototype, "humanize", {
|
||||
get : function(){
|
||||
return this._event.humanize;
|
||||
},
|
||||
set : function(variation){
|
||||
this._event.humanize = variation;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* The probably of the callback being invoked.
|
||||
* @memberOf Tone.Loop#
|
||||
* @type {NormalRange}
|
||||
* @name probability
|
||||
*/
|
||||
Object.defineProperty(Tone.Loop.prototype, "probability", {
|
||||
get : function(){
|
||||
return this._event.probability;
|
||||
},
|
||||
set : function(prob){
|
||||
this._event.probability = prob;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Muting the Loop means that no callbacks are invoked.
|
||||
* @memberOf Tone.Loop#
|
||||
* @type {Boolean}
|
||||
* @name mute
|
||||
*/
|
||||
Object.defineProperty(Tone.Loop.prototype, "mute", {
|
||||
get : function(){
|
||||
return this._event.mute;
|
||||
},
|
||||
set : function(mute){
|
||||
this._event.mute = mute;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* The number of iterations of the loop. The default
|
||||
* value is Infinity (loop forever).
|
||||
* @memberOf Tone.Loop#
|
||||
* @type {Positive}
|
||||
* @name iterations
|
||||
*/
|
||||
Object.defineProperty(Tone.Loop.prototype, "iterations", {
|
||||
get : function(){
|
||||
if (this._event.loop === true){
|
||||
return Infinity;
|
||||
} else {
|
||||
return this._event.loop;
|
||||
}
|
||||
return this._pattern.index;
|
||||
},
|
||||
set : function(iters){
|
||||
if (iters === Infinity){
|
||||
this._event.loop = true;
|
||||
} else {
|
||||
this._event.loop = iters;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Clean up
|
||||
* @return {Tone.Loop} this
|
||||
*/
|
||||
Tone.Loop.prototype.dispose = function(){
|
||||
this._event.dispose();
|
||||
this._event = null;
|
||||
this.callback = null;
|
||||
};
|
||||
|
||||
return Tone.Loop;
|
||||
});
|
Loading…
Reference in a new issue