Gemphet8 ; 8-polyphonic synthesizer control application

Dependencies:   MIDI REnc button mbed

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?

UserRevisionLine numberNew 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 }