|
| 1 | +/* |
| 2 | + This file is part of ttymidi. |
| 3 | +
|
| 4 | + ttymidi is free software: you can redistribute it and/or modify |
| 5 | + it under the terms of the GNU General Public License as published by |
| 6 | + the Free Software Foundation, either version 3 of the License, or |
| 7 | + (at your option) any later version. |
| 8 | +
|
| 9 | + ttymidi is distributed in the hope that it will be useful, |
| 10 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | + GNU General Public License for more details. |
| 13 | +
|
| 14 | + You should have received a copy of the GNU General Public License |
| 15 | + along with ttymidi. If not, see <http://www.gnu.org/licenses/>. |
| 16 | +*/ |
| 17 | +// file version 0.60 |
| 18 | + |
| 19 | +#include "WProgram.h" |
| 20 | +#include "HardwareSerial.h" |
| 21 | +#include "ardumidi.h" |
| 22 | + |
| 23 | +void midi_note_off(byte channel, byte key, byte velocity) |
| 24 | +{ |
| 25 | + midi_command(0x80, channel, key, velocity); |
| 26 | +} |
| 27 | + |
| 28 | +void midi_note_on(byte channel, byte key, byte velocity) |
| 29 | +{ |
| 30 | + midi_command(0x90, channel, key, velocity); |
| 31 | +} |
| 32 | + |
| 33 | +void midi_key_pressure(byte channel, byte key, byte value) |
| 34 | +{ |
| 35 | + midi_command(0xA0, channel, key, value); |
| 36 | +} |
| 37 | + |
| 38 | +void midi_controller_change(byte channel, byte control, byte value) |
| 39 | +{ |
| 40 | + midi_command(0xB0, channel, control, value); |
| 41 | +} |
| 42 | + |
| 43 | +void midi_program_change(byte channel, byte program) |
| 44 | +{ |
| 45 | + midi_command_short(0xC0, channel, program); |
| 46 | +} |
| 47 | + |
| 48 | +void midi_channel_pressure(byte channel, byte value) |
| 49 | +{ |
| 50 | + midi_command_short(0xD0, channel, value); |
| 51 | +} |
| 52 | + |
| 53 | +void midi_pitch_bend(byte channel, int value) |
| 54 | +{ |
| 55 | + midi_command(0xE0, channel, value & 0x7F, value >> 7); |
| 56 | +} |
| 57 | + |
| 58 | +void midi_command(byte command, byte channel, byte param1, byte param2) |
| 59 | +{ |
| 60 | + Serial.print(command | (channel & 0x0F), BYTE); |
| 61 | + Serial.print(param1 & 0x7F, BYTE); |
| 62 | + Serial.print(param2 & 0x7F, BYTE); |
| 63 | +} |
| 64 | + |
| 65 | +void midi_command_short(byte command, byte channel, byte param1) |
| 66 | +{ |
| 67 | + Serial.print(command | (channel & 0x0F), BYTE); |
| 68 | + Serial.print(param1 & 0x7F, BYTE); |
| 69 | +} |
| 70 | + |
| 71 | +void midi_print(char* msg, int len) |
| 72 | +{ |
| 73 | + Serial.print(0xFF, BYTE); |
| 74 | + Serial.print(0x00, BYTE); |
| 75 | + Serial.print(0x00, BYTE); |
| 76 | + Serial.print(len , BYTE); |
| 77 | + Serial.print(msg); |
| 78 | +} |
| 79 | + |
| 80 | +void midi_comment(char* msg) |
| 81 | +{ |
| 82 | + int len = 0; |
| 83 | + char* ptr = msg; |
| 84 | + while (*ptr++) len++; |
| 85 | + midi_print(msg, len); |
| 86 | +} |
| 87 | + |
| 88 | +int midi_message_available() { |
| 89 | + /* |
| 90 | + This bit will check that next bytes to be read would actually |
| 91 | + have the midi status bit. If not it will remove uncorrect bytes |
| 92 | + from internal buffer |
| 93 | + */ |
| 94 | + while ((Serial.available() > 0) && ((Serial.peek() & B10000000) != 0x80)) { |
| 95 | + Serial.read(); |
| 96 | + } |
| 97 | + |
| 98 | + /* Well we don't exactly know how many commands there might be in the Serial buffer |
| 99 | + so we'll just guess it according the type of message that happens to be waiting |
| 100 | + in the buffer. At least we get first one right! */ |
| 101 | + byte command = Serial.peek() & 11110000; |
| 102 | + if (command != MIDI_PROGRAM_CHANGE && command != MIDI_CHANNEL_PRESSURE) { |
| 103 | + return (Serial.available()/2); |
| 104 | + } |
| 105 | + return (Serial.available()/3); |
| 106 | +} |
| 107 | + |
| 108 | +MidiMessage read_midi_message() { |
| 109 | + MidiMessage message; |
| 110 | + byte midi_status = Serial.read(); |
| 111 | + message.command = (midi_status & B11110000); |
| 112 | + message.channel = (midi_status & B00001111); |
| 113 | + message.param1 = Serial.read(); |
| 114 | + if (message.command != MIDI_PROGRAM_CHANGE && message.command != MIDI_CHANNEL_PRESSURE) { |
| 115 | + message.param2 = Serial.read(); |
| 116 | + } |
| 117 | + return message; |
| 118 | +} |
| 119 | + |
| 120 | +int get_pitch_bend(MidiMessage m) { |
| 121 | + return (m.param1 & 0x7F) + ((m.param2 & 0x7F) << 7); |
| 122 | +} |
| 123 | + |
0 commit comments