Gemphet8 ; 8-polyphonic synthesizer control application

Dependencies:   MIDI REnc button mbed

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?

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