synthberry
Software MIDI synthesizer for the Raspberry Pi.
 All Classes Functions
serialmidi.cpp
1 #include <iostream>
2 #include "serialmidi.h"
3 
12 SerialMidi::SerialMidi(std::string serialPath) :
13  serialStream(serialPath),
14  channel(0), // Hardcoded for now
15  status(MidiStatus::None)
16 {
17  serialStream.SetBaudRate(LibSerial::SerialStreamBuf::BAUD_38400);
18  serialStream.SetCharSize(LibSerial::SerialStreamBuf::CHAR_SIZE_8);
19  serialStream.SetNumOfStopBits(1);
20  serialStream.SetParity(LibSerial::SerialStreamBuf::PARITY_NONE);
21  serialStream.SetFlowControl(LibSerial::SerialStreamBuf::FLOW_CONTROL_NONE);
22 }
23 
24 SerialMidi::~SerialMidi()
25 {
26  serialStream.Close();
27 }
28 
37 {
38  uint8_t pos = 0;
39  uint8_t bytesLeft = 0;
40 
41  while(serialStream.good()) {
42  uint8_t c = serialStream.get();
43 
44  if(bytesLeft == 0) {
45  // Not expecting data at this moment
46 
47  if(pos > 0) {
48  // We have just finished receiving a message
49  pos = 0;
50  parseMessage();
51  }
52 
53  if(c < 0x80) {
54  // Data received, reuse last status
55  data[pos++] = c;
56  if(!(status == MidiStatus::ProgramChange) &&
57  !(status == MidiStatus::ChannelPressure))
58  bytesLeft = 1;
59  }
60  else if((c > 0x7F) && (c < 0xF0)) {
61  // Status byte of channel message
62  if((c & 0x0F) == channel) {
63  // Message destined to our channel
64  status = MidiStatus((c & 0xF0));
65  if((status == MidiStatus::ProgramChange) ||
66  (status == MidiStatus::ChannelPressure))
67  bytesLeft = 1;
68  else
69  bytesLeft = 2;
70  }
71  }
72  }
73  else {
74  // Data bytes
75  data[pos++] = c;
76  bytesLeft--;
77  }
78  }
79 }
80 
88 {
89  return notes;
90 }
91 
92 void SerialMidi::parseMessage()
93 {
94  switch(status) {
95  case MidiStatus::NoteOff:
96  notes.removeNote(data[0]);
97  break;
98  case MidiStatus::NoteOn:
99  if(data[1] == 0)
100  notes.removeNote(data[0]); // Disguised NoteOff
101  else
102  notes.addNote(data[0], data[1]);
103  break;
104  default:
105  break;
106  }
107 }