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

From Sonic Potions Wiki
Jump to: navigation, search
Line 22: Line 22:
 
         // You have to add all the new parameters right after a dedicated section in the code declaration  
 
         // 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):
 
         //(otherwise you want link later the knob with the function you want to execute):
         PAR_LOOP,     
+
         '''PAR_LOOP,'''      
 
         ...
 
         ...
  
Line 51: Line 51:
 
            
 
            
 
             // 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 156: Line 156:
 
                 {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  = '
Line 176: Line 175:
 
         {"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 193: Line 192:
 
         {"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
 
         };
 
         };
 
   
 
   
Line 219: Line 218:
 
          
 
          
 
         // YOUR PARAMETER comes right here and not elsewhere!!!!!
 
         // YOUR PARAMETER comes right here and not elsewhere!!!!!
         CC2_LOOP,
+
         '''CC2_LOOP,'''
 
         ....
 
         ....
 
         }
 
         }
Line 228: Line 227:
 
         //-----------------------------------------------------------
 
         //-----------------------------------------------------------
 
         /** handle all incoming CCs and invoke action*/
 
         /** handle all incoming CCs and invoke action*/
         void midiParser_ccHandler(MidiMsg msg, uint8_t updateOriginalValue)
+
         void '''midiParser_ccHandler'''(MidiMsg msg, uint8_t updateOriginalValue)
 
         {
 
         {
 
          
 
          
Line 274: Line 273:
 
                             //
 
                             //
 
                             // rstephane MY FUNCTIONS
 
                             // rstephane MY FUNCTIONS
                             case CC2_LOOP:
+
                             '''case CC2_LOOP:
 
                                   if(msg.data2 == 16)  // reset the loop !  
 
                                   if(msg.data2 == 16)  // reset the loop !  
 
                                   { // we stop the loop effect and
 
                                   { // we stop the loop effect and
Line 284: Line 283:
 
                                           seq_setLoopLength(msg.data2);
 
                                           seq_setLoopLength(msg.data2);
 
                                   }
 
                                   }
                                   break;
+
                                   break;'''
 
                                        
 
                                        
 
                         default:
 
                         default:
Line 293: Line 292:
 
                          
 
                          
  
* open '''sequencer.h''' file
+
* open '''sequencer.h''' file, add the line :  
* add the function  
 
 
         void seq_setLoopLength(uint8_t length);
 
         void seq_setLoopLength(uint8_t length);
  
  
* open '''sequencer.c''' file, add:
+
* open '''sequencer.c''' file, add the function:
 
         void seq_setLoopLength(uint8_t length)
 
         void seq_setLoopLength(uint8_t length)
 
         {
 
         {

Revision as of 23:32, 11 May 2014

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 have:
       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 need now 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 Cc2Text.c file and under the section (i need to explain and complete this section)
      {TEXT_COARSE, PAR_COARSE1},                         //2
      {TEXT_FINE, PAR_FINE1},
      {TEXT_WAVEFORM, PAR_OSC_WAVE_DRUM1},
      {TEXT_LOOP, PAR_LOOP}, // rstephane : added LOOP button <- no really needed, well pass trough this step                                   
                                       
  • 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:
       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 menu PERF menu (normally under the second page, your should see 'LEN' on the first knob).
  • Now, we will create our function
  • We will add a link between this function and our knob.
  • 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!!!!!
       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!