Exemplo n.º 1
0
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
Exemplo n.º 2
0
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);
}