Tone.js/test/event/Loop.js
2016-03-04 15:31:48 -05:00

358 lines
No EOL
7.7 KiB
JavaScript

define(["helper/Basic", "Tone/event/Loop", "Tone/core/Tone",
"Tone/core/Transport", "helper/Offline2"], function (Basic, Loop, Tone, Transport, Offline) {
describe("Loop", function(){
Basic(Loop);
function resetTransport(done){
Tone.Transport.cancel(0);
Tone.Transport.off("start stop pause loop");
Tone.Transport.stop();
Tone.Transport.loop = false;
Tone.Transport.PPQ = 48;
Tone.Transport.bpm.value = 120;
Tone.Transport.timeSignature = [4, 4];
setTimeout(done, 200);
}
context("Constructor", function(){
afterEach(resetTransport);
it ("takes a callback and an interval", function(){
var callback = function(){};
var loop = new Loop(callback, "8n");
expect(loop.callback).to.equal(callback);
expect(loop.interval).to.equal("8n");
loop.dispose();
});
it ("can be constructed with no arguments", function(){
var loop = new Loop();
expect(loop.iterations).to.equal(Infinity);
loop.dispose();
});
it ("can pass in arguments in options object", function(){
var callback = function(){};
var loop = new Loop({
"callback" : callback,
"iterations" : 4,
"probability" : 0.3,
"interval" : "8t"
});
expect(loop.callback).to.equal(callback);
expect(loop.interval).to.equal("8t");
expect(loop.iterations).to.equal(4);
expect(loop.probability).to.equal(0.3);
loop.dispose();
});
});
context("Get/Set", function(){
afterEach(resetTransport);
it ("can set values with object", function(){
var callback = function(){};
var loop = new Loop();
loop.set({
"callback" : callback,
"iterations" : 8
});
expect(loop.callback).to.equal(callback);
expect(loop.iterations).to.equal(8);
loop.dispose();
});
it ("can set get a the values as an object", function(){
var callback = function(){};
var loop = new Loop({
"callback" : callback,
"iterations" : 4,
"probability" : 0.3
});
var values = loop.get();
expect(values.iterations).to.equal(4);
expect(values.probability).to.equal(0.3);
loop.dispose();
});
});
context("Callback", function(){
afterEach(resetTransport);
it ("does not invoke get invoked until started", function(done){
Offline(function(dest, test, after){
var loop = new Loop(function(){
throw new Error("shouldn't call this callback");
}, "8n");
Tone.Transport.start();
after(function(){
loop.dispose();
done();
});
}, 0.3);
});
it ("is invoked after it's started", function(done){
var loop = new Loop(function(){
loop.dispose();
done();
}, "8n").start(0);
Tone.Transport.start();
});
it ("passes in the scheduled time to the callback", function(done){
var now = Tone.Transport.now();
var loop = new Loop(function(time){
expect(time).to.be.a.number;
expect(time - now).to.be.closeTo(0.3, 0.01);
loop.dispose();
done();
});
Tone.Transport.start();
loop.start(0.3);
});
it ("can mute the callback", function(done){
Offline(function(output, test, after){
var loop = new Loop(function(){
throw new Error("shouldn't call this callback");
}, "4n").start();
loop.mute = true;
expect(loop.mute).to.be.true;
Tone.Transport.start();
after(function(){
loop.dispose();
done();
});
}, 0.4);
});
it ("can trigger with some probability", function(done){
Offline(function(output, test, after){
var loop = new Loop(function(){
throw new Error("shouldn't call this callback");
}, "4n").start();
loop.probability = 0;
expect(loop.probability).to.equal(0);
Tone.Transport.start();
after(function(){
loop.dispose();
done();
});
}, 0.4);
});
});
context("Scheduling", function(){
afterEach(resetTransport);
it ("can be started and stopped multiple times", function(done){
Offline(function(output, test, after){
var loop = new Loop().start().stop(0.2).start(0.4);
Tone.Transport.start(0);
test(function(sample, time){
if (time > 0.01 && time < 0.18){
expect(loop.state).to.equal("started");
} else if (time > 0.2 && time < 0.38){
expect(loop.state).to.equal("stopped");
} else if (time > 0.4){
expect(loop.state).to.equal("started");
}
});
after(function(){
loop.dispose();
done();
});
}, 0.6);
});
it ("restarts when transport is restarted", function(done){
var loop = new Loop().start(0).stop(0.4);
setTimeout(function(){
expect(loop.state).to.equal("started");
}, 100);
setTimeout(function(){
expect(loop.state).to.equal("stopped");
Tone.Transport.stop();
setTimeout(function(){
Tone.Transport.start();
setTimeout(function(){
expect(Tone.Transport.state).to.equal("started");
expect(loop.state).to.equal("started");
loop.dispose();
done();
}, 100);
}, 100);
}, 500);
Tone.Transport.start();
});
it ("can be cancelled", function(done){
var loop = new Loop().start(0);
setTimeout(function(){
expect(loop.state).to.equal("started");
Tone.Transport.stop();
loop.cancel();
setTimeout(function(){
Tone.Transport.start();
setTimeout(function(){
expect(loop.state).to.equal("stopped");
loop.dispose();
done();
}, 100);
}, 100);
}, 100);
Tone.Transport.start();
});
});
context("Looping", function(){
afterEach(resetTransport);
it ("loops", function(done){
Offline(function(output, test, after){
var callCount = 0;
var loop = new Loop({
"interval" : 0.1,
"callback" : function(){
callCount++;
}
}).start(0);
Tone.Transport.start();
after(function(){
expect(callCount).to.above(6);
loop.dispose();
done();
});
}, 0.8);
});
it ("loops for the specified interval", function(done){
var lastCall;
var loop = new Loop({
"interval" : "8n",
"callback" : function(time){
if (lastCall){
expect(time - lastCall).to.be.closeTo(0.25, 0.01);
}
lastCall = time;
}
}).start(0);
Tone.Transport.start();
setTimeout(function(){
loop.dispose();
done();
}, 700);
});
it ("can loop a specific number of iterations", function(done){
Offline(function(output, test, after){
var callCount = 0;
var loop = new Loop({
"interval" : 0.1,
"iterations" : 2,
"callback" : function(){
callCount++;
}
}).start(0);
Tone.Transport.start();
after(function(){
expect(callCount).to.equal(2);
expect(loop.state).to.equal("stopped");
loop.dispose();
done();
});
}, 0.4);
});
it ("reports the progress of the loop", function(done){
Offline(function(output, test, after){
var loop = new Loop({
"interval" : 1,
}).start(0);
Tone.Transport.start();
after(function(){
expect(loop.progress).to.be.closeTo(0.8, 0.05);
loop.dispose();
done();
});
}, 0.8);
});
});
context("playbackRate", function(){
afterEach(resetTransport);
it ("can adjust the playbackRate", function(done){
Offline(function(output, test, after){
var lastCall;
var loop = new Loop({
"playbackRate" : 2,
"intervaliter" : 0.5,
"callback" : function(time){
if (lastCall){
expect(time - lastCall).to.be.closeTo(0.25, 0.01);
}
lastCall = time;
}
}).start(0);
Tone.Transport.start();
after(function(){
loop.dispose();
done();
});
}, 0.7);
});
});
});
});