![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Gemphet8 ; 8-polyphonic synthesizer control application
Dependencies: MIDI REnc button mbed
MIDI_Proc/midi_proc.cpp
- Committer:
- ChuckTimber
- Date:
- 2014-08-11
- Revision:
- 4:c18cfcad2c48
File content as of revision 4:c18cfcad2c48:
#include "midi_proc.h" using namespace mbed; MIDI_P::MIDI_P(PinName tx, PinName rx) : _midi(tx, rx) { NoteEnd = { 255, 255, 15, 0 }; NoteStart = { 0, 0, 0, &NoteEnd }; NumOfNotes = POLYPHONICE_NOTES; } /// @brief Reset all MIDI controller void MIDI_P::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 void MIDI_P::midi_resetcontrol(void) { } /// @brief Reset all MIDI controller void MIDI_P::midi_sysreset(void) { midi_allnoteoff(); midi_resetcontrol(); } /// @brief MIDI note structure allocate function MN_p MIDI_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 void MIDI_P::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_P::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_P::midi_pc(byte channel, byte number) { _midi.sendProgramChange(number, channel); } /// @brief MIDI Pitch Bend callback funcion void MIDI_P::midi_pbend(byte channel, int bend) { _midi.sendPitchBend(bend, channel); } /// @brief MIDI Note On callback funcion void MIDI_P::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_P::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; } } } void MIDI_P::Init(void) { _midi.setHandleNoteOff((void (*))(&MIDI_P::midi_noteoff)); _midi.setHandleNoteOn(&MIDI_P::midi_noteon); _midi.setHandleControlChange(&MIDI_P::midi_cc); _midi.setHandleProgramChange(&MIDI_P::midi_pc); _midi.setHandlePitchBend(&MIDI_P::midi_pbend); _midi.setHandleSystemReset(&MIDI_P::midi_sysreset); }