Page 175 - Hacking Roomba
P. 175
156 Part II — Fun Things to Do
Listing 8-1: RoombaComm createSong() and playSong()
public void createSong(int songnum, int song[]) {
int len = song.length;
int songlen = len/2;
byte cmd[] = new byte[len+3];
cmd[0] = (byte) SONG;
cmd[1] = (byte) songnum;
cmd[2] = (byte) songlen;
for( int i=0; i < len; i++ ) {
cmd[3+i] = (byte)song[i];
}
send(cmd);
}
public void playSong(int songnum) {
byte cmd[] = {(byte)PLAY,(byte)songnum };
send(cmd);
}
The createSong() method fixes the most dangerous problem by automatically computing
song length. The process of defining and playing the song becomes:
int notes[] = {48,32, 52,32, 55,32};
roombacomm.createSong(1,notes);
roombacomm.playSong(1);
That’s better, but it still isn’t really conducive to composition, especially if one wants to play in
real time. For that you need to create a way to play a single note.
Playing Single Notes
At the current stage of the ROI protocol, there is no way to play a single note. There may never
be such a feature. However, with clever application of what you already know, a playNote()
RoombaComm command can be created. Listing 8-2 shows one way to implement this. Both
the SONG and PLAY commands are used, one after the other. The SONG command is used
to define a single note song, and the PLAY command immediately plays it. The playNote()
function uses song slot #15 to hold the note, so that slot cannot be used for normal songs.
One thing to note is that unlike MIDI, which uses separate note-on and note-off messages to
indicate when a note starts playing and when it stops, the playNote() command necessarily
must specify a duration. This puts some limitations on expression during real-time perform-
ance, but it’s better than nothing.