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
main.cpp
- Committer:
- ChuckTimber
- Date:
- 2014-08-11
- Revision:
- 6:16aa8fc30ef8
- Parent:
- 1:2760654d0b44
- Child:
- 7:2398a1835eae
File content as of revision 6:16aa8fc30ef8:
/**
* @file main.cpp
* Project Gem8 - handles 8-gembox synth project application
* @brief Gem8 project application
* @version 1.0
* @author Chuck Timber
* @date 08/08/2014
*/
#include "mbed.h"
//#include "button.h"
//#include "REnc.h"
#include "MIDI.h"
// LED (active HIGH)
#define dbg_led_on() { }
#define dbg_led_off() { }
/** MIDI System message */
#define MIDI_ALL_NOTE_OFF 0x7B
#define MIDI_RESET_ALL_CONTROLLERS 0x79
#define POLYPHONICE_NOTES 8
/** @structure MIDI Note management structure
*
*/
typedef struct _MidiNote {
/// MIDI Note number
uint8_t Note;
/// MIDI Note velocity
uint8_t Velocity;
/// MIDI Note channel
uint8_t Channel;
/// pointer to the next _MidiNote object
struct _MidiNote *next;
} MN_t, *MN_p;
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;
/** @brief Prototypes related to MIDI
*
*/
void midi_init(void);
struct _MidiNote *allocN(void);
void freeN(struct _MidiNote *addr);
void midi_allnoteoff(void);
void midi_resetcontrol(void);
void midi_sysreset(void);
void midi_noteoff(byte channel, byte note, byte velocity);
void midi_noteon(byte channel, byte note, byte velocity);
void midi_cc(byte channel, byte number, byte value);
void midi_pc(byte channel, byte number);
void midi_pbend(byte channel, int bend);
uint8_t midi_params[]= {
0,0,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,64,0,0,127,0,32,127,0,0,64,32,
};
DigitalOut myled(LED1);
MIDI midi(dp16, dp15);
int main()
{
midi_init();
while(1) {
myled = 1;
wait(0.2);
myled = 0;
wait(0.2);
}
}
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;
}
}
}