Sunday, January 19, 2014

MIDI2VC code update, addition of "MIDI Key Bucket"

I've added some functionality to the MIDI2VC code. The problem that needed fixing was when multiple MIDI keys where pressed simultaneously, this could confuse the system. What I've added now is a priority system, where the lowest key pressed is the one the generates an output voltage. This is similar to what is used in the Mini Moog. In the future, I might implement a function for choosing one of several priority systems, but I'll need a PIC with more IO's to do that.
I can't test this functionality very well right now, since MIDI Ox only let's me play two simultaneous keys, and I haven't gotten my real MIDI keyboard to work with the MIDI2VC yet. I have tried sending manual MIDI keys, using UART, and that works as expected.
 Here are the updated functions.

   
 //***********************************************************  
 //**************Function processUARTBuffer*******************  
 //Interprets UARTBuffer, toggles LED and sends appropiate  
 //I2C data to DAC  
 //***********************************************************  
   
 void processUARTBuffer(int UARTBufferF[])  
 {  
   extern int i2cData[];  
   extern int MIDISimKeysPressed;  
   const int DACLookupTable[127] = {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, 0x017, 0x072, 0x0C2, 0x116, 0x169, 0x1B9, 0x20C, 0x25F, 0x2B0, 0x305, 0x356, 0x3A9, 0x3FC, 0x44D, 0x4A2, 0x4F5, 0x547, 0x5C7, 0x5EF, 0x63E, 0x691, 0x6E7, 0x739, 0x78E};  
   int DACValue;  
   int DACValue;  
   
   //If UART symbol is MIDI "Note on", light LED and  
   //send lowest data in MIDI key bucket to DAC  
   if (((UARTBufferF[0] & 0xF0) == 0x90) && (UARTBufferF[2] != 0x00))  
   {  
     //Keeps track of number of keys simultaneously pressed  
     MIDISimKeysPressed++;  
   
     pushMIDISimKeysBucket(UARTBufferF[1]);  
   
   
     DACValue = DACLookupTable[isLowestInMIDISimKeysBucket()];  
     i2cData[1] = (DACValue & 0xFF);  
     i2cData[0] = ((DACValue & 0x0F00) >> 8);  
   
     lightLED();  
     i2cDataToBeSent = 1;  
   }  
   
     //If UART symbol is MIDI "Note off", check if there are  
     //other notes in bucket and send their lowest data to DAC, otherwise  
     //turn off LED and send zeros to DAC  
   else if (((UARTBufferF[0] & 0xF0) == 0x80) || (UARTBufferF[2] == 0x00))  
   {  
     MIDISimKeysPressed--;  
     popMIDISimKeysBucket(UARTBufferF[1]);  
   
     if (MIDISimKeysPressed == 0)  
     {  
       i2cData[0] = 0x00;  
       i2cData[1] = 0x00;  
   
       unlightLED();  
       i2cDataToBeSent = 1;  
     }  
     else if (MIDISimKeysPressed > 0)  
     {  
       DACValue = DACLookupTable[isLowestInMIDISimKeysBucket()];  
       i2cData[1] = (DACValue & 0xFF);  
       i2cData[0] = ((DACValue & 0x0F00) >> 8);  
   
       i2cDataToBeSent = 1;  
     }  
   }  
   
   return;  
 }  
   
 //***********************************************************  
 //**************Function pushMIDISimKeysBucket***************  
 //Function for pushing a MIDI key int into the MIDI bucket.  
 //The MIDI bucket is a data sctructure that holds a number  
 //of ints. The pushed int is placed in the first available  
 //empty array slot, in no other order. Empty slots are valued  
 //-1, since 0 is a valid key value.  
 //Each value in the bucket (except -1) is unique, if not, there  
 //is something wrong. No error checking for this is implemented.  
 //***********************************************************  
   
 void pushMIDISimKeysBucket(int midiKey)  
 {  
   extern int MIDISimKeysBucket[];  
   
   //place MIDI key value in first -1 (empty) instance  
   int i = 0;  
   while (i < MIDISimKeysBucketSize)  
   {  
     if (MIDISimKeysBucket[i] == -1)  
     {  
       MIDISimKeysBucket[i] = midiKey;  
       i = MIDISimKeysBucketSize;  
     }  
     else  
     {  
       i++;  
     }  
   }  
   
   return;  
 }  
   
 //***********************************************************  
 //**************Function popMIDISimKeysBucket***************  
 //Function for removing value from bucket.  
 //***********************************************************  
   
 void popMIDISimKeysBucket(int midiKey)  
 {  
   extern int MIDISimKeysBucket[];  
   
   //Find value in array and replace with -1  
   //If no value is found, do nothing  
   int i = 0;  
   while (i < MIDISimKeysBucketSize)  
   {  
     if (MIDISimKeysBucket[i] == midiKey)  
     {  
       MIDISimKeysBucket[i] = -1;  
       i = MIDISimKeysBucketSize;  
     }  
     else  
     {  
       i++;  
     }  
   }  
   
   return;  
 }  
   
   
 //***********************************************************  
 //**************Function isLowestInMIDISimKeysBucket*********  
 //Returns the lowest value in the bucket  
 //***********************************************************  
   
 int isLowestInMIDISimKeysBucket()  
 {  
   extern int MIDISimKeysBucket[];  
   int lowestKey = 0x7f; //Highest legal MIDI key  
   
   
   //Finds lowest key, that isn't -1, in bucket  
   int i = 0;  
   while (i < MIDISimKeysBucketSize)  
   {  
     if ((MIDISimKeysBucket[i] < lowestKey) && (MIDISimKeysBucket[i] > -1))  
     {  
       lowestKey = MIDISimKeysBucket[i];  
     }  
     else  
     {  
       i++;  
     }  
   }  
   
   return lowestKey;  
 }  
   

No comments:

Post a Comment