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