[sdiy] MIDI receiving interrupt function.. a promissing start..

Jean-Pierre Desrochers jpdesroc at oricom.ca
Mon Apr 13 18:01:01 CEST 2020


Hi all,

 

Happy to see this list still alive in these dark moments of COVID19..

 

Anyway I wanted to share with you the actual coding I worked on

on the last weeks. This is the actual MIDI Rx interrupt c code I managed

to tweak and this gives very good results. Fast, efficient and reliable.

I tested my 6 voices poly M100  MIDIDAC
<http://www.arcenson.com/projects/Modular/M100_MIDI_Interface/Module_picture
s/M100_MIDI_interface_assembled_front.jpg>  module's MIDI reception using an
external sequencer (Cakewalk SONAR X3)

through a MIDI cable, running at a rate of around 180bpm! with a polyphonic
Bach song MIDI file.

And this with 4 added continuously changing MIDI layers (velocities, after
touch, Breath, CC)

The result was great ! No losses at all. All the notes clearly received with
no stuck notes.

Please note this code IGNORES ALL THE INCOMING REAL TIME or SYSEX bytes.

Only MIDI voice messages commands are processed. This is what I only needed.

The complete MIDIDAC C code is available here
<http://www.arcenson.com/projects/Modular/M100_MIDI_Interface/Hitech_C_code_
files/MIDIDAC_MPLAB_X_code_files/> .

 

I wish I had these code lines many months ago and hope this will help new
MIDI developers like me..

Here is my interrupt lines:

 

//////////////////////////////////

// ---------------------------- //

//  interrupt service routine   //

// ---------------------------- //

//////////////////////////////////                              

 

void interrupt tmr0_USART_isr (void) 

 {

  unsigned char x;  // intermediate byte value

 

  

    // RS232 receive interrupt                       

  if (RCIF == TRUE && RCIE == TRUE) 

   {                                                                      

 

    if (OERR == TRUE)      // overrun, reset UART

     {                                                      

      CREN = FALSE;     // disable UART

      CREN = TRUE;      // re-enable UART

     }                                         

      

    

    else

     { // Good Rx byte

      x = RCREG;           

      

  //////////////////////////////////////////////////////

  ///////////////// Manage Status Byte /////////////////

  //////////////////////////////////////////////////////

  

      if(x & 0x80) // Bit 7 = 1 (Status byte)

       {

             if((x != 0xF6) & // Not a Real Time Message neither Tune
Request   

                (x != 0xF8) &                          

           (x != 0xFA) &                                  

           (x != 0xFB) &                                  

           (x != 0xFC) &                                          

           (x != 0xFE) &

           (x != 0xFF))

          {

           PendingMIDIStatusByteVal = x; // Here SYSEX Status (0xF0 & 0xF7)
can also be stored as PendingMIDIStatusByteVal

           MIDIThirdByteFlag = FALSE;    // to change the last active
'current' MIDI Status.                   

          }                              // Doing so the SYSEX trailing data
bytes will be differentiated

                                         // from other recognized data bytes
then ignored..

       }  // Bit 7 = 1 (Status byte)    

      

 

  //////////////////////////////////////////////////////

  ///////////////// Manage data Bytes //////////////////

  //////////////////////////////////////////////////////

  

      else // Bit 7 = 0    (data byte)

       {

        if(!MIDIThirdByteFlag) // MIDIThirdByteFlag = 0 ?

         {

          if(PendingMIDIStatusByteVal) // MIDI_Status greater than 0

           {

            // Checking for 0x8n, 0x9n, 0xAn, 0xBn, 0xEn channel messages


            if ( (PendingMIDIStatusByteVal < 0xC0) || 

               ( (PendingMIDIStatusByteVal >= 0xE0) &&
(PendingMIDIStatusByteVal <= 0xEF)) ) // Messages that have 2 data bytes
after Status

             {

              MIDIThirdByteFlag = TRUE; // 2 data bytes Status here

              PendingMIDISecondByteVal = x; // Store second byte..


             }      

            

            // Checking Status byte range: 0xC0 to 0xDF (Status with only
one data byte)

            else if (PendingMIDIStatusByteVal < 0xE0) 

             { 

              PendingMIDISecondByteVal = x; // Store second byte.. No third
byte   

              write_ring_buffer(PendingMIDIStatusByteVal);

              write_ring_buffer(PendingMIDISecondByteVal);

              PendingMIDISecondByteVal = 0; // Ready for next Status Message
or trailing Running Status 2 bytes chunk..

               }   

             

            else if (PendingMIDIStatusByteVal == 0xF2)  // Song Position
Pointer (followed by 2 data bytes..)

             {                                          // Here we must
catch the Status, data1, data2 then throw them away

              MIDIThirdByteFlag = TRUE;                       // after the
third byte is received

              PendingMIDISecondByteVal = x;


             }                  

           } 

         }

        

       else // MIDIThirdByteFlag = 1.. Third byte received here

        {

         MIDIThirdByteFlag = FALSE;     

         PendingMIDIThirdByteVal = x; 

         write_ring_buffer(PendingMIDIStatusByteVal);

         write_ring_buffer(PendingMIDISecondByteVal);

         write_ring_buffer(PendingMIDIThirdByteVal);         

         PendingMIDISecondByteVal = 0; // Ready for next Status Message or
trailing Running Status 2 bytes chunk.. 

         PendingMIDIThirdByteVal = 0;  // And keep the
PendingMIDIStatusByteVal in case it's a Runing Status not finished


        } 

       

       } // Bit 7 = 0 (data byte) 

 

      MIDI_ACTIVITY_LED = ON; //RC0 = 0; // Set led MIDI ACTIVITY to ON

      TMR0 = 0; // restart timer0

      T0IE=1;   // Activates overflow interrupt of TMR0 register

      RCIF = 0; // Erase MIDI RX flag

     

     } // Good Rx byte

        

  }

 

I'm sure someone in the list will see something I did not see (maybe not)
so.. let me know if it's the case.

Cheers !

Jean-Pierre

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://synth-diy.org/pipermail/synth-diy/attachments/20200413/17d49c1c/attachment.htm>


More information about the Synth-diy mailing list