Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: MIDI REnc button mbed
main.cpp@1:2760654d0b44, 2014-08-09 (annotated)
- Committer:
- ChuckTimber
- Date:
- Sat Aug 09 02:17:53 2014 +0000
- Revision:
- 1:2760654d0b44
- Parent:
- 0:3dc89ac1495f
- Child:
- 3:153322cb84f6
- Child:
- 4:c18cfcad2c48
- Child:
- 5:7d7be4c72d21
- Child:
- 6:16aa8fc30ef8
working copy ; compile OK, midi proc wrote
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ChuckTimber | 0:3dc89ac1495f | 1 | /** |
ChuckTimber | 0:3dc89ac1495f | 2 | * @file main.cpp |
ChuckTimber | 0:3dc89ac1495f | 3 | * Project Gem8 - handles 8-gembox synth project application |
ChuckTimber | 0:3dc89ac1495f | 4 | * @brief Gem8 project application |
ChuckTimber | 0:3dc89ac1495f | 5 | * @version 1.0 |
ChuckTimber | 0:3dc89ac1495f | 6 | * @author Chuck Timber |
ChuckTimber | 0:3dc89ac1495f | 7 | * @date 08/08/2014 |
ChuckTimber | 0:3dc89ac1495f | 8 | */ |
ChuckTimber | 0:3dc89ac1495f | 9 | |
ChuckTimber | 0:3dc89ac1495f | 10 | #include "mbed.h" |
ChuckTimber | 0:3dc89ac1495f | 11 | //#include "button.h" |
ChuckTimber | 0:3dc89ac1495f | 12 | //#include "REnc.h" |
ChuckTimber | 0:3dc89ac1495f | 13 | #include "MIDI.h" |
ChuckTimber | 0:3dc89ac1495f | 14 | |
ChuckTimber | 1:2760654d0b44 | 15 | |
ChuckTimber | 1:2760654d0b44 | 16 | // LED (active HIGH) |
ChuckTimber | 1:2760654d0b44 | 17 | #define dbg_led_on() { } |
ChuckTimber | 1:2760654d0b44 | 18 | #define dbg_led_off() { } |
ChuckTimber | 1:2760654d0b44 | 19 | |
ChuckTimber | 1:2760654d0b44 | 20 | |
ChuckTimber | 1:2760654d0b44 | 21 | /** MIDI System message */ |
ChuckTimber | 1:2760654d0b44 | 22 | #define MIDI_ALL_NOTE_OFF 0x7B |
ChuckTimber | 1:2760654d0b44 | 23 | #define MIDI_RESET_ALL_CONTROLLERS 0x79 |
ChuckTimber | 1:2760654d0b44 | 24 | |
ChuckTimber | 0:3dc89ac1495f | 25 | #define POLYPHONICE_NOTES 8 |
ChuckTimber | 1:2760654d0b44 | 26 | |
ChuckTimber | 1:2760654d0b44 | 27 | /** @structure MIDI Note management structure |
ChuckTimber | 1:2760654d0b44 | 28 | * |
ChuckTimber | 1:2760654d0b44 | 29 | */ |
ChuckTimber | 1:2760654d0b44 | 30 | struct _MidiNote { |
ChuckTimber | 1:2760654d0b44 | 31 | /// MIDI Note number |
ChuckTimber | 1:2760654d0b44 | 32 | uint8_t Note; |
ChuckTimber | 1:2760654d0b44 | 33 | /// MIDI Note velocity |
ChuckTimber | 1:2760654d0b44 | 34 | uint8_t Velocity; |
ChuckTimber | 1:2760654d0b44 | 35 | /// MIDI Note channel |
ChuckTimber | 1:2760654d0b44 | 36 | uint8_t Channel; |
ChuckTimber | 1:2760654d0b44 | 37 | /// pointer to the next _MidiNote object |
ChuckTimber | 1:2760654d0b44 | 38 | struct _MidiNote *next; |
ChuckTimber | 1:2760654d0b44 | 39 | }; |
ChuckTimber | 1:2760654d0b44 | 40 | |
ChuckTimber | 1:2760654d0b44 | 41 | struct _MidiNote NoteEnd = { 255, 255, 15, 0 }; |
ChuckTimber | 1:2760654d0b44 | 42 | struct _MidiNote NoteStart = { 0, 0, 0, &NoteEnd }; |
ChuckTimber | 1:2760654d0b44 | 43 | struct _MidiNote MidiNotes[POLYPHONICE_NOTES]; |
ChuckTimber | 1:2760654d0b44 | 44 | static uint16_t MidiNotesTag; |
ChuckTimber | 1:2760654d0b44 | 45 | |
ChuckTimber | 1:2760654d0b44 | 46 | volatile static uint8_t NumOfNotes = POLYPHONICE_NOTES; |
ChuckTimber | 1:2760654d0b44 | 47 | |
ChuckTimber | 1:2760654d0b44 | 48 | /** @brief Prototypes related to MIDI |
ChuckTimber | 1:2760654d0b44 | 49 | * |
ChuckTimber | 1:2760654d0b44 | 50 | */ |
ChuckTimber | 1:2760654d0b44 | 51 | struct _MidiNote *allocN(void); |
ChuckTimber | 1:2760654d0b44 | 52 | void freeN(struct _MidiNote *addr); |
ChuckTimber | 1:2760654d0b44 | 53 | void midi_allnoteoff(void); |
ChuckTimber | 1:2760654d0b44 | 54 | void midi_resetcontrol(void); |
ChuckTimber | 1:2760654d0b44 | 55 | void midi_sysreset(void); |
ChuckTimber | 1:2760654d0b44 | 56 | void midi_noteoff(byte channel, byte note, byte velocity); |
ChuckTimber | 1:2760654d0b44 | 57 | void midi_noteon(byte channel, byte note, byte velocity); |
ChuckTimber | 1:2760654d0b44 | 58 | void midi_cc(byte channel, byte number, byte value); |
ChuckTimber | 1:2760654d0b44 | 59 | void midi_pc(byte channel, byte number); |
ChuckTimber | 1:2760654d0b44 | 60 | void midi_pbend(byte channel, int bend); |
ChuckTimber | 0:3dc89ac1495f | 61 | |
ChuckTimber | 0:3dc89ac1495f | 62 | uint8_t midi_params[]={ |
ChuckTimber | 0:3dc89ac1495f | 63 | 0,0,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
ChuckTimber | 0:3dc89ac1495f | 64 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
ChuckTimber | 0:3dc89ac1495f | 65 | 0,0,0,0,0,0,0,64,0,0,127,0,32,127,0,0,64,32, |
ChuckTimber | 0:3dc89ac1495f | 66 | }; |
ChuckTimber | 0:3dc89ac1495f | 67 | |
ChuckTimber | 0:3dc89ac1495f | 68 | DigitalOut myled(LED1); |
ChuckTimber | 0:3dc89ac1495f | 69 | MIDI midi(dp16, dp15); |
ChuckTimber | 0:3dc89ac1495f | 70 | |
ChuckTimber | 0:3dc89ac1495f | 71 | |
ChuckTimber | 0:3dc89ac1495f | 72 | int main() { |
ChuckTimber | 0:3dc89ac1495f | 73 | |
ChuckTimber | 0:3dc89ac1495f | 74 | midi.setHandleNoteOff(&midi_noteoff); |
ChuckTimber | 0:3dc89ac1495f | 75 | midi.setHandleNoteOn(&midi_noteon); |
ChuckTimber | 0:3dc89ac1495f | 76 | midi.setHandleControlChange(&midi_cc); |
ChuckTimber | 0:3dc89ac1495f | 77 | midi.setHandleProgramChange(&midi_pc); |
ChuckTimber | 0:3dc89ac1495f | 78 | midi.setHandlePitchBend(&midi_pbend); |
ChuckTimber | 0:3dc89ac1495f | 79 | midi.setHandleSystemReset(&midi_sysreset); |
ChuckTimber | 0:3dc89ac1495f | 80 | |
ChuckTimber | 0:3dc89ac1495f | 81 | |
ChuckTimber | 0:3dc89ac1495f | 82 | while(1) { |
ChuckTimber | 0:3dc89ac1495f | 83 | myled = 1; |
ChuckTimber | 0:3dc89ac1495f | 84 | wait(0.2); |
ChuckTimber | 0:3dc89ac1495f | 85 | myled = 0; |
ChuckTimber | 0:3dc89ac1495f | 86 | wait(0.2); |
ChuckTimber | 0:3dc89ac1495f | 87 | } |
ChuckTimber | 0:3dc89ac1495f | 88 | } |
ChuckTimber | 0:3dc89ac1495f | 89 | |
ChuckTimber | 1:2760654d0b44 | 90 | /// @brief Reset all MIDI controller |
ChuckTimber | 1:2760654d0b44 | 91 | static void midi_allnoteoff(void) |
ChuckTimber | 1:2760654d0b44 | 92 | { |
ChuckTimber | 1:2760654d0b44 | 93 | int i; |
ChuckTimber | 1:2760654d0b44 | 94 | uint16_t msk; |
ChuckTimber | 1:2760654d0b44 | 95 | |
ChuckTimber | 1:2760654d0b44 | 96 | for (i = 0, msk = 0x01; i < NumOfNotes; i++, msk<<=1) { |
ChuckTimber | 1:2760654d0b44 | 97 | if (MidiNotesTag & msk) { |
ChuckTimber | 1:2760654d0b44 | 98 | midi.sendNoteOff(MidiNotes[i].Note, MidiNotes[i].Velocity, MidiNotes[i].Channel); |
ChuckTimber | 1:2760654d0b44 | 99 | MidiNotesTag &= ~msk; |
ChuckTimber | 1:2760654d0b44 | 100 | } |
ChuckTimber | 1:2760654d0b44 | 101 | } |
ChuckTimber | 1:2760654d0b44 | 102 | |
ChuckTimber | 1:2760654d0b44 | 103 | MidiNotesTag = 0x0000; |
ChuckTimber | 1:2760654d0b44 | 104 | NoteEnd.next = NULL; |
ChuckTimber | 1:2760654d0b44 | 105 | NoteStart.next = &NoteEnd; |
ChuckTimber | 1:2760654d0b44 | 106 | } |
ChuckTimber | 1:2760654d0b44 | 107 | |
ChuckTimber | 1:2760654d0b44 | 108 | /// @brief Reset MIDI controller |
ChuckTimber | 1:2760654d0b44 | 109 | static void midi_resetcontrol(void) |
ChuckTimber | 1:2760654d0b44 | 110 | { |
ChuckTimber | 1:2760654d0b44 | 111 | } |
ChuckTimber | 1:2760654d0b44 | 112 | |
ChuckTimber | 1:2760654d0b44 | 113 | /// @brief Reset all MIDI controller |
ChuckTimber | 1:2760654d0b44 | 114 | void midi_sysreset(void) |
ChuckTimber | 1:2760654d0b44 | 115 | { |
ChuckTimber | 1:2760654d0b44 | 116 | midi_allnoteoff(); |
ChuckTimber | 1:2760654d0b44 | 117 | midi_resetcontrol(); |
ChuckTimber | 1:2760654d0b44 | 118 | } |
ChuckTimber | 1:2760654d0b44 | 119 | |
ChuckTimber | 1:2760654d0b44 | 120 | /// @brief MIDI note structure allocate function |
ChuckTimber | 1:2760654d0b44 | 121 | static struct _MidiNote *allocN(void) |
ChuckTimber | 1:2760654d0b44 | 122 | { |
ChuckTimber | 1:2760654d0b44 | 123 | int i; |
ChuckTimber | 1:2760654d0b44 | 124 | uint16_t msk; |
ChuckTimber | 1:2760654d0b44 | 125 | |
ChuckTimber | 1:2760654d0b44 | 126 | for (i = 0, msk = 0x01; i < NumOfNotes; i++, msk<<=1) { |
ChuckTimber | 1:2760654d0b44 | 127 | if (!(MidiNotesTag & msk)) { |
ChuckTimber | 1:2760654d0b44 | 128 | MidiNotesTag |= msk; |
ChuckTimber | 1:2760654d0b44 | 129 | MidiNotes[i].Channel = i; |
ChuckTimber | 1:2760654d0b44 | 130 | return (&MidiNotes[i]); |
ChuckTimber | 1:2760654d0b44 | 131 | } |
ChuckTimber | 1:2760654d0b44 | 132 | } |
ChuckTimber | 1:2760654d0b44 | 133 | return NULL; |
ChuckTimber | 1:2760654d0b44 | 134 | } |
ChuckTimber | 1:2760654d0b44 | 135 | |
ChuckTimber | 1:2760654d0b44 | 136 | /// @brief MIDI note structure free function |
ChuckTimber | 1:2760654d0b44 | 137 | static void freeN(struct _MidiNote *addr) |
ChuckTimber | 1:2760654d0b44 | 138 | { |
ChuckTimber | 1:2760654d0b44 | 139 | int i; |
ChuckTimber | 1:2760654d0b44 | 140 | uint16_t msk; |
ChuckTimber | 1:2760654d0b44 | 141 | |
ChuckTimber | 1:2760654d0b44 | 142 | for (i = 0, msk = 0x01; i < NumOfNotes; i++, msk<<=1) { |
ChuckTimber | 1:2760654d0b44 | 143 | if (addr == &MidiNotes[i]) |
ChuckTimber | 1:2760654d0b44 | 144 | MidiNotesTag &= ~msk; |
ChuckTimber | 1:2760654d0b44 | 145 | } |
ChuckTimber | 1:2760654d0b44 | 146 | } |
ChuckTimber | 1:2760654d0b44 | 147 | |
ChuckTimber | 1:2760654d0b44 | 148 | /// @brief MIDI Control Change callback funcion |
ChuckTimber | 1:2760654d0b44 | 149 | void midi_cc(byte channel, byte number, byte value) |
ChuckTimber | 1:2760654d0b44 | 150 | { |
ChuckTimber | 1:2760654d0b44 | 151 | if (number == MIDI_ALL_NOTE_OFF) { |
ChuckTimber | 1:2760654d0b44 | 152 | midi_allnoteoff(); |
ChuckTimber | 1:2760654d0b44 | 153 | } |
ChuckTimber | 1:2760654d0b44 | 154 | if (number == MIDI_RESET_ALL_CONTROLLERS) { |
ChuckTimber | 1:2760654d0b44 | 155 | midi_resetcontrol(); |
ChuckTimber | 1:2760654d0b44 | 156 | } |
ChuckTimber | 1:2760654d0b44 | 157 | midi.sendControlChange(number, value, channel); |
ChuckTimber | 1:2760654d0b44 | 158 | } |
ChuckTimber | 1:2760654d0b44 | 159 | |
ChuckTimber | 1:2760654d0b44 | 160 | /// @brief MIDI Program Change callback funcion |
ChuckTimber | 1:2760654d0b44 | 161 | void midi_pc(byte channel, byte number) |
ChuckTimber | 1:2760654d0b44 | 162 | { |
ChuckTimber | 1:2760654d0b44 | 163 | midi.sendProgramChange(number, channel); |
ChuckTimber | 1:2760654d0b44 | 164 | } |
ChuckTimber | 1:2760654d0b44 | 165 | |
ChuckTimber | 1:2760654d0b44 | 166 | /// @brief MIDI Pitch Bend callback funcion |
ChuckTimber | 1:2760654d0b44 | 167 | void midi_pbend(byte channel, int bend) |
ChuckTimber | 1:2760654d0b44 | 168 | { |
ChuckTimber | 1:2760654d0b44 | 169 | midi.sendPitchBend(bend, channel); |
ChuckTimber | 1:2760654d0b44 | 170 | } |
ChuckTimber | 1:2760654d0b44 | 171 | |
ChuckTimber | 1:2760654d0b44 | 172 | /// @brief MIDI Note On callback funcion |
ChuckTimber | 1:2760654d0b44 | 173 | void midi_noteon(byte channel, byte note, byte velocity) |
ChuckTimber | 1:2760654d0b44 | 174 | { |
ChuckTimber | 1:2760654d0b44 | 175 | struct _MidiNote *ptr, *newnote; |
ChuckTimber | 1:2760654d0b44 | 176 | |
ChuckTimber | 1:2760654d0b44 | 177 | if ((newnote = allocN()) == NULL) { // if table full, release oldest note |
ChuckTimber | 1:2760654d0b44 | 178 | ptr = NoteStart.next; |
ChuckTimber | 1:2760654d0b44 | 179 | midi.sendNoteOff(ptr->Note, ptr->Velocity, ptr->Channel); |
ChuckTimber | 1:2760654d0b44 | 180 | NoteStart.next = ptr->next; |
ChuckTimber | 1:2760654d0b44 | 181 | freeN(ptr); |
ChuckTimber | 1:2760654d0b44 | 182 | newnote = allocN(); |
ChuckTimber | 1:2760654d0b44 | 183 | } |
ChuckTimber | 1:2760654d0b44 | 184 | newnote->Note = note; |
ChuckTimber | 1:2760654d0b44 | 185 | newnote->Velocity = velocity; |
ChuckTimber | 1:2760654d0b44 | 186 | // newnote->Channel // do not set channel |
ChuckTimber | 1:2760654d0b44 | 187 | midi.sendNoteOn(note, velocity, newnote->Channel); |
ChuckTimber | 1:2760654d0b44 | 188 | for (ptr = &NoteStart; ptr->next; ptr = ptr->next) { // put newnote on the tail |
ChuckTimber | 1:2760654d0b44 | 189 | if (ptr->next == &NoteEnd) { |
ChuckTimber | 1:2760654d0b44 | 190 | newnote->next = ptr->next; |
ChuckTimber | 1:2760654d0b44 | 191 | ptr->next = newnote; |
ChuckTimber | 1:2760654d0b44 | 192 | break; |
ChuckTimber | 1:2760654d0b44 | 193 | } |
ChuckTimber | 1:2760654d0b44 | 194 | } |
ChuckTimber | 1:2760654d0b44 | 195 | } |
ChuckTimber | 1:2760654d0b44 | 196 | |
ChuckTimber | 1:2760654d0b44 | 197 | /// @brief MIDI Note Off callback funcion |
ChuckTimber | 1:2760654d0b44 | 198 | void midi_noteoff(byte channel, byte note, byte velocity) |
ChuckTimber | 1:2760654d0b44 | 199 | { |
ChuckTimber | 1:2760654d0b44 | 200 | struct _MidiNote *ptr, *lastptr; |
ChuckTimber | 1:2760654d0b44 | 201 | |
ChuckTimber | 1:2760654d0b44 | 202 | for (ptr = &NoteStart; ptr->next; ptr = ptr->next) { |
ChuckTimber | 1:2760654d0b44 | 203 | if (note == ptr->next->Note) { |
ChuckTimber | 1:2760654d0b44 | 204 | lastptr = ptr->next; |
ChuckTimber | 1:2760654d0b44 | 205 | midi.sendNoteOff(lastptr->Note, lastptr->Velocity, lastptr->Channel); |
ChuckTimber | 1:2760654d0b44 | 206 | ptr->next = lastptr->next; |
ChuckTimber | 1:2760654d0b44 | 207 | freeN(lastptr); |
ChuckTimber | 1:2760654d0b44 | 208 | break; |
ChuckTimber | 1:2760654d0b44 | 209 | } |
ChuckTimber | 1:2760654d0b44 | 210 | } |
ChuckTimber | 1:2760654d0b44 | 211 | } |