Gemphet8 ; 8-polyphonic synthesizer control application
Dependencies: MIDI REnc button mbed
MIDI_Proc/midi_proc.cpp@12:dc6208de53cc, 2014-12-13 (annotated)
- Committer:
- ChuckTimber
- Date:
- Sat Dec 13 10:51:48 2014 +0000
- Revision:
- 12:dc6208de53cc
- Parent:
- 11:e6a47dc75120
Gemphet8 2014/11/29 version.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ChuckTimber | 5:7d7be4c72d21 | 1 | #include "midi_proc.h" |
ChuckTimber | 5:7d7be4c72d21 | 2 | |
ChuckTimber | 5:7d7be4c72d21 | 3 | using namespace mbed; |
ChuckTimber | 5:7d7be4c72d21 | 4 | |
ChuckTimber | 5:7d7be4c72d21 | 5 | MN_t NoteEnd = { 255, 255, 15, 0 }; |
ChuckTimber | 5:7d7be4c72d21 | 6 | MN_t NoteStart = { 0, 0, 0, &NoteEnd }; |
ChuckTimber | 5:7d7be4c72d21 | 7 | MN_t MidiNotes[POLYPHONICE_NOTES]; |
ChuckTimber | 5:7d7be4c72d21 | 8 | static uint16_t MidiNotesTag; |
ChuckTimber | 9:a86ad099f24d | 9 | uint8_t NumOfNotes = POLYPHONICE_NOTES; |
ChuckTimber | 5:7d7be4c72d21 | 10 | |
ChuckTimber | 5:7d7be4c72d21 | 11 | |
ChuckTimber | 5:7d7be4c72d21 | 12 | void midi_init(void) |
ChuckTimber | 5:7d7be4c72d21 | 13 | { |
ChuckTimber | 10:c3b797b62ddb | 14 | midi.begin(); |
ChuckTimber | 11:e6a47dc75120 | 15 | |
ChuckTimber | 5:7d7be4c72d21 | 16 | midi.setHandleNoteOff(&midi_noteoff); |
ChuckTimber | 5:7d7be4c72d21 | 17 | midi.setHandleNoteOn(&midi_noteon); |
ChuckTimber | 5:7d7be4c72d21 | 18 | midi.setHandleControlChange(&midi_cc); |
ChuckTimber | 5:7d7be4c72d21 | 19 | midi.setHandleProgramChange(&midi_pc); |
ChuckTimber | 5:7d7be4c72d21 | 20 | midi.setHandlePitchBend(&midi_pbend); |
ChuckTimber | 5:7d7be4c72d21 | 21 | midi.setHandleSystemReset(&midi_sysreset); |
ChuckTimber | 11:e6a47dc75120 | 22 | |
ChuckTimber | 5:7d7be4c72d21 | 23 | } |
ChuckTimber | 5:7d7be4c72d21 | 24 | |
ChuckTimber | 5:7d7be4c72d21 | 25 | /// @brief Reset all MIDI controller |
ChuckTimber | 5:7d7be4c72d21 | 26 | static void midi_allnoteoff(void) |
ChuckTimber | 5:7d7be4c72d21 | 27 | { |
ChuckTimber | 5:7d7be4c72d21 | 28 | int i; |
ChuckTimber | 5:7d7be4c72d21 | 29 | uint16_t msk; |
ChuckTimber | 5:7d7be4c72d21 | 30 | |
ChuckTimber | 5:7d7be4c72d21 | 31 | for (i = 0, msk = 0x01; i < NumOfNotes; i++, msk<<=1) { |
ChuckTimber | 5:7d7be4c72d21 | 32 | if (MidiNotesTag & msk) { |
ChuckTimber | 5:7d7be4c72d21 | 33 | midi.sendNoteOff(MidiNotes[i].Note, MidiNotes[i].Velocity, MidiNotes[i].Channel); |
ChuckTimber | 5:7d7be4c72d21 | 34 | MidiNotesTag &= ~msk; |
ChuckTimber | 5:7d7be4c72d21 | 35 | } |
ChuckTimber | 5:7d7be4c72d21 | 36 | } |
ChuckTimber | 5:7d7be4c72d21 | 37 | |
ChuckTimber | 5:7d7be4c72d21 | 38 | MidiNotesTag = 0x0000; |
ChuckTimber | 5:7d7be4c72d21 | 39 | NoteEnd.next = NULL; |
ChuckTimber | 5:7d7be4c72d21 | 40 | NoteStart.next = &NoteEnd; |
ChuckTimber | 5:7d7be4c72d21 | 41 | } |
ChuckTimber | 5:7d7be4c72d21 | 42 | |
ChuckTimber | 5:7d7be4c72d21 | 43 | /// @brief Reset MIDI controller |
ChuckTimber | 5:7d7be4c72d21 | 44 | static void midi_resetcontrol(void) |
ChuckTimber | 5:7d7be4c72d21 | 45 | { |
ChuckTimber | 5:7d7be4c72d21 | 46 | } |
ChuckTimber | 5:7d7be4c72d21 | 47 | |
ChuckTimber | 5:7d7be4c72d21 | 48 | /// @brief Reset all MIDI controller |
ChuckTimber | 5:7d7be4c72d21 | 49 | void midi_sysreset(void) |
ChuckTimber | 5:7d7be4c72d21 | 50 | { |
ChuckTimber | 5:7d7be4c72d21 | 51 | midi_allnoteoff(); |
ChuckTimber | 5:7d7be4c72d21 | 52 | midi_resetcontrol(); |
ChuckTimber | 5:7d7be4c72d21 | 53 | } |
ChuckTimber | 5:7d7be4c72d21 | 54 | |
ChuckTimber | 5:7d7be4c72d21 | 55 | /// @brief MIDI note structure allocate function |
ChuckTimber | 5:7d7be4c72d21 | 56 | static MN_p allocN(void) { |
ChuckTimber | 5:7d7be4c72d21 | 57 | int i; |
ChuckTimber | 5:7d7be4c72d21 | 58 | uint16_t msk; |
ChuckTimber | 5:7d7be4c72d21 | 59 | |
ChuckTimber | 5:7d7be4c72d21 | 60 | for (i = 0, msk = 0x01; i < NumOfNotes; i++, msk<<=1) { |
ChuckTimber | 5:7d7be4c72d21 | 61 | if (!(MidiNotesTag & msk)) { |
ChuckTimber | 5:7d7be4c72d21 | 62 | MidiNotesTag |= msk; |
ChuckTimber | 11:e6a47dc75120 | 63 | MidiNotes[i].Channel = i + 1; |
ChuckTimber | 5:7d7be4c72d21 | 64 | return (&MidiNotes[i]); |
ChuckTimber | 5:7d7be4c72d21 | 65 | } |
ChuckTimber | 5:7d7be4c72d21 | 66 | } |
ChuckTimber | 5:7d7be4c72d21 | 67 | return NULL; |
ChuckTimber | 5:7d7be4c72d21 | 68 | } |
ChuckTimber | 5:7d7be4c72d21 | 69 | |
ChuckTimber | 5:7d7be4c72d21 | 70 | /// @brief MIDI note structure free function |
ChuckTimber | 5:7d7be4c72d21 | 71 | static void freeN(MN_p addr) |
ChuckTimber | 5:7d7be4c72d21 | 72 | { |
ChuckTimber | 5:7d7be4c72d21 | 73 | int i; |
ChuckTimber | 5:7d7be4c72d21 | 74 | uint16_t msk; |
ChuckTimber | 5:7d7be4c72d21 | 75 | |
ChuckTimber | 5:7d7be4c72d21 | 76 | for (i = 0, msk = 0x01; i < NumOfNotes; i++, msk<<=1) { |
ChuckTimber | 5:7d7be4c72d21 | 77 | if (addr == &MidiNotes[i]) |
ChuckTimber | 5:7d7be4c72d21 | 78 | MidiNotesTag &= ~msk; |
ChuckTimber | 5:7d7be4c72d21 | 79 | } |
ChuckTimber | 5:7d7be4c72d21 | 80 | } |
ChuckTimber | 5:7d7be4c72d21 | 81 | |
ChuckTimber | 5:7d7be4c72d21 | 82 | /// @brief MIDI Control Change callback funcion |
ChuckTimber | 5:7d7be4c72d21 | 83 | void midi_cc(byte channel, byte number, byte value) |
ChuckTimber | 5:7d7be4c72d21 | 84 | { |
ChuckTimber | 5:7d7be4c72d21 | 85 | if (number == MIDI_ALL_NOTE_OFF) { |
ChuckTimber | 5:7d7be4c72d21 | 86 | midi_allnoteoff(); |
ChuckTimber | 5:7d7be4c72d21 | 87 | } |
ChuckTimber | 5:7d7be4c72d21 | 88 | if (number == MIDI_RESET_ALL_CONTROLLERS) { |
ChuckTimber | 5:7d7be4c72d21 | 89 | midi_resetcontrol(); |
ChuckTimber | 5:7d7be4c72d21 | 90 | } |
ChuckTimber | 5:7d7be4c72d21 | 91 | midi.sendControlChange(number, value, channel); |
ChuckTimber | 5:7d7be4c72d21 | 92 | } |
ChuckTimber | 5:7d7be4c72d21 | 93 | |
ChuckTimber | 5:7d7be4c72d21 | 94 | /// @brief MIDI Program Change callback funcion |
ChuckTimber | 5:7d7be4c72d21 | 95 | void midi_pc(byte channel, byte number) |
ChuckTimber | 5:7d7be4c72d21 | 96 | { |
ChuckTimber | 5:7d7be4c72d21 | 97 | midi.sendProgramChange(number, channel); |
ChuckTimber | 5:7d7be4c72d21 | 98 | } |
ChuckTimber | 5:7d7be4c72d21 | 99 | |
ChuckTimber | 5:7d7be4c72d21 | 100 | /// @brief MIDI Pitch Bend callback funcion |
ChuckTimber | 5:7d7be4c72d21 | 101 | void midi_pbend(byte channel, int bend) |
ChuckTimber | 5:7d7be4c72d21 | 102 | { |
ChuckTimber | 5:7d7be4c72d21 | 103 | midi.sendPitchBend(bend, channel); |
ChuckTimber | 5:7d7be4c72d21 | 104 | } |
ChuckTimber | 5:7d7be4c72d21 | 105 | |
ChuckTimber | 5:7d7be4c72d21 | 106 | /// @brief MIDI Note On callback funcion |
ChuckTimber | 5:7d7be4c72d21 | 107 | void midi_noteon(byte channel, byte note, byte velocity) |
ChuckTimber | 5:7d7be4c72d21 | 108 | { |
ChuckTimber | 5:7d7be4c72d21 | 109 | MN_p ptr, newnote; |
ChuckTimber | 5:7d7be4c72d21 | 110 | |
ChuckTimber | 5:7d7be4c72d21 | 111 | if ((newnote = allocN()) == NULL) { // if table full, release oldest note |
ChuckTimber | 5:7d7be4c72d21 | 112 | ptr = NoteStart.next; |
ChuckTimber | 5:7d7be4c72d21 | 113 | midi.sendNoteOff(ptr->Note, ptr->Velocity, ptr->Channel); |
ChuckTimber | 5:7d7be4c72d21 | 114 | NoteStart.next = ptr->next; |
ChuckTimber | 5:7d7be4c72d21 | 115 | freeN(ptr); |
ChuckTimber | 5:7d7be4c72d21 | 116 | newnote = allocN(); |
ChuckTimber | 5:7d7be4c72d21 | 117 | } |
ChuckTimber | 5:7d7be4c72d21 | 118 | newnote->Note = note; |
ChuckTimber | 5:7d7be4c72d21 | 119 | newnote->Velocity = velocity; |
ChuckTimber | 5:7d7be4c72d21 | 120 | // newnote->Channel // do not set channel |
ChuckTimber | 5:7d7be4c72d21 | 121 | midi.sendNoteOn(note, velocity, newnote->Channel); |
ChuckTimber | 5:7d7be4c72d21 | 122 | for (ptr = &NoteStart; ptr->next; ptr = ptr->next) { // put newnote on the tail |
ChuckTimber | 5:7d7be4c72d21 | 123 | if (ptr->next == &NoteEnd) { |
ChuckTimber | 5:7d7be4c72d21 | 124 | newnote->next = ptr->next; |
ChuckTimber | 5:7d7be4c72d21 | 125 | ptr->next = newnote; |
ChuckTimber | 5:7d7be4c72d21 | 126 | break; |
ChuckTimber | 5:7d7be4c72d21 | 127 | } |
ChuckTimber | 5:7d7be4c72d21 | 128 | } |
ChuckTimber | 5:7d7be4c72d21 | 129 | } |
ChuckTimber | 5:7d7be4c72d21 | 130 | |
ChuckTimber | 5:7d7be4c72d21 | 131 | /// @brief MIDI Note Off callback funcion |
ChuckTimber | 5:7d7be4c72d21 | 132 | void midi_noteoff(byte channel, byte note, byte velocity) |
ChuckTimber | 5:7d7be4c72d21 | 133 | { |
ChuckTimber | 5:7d7be4c72d21 | 134 | MN_p ptr, lastptr; |
ChuckTimber | 5:7d7be4c72d21 | 135 | |
ChuckTimber | 5:7d7be4c72d21 | 136 | for (ptr = &NoteStart; ptr->next; ptr = ptr->next) { |
ChuckTimber | 5:7d7be4c72d21 | 137 | if (note == ptr->next->Note) { |
ChuckTimber | 5:7d7be4c72d21 | 138 | lastptr = ptr->next; |
ChuckTimber | 11:e6a47dc75120 | 139 | midi.sendNoteOff(lastptr->Note, velocity, lastptr->Channel); |
ChuckTimber | 5:7d7be4c72d21 | 140 | ptr->next = lastptr->next; |
ChuckTimber | 5:7d7be4c72d21 | 141 | freeN(lastptr); |
ChuckTimber | 5:7d7be4c72d21 | 142 | break; |
ChuckTimber | 5:7d7be4c72d21 | 143 | } |
ChuckTimber | 5:7d7be4c72d21 | 144 | } |
ChuckTimber | 5:7d7be4c72d21 | 145 | } |