Difference between revisions of "How to create and add a new function to the LXR"

From Sonic Potions Wiki
Jump to: navigation, search
 
(13 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 +
        Where to get the source:
 +
        https://github.com/SonicPotions/LXR
 +
 
This is a DRAFT !!!! I will correct it during the next days :-)
 
This is a DRAFT !!!! I will correct it during the next days :-)
  
* GOAL, we will implement a function that change the length of all the tracks at once. A sort of loop/divide (like on the arturia spark machine). We will add a special knob in the PERF menu, when this knob is turned, the length of the tracks changes from 1 to 16 making the whole pattern ROLL :-)
+
* GOAL:
 
+
* We will implement a function that change the length of all the tracks at once. A sort of loop/divide (like on the arturia spark machine). We will add a special knob in the PERF menu: when this knob is turned, the length of the tracks changes from 1 to 16 making the whole pattern ROLL :-)
* We start by adding a new knob 'LEN' (for Length) in  the PERF menu on the LCD display.
+
* another aim is to make you look at the difrent files, inspect them and start undestand the logic of the LXR drum system that Julian made :-)
 
 
* Open the file ''''Parameters.h'''', we first declare our parameter and its type.
 
  
* Add in the section: 'enum ParamEnums' your new parameter. In our case we will add the parameter : PAR_LOOP
+
* First step, we start by adding a new knob 'LEN' (for Length) in the PERF menu on the LCD display.
  
* You have to add all the new parameters right after a dedicated section in the code declaration (otherwise you want link later the knob with the function you want to execute):
+
* Open the file ''''Parameters.h'''', Add in the section 'enum ParamEnums' the new parameter. In our case : PAR_LOOP
  
 
         example:  
 
         example:  
Line 21: Line 22:
 
         PAR_MIDI_NOTE5,
 
         PAR_MIDI_NOTE5,
 
         PAR_MIDI_NOTE6,
 
         PAR_MIDI_NOTE6,
         PAR_MIDI_NOTE7,
+
         PAR_MIDI_NOTE7, // <--- YOUR parameters comes right after thoses lines...
        // YOUR parameters comes right after thoses lines...
+
        // You have to add all the new parameters right after a dedicated section in the code declaration
                 
+
         //(otherwise you want link later the knob with the function you want to execute):
         // rstephane MY VALUES ADDED FOR LOOP FUNCTION
+
         '''PAR_LOOP,'''      
         PAR_LOOP,     
 
 
         ...
 
         ...
  
  
* We need to open the '''menu.c''' file. we want that our knob display a name 'LEN'
+
* We need to open the '''menu.c''' file. we declare our parameter and its type :
  
  
Line 54: Line 54:
 
            
 
            
 
             // YOUR PARAMETER comes right here and not elsewhere!!!!!
 
             // YOUR PARAMETER comes right here and not elsewhere!!!!!
             /*PAR_LOOP*/                      DTYPE_1B16, // Values goes from 1 to 16 steps
+
             /'''*PAR_LOOP*/                      DTYPE_1B16,''' // Values goes from 1 to 16 steps
 
              
 
              
 
             /*PAR_ROLL*/                        DTYPE_MENU | (MENU_ROLL_RATES<<4),
 
             /*PAR_ROLL*/                        DTYPE_MENU | (MENU_ROLL_RATES<<4),
Line 93: Line 93:
 
* This array hold the whole menu structure. each voice has different pages. The pages hold the top and bottom enums to indicate which values and descriptors to show
 
* This array hold the whole menu structure. each voice has different pages. The pages hold the top and bottom enums to indicate which values and descriptors to show
  
* in the section: const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM ... add your MENU  
+
* in the section: const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM ... add your MENU (we want that our knob display a name 'LEN')
  
* in our case, we have:
+
* in our case, we add TEXT_LOOP and PAR_ROLL:
  
 
         const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM =
 
         const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM =
Line 108: Line 108:
 
         ...
 
         ...
 
         //Page 10
 
         //Page 10
//---------------- Performance Mode Menu pages ---------------------------
+
        //---------------- Performance Mode Menu pages ---------------------------
//These pages are shown when the selected mode is the "mute/pattern select" page
+
        //These pages are shown when the selected mode is the "mute/pattern select" page
//there is only one page with subpages shown for the whole mode
+
        //there is only one page with subpages shown for the whole mode
{
+
        {
{
+
        {
TEXT_SHUFFLE, TEXT_ROLL_SPEED, TEXT_X_FADE, TEXT_SAMPLE_RATE, '''TEXT_LOOP''', TEXT_EMPTY,
+
        TEXT_SHUFFLE, TEXT_ROLL_SPEED, TEXT_X_FADE, TEXT_SAMPLE_RATE, '''TEXT_LOOP''', TEXT_EMPTY,
PAR_SHUFFLE, '''PAR_ROLL''', PAR_MORPH, PAR_VOICE_DECIMATION_ALL, PAR_LOOP,
+
        PAR_SHUFFLE, '''PAR_ROLL''', PAR_MORPH, PAR_VOICE_DECIMATION_ALL, PAR_LOOP,
},
+
        },
 
         ...
 
         ...
  
  
* We need now to declare the TEXT_LOOP and PAR_LOOP in other files :-)
+
* We also need to declare the TEXT_LOOP and PAR_LOOP in other files :-)
  
* Open file '''menu.h''', and go to section  
+
* Open file '''menu.h''', go to section 'NamesEnum', add at the end the text 'TEXT_LOOP" :
  
 
         enum NamesEnum
 
         enum NamesEnum
Line 133: Line 133:
 
         TEXT_MOD_AMOUNT,                 
 
         TEXT_MOD_AMOUNT,                 
 
         ....
 
         ....
 
* Add at the end, the text 'TEXT_LOOP" :
 
       
 
 
         ....
 
         ....
 
         TEXT_BAR_RESET_MODE,
 
         TEXT_BAR_RESET_MODE,
Line 142: Line 139:
 
         NUM_NAMES
 
         NUM_NAMES
 
         };
 
         };
 
+
                               
* Open '''Cc2Text.c''' file and under the section
 
 
 
//Voice 1 - Drum 1
 
//  1 Oscillator
 
{TEXT_COARSE, PAR_COARSE1},                        //2
 
{TEXT_FINE, PAR_FINE1},
 
{TEXT_WAVEFORM, PAR_OSC_WAVE_DRUM1},
 
{TEXT_RND_VOICE, PAR_RND_VOICE1}, // rstephane : added random button                                       
 
                                       
 
  
 
* Open the '''menu.c''' file, go to section '''valueNames'''
 
* Open the '''menu.c''' file, go to section '''valueNames'''
Line 164: Line 152:
 
                 {SHORT_BAR_RESET_MODE, CAT_SEQUENCER, LONG_BAR_RESET_MODE}, // TEXT_BAR_RESET_MODE
 
                 {SHORT_BAR_RESET_MODE, CAT_SEQUENCER, LONG_BAR_RESET_MODE}, // TEXT_BAR_RESET_MODE
 
                 {SHORT_CHANNEL, CAT_MIDI, LONG_MIDI_CHANNEL}, // TEXT_MIDI_CHAN_GLOBAL
 
                 {SHORT_CHANNEL, CAT_MIDI, LONG_MIDI_CHANNEL}, // TEXT_MIDI_CHAN_GLOBAL
                 {SHORT_LOOP, CAT_SEQUENCER, LONG_LOOP}, // rstephane: TEXT_LOOP
+
                 '''{SHORT_LOOP, CAT_SEQUENCER, LONG_LOOP}, // We declare it at the end of the section :-)''
 
          
 
          
  
* We NEED declare it at the end of the section :-)
 
 
* now, open the '''MenuText.h''' file to declare the '''short and long version of the TEXT''' (TEXT_LOOP)
 
* now, open the '''MenuText.h''' file to declare the '''short and long version of the TEXT''' (TEXT_LOOP)
 
* go to section 'const char longNames[][16] PROGMEM = ' and 'const char shortNames[][4] PROGMEM  = '
 
* go to section 'const char longNames[][16] PROGMEM = ' and 'const char shortNames[][4] PROGMEM  = '
* add the parameters:
+
* add the parameters marked in bold:
  
 
         const char shortNames[][4] PROGMEM  =  
 
         const char shortNames[][4] PROGMEM  =  
Line 184: Line 171:
 
         {"co2"},  // trigger clock out2 ppq
 
         {"co2"},  // trigger clock out2 ppq
 
         {"pcr"}, // pattern change resets bar counter
 
         {"pcr"}, // pattern change resets bar counter
         {"LEN"}, // rstephane: LEN for LOOP :-)
+
         '''{"LEN"}''', // rstephane: LEN for LOOP :-)
 
          
 
          
 
         };         
 
         };         
Line 201: Line 188:
 
         {"Gate Mode"},
 
         {"Gate Mode"},
 
         {"PCReset" }, // reset bar counter on manual pattern change
 
         {"PCReset" }, // reset bar counter on manual pattern change
         {"Loop"}, // rstephane: LOOP LONG text
+
         '''{"Loop"}''', // rstephane: LOOP LONG text
 
         };
 
         };
 
   
 
   
  
* If you want you can already compile and see the results under the menu PERF menu (normally under the second page, your should see 'LEN' on the first knob).
+
* If you want you can already compile and see the results: under the PERF sub menu, your should see 'LEN' on the first knob.
 
 
 
* Now, '''we will create our function'''
 
* Now, '''we will create our function'''
* We will add a link between this function and our knob.
 
 
 
* open '''midimessage.h''' file
 
* open '''midimessage.h''' file
  
  
//for all parameters above 127 <- our case
+
        //for all parameters above 127 <- our case
enum
+
        enum
{
+
        {
 
         ....
 
         ....
 
         // Again, place your parameter at a special place, right after the section:
 
         // Again, place your parameter at a special place, right after the section:
Line 227: Line 211:
 
          
 
          
 
         // YOUR PARAMETER comes right here and not elsewhere!!!!!
 
         // YOUR PARAMETER comes right here and not elsewhere!!!!!
         // rstephane MY VALUES ADDED FOR RANDOM FUNCTION
+
         // When the knob is turned , it send the CC2_LOOP message
        // rstephane : RND button :-) for CASE switch in MidiParser.C
+
         '''CC2_LOOP,'''
         CC2_RND_VOICE1,
 
 
         ....
 
         ....
}Param2Enums;
+
        }
 +
        Param2Enums;
 +
 
 +
* open  '''MidiParser.c''' file
  
open
+
        //-----------------------------------------------------------
* MidiParser.c
+
        /** handle all incoming CCs and invoke action*/
//-----------------------------------------------------------
+
        void '''midiParser_ccHandler'''(MidiMsg msg, uint8_t updateOriginalValue)
/** handle all incoming CCs and invoke action*/
+
        {
void midiParser_ccHandler(MidiMsg msg, uint8_t updateOriginalValue)
 
{
 
 
          
 
          
 
         ...
 
         ...
Line 261: Line 245:
  
 
         ...
 
         ...
        case CC2_MUTE_1:
+
                        case CC2_MUTE_1:
 
                         case CC2_MUTE_2:
 
                         case CC2_MUTE_2:
 
                         case CC2_MUTE_3:
 
                         case CC2_MUTE_3:
Line 281: Line 265:
 
                         }
 
                         }
 
                                 break;
 
                                 break;
                        // rstephane MY FUNCTIONS
+
                            //
                        // rstephane : Handle the RND button
+
                            // rstephane MY FUNCTIONS
                        case CC2_RND_VOICE1:
+
                            '''case CC2_LOOP:
                                if(msg.data2 == 1)
+
                                  if(msg.data2 == 16) // reset the loop !
                                {
+
                                  { // we stop the loop effect and
                                        // RND is ON
+
                                          // go back to prevoious track lenght
                                        randomDrumVoice123(0); //voice1 = 0, voice2 = 1 etc...
+
                                          seq_setLoopLength(16);
                                }
+
                                  }
                                break;      
+
                                  else
                                                       
+
                                  { // we change the tracks lenght
 +
                                          seq_setLoopLength(msg.data2);
 +
                                  }
 +
                                  break;'''
 +
                                     
 
                         default:
 
                         default:
 
                                 break;
 
                                 break;
Line 297: Line 285:
 
                          
 
                          
 
                          
 
                          
+
 
open drumvoice.h
 
  
 +
* open '''sequencer.h''' file, add the line : 
 +
        void seq_setLoopLength(uint8_t length);
  
// rstephane : my functions
 
//random all the parameters for voice 1 2 and 3
 
void randomDrumVoice123(const uint8_t voiceNr); 
 
  
 +
* open '''sequencer.c''' file, add the function:
 +
        void seq_setLoopLength(uint8_t length)
 +
        {
 +
        uint8_t i;
 +
        // we set the new Loop Track Lenght
 +
        for(i=0;i<NUM_TRACKS;i++) {
 +
                seq_setTrackLength(i, length);
 +
        }
 +
        }
  
 
+
* compile !
+
+
* upload on the machine with the new firmware
open drumvoice.c
+
* test!
 
 
 
 
// rstephane : pour random functions
 
#include "valueShaper.h"
 
 
 
+
 
 
 
//---------------------------------------------------
 
// rstephane : my functions
 
//random all the parameters for voice 1 2 and 3
 
//---------------------------------------------------
 
void randomDrumVoice123(const uint8_t voiceNr)
 
{
 
                uint8_t rndData; // , new_min, new_max;
 
                // uint32_t rndDataTemp, old_min, old_max;
 
                // COARSE
 
                rndData = (uint8_t) GetRngValue();
 
                //clear upper nibble
 
                voiceArray[voiceNr].osc.midiFreq &= 0x00ff;
 
                //set upper nibble
 
                voiceArray[voiceNr].osc.midiFreq |= rndData << 8;
 
                osc_recalcFreq(&voiceArray[voiceNr].osc);
 
                //OSC1_DIST:
 
                rndData = (uint8_t) GetRngValue();
 
#if USE_FILTER_DRIVE
 
                voiceArray[voiceNr].filter.drive = 0.5f + (rndData/127.f) *6;
 
#else
 
                setDistortionShape(&voiceArray[voiceNr].distortion,rndData);
 
#endif                       
 
               
 
}
 

Latest revision as of 11:04, 8 June 2015

       Where to get the source:
       https://github.com/SonicPotions/LXR

This is a DRAFT !!!! I will correct it during the next days :-)

  • GOAL:
  • We will implement a function that change the length of all the tracks at once. A sort of loop/divide (like on the arturia spark machine). We will add a special knob in the PERF menu: when this knob is turned, the length of the tracks changes from 1 to 16 making the whole pattern ROLL :-)
  • another aim is to make you look at the difrent files, inspect them and start undestand the logic of the LXR drum system that Julian made :-)
  • First step, we start by adding a new knob 'LEN' (for Length) in the PERF menu on the LCD display.
  • Open the file 'Parameters.h', Add in the section 'enum ParamEnums' the new parameter. In our case : PAR_LOOP
       example: 
       
       enum ParamEnums = {
       ...
       PAR_MIDI_NOTE1,
       PAR_MIDI_NOTE2,
       PAR_MIDI_NOTE3,
       PAR_MIDI_NOTE4,
       PAR_MIDI_NOTE5,
       PAR_MIDI_NOTE6,
       PAR_MIDI_NOTE7, // <--- YOUR parameters comes right after thoses lines...
       // You have to add all the new parameters right after a dedicated section in the code declaration 
       //(otherwise you want link later the knob with the function you want to execute):
       PAR_LOOP,     
       ...


  • We need to open the menu.c file. we declare our parameter and its type :


       menu.c
       //---------------------------------------------------------------
       // Parameter types. These correspond with ParamEnums and entries in parameter_values
       const enum Datatypes PROGMEM parameter_dtypes[NUM_PARAMS] = {
           /*PAR_NONE*/                         DTYPE_0B127,                                                        // 0
           /*PAR_OSC_WAVE_DRUM1*/         DTYPE_MENU | (MENU_WAVEFORM<<4),
           /*PAR_OSC_WAVE_DRUM2*/         DTYPE_MENU | (MENU_WAVEFORM<<4),
           /*PAR_OSC_WAVE_DRUM3*/         DTYPE_MENU | (MENU_WAVEFORM<<4),
           /*PAR_OSC_WAVE_SNARE*/  DTYPE_MENU | (MENU_WAVEFORM<<4),
       ....
  • Place your parameter at a special place, right after the section:
           /*PAR_MIDI_NOTE1*/                DTYPE_NOTE_NAME,
           /*PAR_MIDI_NOTE2*/                DTYPE_NOTE_NAME,
           /*PAR_MIDI_NOTE3*/                DTYPE_NOTE_NAME,
           /*PAR_MIDI_NOTE4*/                DTYPE_NOTE_NAME,
           /*PAR_MIDI_NOTE5*/                DTYPE_NOTE_NAME,
           /*PAR_MIDI_NOTE6*/                DTYPE_NOTE_NAME,
           /*PAR_MIDI_NOTE7*/                DTYPE_NOTE_NAME,
          
           // YOUR PARAMETER comes right here and not elsewhere!!!!!
           /*PAR_LOOP*/                      DTYPE_1B16, // Values goes from 1 to 16 steps
           
           /*PAR_ROLL*/                         DTYPE_MENU | (MENU_ROLL_RATES<<4),
           /*PAR_MORPH*/                         DTYPE_0B255,
           ...
               

Here the list of parameters you can choose from...

       Type of parameters:
       //-----------------------------------------------------------------
       enum Datatypes
       {
       DTYPE_0B255,        //0:255
       DTYPE_0B127,        //0-127
       DTYPE_PM100,        //-100:100
       DTYPE_MENU,                //text type outputs 
       DTYPE_PM63,                //-63 <-> 63
       DTYPE_1B16,                //1-16
       DTYPE_ON_OFF,        //0-1
       DTYPE_MIX_FM,        //0-1
       DTYPE_TARGET_SELECTION_LFO,
       DTYPE_TARGET_SELECTION_VELO,        
       DTYPE_VOICE_LFO,
       DTYPE_AUTOM_TARGET,
       DTYPE_0b1,
       DTYPE_NOTE_NAME, // --AS eg C#0, D 1 for note name
       DTYPE_0B15,                //0-15
       /*15*/
       /*16*/
       // --AS warning, we can only have 16 on this list the way things are laid out
       };
  • oki, once this done, we need to fill other information in the code
  • Open the file menuPages.h
  • This array hold the whole menu structure. each voice has different pages. The pages hold the top and bottom enums to indicate which values and descriptors to show
  • in the section: const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM ... add your MENU (we want that our knob display a name 'LEN')
  • in our case, we add TEXT_LOOP and PAR_ROLL:
       const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM =
       {
       //page 1 - Voice 1
       {
       //sub page 1 - Oscillator
       {
       TEXT_COARSE,        TEXT_FINE,        TEXT_WAVEFORM,                TEXT_RND_VOICE,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,
       PAR_COARSE1,        PAR_FINE1,        PAR_OSC_WAVE_DRUM1,        PAR_RND_VOICE1,PAR_NONE,PAR_NONE,PAR_NONE,PAR_NONE
               },        
       ...
       //Page 10
       //---------------- Performance Mode Menu pages ---------------------------
       //These pages are shown when the selected mode is the "mute/pattern select" page
       //there is only one page with subpages shown for the whole mode
       {
       {		
       TEXT_SHUFFLE,	TEXT_ROLL_SPEED,	TEXT_X_FADE,	TEXT_SAMPLE_RATE,		 TEXT_LOOP,	TEXT_EMPTY,
       PAR_SHUFFLE,	PAR_ROLL,			PAR_MORPH,		PAR_VOICE_DECIMATION_ALL,		PAR_LOOP,
       },
       ...


  • We also need to declare the TEXT_LOOP and PAR_LOOP in other files :-)
  • Open file menu.h, go to section 'NamesEnum', add at the end the text 'TEXT_LOOP" :
       enum NamesEnum
       {
       TEXT_EMPTY = 0,                                        //0
       TEXT_COARSE,
       TEXT_FINE,
       TEXT_ATTACK,
       TEXT_DECAY,
       TEXT_PITCH_DECAY,
       TEXT_MOD_AMOUNT,                
       ....
       ....
       TEXT_BAR_RESET_MODE,
       TEXT_MIDI_CHAN_GLOBAL,
       TEXT_LOOP,        // rstephane: LOOP text 
       NUM_NAMES
       };
                                
  • Open the menu.c file, go to section valueNames
       const Name valueNames[NUM_NAMES] PROGMEM =
       {
               {SHORT_EMPTY,CAT_EMPTY,LONG_EMPTY},
               ....
  • Add the following information:
               ....
               {SHORT_BAR_RESET_MODE, CAT_SEQUENCER, LONG_BAR_RESET_MODE}, // TEXT_BAR_RESET_MODE
               {SHORT_CHANNEL, CAT_MIDI, LONG_MIDI_CHANNEL}, // TEXT_MIDI_CHAN_GLOBAL
               '{SHORT_LOOP, CAT_SEQUENCER, LONG_LOOP}, // We declare it at the end of the section :-)
       
  • now, open the MenuText.h file to declare the short and long version of the TEXT (TEXT_LOOP)
  • go to section 'const char longNames[][16] PROGMEM = ' and 'const char shortNames[][4] PROGMEM = '
  • add the parameters marked in bold:
       const char shortNames[][4] PROGMEM  = 
       {
       {""},
       {"coa"},
       {"fin"},
       {"atk"},
       {"dec"},
       {"eg2"},
       ....
       
       {"co2"},  // trigger clock out2 ppq
       {"pcr"}, // pattern change resets bar counter
       {"LEN"}, // rstephane: LEN for LOOP :-)
       
       };        
       const char longNames[][16] PROGMEM = 
       {
       {""},
       //01234567
       {"Coarse"},
       {"Fine"},
       {"Attack"},
       {"Decay"},
       {"Amount"},
       ....
       {"Out2 PPQ"},
       {"Gate Mode"},
       {"PCReset" }, // reset bar counter on manual pattern change
       {"Loop"}, // rstephane: LOOP LONG text
       };

  • If you want you can already compile and see the results: under the PERF sub menu, your should see 'LEN' on the first knob.
  • Now, we will create our function
  • open midimessage.h file


       //for all parameters above 127 <- our case
       enum
       {
       ....
       // Again, place your parameter at a special place, right after the section:
       CC2_MIDI_NOTE1,
       CC2_MIDI_NOTE2,
       CC2_MIDI_NOTE3,
       CC2_MIDI_NOTE4,
       CC2_MIDI_NOTE5,
       CC2_MIDI_NOTE6,
       CC2_MIDI_NOTE7, // s/b 111 i think
       
       // YOUR PARAMETER comes right here and not elsewhere!!!!!
       // When the knob is turned , it send the CC2_LOOP message
       CC2_LOOP,
       ....
       }
       Param2Enums;
  • open MidiParser.c file
       //-----------------------------------------------------------
       /** handle all incoming CCs and invoke action*/
       void midiParser_ccHandler(MidiMsg msg, uint8_t updateOriginalValue)
       {
       
       ...
       
       else //MIDI_CC2
       {
               const uint16_t paramNr = msg.data1+1 + 127;
               if(updateOriginalValue) {
                       midiParser_originalCcValues[paramNr] = msg.data2;
               }
               switch(msg.data1)
               {
                       case CC2_TRANS1_WAVE:
                                       voiceArray[0].transGen.waveform = msg.data2;
                               break;
                       case CC2_TRANS1_VOL:
                               voiceArray[0].transGen.volume = msg.data2/127.f;
                               break;
       ...
                       case CC2_MUTE_1:
                       case CC2_MUTE_2:
                       case CC2_MUTE_3:
                       case CC2_MUTE_4:
                       case CC2_MUTE_5:
                       case CC2_MUTE_6:
                       case CC2_MUTE_7:
                       {
                               const uint8_t voiceNr = msg.data1 - CC2_MUTE_1;
                               if(msg.data2 == 0)
                               {
                                       seq_setMute(voiceNr,0);
                               }
                               else
                               {
                                       seq_setMute(voiceNr,1);
                               }
                       }
                               break;
                           //
                           // rstephane MY FUNCTIONS
                           case CC2_LOOP:
                                  if(msg.data2 == 16)  // reset the loop ! 
                                  {	// we stop the loop effect and
                                         // go back to prevoious track lenght
                                         seq_setLoopLength(16);
                                  }
                                  else
                                  {	// we change the tracks lenght
                                         seq_setLoopLength(msg.data2);
                                  }
                                  break;			
                                      
                       default:
                               break;
                               
                       ....
                       
                       
  • open sequencer.h file, add the line :
       void seq_setLoopLength(uint8_t length);


  • open sequencer.c file, add the function:
       void seq_setLoopLength(uint8_t length)
       {
       uint8_t i;
       // we set the new Loop Track Lenght
       for(i=0;i<NUM_TRACKS;i++) {
               seq_setTrackLength(i, length);	
       }
       }
  • compile !
  • upload on the machine with the new firmware
  • test!