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