Page 184 - Hacking Roomba
P. 184

Chapter 8 — Making Roomba Sing                165



                             The second parameter of destinationCreate() determines what object to notify when MIDI
                             data arrives for that MIDIClient, and it is set to the RoombaMidi object itself. This means that
                             RoombaMidi must implement MIDIReadProc, and it must have an appropriate execute()
                             method. Listing 8-6 also shows the very simple execute() method that goes through the
                             incoming MIDIPacketList and processes each MIDIPacket with processMIDIEvent().
                             The processMIDIEvent() method parses the incoming MIDI data, looking for a note-on
                             (0x90) or note-off (0x80) MIDI message. If it finds one of them, it extracts the entire message
                             from the MIDIData buffer and invokes doNote() with it. Finally, doNote() finds the corre-
                             sponding RoombaCommPanel based off of MIDI channel, and calls playMidiNote() to
                             cause Roomba to sing or dance.


                               Listing 8-6: RoombaMidi.java MIDI Handling Methods

                               public void setupMidi() {
                                 try {
                                   midiclient = new MIDIClient(new CAFString(“RoombaMidi”),
                               null);
                                   midiclient.destinationCreate(new CAFString(“RoombaMidi
                               In”), this);
                                 } catch(Exception e) {
                                   e.printStackTrace();
                                 }
                               }
                               public void execute(MIDIInputPort port, MIDIEndpoint
                               srcEndPoint,
                                                     MIDIPacketList list) {
                                 for(int i = 0; i < list.numPackets(); i++) {
                                   MIDIPacket packet = list.getPacket(i);
                                   processMIDIEvent(port, srcEndPoint, packet.getData());
                                 }
                               }
                               void processMIDIEvent(MIDIInputPort port, MIDIEndpoint
                               endpoint,
                                                       MIDIData data) {
                                 try {
                                   int startOffset = data.getMIDIDataOffset();
                                   int numMIDIdata = startOffset + data.getMIDIDataLength();
                                   int i = startOffset;
                                   do {
                                     if(i >= numMIDIdata)
                                        break;
                                     int commandByte = data.getUByteAt(i);
                                     int command = commandByte & 0xf0;
                                     int channel = commandByte & ~0xf0;
                                     if(command == 0x90 || command == 0x80) {  // NOTE_ON or
                               NOTE_OFF
                                        doNote(command, channel, data.getByteAt(i+1),
                                                                   data.getByteAt(i+2));
                                                                                              Continued
   179   180   181   182   183   184   185   186   187   188   189