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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103 | 1
1
4
1
2
2
2
2
2
2
2
2
1
1
1
1
1
1
16
16
16
1
1
1
1
1
1
1
1
1
1
1
1
1
1
| var async = require('async'),
Playlist = require('./playlist'),
roomba = require('roomba');
/**
* class Roombox
*/
function Roombox() {
this.playlist = new Playlist();
}
/**
* Start Roombox, load songs, and connect to Roomba.
*
* @param {Object} _opts: optional
* - dir: song data directory
* - path: serial port path
* - baudrate: baud rate, default: 57600
* @param {Function} cb: standard cb(err, result) callback
*/
Roombox.prototype.start = function (_opts, cb) {
console.log('Loading songs on %s', _opts.dir);
this.playlist.load(_opts.dir);
var opts = {
sp: {
path: _opts.path || '/dev/tty.roomba',
options: {
baudrate: _opts.baudrate || 57600
}
},
update_freq: 200
},
self = this;
console.log(
'Starting Roombox with path %s at baudrate %d',
opts.sp.path,
opts.sp.options.baudrate);
this.bot = new roomba.Roomba(opts);
this.bot.once('ready', function () {
self.playlist.displaySongs();
cb();
});
};
/**
* Play a song on the Roomba.
*
* @param {Number} trackNumber: song track number on the playlist
* @param {Function} cb: standard cb(err, result) callback
*/
Roombox.prototype.play = function (trackNumber, cb) {
const MAX_SEGMENTS = 4,
MAX_NOTES = 16,
INTERVAL = 200;
var song = this.playlist.getSong(trackNumber),
self = this;
console.log('Preparing track %d: %s - %s',
trackNumber, song.title, song.by);
var numNotes = song.notes.length,
numSegments = Math.min(Math.ceil(numNotes / MAX_NOTES), MAX_SEGMENTS),
segments = [],
data,
duration;
function _processSegmentNote(note) {
note[1] = Math.ceil(note[1] / 1.7);
data = data.concat(note);
duration += note[1];
}
for (var i = 0; i < numSegments; i += 1) {
var start = i * MAX_NOTES,
end = start + MAX_NOTES,
segmentNotes = song.notes.slice(start, end);
data = [i, segmentNotes.length];
duration = 0;
segmentNotes.forEach(_processSegmentNote);
segments.push({ index: i, notes: segmentNotes, duration: duration });
self.bot.send({ cmd: 'SONG', data: data });
}
function play(segment, cb) {
var duration = segment.duration * 1000 / 64;
console.log('Playing segment %d with duration %d ms', segment.index, duration);
self.bot.send({ cmd: 'PLAY', data: [segment.index] });
setTimeout(cb, INTERVAL + duration);
}
async.eachSeries(segments, play, cb);
};
module.exports = Roombox;
|