void midi_process(snd_seq_event_t *ev) { //If this event is a PGMCHANGE type, it's a request to map a channel to an instrument if( ev->type == SND_SEQ_EVENT_PGMCHANGE ) { //Clear pins state, this is probably the beginning of a new song clearPinsState(); setPlayChannel(ev->data.control.channel, 1); } else if ( ((ev->type == SND_SEQ_EVENT_NOTEON)||(ev->type == SND_SEQ_EVENT_NOTEOFF)) ) { //Note on/off event int isOn = 1; //Note velocity == 0 means the same thing as a NOTEOFF type event if( ev->data.note.velocity == 0 || ev->type == SND_SEQ_EVENT_NOTEOFF) { isOn = 0; } //There are 12 different kinds of notes. (I will only use the first 8 for my rig but I need to the modulus. will be 0-11.) int pinIdx = ev->data.note.note % 12; //If pin is set to be turned on if( isOn ) { //If pin is currently available to play a note, or if currently playing channel can be overriden due to higher priority channel if( pinNotes[pinIdx] == -1 || pinChannels[pinIdx] > ev->data.note.channel ) { //Write to the pin, save the note to pinNotes digitalWrite(pinIdx, 1); pinNotes[pinIdx] = ev->data.note.note; pinChannels[pinIdx] = ev->data.note.channel; } } else { //Pin is to be turned off //If this is the note that turned the pin on.. if( pinNotes[pinIdx] == ev->data.note.note && pinChannels[pinIdx] == ev->data.note.channel ) { //Write to the pin, indicate that pin is available digitalWrite(pinIdx, 0); pinNotes[pinIdx] = -1; pinChannels[pinIdx] = INT_MAX; } } } else { printf("Unhandled event %2d\n", ev->type); } snd_seq_free_event(ev); } // end of midi_process
void midi_process(snd_seq_event_t *ev) { //If this event is a PGMCHANGE type, it's a request to map a channel to an instrument if( ev->type == SND_SEQ_EVENT_PGMCHANGE ) { printf("PGMCHANGE: channel %2d, %5d, %5d\n", ev->data.control.channel, ev->data.control.param, ev->data.control.value); //Clear pins state, this is probably the beginning of a new song clearPinsState(); //Filter out this channel if it's a base, percussion, or synth instrument if( (ev->data.control.value >= 8 && ev->data.control.value <= 15) || //Percussion (ev->data.control.value >= 32 && ev->data.control.value <= 39) || //Base (ev->data.control.value >= 88 && ev->data.control.value <= 103) //Synth ) { setPlayChannel(ev->data.control.channel, 0); } else { setPlayChannel(ev->data.control.channel, 1); } } //Note on/off event else if ( ((ev->type == SND_SEQ_EVENT_NOTEON)||(ev->type == SND_SEQ_EVENT_NOTEOFF)) ) { //If it's on a channel I care about if( isPlayChannel(ev->data.note.channel) ) { int isOn = 1; //Note velocity == 0 means the same thing as a NOTEOFF type event if( ev->data.note.velocity == 0 || ev->type == SND_SEQ_EVENT_NOTEOFF) { isOn = 0; } //There are 12 different kinds of notes. int noteMod = ev->data.note.note % 12; //Cast to double double noteModDouble = noteMod; //The pin to use is determined by: // ( pitch / ( Total number of notes / Total Number of Pins) ) double noteBin = noteModDouble / (12.0 / MY_NUM_PINS); //Cast back to int int pinIdx = (int)noteBin; //If pin is set to be turned on if( isOn ) { //If pin is currently available to play a note, or if currently playing channel can be overriden due to higher priority channel if( pinNotes[pinIdx] == -1 || pinChannels[pinIdx] > ev->data.note.channel ) { if( (pinChannels[pinIdx] > ev->data.note.channel ) && pinNotes[pinIdx] != -1) { printf("OVERRIDING CHANNEL %i for %i\n", pinChannels[pinIdx], ev->data.note.channel); } //Write to the pin, save the note to pinNotes //printf("Pin %i - %s %i %i \n", pinIdx, isOn ? "on" : "off", ev->data.note.note, ev->data.note.channel); digitalWrite(pinIdx, 1); pinNotes[pinIdx] = ev->data.note.note; pinChannels[pinIdx] = ev->data.note.channel; } } //Pin is to be turned off else { //If this is the note that turned the pin on.. if( pinNotes[pinIdx] == ev->data.note.note && pinChannels[pinIdx] == ev->data.note.channel ) { //Write to the pin, indicate that pin is available //printf("Pin %i - %s %i %i \n", pinIdx, isOn ? "on" : "off", ev->data.note.note, ev->data.note.channel); digitalWrite(pinIdx, 0); pinNotes[pinIdx] = -1; pinChannels[pinIdx] = INT_MAX; } } } } else { printf("Unhandled event %2d\n", ev->type); } snd_seq_free_event(ev); }