Gemphet8 ; 8-polyphonic synthesizer control application
Dependencies: MIDI REnc button mbed
MIDI_Proc/midi_proc.c
- Committer:
- ChuckTimber
- Date:
- 2014-08-11
- Revision:
- 5:7d7be4c72d21
File content as of revision 5:7d7be4c72d21:
#include "midi_proc.h" using namespace mbed; MN_t NoteEnd = { 255, 255, 15, 0 }; MN_t NoteStart = { 0, 0, 0, &NoteEnd }; MN_t MidiNotes[POLYPHONICE_NOTES]; static uint16_t MidiNotesTag; volatile static uint8_t NumOfNotes = POLYPHONICE_NOTES; MIDI midi(dp16, dp15); void midi_init(void) { midi.setHandleNoteOff(&midi_noteoff); midi.setHandleNoteOn(&midi_noteon); midi.setHandleControlChange(&midi_cc); midi.setHandleProgramChange(&midi_pc); midi.setHandlePitchBend(&midi_pbend); midi.setHandleSystemReset(&midi_sysreset); } /// @brief Reset all MIDI controller static void midi_allnoteoff(void) { int i; uint16_t msk; for (i = 0, msk = 0x01; i < NumOfNotes; i++, msk<<=1) { if (MidiNotesTag & msk) { midi.sendNoteOff(MidiNotes[i].Note, MidiNotes[i].Velocity, MidiNotes[i].Channel); MidiNotesTag &= ~msk; } } MidiNotesTag = 0x0000; NoteEnd.next = NULL; NoteStart.next = &NoteEnd; } /// @brief Reset MIDI controller static void midi_resetcontrol(void) { } /// @brief Reset all MIDI controller void midi_sysreset(void) { midi_allnoteoff(); midi_resetcontrol(); } /// @brief MIDI note structure allocate function static MN_p allocN(void) { int i; uint16_t msk; for (i = 0, msk = 0x01; i < NumOfNotes; i++, msk<<=1) { if (!(MidiNotesTag & msk)) { MidiNotesTag |= msk; MidiNotes[i].Channel = i; return (&MidiNotes[i]); } } return NULL; } /// @brief MIDI note structure free function static void freeN(MN_p addr) { int i; uint16_t msk; for (i = 0, msk = 0x01; i < NumOfNotes; i++, msk<<=1) { if (addr == &MidiNotes[i]) MidiNotesTag &= ~msk; } } /// @brief MIDI Control Change callback funcion void midi_cc(byte channel, byte number, byte value) { if (number == MIDI_ALL_NOTE_OFF) { midi_allnoteoff(); } if (number == MIDI_RESET_ALL_CONTROLLERS) { midi_resetcontrol(); } midi.sendControlChange(number, value, channel); } /// @brief MIDI Program Change callback funcion void midi_pc(byte channel, byte number) { midi.sendProgramChange(number, channel); } /// @brief MIDI Pitch Bend callback funcion void midi_pbend(byte channel, int bend) { midi.sendPitchBend(bend, channel); } /// @brief MIDI Note On callback funcion void midi_noteon(byte channel, byte note, byte velocity) { MN_p ptr, newnote; if ((newnote = allocN()) == NULL) { // if table full, release oldest note ptr = NoteStart.next; midi.sendNoteOff(ptr->Note, ptr->Velocity, ptr->Channel); NoteStart.next = ptr->next; freeN(ptr); newnote = allocN(); } newnote->Note = note; newnote->Velocity = velocity; // newnote->Channel // do not set channel midi.sendNoteOn(note, velocity, newnote->Channel); for (ptr = &NoteStart; ptr->next; ptr = ptr->next) { // put newnote on the tail if (ptr->next == &NoteEnd) { newnote->next = ptr->next; ptr->next = newnote; break; } } } /// @brief MIDI Note Off callback funcion void midi_noteoff(byte channel, byte note, byte velocity) { MN_p ptr, lastptr; for (ptr = &NoteStart; ptr->next; ptr = ptr->next) { if (note == ptr->next->Note) { lastptr = ptr->next; midi.sendNoteOff(lastptr->Note, lastptr->Velocity, lastptr->Channel); ptr->next = lastptr->next; freeN(lastptr); break; } } }