-
Notifications
You must be signed in to change notification settings - Fork 3
/
index.js
78 lines (64 loc) · 2.2 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
'use strict';
var EventEmitter = require('events').EventEmitter;
var inherits = require('util').inherits;
var NanoTimer = require('nanotimer');
function play() {
if (this._playing) return;
this.step = 0;
this._playing = true;
loop.call(this);
}
function loop() {
var self = this;
self.timer.setTimeout(function () {
advance.call(self);
if (self._playing) loop.call(self);
}, '', self.timeout);
}
function advance() {
this.emit('' + this.step, this.sequence[this.step]);
this.step = (this.step + 1);
if (this.step === this.sequence.length) this.step = 0;
}
function resume() {
if (this._playing) return;
this._playing = true;
loop.call(this);
}
function stop() {
if (!this._playing) return;
this._playing = false;
this.timer.clearTimeout();
}
function setTempo(tempo) {
if (typeof tempo !== 'number') throw new TypeError('Tempo must be a number');
this.tempo = tempo;
this.timeout = Math.floor((60 / (this.tempo * this.division)) * 10e8) + 'n';
}
function setSequence(division, sequence) {
if (typeof division !== 'number') throw new TypeError('Division must be a number');
if (!(sequence instanceof Array)) throw new TypeError('Sequence must be an array');
this.division = division;
this.sequence = sequence;
this.timeout = Math.floor((60 / (this.tempo * this.division)) * 10e8) + 'n';
}
function StepSequencer(tempo, division, sequence) {
if (tempo && typeof tempo !== 'number') throw new TypeError('Tempo must be a number');
if (division && typeof division !== 'number') throw new TypeError('Division must be a number');
if (sequence && !(sequence instanceof Array)) throw new TypeError('Sequence must be an array');
this.tempo = tempo || 120;
this.division = division || 4;
this.sequence = sequence || [];
this.step = 0;
this.timer = new NanoTimer();
this.timeout = Math.floor((60 / (this.tempo * this.division)) * 10e8) + 'n';
this._playing = false;
EventEmitter.call(this);
}
inherits(StepSequencer, EventEmitter);
StepSequencer.prototype.play = play;
StepSequencer.prototype.resume = resume;
StepSequencer.prototype.stop = stop;
StepSequencer.prototype.setTempo = setTempo;
StepSequencer.prototype.setSequence = setSequence;
module.exports = StepSequencer;