<br />
<b>Warning</b>:  "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in <b>/www/htdocs/w0069e04/sonic-potions/wiki/includes/json/FormatJson.php</b> on line <b>297</b><br />
<br />
<b>Deprecated</b>:  Optional parameter $ellipsis declared before required parameter $getSubstring is implicitly treated as a required parameter in <b>/www/htdocs/w0069e04/sonic-potions/wiki/languages/Language.php</b> on line <b>3560</b><br />
<br />
<b>Deprecated</b>:  Optional parameter $adjustLength declared before required parameter $getSubstring is implicitly treated as a required parameter in <b>/www/htdocs/w0069e04/sonic-potions/wiki/languages/Language.php</b> on line <b>0</b><br />
<br />
<b>Deprecated</b>:  Optional parameter $prefix declared before required parameter $code is implicitly treated as a required parameter in <b>/www/htdocs/w0069e04/sonic-potions/wiki/languages/Language.php</b> on line <b>4478</b><br />
<br />
<b>Warning</b>:  "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in <b>/www/htdocs/w0069e04/sonic-potions/wiki/languages/LanguageConverter.php</b> on line <b>773</b><br />
<br />
<b>Deprecated</b>:  Return type of MediaWiki\Session\PHPSessionHandler::open($save_path, $session_name) should either be compatible with SessionHandlerInterface::open(string $path, string $name): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/www/htdocs/w0069e04/sonic-potions/wiki/includes/session/PHPSessionHandler.php</b> on line <b>199</b><br />
<br />
<b>Deprecated</b>:  Return type of MediaWiki\Session\PHPSessionHandler::close() should either be compatible with SessionHandlerInterface::close(): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/www/htdocs/w0069e04/sonic-potions/wiki/includes/session/PHPSessionHandler.php</b> on line <b>214</b><br />
<br />
<b>Deprecated</b>:  Return type of MediaWiki\Session\PHPSessionHandler::read($id) should either be compatible with SessionHandlerInterface::read(string $id): string|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/www/htdocs/w0069e04/sonic-potions/wiki/includes/session/PHPSessionHandler.php</b> on line <b>228</b><br />
<br />
<b>Deprecated</b>:  Return type of MediaWiki\Session\PHPSessionHandler::write($id, $dataStr) should either be compatible with SessionHandlerInterface::write(string $id, string $data): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/www/htdocs/w0069e04/sonic-potions/wiki/includes/session/PHPSessionHandler.php</b> on line <b>256</b><br />
<br />
<b>Deprecated</b>:  Return type of MediaWiki\Session\PHPSessionHandler::destroy($id) should either be compatible with SessionHandlerInterface::destroy(string $id): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/www/htdocs/w0069e04/sonic-potions/wiki/includes/session/PHPSessionHandler.php</b> on line <b>362</b><br />
<br />
<b>Deprecated</b>:  Return type of MediaWiki\Session\PHPSessionHandler::gc($maxlifetime) should either be compatible with SessionHandlerInterface::gc(int $max_lifetime): int|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/www/htdocs/w0069e04/sonic-potions/wiki/includes/session/PHPSessionHandler.php</b> on line <b>383</b><br />
<br />
<b>Deprecated</b>:  Return type of Wikimedia\Rdbms\IResultWrapper::current() should either be compatible with Iterator::current(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/www/htdocs/w0069e04/sonic-potions/wiki/includes/libs/rdbms/database/resultwrapper/IResultWrapper.php</b> on line <b>70</b><br />
<br />
<b>Deprecated</b>:  Return type of Wikimedia\Rdbms\IResultWrapper::next() should either be compatible with Iterator::next(): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/www/htdocs/w0069e04/sonic-potions/wiki/includes/libs/rdbms/database/resultwrapper/IResultWrapper.php</b> on line <b>80</b><br />
<br />
<b>Deprecated</b>:  Return type of Wikimedia\Rdbms\IResultWrapper::key() should either be compatible with Iterator::key(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/www/htdocs/w0069e04/sonic-potions/wiki/includes/libs/rdbms/database/resultwrapper/IResultWrapper.php</b> on line <b>75</b><br />
<br />
<b>Deprecated</b>:  Return type of Wikimedia\Rdbms\ResultWrapper::valid() should either be compatible with Iterator::valid(): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/www/htdocs/w0069e04/sonic-potions/wiki/includes/libs/rdbms/database/resultwrapper/ResultWrapper.php</b> on line <b>117</b><br />
<br />
<b>Deprecated</b>:  Return type of Wikimedia\Rdbms\ResultWrapper::rewind() should either be compatible with Iterator::rewind(): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/www/htdocs/w0069e04/sonic-potions/wiki/includes/libs/rdbms/database/resultwrapper/ResultWrapper.php</b> on line <b>90</b><br />
<br />
<b>Deprecated</b>:  Return type of MediaWiki\Session\Session::count() should either be compatible with Countable::count(): int, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/www/htdocs/w0069e04/sonic-potions/wiki/includes/session/Session.php</b> on line <b>625</b><br />
<br />
<b>Deprecated</b>:  Return type of MediaWiki\Session\Session::current() should either be compatible with Iterator::current(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/www/htdocs/w0069e04/sonic-potions/wiki/includes/session/Session.php</b> on line <b>631</b><br />
<br />
<b>Deprecated</b>:  Return type of MediaWiki\Session\Session::next() should either be compatible with Iterator::next(): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/www/htdocs/w0069e04/sonic-potions/wiki/includes/session/Session.php</b> on line <b>643</b><br />
<br />
<b>Deprecated</b>:  Return type of MediaWiki\Session\Session::key() should either be compatible with Iterator::key(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/www/htdocs/w0069e04/sonic-potions/wiki/includes/session/Session.php</b> on line <b>637</b><br />
<br />
<b>Deprecated</b>:  Return type of MediaWiki\Session\Session::valid() should either be compatible with Iterator::valid(): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/www/htdocs/w0069e04/sonic-potions/wiki/includes/session/Session.php</b> on line <b>655</b><br />
<br />
<b>Deprecated</b>:  Return type of MediaWiki\Session\Session::rewind() should either be compatible with Iterator::rewind(): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/www/htdocs/w0069e04/sonic-potions/wiki/includes/session/Session.php</b> on line <b>649</b><br />
<br />
<b>Deprecated</b>:  Return type of MediaWiki\Session\Session::offsetExists($offset) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/www/htdocs/w0069e04/sonic-potions/wiki/includes/session/Session.php</b> on line <b>665</b><br />
<br />
<b>Deprecated</b>:  Return type of & MediaWiki\Session\Session::offsetGet($offset) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/www/htdocs/w0069e04/sonic-potions/wiki/includes/session/Session.php</b> on line <b>678</b><br />
<br />
<b>Deprecated</b>:  Return type of MediaWiki\Session\Session::offsetSet($offset, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/www/htdocs/w0069e04/sonic-potions/wiki/includes/session/Session.php</b> on line <b>688</b><br />
<br />
<b>Deprecated</b>:  Return type of MediaWiki\Session\Session::offsetUnset($offset) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/www/htdocs/w0069e04/sonic-potions/wiki/includes/session/Session.php</b> on line <b>693</b><br />
<br />
<b>Deprecated</b>:  Optional parameter $style declared before required parameter $ts is implicitly treated as a required parameter in <b>/www/htdocs/w0069e04/sonic-potions/wiki/vendor/wikimedia/timestamp/src/ConvertibleTimestamp.php</b> on line <b>176</b><br />
<br />
<b>Deprecated</b>:  Creation of dynamic property ApiMain::$mCommit is deprecated in <b>/www/htdocs/w0069e04/sonic-potions/wiki/includes/api/ApiMain.php</b> on line <b>296</b><br />
<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://wiki.sonic-potions.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Rstephane</id>
	<title>Sonic Potions Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.sonic-potions.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Rstephane"/>
	<link rel="alternate" type="text/html" href="http://wiki.sonic-potions.com/index.php?title=Special:Contributions/Rstephane"/>
	<updated>2026-04-29T08:54:21Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.0</generator>
	<entry>
		<id>http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=246</id>
		<title>How to create and add a new function to the LXR</title>
		<link rel="alternate" type="text/html" href="http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=246"/>
		<updated>2014-05-12T11:11:57Z</updated>

		<summary type="html">&lt;p&gt;Rstephane: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a DRAFT !!!! I will correct it during the next days :-)&lt;br /&gt;
&lt;br /&gt;
* GOAL:&lt;br /&gt;
* 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 :-)&lt;br /&gt;
* 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 :-)&lt;br /&gt;
&lt;br /&gt;
* First step, we start by adding a new knob &amp;#039;LEN&amp;#039; (for Length) in  the PERF menu on the LCD display.&lt;br /&gt;
&lt;br /&gt;
* Open the file &amp;#039;&amp;#039;&amp;#039;&amp;#039;Parameters.h&amp;#039;&amp;#039;&amp;#039;&amp;#039;, Add in the section &amp;#039;enum ParamEnums&amp;#039; the new parameter. In our case : PAR_LOOP&lt;br /&gt;
&lt;br /&gt;
        example: &lt;br /&gt;
        &lt;br /&gt;
        enum ParamEnums = {&lt;br /&gt;
        ...&lt;br /&gt;
        PAR_MIDI_NOTE1,&lt;br /&gt;
        PAR_MIDI_NOTE2,&lt;br /&gt;
        PAR_MIDI_NOTE3,&lt;br /&gt;
        PAR_MIDI_NOTE4,&lt;br /&gt;
        PAR_MIDI_NOTE5,&lt;br /&gt;
        PAR_MIDI_NOTE6,&lt;br /&gt;
        PAR_MIDI_NOTE7, // &amp;lt;--- YOUR parameters comes right after thoses lines...&lt;br /&gt;
        // You have to add all the new parameters right after a dedicated section in the code declaration &lt;br /&gt;
        //(otherwise you want link later the knob with the function you want to execute):&lt;br /&gt;
        &amp;#039;&amp;#039;&amp;#039;PAR_LOOP,&amp;#039;&amp;#039;&amp;#039;     &lt;br /&gt;
        ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* We need to open the &amp;#039;&amp;#039;&amp;#039;menu.c&amp;#039;&amp;#039;&amp;#039; file. we declare our parameter and its type :&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        menu.c&lt;br /&gt;
        //---------------------------------------------------------------&lt;br /&gt;
        // Parameter types. These correspond with ParamEnums and entries in parameter_values&lt;br /&gt;
        const enum Datatypes PROGMEM parameter_dtypes[NUM_PARAMS] = {&lt;br /&gt;
            /*PAR_NONE*/                         DTYPE_0B127,                                                        // 0&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM1*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM2*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM3*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_SNARE*/  DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
        ....&lt;br /&gt;
&lt;br /&gt;
* Place your parameter at a special place, right after the section:&lt;br /&gt;
&lt;br /&gt;
            /*PAR_MIDI_NOTE1*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE2*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE3*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE4*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE5*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE6*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE7*/                DTYPE_NOTE_NAME,&lt;br /&gt;
           &lt;br /&gt;
            // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
            /&amp;#039;&amp;#039;&amp;#039;*PAR_LOOP*/                      DTYPE_1B16,&amp;#039;&amp;#039;&amp;#039; // Values goes from 1 to 16 steps&lt;br /&gt;
            &lt;br /&gt;
            /*PAR_ROLL*/                         DTYPE_MENU | (MENU_ROLL_RATES&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_MORPH*/                         DTYPE_0B255,&lt;br /&gt;
            ...&lt;br /&gt;
                &lt;br /&gt;
&lt;br /&gt;
Here the list of parameters you can choose from...&lt;br /&gt;
&lt;br /&gt;
        Type of parameters:&lt;br /&gt;
        //-----------------------------------------------------------------&lt;br /&gt;
        enum Datatypes&lt;br /&gt;
        {&lt;br /&gt;
        DTYPE_0B255,        //0:255&lt;br /&gt;
        DTYPE_0B127,        //0-127&lt;br /&gt;
        DTYPE_PM100,        //-100:100&lt;br /&gt;
        DTYPE_MENU,                //text type outputs &lt;br /&gt;
        DTYPE_PM63,                //-63 &amp;lt;-&amp;gt; 63&lt;br /&gt;
        DTYPE_1B16,                //1-16&lt;br /&gt;
        DTYPE_ON_OFF,        //0-1&lt;br /&gt;
        DTYPE_MIX_FM,        //0-1&lt;br /&gt;
        DTYPE_TARGET_SELECTION_LFO,&lt;br /&gt;
        DTYPE_TARGET_SELECTION_VELO,        &lt;br /&gt;
        DTYPE_VOICE_LFO,&lt;br /&gt;
        DTYPE_AUTOM_TARGET,&lt;br /&gt;
        DTYPE_0b1,&lt;br /&gt;
        DTYPE_NOTE_NAME, // --AS eg C#0, D 1 for note name&lt;br /&gt;
        DTYPE_0B15,                //0-15&lt;br /&gt;
        /*15*/&lt;br /&gt;
        /*16*/&lt;br /&gt;
        // --AS warning, we can only have 16 on this list the way things are laid out&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
* oki, once this done, we need to fill other information in the code&lt;br /&gt;
&lt;br /&gt;
* Open the file &amp;#039;&amp;#039;&amp;#039;menuPages.h&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
* 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&lt;br /&gt;
&lt;br /&gt;
* in the section: const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM ... add your MENU (we want that our knob display a name &amp;#039;LEN&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
* in our case, we add TEXT_LOOP and PAR_ROLL:&lt;br /&gt;
&lt;br /&gt;
        const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM =&lt;br /&gt;
        {&lt;br /&gt;
        //page 1 - Voice 1&lt;br /&gt;
        {&lt;br /&gt;
        //sub page 1 - Oscillator&lt;br /&gt;
        {&lt;br /&gt;
        TEXT_COARSE,        TEXT_FINE,        TEXT_WAVEFORM,                TEXT_RND_VOICE,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,&lt;br /&gt;
        PAR_COARSE1,        PAR_FINE1,        PAR_OSC_WAVE_DRUM1,        PAR_RND_VOICE1,PAR_NONE,PAR_NONE,PAR_NONE,PAR_NONE&lt;br /&gt;
                },        &lt;br /&gt;
        ...&lt;br /&gt;
        //Page 10&lt;br /&gt;
        //---------------- Performance Mode Menu pages ---------------------------&lt;br /&gt;
        //These pages are shown when the selected mode is the &amp;quot;mute/pattern select&amp;quot; page&lt;br /&gt;
        //there is only one page with subpages shown for the whole mode&lt;br /&gt;
        {&lt;br /&gt;
        {		&lt;br /&gt;
        TEXT_SHUFFLE,	TEXT_ROLL_SPEED,	TEXT_X_FADE,	TEXT_SAMPLE_RATE,		 &amp;#039;&amp;#039;&amp;#039;TEXT_LOOP&amp;#039;&amp;#039;&amp;#039;,	TEXT_EMPTY,&lt;br /&gt;
        PAR_SHUFFLE,	&amp;#039;&amp;#039;&amp;#039;PAR_ROLL&amp;#039;&amp;#039;&amp;#039;,			PAR_MORPH,		PAR_VOICE_DECIMATION_ALL,		PAR_LOOP,&lt;br /&gt;
        },&lt;br /&gt;
        ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* We also need to declare the TEXT_LOOP and PAR_LOOP in other files :-)&lt;br /&gt;
&lt;br /&gt;
* Open file &amp;#039;&amp;#039;&amp;#039;menu.h&amp;#039;&amp;#039;&amp;#039;, go to section &amp;#039;NamesEnum&amp;#039;, add at the end the text &amp;#039;TEXT_LOOP&amp;quot; : &lt;br /&gt;
&lt;br /&gt;
        enum NamesEnum&lt;br /&gt;
        {&lt;br /&gt;
        TEXT_EMPTY = 0,                                        //0&lt;br /&gt;
        TEXT_COARSE,&lt;br /&gt;
        TEXT_FINE,&lt;br /&gt;
        TEXT_ATTACK,&lt;br /&gt;
        TEXT_DECAY,&lt;br /&gt;
        TEXT_PITCH_DECAY,&lt;br /&gt;
        TEXT_MOD_AMOUNT,                &lt;br /&gt;
        ....&lt;br /&gt;
        ....&lt;br /&gt;
        TEXT_BAR_RESET_MODE,&lt;br /&gt;
        TEXT_MIDI_CHAN_GLOBAL,&lt;br /&gt;
        &amp;#039;&amp;#039;&amp;#039;TEXT_LOOP&amp;#039;&amp;#039;&amp;#039;,        // rstephane: LOOP text &lt;br /&gt;
        NUM_NAMES&lt;br /&gt;
        };&lt;br /&gt;
                                 &lt;br /&gt;
&lt;br /&gt;
* Open the &amp;#039;&amp;#039;&amp;#039;menu.c&amp;#039;&amp;#039;&amp;#039; file, go to section &amp;#039;&amp;#039;&amp;#039;valueNames&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
        const Name valueNames[NUM_NAMES] PROGMEM =&lt;br /&gt;
        {&lt;br /&gt;
                {SHORT_EMPTY,CAT_EMPTY,LONG_EMPTY},&lt;br /&gt;
                ....&lt;br /&gt;
&lt;br /&gt;
* Add the following information:&lt;br /&gt;
                ....&lt;br /&gt;
                {SHORT_BAR_RESET_MODE, CAT_SEQUENCER, LONG_BAR_RESET_MODE}, // TEXT_BAR_RESET_MODE&lt;br /&gt;
                {SHORT_CHANNEL, CAT_MIDI, LONG_MIDI_CHANNEL}, // TEXT_MIDI_CHAN_GLOBAL&lt;br /&gt;
                &amp;#039;&amp;#039;&amp;#039;{SHORT_LOOP, CAT_SEQUENCER, LONG_LOOP}, // We declare it at the end of the section :-)&amp;#039;&amp;#039;&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
* now, open the &amp;#039;&amp;#039;&amp;#039;MenuText.h&amp;#039;&amp;#039;&amp;#039; file to declare the &amp;#039;&amp;#039;&amp;#039;short and long version of the TEXT&amp;#039;&amp;#039;&amp;#039; (TEXT_LOOP)&lt;br /&gt;
* go to section &amp;#039;const char longNames[][16] PROGMEM = &amp;#039; and &amp;#039;const char shortNames[][4] PROGMEM  = &amp;#039;&lt;br /&gt;
* add the parameters marked in bold:&lt;br /&gt;
&lt;br /&gt;
        const char shortNames[][4] PROGMEM  = &lt;br /&gt;
        {&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        {&amp;quot;coa&amp;quot;},&lt;br /&gt;
        {&amp;quot;fin&amp;quot;},&lt;br /&gt;
        {&amp;quot;atk&amp;quot;},&lt;br /&gt;
        {&amp;quot;dec&amp;quot;},&lt;br /&gt;
        {&amp;quot;eg2&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        &lt;br /&gt;
        {&amp;quot;co2&amp;quot;},  // trigger clock out2 ppq&lt;br /&gt;
        {&amp;quot;pcr&amp;quot;}, // pattern change resets bar counter&lt;br /&gt;
        &amp;#039;&amp;#039;&amp;#039;{&amp;quot;LEN&amp;quot;}&amp;#039;&amp;#039;&amp;#039;, // rstephane: LEN for LOOP :-)&lt;br /&gt;
        &lt;br /&gt;
        };        &lt;br /&gt;
&lt;br /&gt;
        const char longNames[][16] PROGMEM = &lt;br /&gt;
        {&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        //01234567&lt;br /&gt;
        {&amp;quot;Coarse&amp;quot;},&lt;br /&gt;
        {&amp;quot;Fine&amp;quot;},&lt;br /&gt;
        {&amp;quot;Attack&amp;quot;},&lt;br /&gt;
        {&amp;quot;Decay&amp;quot;},&lt;br /&gt;
        {&amp;quot;Amount&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        {&amp;quot;Out2 PPQ&amp;quot;},&lt;br /&gt;
        {&amp;quot;Gate Mode&amp;quot;},&lt;br /&gt;
        {&amp;quot;PCReset&amp;quot; }, // reset bar counter on manual pattern change&lt;br /&gt;
        &amp;#039;&amp;#039;&amp;#039;{&amp;quot;Loop&amp;quot;}&amp;#039;&amp;#039;&amp;#039;, // rstephane: LOOP LONG text&lt;br /&gt;
        };&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
* If you want you can already compile and see the results: under the PERF sub menu, your should see &amp;#039;LEN&amp;#039; on the first knob.&lt;br /&gt;
* Now, &amp;#039;&amp;#039;&amp;#039;we will create our function&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* open &amp;#039;&amp;#039;&amp;#039;midimessage.h&amp;#039;&amp;#039;&amp;#039; file&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        //for all parameters above 127 &amp;lt;- our case&lt;br /&gt;
        enum&lt;br /&gt;
        {&lt;br /&gt;
        ....&lt;br /&gt;
        // Again, place your parameter at a special place, right after the section:&lt;br /&gt;
        CC2_MIDI_NOTE1,&lt;br /&gt;
        CC2_MIDI_NOTE2,&lt;br /&gt;
        CC2_MIDI_NOTE3,&lt;br /&gt;
        CC2_MIDI_NOTE4,&lt;br /&gt;
        CC2_MIDI_NOTE5,&lt;br /&gt;
        CC2_MIDI_NOTE6,&lt;br /&gt;
        CC2_MIDI_NOTE7, // s/b 111 i think&lt;br /&gt;
        &lt;br /&gt;
        // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
        // When the knob is turned , it send the CC2_LOOP message&lt;br /&gt;
        &amp;#039;&amp;#039;&amp;#039;CC2_LOOP,&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
        ....&lt;br /&gt;
        }&lt;br /&gt;
        Param2Enums;&lt;br /&gt;
&lt;br /&gt;
* open  &amp;#039;&amp;#039;&amp;#039;MidiParser.c&amp;#039;&amp;#039;&amp;#039; file &lt;br /&gt;
&lt;br /&gt;
        //-----------------------------------------------------------&lt;br /&gt;
        /** handle all incoming CCs and invoke action*/&lt;br /&gt;
        void &amp;#039;&amp;#039;&amp;#039;midiParser_ccHandler&amp;#039;&amp;#039;&amp;#039;(MidiMsg msg, uint8_t updateOriginalValue)&lt;br /&gt;
        {&lt;br /&gt;
        &lt;br /&gt;
        ...&lt;br /&gt;
        &lt;br /&gt;
        else //MIDI_CC2&lt;br /&gt;
        {&lt;br /&gt;
                const uint16_t paramNr = msg.data1+1 + 127;&lt;br /&gt;
&lt;br /&gt;
                if(updateOriginalValue) {&lt;br /&gt;
                        midiParser_originalCcValues[paramNr] = msg.data2;&lt;br /&gt;
                }&lt;br /&gt;
                switch(msg.data1)&lt;br /&gt;
                {&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_WAVE:&lt;br /&gt;
                                        voiceArray[0].transGen.waveform = msg.data2;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_VOL:&lt;br /&gt;
                                voiceArray[0].transGen.volume = msg.data2/127.f;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
        ...&lt;br /&gt;
                        case CC2_MUTE_1:&lt;br /&gt;
                        case CC2_MUTE_2:&lt;br /&gt;
                        case CC2_MUTE_3:&lt;br /&gt;
                        case CC2_MUTE_4:&lt;br /&gt;
                        case CC2_MUTE_5:&lt;br /&gt;
                        case CC2_MUTE_6:&lt;br /&gt;
                        case CC2_MUTE_7:&lt;br /&gt;
                        {&lt;br /&gt;
                                const uint8_t voiceNr = msg.data1 - CC2_MUTE_1;&lt;br /&gt;
                                if(msg.data2 == 0)&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,0);&lt;br /&gt;
                                }&lt;br /&gt;
                                else&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,1);&lt;br /&gt;
                                }&lt;br /&gt;
&lt;br /&gt;
                        }&lt;br /&gt;
                                break;&lt;br /&gt;
                            //&lt;br /&gt;
                            // rstephane MY FUNCTIONS&lt;br /&gt;
                            &amp;#039;&amp;#039;&amp;#039;case CC2_LOOP:&lt;br /&gt;
                                   if(msg.data2 == 16)  // reset the loop ! &lt;br /&gt;
                                   {	// we stop the loop effect and&lt;br /&gt;
                                          // go back to prevoious track lenght&lt;br /&gt;
                                          seq_setLoopLength(16);&lt;br /&gt;
                                   }&lt;br /&gt;
                                   else&lt;br /&gt;
                                   {	// we change the tracks lenght&lt;br /&gt;
                                          seq_setLoopLength(msg.data2);&lt;br /&gt;
                                   }&lt;br /&gt;
                                   break;&amp;#039;&amp;#039;&amp;#039;			&lt;br /&gt;
                                       &lt;br /&gt;
                        default:&lt;br /&gt;
                                break;&lt;br /&gt;
                                &lt;br /&gt;
                        ....&lt;br /&gt;
                        &lt;br /&gt;
                        &lt;br /&gt;
&lt;br /&gt;
* open &amp;#039;&amp;#039;&amp;#039;sequencer.h&amp;#039;&amp;#039;&amp;#039; file, add the line :  &lt;br /&gt;
        void seq_setLoopLength(uint8_t length);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* open &amp;#039;&amp;#039;&amp;#039;sequencer.c&amp;#039;&amp;#039;&amp;#039; file, add the function:&lt;br /&gt;
        void seq_setLoopLength(uint8_t length)&lt;br /&gt;
        {&lt;br /&gt;
        uint8_t i;&lt;br /&gt;
        // we set the new Loop Track Lenght&lt;br /&gt;
        for(i=0;i&amp;lt;NUM_TRACKS;i++) {&lt;br /&gt;
                seq_setTrackLength(i, length);	&lt;br /&gt;
        }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
* compile !&lt;br /&gt;
* upload on the machine with the new firmware&lt;br /&gt;
* test!&lt;/div&gt;</summary>
		<author><name>Rstephane</name></author>
		
	</entry>
	<entry>
		<id>http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=245</id>
		<title>How to create and add a new function to the LXR</title>
		<link rel="alternate" type="text/html" href="http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=245"/>
		<updated>2014-05-11T21:36:57Z</updated>

		<summary type="html">&lt;p&gt;Rstephane: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a DRAFT !!!! I will correct it during the next days :-)&lt;br /&gt;
&lt;br /&gt;
* GOAL:&lt;br /&gt;
* 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 :-)&lt;br /&gt;
* 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 :-)&lt;br /&gt;
&lt;br /&gt;
* First step, we start by adding a new knob &amp;#039;LEN&amp;#039; (for Length) in  the PERF menu on the LCD display.&lt;br /&gt;
&lt;br /&gt;
* Open the file &amp;#039;&amp;#039;&amp;#039;&amp;#039;Parameters.h&amp;#039;&amp;#039;&amp;#039;&amp;#039;, Add in the section &amp;#039;enum ParamEnums&amp;#039; the new parameter. In our case : PAR_LOOP&lt;br /&gt;
&lt;br /&gt;
        example: &lt;br /&gt;
        &lt;br /&gt;
        enum ParamEnums = {&lt;br /&gt;
        ...&lt;br /&gt;
        PAR_MIDI_NOTE1,&lt;br /&gt;
        PAR_MIDI_NOTE2,&lt;br /&gt;
        PAR_MIDI_NOTE3,&lt;br /&gt;
        PAR_MIDI_NOTE4,&lt;br /&gt;
        PAR_MIDI_NOTE5,&lt;br /&gt;
        PAR_MIDI_NOTE6,&lt;br /&gt;
        PAR_MIDI_NOTE7, // &amp;lt;--- YOUR parameters comes right after thoses lines...&lt;br /&gt;
        // You have to add all the new parameters right after a dedicated section in the code declaration &lt;br /&gt;
        //(otherwise you want link later the knob with the function you want to execute):&lt;br /&gt;
        &amp;#039;&amp;#039;&amp;#039;PAR_LOOP,&amp;#039;&amp;#039;&amp;#039;     &lt;br /&gt;
        ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* We need to open the &amp;#039;&amp;#039;&amp;#039;menu.c&amp;#039;&amp;#039;&amp;#039; file. we declare our parameter and its type :&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        menu.c&lt;br /&gt;
        //---------------------------------------------------------------&lt;br /&gt;
        // Parameter types. These correspond with ParamEnums and entries in parameter_values&lt;br /&gt;
        const enum Datatypes PROGMEM parameter_dtypes[NUM_PARAMS] = {&lt;br /&gt;
            /*PAR_NONE*/                         DTYPE_0B127,                                                        // 0&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM1*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM2*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM3*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_SNARE*/  DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
        ....&lt;br /&gt;
&lt;br /&gt;
* Place your parameter at a special place, right after the section:&lt;br /&gt;
&lt;br /&gt;
            /*PAR_MIDI_NOTE1*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE2*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE3*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE4*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE5*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE6*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE7*/                DTYPE_NOTE_NAME,&lt;br /&gt;
           &lt;br /&gt;
            // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
            /&amp;#039;&amp;#039;&amp;#039;*PAR_LOOP*/                      DTYPE_1B16,&amp;#039;&amp;#039;&amp;#039; // Values goes from 1 to 16 steps&lt;br /&gt;
            &lt;br /&gt;
            /*PAR_ROLL*/                         DTYPE_MENU | (MENU_ROLL_RATES&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_MORPH*/                         DTYPE_0B255,&lt;br /&gt;
            ...&lt;br /&gt;
                &lt;br /&gt;
&lt;br /&gt;
Here the list of parameters you can choose from...&lt;br /&gt;
&lt;br /&gt;
        Type of parameters:&lt;br /&gt;
        //-----------------------------------------------------------------&lt;br /&gt;
        enum Datatypes&lt;br /&gt;
        {&lt;br /&gt;
        DTYPE_0B255,        //0:255&lt;br /&gt;
        DTYPE_0B127,        //0-127&lt;br /&gt;
        DTYPE_PM100,        //-100:100&lt;br /&gt;
        DTYPE_MENU,                //text type outputs &lt;br /&gt;
        DTYPE_PM63,                //-63 &amp;lt;-&amp;gt; 63&lt;br /&gt;
        DTYPE_1B16,                //1-16&lt;br /&gt;
        DTYPE_ON_OFF,        //0-1&lt;br /&gt;
        DTYPE_MIX_FM,        //0-1&lt;br /&gt;
        DTYPE_TARGET_SELECTION_LFO,&lt;br /&gt;
        DTYPE_TARGET_SELECTION_VELO,        &lt;br /&gt;
        DTYPE_VOICE_LFO,&lt;br /&gt;
        DTYPE_AUTOM_TARGET,&lt;br /&gt;
        DTYPE_0b1,&lt;br /&gt;
        DTYPE_NOTE_NAME, // --AS eg C#0, D 1 for note name&lt;br /&gt;
        DTYPE_0B15,                //0-15&lt;br /&gt;
        /*15*/&lt;br /&gt;
        /*16*/&lt;br /&gt;
        // --AS warning, we can only have 16 on this list the way things are laid out&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
* oki, once this done, we need to fill other information in the code&lt;br /&gt;
&lt;br /&gt;
* Open the file &amp;#039;&amp;#039;&amp;#039;menuPages.h&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
* 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&lt;br /&gt;
&lt;br /&gt;
* in the section: const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM ... add your MENU (we want that our knob display a name &amp;#039;LEN&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
* in our case, we add TEXT_LOOP and PAR_ROLL:&lt;br /&gt;
&lt;br /&gt;
        const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM =&lt;br /&gt;
        {&lt;br /&gt;
        //page 1 - Voice 1&lt;br /&gt;
        {&lt;br /&gt;
        //sub page 1 - Oscillator&lt;br /&gt;
        {&lt;br /&gt;
        TEXT_COARSE,        TEXT_FINE,        TEXT_WAVEFORM,                TEXT_RND_VOICE,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,&lt;br /&gt;
        PAR_COARSE1,        PAR_FINE1,        PAR_OSC_WAVE_DRUM1,        PAR_RND_VOICE1,PAR_NONE,PAR_NONE,PAR_NONE,PAR_NONE&lt;br /&gt;
                },        &lt;br /&gt;
        ...&lt;br /&gt;
        //Page 10&lt;br /&gt;
        //---------------- Performance Mode Menu pages ---------------------------&lt;br /&gt;
        //These pages are shown when the selected mode is the &amp;quot;mute/pattern select&amp;quot; page&lt;br /&gt;
        //there is only one page with subpages shown for the whole mode&lt;br /&gt;
        {&lt;br /&gt;
        {		&lt;br /&gt;
        TEXT_SHUFFLE,	TEXT_ROLL_SPEED,	TEXT_X_FADE,	TEXT_SAMPLE_RATE,		 &amp;#039;&amp;#039;&amp;#039;TEXT_LOOP&amp;#039;&amp;#039;&amp;#039;,	TEXT_EMPTY,&lt;br /&gt;
        PAR_SHUFFLE,	&amp;#039;&amp;#039;&amp;#039;PAR_ROLL&amp;#039;&amp;#039;&amp;#039;,			PAR_MORPH,		PAR_VOICE_DECIMATION_ALL,		PAR_LOOP,&lt;br /&gt;
        },&lt;br /&gt;
        ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* We also need to declare the TEXT_LOOP and PAR_LOOP in other files :-)&lt;br /&gt;
&lt;br /&gt;
* Open file &amp;#039;&amp;#039;&amp;#039;menu.h&amp;#039;&amp;#039;&amp;#039;, go to section &amp;#039;NamesEnum&amp;#039;, add at the end the text &amp;#039;TEXT_LOOP&amp;quot; : &lt;br /&gt;
&lt;br /&gt;
        enum NamesEnum&lt;br /&gt;
        {&lt;br /&gt;
        TEXT_EMPTY = 0,                                        //0&lt;br /&gt;
        TEXT_COARSE,&lt;br /&gt;
        TEXT_FINE,&lt;br /&gt;
        TEXT_ATTACK,&lt;br /&gt;
        TEXT_DECAY,&lt;br /&gt;
        TEXT_PITCH_DECAY,&lt;br /&gt;
        TEXT_MOD_AMOUNT,                &lt;br /&gt;
        ....&lt;br /&gt;
        ....&lt;br /&gt;
        TEXT_BAR_RESET_MODE,&lt;br /&gt;
        TEXT_MIDI_CHAN_GLOBAL,&lt;br /&gt;
        &amp;#039;&amp;#039;&amp;#039;TEXT_LOOP&amp;#039;&amp;#039;&amp;#039;,        // rstephane: LOOP text &lt;br /&gt;
        NUM_NAMES&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
* Open &amp;#039;&amp;#039;&amp;#039;Cc2Text.c&amp;#039;&amp;#039;&amp;#039; file and under the section (i need to explain and complete this section)&lt;br /&gt;
&lt;br /&gt;
       {TEXT_COARSE, PAR_COARSE1},                         //2&lt;br /&gt;
       {TEXT_FINE, PAR_FINE1},&lt;br /&gt;
       {TEXT_WAVEFORM, PAR_OSC_WAVE_DRUM1},&lt;br /&gt;
       {TEXT_LOOP, PAR_LOOP}, // rstephane : added LOOP button &amp;lt;- no really needed, well pass trough this step                                   &lt;br /&gt;
                                        &lt;br /&gt;
&lt;br /&gt;
* Open the &amp;#039;&amp;#039;&amp;#039;menu.c&amp;#039;&amp;#039;&amp;#039; file, go to section &amp;#039;&amp;#039;&amp;#039;valueNames&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
        const Name valueNames[NUM_NAMES] PROGMEM =&lt;br /&gt;
        {&lt;br /&gt;
                {SHORT_EMPTY,CAT_EMPTY,LONG_EMPTY},&lt;br /&gt;
                ....&lt;br /&gt;
&lt;br /&gt;
* Add the following information:&lt;br /&gt;
                ....&lt;br /&gt;
                {SHORT_BAR_RESET_MODE, CAT_SEQUENCER, LONG_BAR_RESET_MODE}, // TEXT_BAR_RESET_MODE&lt;br /&gt;
                {SHORT_CHANNEL, CAT_MIDI, LONG_MIDI_CHANNEL}, // TEXT_MIDI_CHAN_GLOBAL&lt;br /&gt;
                &amp;#039;&amp;#039;&amp;#039;{SHORT_LOOP, CAT_SEQUENCER, LONG_LOOP}, // We declare it at the end of the section :-)&amp;#039;&amp;#039;&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
* now, open the &amp;#039;&amp;#039;&amp;#039;MenuText.h&amp;#039;&amp;#039;&amp;#039; file to declare the &amp;#039;&amp;#039;&amp;#039;short and long version of the TEXT&amp;#039;&amp;#039;&amp;#039; (TEXT_LOOP)&lt;br /&gt;
* go to section &amp;#039;const char longNames[][16] PROGMEM = &amp;#039; and &amp;#039;const char shortNames[][4] PROGMEM  = &amp;#039;&lt;br /&gt;
* add the parameters marked in bold:&lt;br /&gt;
&lt;br /&gt;
        const char shortNames[][4] PROGMEM  = &lt;br /&gt;
        {&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        {&amp;quot;coa&amp;quot;},&lt;br /&gt;
        {&amp;quot;fin&amp;quot;},&lt;br /&gt;
        {&amp;quot;atk&amp;quot;},&lt;br /&gt;
        {&amp;quot;dec&amp;quot;},&lt;br /&gt;
        {&amp;quot;eg2&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        &lt;br /&gt;
        {&amp;quot;co2&amp;quot;},  // trigger clock out2 ppq&lt;br /&gt;
        {&amp;quot;pcr&amp;quot;}, // pattern change resets bar counter&lt;br /&gt;
        &amp;#039;&amp;#039;&amp;#039;{&amp;quot;LEN&amp;quot;}&amp;#039;&amp;#039;&amp;#039;, // rstephane: LEN for LOOP :-)&lt;br /&gt;
        &lt;br /&gt;
        };        &lt;br /&gt;
&lt;br /&gt;
        const char longNames[][16] PROGMEM = &lt;br /&gt;
        {&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        //01234567&lt;br /&gt;
        {&amp;quot;Coarse&amp;quot;},&lt;br /&gt;
        {&amp;quot;Fine&amp;quot;},&lt;br /&gt;
        {&amp;quot;Attack&amp;quot;},&lt;br /&gt;
        {&amp;quot;Decay&amp;quot;},&lt;br /&gt;
        {&amp;quot;Amount&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        {&amp;quot;Out2 PPQ&amp;quot;},&lt;br /&gt;
        {&amp;quot;Gate Mode&amp;quot;},&lt;br /&gt;
        {&amp;quot;PCReset&amp;quot; }, // reset bar counter on manual pattern change&lt;br /&gt;
        &amp;#039;&amp;#039;&amp;#039;{&amp;quot;Loop&amp;quot;}&amp;#039;&amp;#039;&amp;#039;, // rstephane: LOOP LONG text&lt;br /&gt;
        };&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
* If you want you can already compile and see the results: under the PERF sub menu, your should see &amp;#039;LEN&amp;#039; on the first knob.&lt;br /&gt;
* Now, &amp;#039;&amp;#039;&amp;#039;we will create our function&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* open &amp;#039;&amp;#039;&amp;#039;midimessage.h&amp;#039;&amp;#039;&amp;#039; file&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        //for all parameters above 127 &amp;lt;- our case&lt;br /&gt;
        enum&lt;br /&gt;
        {&lt;br /&gt;
        ....&lt;br /&gt;
        // Again, place your parameter at a special place, right after the section:&lt;br /&gt;
        CC2_MIDI_NOTE1,&lt;br /&gt;
        CC2_MIDI_NOTE2,&lt;br /&gt;
        CC2_MIDI_NOTE3,&lt;br /&gt;
        CC2_MIDI_NOTE4,&lt;br /&gt;
        CC2_MIDI_NOTE5,&lt;br /&gt;
        CC2_MIDI_NOTE6,&lt;br /&gt;
        CC2_MIDI_NOTE7, // s/b 111 i think&lt;br /&gt;
        &lt;br /&gt;
        // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
        // When the knob is turned , it send the CC2_LOOP message&lt;br /&gt;
        &amp;#039;&amp;#039;&amp;#039;CC2_LOOP,&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
        ....&lt;br /&gt;
        }&lt;br /&gt;
        Param2Enums;&lt;br /&gt;
&lt;br /&gt;
* open  &amp;#039;&amp;#039;&amp;#039;MidiParser.c&amp;#039;&amp;#039;&amp;#039; file &lt;br /&gt;
&lt;br /&gt;
        //-----------------------------------------------------------&lt;br /&gt;
        /** handle all incoming CCs and invoke action*/&lt;br /&gt;
        void &amp;#039;&amp;#039;&amp;#039;midiParser_ccHandler&amp;#039;&amp;#039;&amp;#039;(MidiMsg msg, uint8_t updateOriginalValue)&lt;br /&gt;
        {&lt;br /&gt;
        &lt;br /&gt;
        ...&lt;br /&gt;
        &lt;br /&gt;
        else //MIDI_CC2&lt;br /&gt;
        {&lt;br /&gt;
                const uint16_t paramNr = msg.data1+1 + 127;&lt;br /&gt;
&lt;br /&gt;
                if(updateOriginalValue) {&lt;br /&gt;
                        midiParser_originalCcValues[paramNr] = msg.data2;&lt;br /&gt;
                }&lt;br /&gt;
                switch(msg.data1)&lt;br /&gt;
                {&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_WAVE:&lt;br /&gt;
                                        voiceArray[0].transGen.waveform = msg.data2;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_VOL:&lt;br /&gt;
                                voiceArray[0].transGen.volume = msg.data2/127.f;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
        ...&lt;br /&gt;
                        case CC2_MUTE_1:&lt;br /&gt;
                        case CC2_MUTE_2:&lt;br /&gt;
                        case CC2_MUTE_3:&lt;br /&gt;
                        case CC2_MUTE_4:&lt;br /&gt;
                        case CC2_MUTE_5:&lt;br /&gt;
                        case CC2_MUTE_6:&lt;br /&gt;
                        case CC2_MUTE_7:&lt;br /&gt;
                        {&lt;br /&gt;
                                const uint8_t voiceNr = msg.data1 - CC2_MUTE_1;&lt;br /&gt;
                                if(msg.data2 == 0)&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,0);&lt;br /&gt;
                                }&lt;br /&gt;
                                else&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,1);&lt;br /&gt;
                                }&lt;br /&gt;
&lt;br /&gt;
                        }&lt;br /&gt;
                                break;&lt;br /&gt;
                            //&lt;br /&gt;
                            // rstephane MY FUNCTIONS&lt;br /&gt;
                            &amp;#039;&amp;#039;&amp;#039;case CC2_LOOP:&lt;br /&gt;
                                   if(msg.data2 == 16)  // reset the loop ! &lt;br /&gt;
                                   {	// we stop the loop effect and&lt;br /&gt;
                                          // go back to prevoious track lenght&lt;br /&gt;
                                          seq_setLoopLength(16);&lt;br /&gt;
                                   }&lt;br /&gt;
                                   else&lt;br /&gt;
                                   {	// we change the tracks lenght&lt;br /&gt;
                                          seq_setLoopLength(msg.data2);&lt;br /&gt;
                                   }&lt;br /&gt;
                                   break;&amp;#039;&amp;#039;&amp;#039;			&lt;br /&gt;
                                       &lt;br /&gt;
                        default:&lt;br /&gt;
                                break;&lt;br /&gt;
                                &lt;br /&gt;
                        ....&lt;br /&gt;
                        &lt;br /&gt;
                        &lt;br /&gt;
&lt;br /&gt;
* open &amp;#039;&amp;#039;&amp;#039;sequencer.h&amp;#039;&amp;#039;&amp;#039; file, add the line :  &lt;br /&gt;
        void seq_setLoopLength(uint8_t length);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* open &amp;#039;&amp;#039;&amp;#039;sequencer.c&amp;#039;&amp;#039;&amp;#039; file, add the function:&lt;br /&gt;
        void seq_setLoopLength(uint8_t length)&lt;br /&gt;
        {&lt;br /&gt;
        uint8_t i;&lt;br /&gt;
        // we set the new Loop Track Lenght&lt;br /&gt;
        for(i=0;i&amp;lt;NUM_TRACKS;i++) {&lt;br /&gt;
                seq_setTrackLength(i, length);	&lt;br /&gt;
        }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
* compile !&lt;br /&gt;
* upload on the machine with the new firmware&lt;br /&gt;
* test!&lt;/div&gt;</summary>
		<author><name>Rstephane</name></author>
		
	</entry>
	<entry>
		<id>http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=244</id>
		<title>How to create and add a new function to the LXR</title>
		<link rel="alternate" type="text/html" href="http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=244"/>
		<updated>2014-05-11T21:32:41Z</updated>

		<summary type="html">&lt;p&gt;Rstephane: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a DRAFT !!!! I will correct it during the next days :-)&lt;br /&gt;
&lt;br /&gt;
* GOAL:&lt;br /&gt;
* 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 :-)&lt;br /&gt;
* 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 :-)&lt;br /&gt;
&lt;br /&gt;
* First step, we start by adding a new knob &amp;#039;LEN&amp;#039; (for Length) in  the PERF menu on the LCD display.&lt;br /&gt;
&lt;br /&gt;
* Open the file &amp;#039;&amp;#039;&amp;#039;&amp;#039;Parameters.h&amp;#039;&amp;#039;&amp;#039;&amp;#039;, Add in the section &amp;#039;enum ParamEnums&amp;#039; the new parameter. In our case : PAR_LOOP&lt;br /&gt;
&lt;br /&gt;
        example: &lt;br /&gt;
        &lt;br /&gt;
        enum ParamEnums = {&lt;br /&gt;
        ...&lt;br /&gt;
        PAR_MIDI_NOTE1,&lt;br /&gt;
        PAR_MIDI_NOTE2,&lt;br /&gt;
        PAR_MIDI_NOTE3,&lt;br /&gt;
        PAR_MIDI_NOTE4,&lt;br /&gt;
        PAR_MIDI_NOTE5,&lt;br /&gt;
        PAR_MIDI_NOTE6,&lt;br /&gt;
        PAR_MIDI_NOTE7, // &amp;lt;--- YOUR parameters comes right after thoses lines...&lt;br /&gt;
        // You have to add all the new parameters right after a dedicated section in the code declaration &lt;br /&gt;
        //(otherwise you want link later the knob with the function you want to execute):&lt;br /&gt;
        &amp;#039;&amp;#039;&amp;#039;PAR_LOOP,&amp;#039;&amp;#039;&amp;#039;     &lt;br /&gt;
        ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* We need to open the &amp;#039;&amp;#039;&amp;#039;menu.c&amp;#039;&amp;#039;&amp;#039; file. we declare our parameter and its type :&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        menu.c&lt;br /&gt;
        //---------------------------------------------------------------&lt;br /&gt;
        // Parameter types. These correspond with ParamEnums and entries in parameter_values&lt;br /&gt;
        const enum Datatypes PROGMEM parameter_dtypes[NUM_PARAMS] = {&lt;br /&gt;
            /*PAR_NONE*/                         DTYPE_0B127,                                                        // 0&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM1*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM2*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM3*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_SNARE*/  DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
        ....&lt;br /&gt;
&lt;br /&gt;
* Place your parameter at a special place, right after the section:&lt;br /&gt;
&lt;br /&gt;
            /*PAR_MIDI_NOTE1*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE2*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE3*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE4*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE5*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE6*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE7*/                DTYPE_NOTE_NAME,&lt;br /&gt;
           &lt;br /&gt;
            // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
            /&amp;#039;&amp;#039;&amp;#039;*PAR_LOOP*/                      DTYPE_1B16,&amp;#039;&amp;#039;&amp;#039; // Values goes from 1 to 16 steps&lt;br /&gt;
            &lt;br /&gt;
            /*PAR_ROLL*/                         DTYPE_MENU | (MENU_ROLL_RATES&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_MORPH*/                         DTYPE_0B255,&lt;br /&gt;
            ...&lt;br /&gt;
                &lt;br /&gt;
&lt;br /&gt;
Here the list of parameters you can choose from...&lt;br /&gt;
&lt;br /&gt;
        Type of parameters:&lt;br /&gt;
        //-----------------------------------------------------------------&lt;br /&gt;
        enum Datatypes&lt;br /&gt;
        {&lt;br /&gt;
        DTYPE_0B255,        //0:255&lt;br /&gt;
        DTYPE_0B127,        //0-127&lt;br /&gt;
        DTYPE_PM100,        //-100:100&lt;br /&gt;
        DTYPE_MENU,                //text type outputs &lt;br /&gt;
        DTYPE_PM63,                //-63 &amp;lt;-&amp;gt; 63&lt;br /&gt;
        DTYPE_1B16,                //1-16&lt;br /&gt;
        DTYPE_ON_OFF,        //0-1&lt;br /&gt;
        DTYPE_MIX_FM,        //0-1&lt;br /&gt;
        DTYPE_TARGET_SELECTION_LFO,&lt;br /&gt;
        DTYPE_TARGET_SELECTION_VELO,        &lt;br /&gt;
        DTYPE_VOICE_LFO,&lt;br /&gt;
        DTYPE_AUTOM_TARGET,&lt;br /&gt;
        DTYPE_0b1,&lt;br /&gt;
        DTYPE_NOTE_NAME, // --AS eg C#0, D 1 for note name&lt;br /&gt;
        DTYPE_0B15,                //0-15&lt;br /&gt;
        /*15*/&lt;br /&gt;
        /*16*/&lt;br /&gt;
        // --AS warning, we can only have 16 on this list the way things are laid out&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
* oki, once this done, we need to fill other information in the code&lt;br /&gt;
&lt;br /&gt;
* Open the file &amp;#039;&amp;#039;&amp;#039;menuPages.h&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
* 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&lt;br /&gt;
&lt;br /&gt;
* in the section: const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM ... add your MENU (we want that our knob display a name &amp;#039;LEN&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
* in our case, we have:&lt;br /&gt;
&lt;br /&gt;
        const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM =&lt;br /&gt;
        {&lt;br /&gt;
        //page 1 - Voice 1&lt;br /&gt;
        {&lt;br /&gt;
        //sub page 1 - Oscillator&lt;br /&gt;
        {&lt;br /&gt;
        TEXT_COARSE,        TEXT_FINE,        TEXT_WAVEFORM,                TEXT_RND_VOICE,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,&lt;br /&gt;
        PAR_COARSE1,        PAR_FINE1,        PAR_OSC_WAVE_DRUM1,        PAR_RND_VOICE1,PAR_NONE,PAR_NONE,PAR_NONE,PAR_NONE&lt;br /&gt;
                },        &lt;br /&gt;
        ...&lt;br /&gt;
        //Page 10&lt;br /&gt;
        //---------------- Performance Mode Menu pages ---------------------------&lt;br /&gt;
        //These pages are shown when the selected mode is the &amp;quot;mute/pattern select&amp;quot; page&lt;br /&gt;
        //there is only one page with subpages shown for the whole mode&lt;br /&gt;
        {&lt;br /&gt;
        {		&lt;br /&gt;
        TEXT_SHUFFLE,	TEXT_ROLL_SPEED,	TEXT_X_FADE,	TEXT_SAMPLE_RATE,		 &amp;#039;&amp;#039;&amp;#039;TEXT_LOOP&amp;#039;&amp;#039;&amp;#039;,	TEXT_EMPTY,&lt;br /&gt;
        PAR_SHUFFLE,	&amp;#039;&amp;#039;&amp;#039;PAR_ROLL&amp;#039;&amp;#039;&amp;#039;,			PAR_MORPH,		PAR_VOICE_DECIMATION_ALL,		PAR_LOOP,&lt;br /&gt;
        },&lt;br /&gt;
        ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* We need now to declare the TEXT_LOOP and PAR_LOOP in other files :-)&lt;br /&gt;
&lt;br /&gt;
* Open file &amp;#039;&amp;#039;&amp;#039;menu.h&amp;#039;&amp;#039;&amp;#039;, go to section &amp;#039;NamesEnum&amp;#039;, add at the end the text &amp;#039;TEXT_LOOP&amp;quot; : &lt;br /&gt;
&lt;br /&gt;
        enum NamesEnum&lt;br /&gt;
        {&lt;br /&gt;
        TEXT_EMPTY = 0,                                        //0&lt;br /&gt;
        TEXT_COARSE,&lt;br /&gt;
        TEXT_FINE,&lt;br /&gt;
        TEXT_ATTACK,&lt;br /&gt;
        TEXT_DECAY,&lt;br /&gt;
        TEXT_PITCH_DECAY,&lt;br /&gt;
        TEXT_MOD_AMOUNT,                &lt;br /&gt;
        ....&lt;br /&gt;
        ....&lt;br /&gt;
        TEXT_BAR_RESET_MODE,&lt;br /&gt;
        TEXT_MIDI_CHAN_GLOBAL,&lt;br /&gt;
        &amp;#039;&amp;#039;&amp;#039;TEXT_LOOP&amp;#039;&amp;#039;&amp;#039;,        // rstephane: LOOP text &lt;br /&gt;
        NUM_NAMES&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
* Open &amp;#039;&amp;#039;&amp;#039;Cc2Text.c&amp;#039;&amp;#039;&amp;#039; file and under the section (i need to explain and complete this section)&lt;br /&gt;
&lt;br /&gt;
       {TEXT_COARSE, PAR_COARSE1},                         //2&lt;br /&gt;
       {TEXT_FINE, PAR_FINE1},&lt;br /&gt;
       {TEXT_WAVEFORM, PAR_OSC_WAVE_DRUM1},&lt;br /&gt;
       {TEXT_LOOP, PAR_LOOP}, // rstephane : added LOOP button &amp;lt;- no really needed, well pass trough this step                                   &lt;br /&gt;
                                        &lt;br /&gt;
&lt;br /&gt;
* Open the &amp;#039;&amp;#039;&amp;#039;menu.c&amp;#039;&amp;#039;&amp;#039; file, go to section &amp;#039;&amp;#039;&amp;#039;valueNames&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
        const Name valueNames[NUM_NAMES] PROGMEM =&lt;br /&gt;
        {&lt;br /&gt;
                {SHORT_EMPTY,CAT_EMPTY,LONG_EMPTY},&lt;br /&gt;
                ....&lt;br /&gt;
&lt;br /&gt;
* Add the following information:&lt;br /&gt;
                ....&lt;br /&gt;
                {SHORT_BAR_RESET_MODE, CAT_SEQUENCER, LONG_BAR_RESET_MODE}, // TEXT_BAR_RESET_MODE&lt;br /&gt;
                {SHORT_CHANNEL, CAT_MIDI, LONG_MIDI_CHANNEL}, // TEXT_MIDI_CHAN_GLOBAL&lt;br /&gt;
                &amp;#039;&amp;#039;&amp;#039;{SHORT_LOOP, CAT_SEQUENCER, LONG_LOOP}, // We declare it at the end of the section :-)&amp;#039;&amp;#039;&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
* now, open the &amp;#039;&amp;#039;&amp;#039;MenuText.h&amp;#039;&amp;#039;&amp;#039; file to declare the &amp;#039;&amp;#039;&amp;#039;short and long version of the TEXT&amp;#039;&amp;#039;&amp;#039; (TEXT_LOOP)&lt;br /&gt;
* go to section &amp;#039;const char longNames[][16] PROGMEM = &amp;#039; and &amp;#039;const char shortNames[][4] PROGMEM  = &amp;#039;&lt;br /&gt;
* add the parameters:&lt;br /&gt;
&lt;br /&gt;
        const char shortNames[][4] PROGMEM  = &lt;br /&gt;
        {&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        {&amp;quot;coa&amp;quot;},&lt;br /&gt;
        {&amp;quot;fin&amp;quot;},&lt;br /&gt;
        {&amp;quot;atk&amp;quot;},&lt;br /&gt;
        {&amp;quot;dec&amp;quot;},&lt;br /&gt;
        {&amp;quot;eg2&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        &lt;br /&gt;
        {&amp;quot;co2&amp;quot;},  // trigger clock out2 ppq&lt;br /&gt;
        {&amp;quot;pcr&amp;quot;}, // pattern change resets bar counter&lt;br /&gt;
        &amp;#039;&amp;#039;&amp;#039;{&amp;quot;LEN&amp;quot;}&amp;#039;&amp;#039;&amp;#039;, // rstephane: LEN for LOOP :-)&lt;br /&gt;
        &lt;br /&gt;
        };        &lt;br /&gt;
&lt;br /&gt;
        const char longNames[][16] PROGMEM = &lt;br /&gt;
        {&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        //01234567&lt;br /&gt;
        {&amp;quot;Coarse&amp;quot;},&lt;br /&gt;
        {&amp;quot;Fine&amp;quot;},&lt;br /&gt;
        {&amp;quot;Attack&amp;quot;},&lt;br /&gt;
        {&amp;quot;Decay&amp;quot;},&lt;br /&gt;
        {&amp;quot;Amount&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        {&amp;quot;Out2 PPQ&amp;quot;},&lt;br /&gt;
        {&amp;quot;Gate Mode&amp;quot;},&lt;br /&gt;
        {&amp;quot;PCReset&amp;quot; }, // reset bar counter on manual pattern change&lt;br /&gt;
        &amp;#039;&amp;#039;&amp;#039;{&amp;quot;Loop&amp;quot;}&amp;#039;&amp;#039;&amp;#039;, // rstephane: LOOP LONG text&lt;br /&gt;
        };&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
* If you want you can already compile and see the results under the menu PERF menu (normally under the second page, your should see &amp;#039;LEN&amp;#039; on the first knob).&lt;br /&gt;
&lt;br /&gt;
* Now, &amp;#039;&amp;#039;&amp;#039;we will create our function&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* We will add a link between this function and our knob.&lt;br /&gt;
&lt;br /&gt;
* open &amp;#039;&amp;#039;&amp;#039;midimessage.h&amp;#039;&amp;#039;&amp;#039; file&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        //for all parameters above 127 &amp;lt;- our case&lt;br /&gt;
        enum&lt;br /&gt;
        {&lt;br /&gt;
        ....&lt;br /&gt;
        // Again, place your parameter at a special place, right after the section:&lt;br /&gt;
        CC2_MIDI_NOTE1,&lt;br /&gt;
        CC2_MIDI_NOTE2,&lt;br /&gt;
        CC2_MIDI_NOTE3,&lt;br /&gt;
        CC2_MIDI_NOTE4,&lt;br /&gt;
        CC2_MIDI_NOTE5,&lt;br /&gt;
        CC2_MIDI_NOTE6,&lt;br /&gt;
        CC2_MIDI_NOTE7, // s/b 111 i think&lt;br /&gt;
        &lt;br /&gt;
        // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
        &amp;#039;&amp;#039;&amp;#039;CC2_LOOP,&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
        ....&lt;br /&gt;
        }&lt;br /&gt;
        Param2Enums;&lt;br /&gt;
&lt;br /&gt;
* open  &amp;#039;&amp;#039;&amp;#039;MidiParser.c&amp;#039;&amp;#039;&amp;#039; file &lt;br /&gt;
&lt;br /&gt;
        //-----------------------------------------------------------&lt;br /&gt;
        /** handle all incoming CCs and invoke action*/&lt;br /&gt;
        void &amp;#039;&amp;#039;&amp;#039;midiParser_ccHandler&amp;#039;&amp;#039;&amp;#039;(MidiMsg msg, uint8_t updateOriginalValue)&lt;br /&gt;
        {&lt;br /&gt;
        &lt;br /&gt;
        ...&lt;br /&gt;
        &lt;br /&gt;
        else //MIDI_CC2&lt;br /&gt;
        {&lt;br /&gt;
                const uint16_t paramNr = msg.data1+1 + 127;&lt;br /&gt;
&lt;br /&gt;
                if(updateOriginalValue) {&lt;br /&gt;
                        midiParser_originalCcValues[paramNr] = msg.data2;&lt;br /&gt;
                }&lt;br /&gt;
                switch(msg.data1)&lt;br /&gt;
                {&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_WAVE:&lt;br /&gt;
                                        voiceArray[0].transGen.waveform = msg.data2;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_VOL:&lt;br /&gt;
                                voiceArray[0].transGen.volume = msg.data2/127.f;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
        ...&lt;br /&gt;
                        case CC2_MUTE_1:&lt;br /&gt;
                        case CC2_MUTE_2:&lt;br /&gt;
                        case CC2_MUTE_3:&lt;br /&gt;
                        case CC2_MUTE_4:&lt;br /&gt;
                        case CC2_MUTE_5:&lt;br /&gt;
                        case CC2_MUTE_6:&lt;br /&gt;
                        case CC2_MUTE_7:&lt;br /&gt;
                        {&lt;br /&gt;
                                const uint8_t voiceNr = msg.data1 - CC2_MUTE_1;&lt;br /&gt;
                                if(msg.data2 == 0)&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,0);&lt;br /&gt;
                                }&lt;br /&gt;
                                else&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,1);&lt;br /&gt;
                                }&lt;br /&gt;
&lt;br /&gt;
                        }&lt;br /&gt;
                                break;&lt;br /&gt;
                            //&lt;br /&gt;
                            // rstephane MY FUNCTIONS&lt;br /&gt;
                            &amp;#039;&amp;#039;&amp;#039;case CC2_LOOP:&lt;br /&gt;
                                   if(msg.data2 == 16)  // reset the loop ! &lt;br /&gt;
                                   {	// we stop the loop effect and&lt;br /&gt;
                                          // go back to prevoious track lenght&lt;br /&gt;
                                          seq_setLoopLength(16);&lt;br /&gt;
                                   }&lt;br /&gt;
                                   else&lt;br /&gt;
                                   {	// we change the tracks lenght&lt;br /&gt;
                                          seq_setLoopLength(msg.data2);&lt;br /&gt;
                                   }&lt;br /&gt;
                                   break;&amp;#039;&amp;#039;&amp;#039;			&lt;br /&gt;
                                       &lt;br /&gt;
                        default:&lt;br /&gt;
                                break;&lt;br /&gt;
                                &lt;br /&gt;
                        ....&lt;br /&gt;
                        &lt;br /&gt;
                        &lt;br /&gt;
&lt;br /&gt;
* open &amp;#039;&amp;#039;&amp;#039;sequencer.h&amp;#039;&amp;#039;&amp;#039; file, add the line :  &lt;br /&gt;
        void seq_setLoopLength(uint8_t length);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* open &amp;#039;&amp;#039;&amp;#039;sequencer.c&amp;#039;&amp;#039;&amp;#039; file, add the function:&lt;br /&gt;
        void seq_setLoopLength(uint8_t length)&lt;br /&gt;
        {&lt;br /&gt;
        uint8_t i;&lt;br /&gt;
        // we set the new Loop Track Lenght&lt;br /&gt;
        for(i=0;i&amp;lt;NUM_TRACKS;i++) {&lt;br /&gt;
                seq_setTrackLength(i, length);	&lt;br /&gt;
        }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
* compile !&lt;br /&gt;
* upload on the machine with the new firmware&lt;br /&gt;
* test!&lt;/div&gt;</summary>
		<author><name>Rstephane</name></author>
		
	</entry>
	<entry>
		<id>http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=243</id>
		<title>How to create and add a new function to the LXR</title>
		<link rel="alternate" type="text/html" href="http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=243"/>
		<updated>2014-05-11T21:29:06Z</updated>

		<summary type="html">&lt;p&gt;Rstephane: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a DRAFT !!!! I will correct it during the next days :-)&lt;br /&gt;
&lt;br /&gt;
* GOAL:&lt;br /&gt;
* 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 :-)&lt;br /&gt;
* 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 :-)&lt;br /&gt;
&lt;br /&gt;
* First step, we start by adding a new knob &amp;#039;LEN&amp;#039; (for Length) in  the PERF menu on the LCD display.&lt;br /&gt;
&lt;br /&gt;
* Open the file &amp;#039;&amp;#039;&amp;#039;&amp;#039;Parameters.h&amp;#039;&amp;#039;&amp;#039;&amp;#039;, Add in the section &amp;#039;enum ParamEnums&amp;#039; the new parameter. In our case : PAR_LOOP&lt;br /&gt;
&lt;br /&gt;
        example: &lt;br /&gt;
        &lt;br /&gt;
        enum ParamEnums = {&lt;br /&gt;
        ...&lt;br /&gt;
        PAR_MIDI_NOTE1,&lt;br /&gt;
        PAR_MIDI_NOTE2,&lt;br /&gt;
        PAR_MIDI_NOTE3,&lt;br /&gt;
        PAR_MIDI_NOTE4,&lt;br /&gt;
        PAR_MIDI_NOTE5,&lt;br /&gt;
        PAR_MIDI_NOTE6,&lt;br /&gt;
        PAR_MIDI_NOTE7, // &amp;lt;--- YOUR parameters comes right after thoses lines...&lt;br /&gt;
        // You have to add all the new parameters right after a dedicated section in the code declaration &lt;br /&gt;
        //(otherwise you want link later the knob with the function you want to execute):&lt;br /&gt;
        PAR_LOOP,     &lt;br /&gt;
        ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* We need to open the &amp;#039;&amp;#039;&amp;#039;menu.c&amp;#039;&amp;#039;&amp;#039; file. we declare our parameter and its type :&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        menu.c&lt;br /&gt;
        //---------------------------------------------------------------&lt;br /&gt;
        // Parameter types. These correspond with ParamEnums and entries in parameter_values&lt;br /&gt;
        const enum Datatypes PROGMEM parameter_dtypes[NUM_PARAMS] = {&lt;br /&gt;
            /*PAR_NONE*/                         DTYPE_0B127,                                                        // 0&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM1*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM2*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM3*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_SNARE*/  DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
        ....&lt;br /&gt;
&lt;br /&gt;
* Place your parameter at a special place, right after the section:&lt;br /&gt;
&lt;br /&gt;
            /*PAR_MIDI_NOTE1*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE2*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE3*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE4*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE5*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE6*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE7*/                DTYPE_NOTE_NAME,&lt;br /&gt;
           &lt;br /&gt;
            // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
            /*PAR_LOOP*/                      DTYPE_1B16, // Values goes from 1 to 16 steps&lt;br /&gt;
            &lt;br /&gt;
            /*PAR_ROLL*/                         DTYPE_MENU | (MENU_ROLL_RATES&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_MORPH*/                         DTYPE_0B255,&lt;br /&gt;
            ...&lt;br /&gt;
                &lt;br /&gt;
&lt;br /&gt;
Here the list of parameters you can choose from...&lt;br /&gt;
&lt;br /&gt;
        Type of parameters:&lt;br /&gt;
        //-----------------------------------------------------------------&lt;br /&gt;
        enum Datatypes&lt;br /&gt;
        {&lt;br /&gt;
        DTYPE_0B255,        //0:255&lt;br /&gt;
        DTYPE_0B127,        //0-127&lt;br /&gt;
        DTYPE_PM100,        //-100:100&lt;br /&gt;
        DTYPE_MENU,                //text type outputs &lt;br /&gt;
        DTYPE_PM63,                //-63 &amp;lt;-&amp;gt; 63&lt;br /&gt;
        DTYPE_1B16,                //1-16&lt;br /&gt;
        DTYPE_ON_OFF,        //0-1&lt;br /&gt;
        DTYPE_MIX_FM,        //0-1&lt;br /&gt;
        DTYPE_TARGET_SELECTION_LFO,&lt;br /&gt;
        DTYPE_TARGET_SELECTION_VELO,        &lt;br /&gt;
        DTYPE_VOICE_LFO,&lt;br /&gt;
        DTYPE_AUTOM_TARGET,&lt;br /&gt;
        DTYPE_0b1,&lt;br /&gt;
        DTYPE_NOTE_NAME, // --AS eg C#0, D 1 for note name&lt;br /&gt;
        DTYPE_0B15,                //0-15&lt;br /&gt;
        /*15*/&lt;br /&gt;
        /*16*/&lt;br /&gt;
        // --AS warning, we can only have 16 on this list the way things are laid out&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
* oki, once this done, we need to fill other information in the code&lt;br /&gt;
&lt;br /&gt;
* Open the file &amp;#039;&amp;#039;&amp;#039;menuPages.h&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
* 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&lt;br /&gt;
&lt;br /&gt;
* in the section: const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM ... add your MENU (we want that our knob display a name &amp;#039;LEN&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
* in our case, we have:&lt;br /&gt;
&lt;br /&gt;
        const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM =&lt;br /&gt;
        {&lt;br /&gt;
        //page 1 - Voice 1&lt;br /&gt;
        {&lt;br /&gt;
        //sub page 1 - Oscillator&lt;br /&gt;
        {&lt;br /&gt;
        TEXT_COARSE,        TEXT_FINE,        TEXT_WAVEFORM,                TEXT_RND_VOICE,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,&lt;br /&gt;
        PAR_COARSE1,        PAR_FINE1,        PAR_OSC_WAVE_DRUM1,        PAR_RND_VOICE1,PAR_NONE,PAR_NONE,PAR_NONE,PAR_NONE&lt;br /&gt;
                },        &lt;br /&gt;
        ...&lt;br /&gt;
        //Page 10&lt;br /&gt;
        //---------------- Performance Mode Menu pages ---------------------------&lt;br /&gt;
        //These pages are shown when the selected mode is the &amp;quot;mute/pattern select&amp;quot; page&lt;br /&gt;
        //there is only one page with subpages shown for the whole mode&lt;br /&gt;
        {&lt;br /&gt;
        {		&lt;br /&gt;
        TEXT_SHUFFLE,	TEXT_ROLL_SPEED,	TEXT_X_FADE,	TEXT_SAMPLE_RATE,		 &amp;#039;&amp;#039;&amp;#039;TEXT_LOOP&amp;#039;&amp;#039;&amp;#039;,	TEXT_EMPTY,&lt;br /&gt;
        PAR_SHUFFLE,	&amp;#039;&amp;#039;&amp;#039;PAR_ROLL&amp;#039;&amp;#039;&amp;#039;,			PAR_MORPH,		PAR_VOICE_DECIMATION_ALL,		PAR_LOOP,&lt;br /&gt;
        },&lt;br /&gt;
        ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* We need now to declare the TEXT_LOOP and PAR_LOOP in other files :-)&lt;br /&gt;
&lt;br /&gt;
* Open file &amp;#039;&amp;#039;&amp;#039;menu.h&amp;#039;&amp;#039;&amp;#039;, go to section &amp;#039;NamesEnum&amp;#039;, add at the end the text &amp;#039;TEXT_LOOP&amp;quot; : &lt;br /&gt;
&lt;br /&gt;
        enum NamesEnum&lt;br /&gt;
        {&lt;br /&gt;
        TEXT_EMPTY = 0,                                        //0&lt;br /&gt;
        TEXT_COARSE,&lt;br /&gt;
        TEXT_FINE,&lt;br /&gt;
        TEXT_ATTACK,&lt;br /&gt;
        TEXT_DECAY,&lt;br /&gt;
        TEXT_PITCH_DECAY,&lt;br /&gt;
        TEXT_MOD_AMOUNT,                &lt;br /&gt;
        ....&lt;br /&gt;
        ....&lt;br /&gt;
        TEXT_BAR_RESET_MODE,&lt;br /&gt;
        TEXT_MIDI_CHAN_GLOBAL,&lt;br /&gt;
        &amp;#039;&amp;#039;&amp;#039;TEXT_LOOP&amp;#039;&amp;#039;&amp;#039;,        // rstephane: LOOP text &lt;br /&gt;
        NUM_NAMES&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
* Open &amp;#039;&amp;#039;&amp;#039;Cc2Text.c&amp;#039;&amp;#039;&amp;#039; file and under the section (i need to explain and complete this section)&lt;br /&gt;
&lt;br /&gt;
       {TEXT_COARSE, PAR_COARSE1},                         //2&lt;br /&gt;
       {TEXT_FINE, PAR_FINE1},&lt;br /&gt;
       {TEXT_WAVEFORM, PAR_OSC_WAVE_DRUM1},&lt;br /&gt;
       {TEXT_LOOP, PAR_LOOP}, // rstephane : added LOOP button &amp;lt;- no really needed, well pass trough this step                                   &lt;br /&gt;
                                        &lt;br /&gt;
&lt;br /&gt;
* Open the &amp;#039;&amp;#039;&amp;#039;menu.c&amp;#039;&amp;#039;&amp;#039; file, go to section &amp;#039;&amp;#039;&amp;#039;valueNames&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
        const Name valueNames[NUM_NAMES] PROGMEM =&lt;br /&gt;
        {&lt;br /&gt;
                {SHORT_EMPTY,CAT_EMPTY,LONG_EMPTY},&lt;br /&gt;
                ....&lt;br /&gt;
&lt;br /&gt;
* Add the following information:&lt;br /&gt;
                ....&lt;br /&gt;
                {SHORT_BAR_RESET_MODE, CAT_SEQUENCER, LONG_BAR_RESET_MODE}, // TEXT_BAR_RESET_MODE&lt;br /&gt;
                {SHORT_CHANNEL, CAT_MIDI, LONG_MIDI_CHANNEL}, // TEXT_MIDI_CHAN_GLOBAL&lt;br /&gt;
                {SHORT_LOOP, CAT_SEQUENCER, LONG_LOOP}, // rstephane: TEXT_LOOP&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
* We NEED declare it at the end of the section :-)&lt;br /&gt;
* now, open the &amp;#039;&amp;#039;&amp;#039;MenuText.h&amp;#039;&amp;#039;&amp;#039; file to declare the &amp;#039;&amp;#039;&amp;#039;short and long version of the TEXT&amp;#039;&amp;#039;&amp;#039; (TEXT_LOOP)&lt;br /&gt;
* go to section &amp;#039;const char longNames[][16] PROGMEM = &amp;#039; and &amp;#039;const char shortNames[][4] PROGMEM  = &amp;#039;&lt;br /&gt;
* add the parameters:&lt;br /&gt;
&lt;br /&gt;
        const char shortNames[][4] PROGMEM  = &lt;br /&gt;
        {&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        {&amp;quot;coa&amp;quot;},&lt;br /&gt;
        {&amp;quot;fin&amp;quot;},&lt;br /&gt;
        {&amp;quot;atk&amp;quot;},&lt;br /&gt;
        {&amp;quot;dec&amp;quot;},&lt;br /&gt;
        {&amp;quot;eg2&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        &lt;br /&gt;
        {&amp;quot;co2&amp;quot;},  // trigger clock out2 ppq&lt;br /&gt;
        {&amp;quot;pcr&amp;quot;}, // pattern change resets bar counter&lt;br /&gt;
        {&amp;quot;LEN&amp;quot;}, // rstephane: LEN for LOOP :-)&lt;br /&gt;
        &lt;br /&gt;
        };        &lt;br /&gt;
&lt;br /&gt;
        const char longNames[][16] PROGMEM = &lt;br /&gt;
        {&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        //01234567&lt;br /&gt;
        {&amp;quot;Coarse&amp;quot;},&lt;br /&gt;
        {&amp;quot;Fine&amp;quot;},&lt;br /&gt;
        {&amp;quot;Attack&amp;quot;},&lt;br /&gt;
        {&amp;quot;Decay&amp;quot;},&lt;br /&gt;
        {&amp;quot;Amount&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        {&amp;quot;Out2 PPQ&amp;quot;},&lt;br /&gt;
        {&amp;quot;Gate Mode&amp;quot;},&lt;br /&gt;
        {&amp;quot;PCReset&amp;quot; }, // reset bar counter on manual pattern change&lt;br /&gt;
        {&amp;quot;Loop&amp;quot;}, // rstephane: LOOP LONG text&lt;br /&gt;
        };&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
* If you want you can already compile and see the results under the menu PERF menu (normally under the second page, your should see &amp;#039;LEN&amp;#039; on the first knob).&lt;br /&gt;
&lt;br /&gt;
* Now, &amp;#039;&amp;#039;&amp;#039;we will create our function&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* We will add a link between this function and our knob.&lt;br /&gt;
&lt;br /&gt;
* open &amp;#039;&amp;#039;&amp;#039;midimessage.h&amp;#039;&amp;#039;&amp;#039; file&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        //for all parameters above 127 &amp;lt;- our case&lt;br /&gt;
        enum&lt;br /&gt;
        {&lt;br /&gt;
        ....&lt;br /&gt;
        // Again, place your parameter at a special place, right after the section:&lt;br /&gt;
        CC2_MIDI_NOTE1,&lt;br /&gt;
        CC2_MIDI_NOTE2,&lt;br /&gt;
        CC2_MIDI_NOTE3,&lt;br /&gt;
        CC2_MIDI_NOTE4,&lt;br /&gt;
        CC2_MIDI_NOTE5,&lt;br /&gt;
        CC2_MIDI_NOTE6,&lt;br /&gt;
        CC2_MIDI_NOTE7, // s/b 111 i think&lt;br /&gt;
        &lt;br /&gt;
        // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
        CC2_LOOP,&lt;br /&gt;
        ....&lt;br /&gt;
        }&lt;br /&gt;
        Param2Enums;&lt;br /&gt;
&lt;br /&gt;
* open  &amp;#039;&amp;#039;&amp;#039;MidiParser.c&amp;#039;&amp;#039;&amp;#039; file &lt;br /&gt;
&lt;br /&gt;
        //-----------------------------------------------------------&lt;br /&gt;
        /** handle all incoming CCs and invoke action*/&lt;br /&gt;
        void midiParser_ccHandler(MidiMsg msg, uint8_t updateOriginalValue)&lt;br /&gt;
        {&lt;br /&gt;
        &lt;br /&gt;
        ...&lt;br /&gt;
        &lt;br /&gt;
        else //MIDI_CC2&lt;br /&gt;
        {&lt;br /&gt;
                const uint16_t paramNr = msg.data1+1 + 127;&lt;br /&gt;
&lt;br /&gt;
                if(updateOriginalValue) {&lt;br /&gt;
                        midiParser_originalCcValues[paramNr] = msg.data2;&lt;br /&gt;
                }&lt;br /&gt;
                switch(msg.data1)&lt;br /&gt;
                {&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_WAVE:&lt;br /&gt;
                                        voiceArray[0].transGen.waveform = msg.data2;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_VOL:&lt;br /&gt;
                                voiceArray[0].transGen.volume = msg.data2/127.f;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
        ...&lt;br /&gt;
                        case CC2_MUTE_1:&lt;br /&gt;
                        case CC2_MUTE_2:&lt;br /&gt;
                        case CC2_MUTE_3:&lt;br /&gt;
                        case CC2_MUTE_4:&lt;br /&gt;
                        case CC2_MUTE_5:&lt;br /&gt;
                        case CC2_MUTE_6:&lt;br /&gt;
                        case CC2_MUTE_7:&lt;br /&gt;
                        {&lt;br /&gt;
                                const uint8_t voiceNr = msg.data1 - CC2_MUTE_1;&lt;br /&gt;
                                if(msg.data2 == 0)&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,0);&lt;br /&gt;
                                }&lt;br /&gt;
                                else&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,1);&lt;br /&gt;
                                }&lt;br /&gt;
&lt;br /&gt;
                        }&lt;br /&gt;
                                break;&lt;br /&gt;
                            //&lt;br /&gt;
                            // rstephane MY FUNCTIONS&lt;br /&gt;
                            case CC2_LOOP:&lt;br /&gt;
                                   if(msg.data2 == 16)  // reset the loop ! &lt;br /&gt;
                                   {	// we stop the loop effect and&lt;br /&gt;
                                          // go back to prevoious track lenght&lt;br /&gt;
                                          seq_setLoopLength(16);&lt;br /&gt;
                                   }&lt;br /&gt;
                                   else&lt;br /&gt;
                                   {	// we change the tracks lenght&lt;br /&gt;
                                          seq_setLoopLength(msg.data2);&lt;br /&gt;
                                   }&lt;br /&gt;
                                   break;			&lt;br /&gt;
                                       &lt;br /&gt;
                        default:&lt;br /&gt;
                                break;&lt;br /&gt;
                                &lt;br /&gt;
                        ....&lt;br /&gt;
                        &lt;br /&gt;
                        &lt;br /&gt;
&lt;br /&gt;
* open &amp;#039;&amp;#039;&amp;#039;sequencer.h&amp;#039;&amp;#039;&amp;#039; file&lt;br /&gt;
* add the function  &lt;br /&gt;
        void seq_setLoopLength(uint8_t length);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* open &amp;#039;&amp;#039;&amp;#039;sequencer.c&amp;#039;&amp;#039;&amp;#039; file, add:&lt;br /&gt;
        void seq_setLoopLength(uint8_t length)&lt;br /&gt;
        {&lt;br /&gt;
        uint8_t i;&lt;br /&gt;
        // we set the new Loop Track Lenght&lt;br /&gt;
        for(i=0;i&amp;lt;NUM_TRACKS;i++) {&lt;br /&gt;
                seq_setTrackLength(i, length);	&lt;br /&gt;
        }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
* compile !&lt;br /&gt;
* upload on the machine with the new firmware&lt;br /&gt;
* test!&lt;/div&gt;</summary>
		<author><name>Rstephane</name></author>
		
	</entry>
	<entry>
		<id>http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=242</id>
		<title>How to create and add a new function to the LXR</title>
		<link rel="alternate" type="text/html" href="http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=242"/>
		<updated>2014-05-11T21:23:50Z</updated>

		<summary type="html">&lt;p&gt;Rstephane: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a DRAFT !!!! I will correct it during the next days :-)&lt;br /&gt;
&lt;br /&gt;
* GOAL:&lt;br /&gt;
* 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 :-)&lt;br /&gt;
* 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 :-)&lt;br /&gt;
&lt;br /&gt;
* First step, we start by adding a new knob &amp;#039;LEN&amp;#039; (for Length) in  the PERF menu on the LCD display.&lt;br /&gt;
&lt;br /&gt;
* Open the file &amp;#039;&amp;#039;&amp;#039;&amp;#039;Parameters.h&amp;#039;&amp;#039;&amp;#039;&amp;#039;, Add in the section &amp;#039;enum ParamEnums&amp;#039; the new parameter. In our case : PAR_LOOP&lt;br /&gt;
&lt;br /&gt;
        example: &lt;br /&gt;
        &lt;br /&gt;
        enum ParamEnums = {&lt;br /&gt;
        ...&lt;br /&gt;
        PAR_MIDI_NOTE1,&lt;br /&gt;
        PAR_MIDI_NOTE2,&lt;br /&gt;
        PAR_MIDI_NOTE3,&lt;br /&gt;
        PAR_MIDI_NOTE4,&lt;br /&gt;
        PAR_MIDI_NOTE5,&lt;br /&gt;
        PAR_MIDI_NOTE6,&lt;br /&gt;
        PAR_MIDI_NOTE7, // &amp;lt;--- YOUR parameters comes right after thoses lines...&lt;br /&gt;
        // You have to add all the new parameters right after a dedicated section in the code declaration &lt;br /&gt;
        //(otherwise you want link later the knob with the function you want to execute):&lt;br /&gt;
        PAR_LOOP,     &lt;br /&gt;
        ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* We need to open the &amp;#039;&amp;#039;&amp;#039;menu.c&amp;#039;&amp;#039;&amp;#039; file. we declare our parameter and its type :&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        menu.c&lt;br /&gt;
        //---------------------------------------------------------------&lt;br /&gt;
        // Parameter types. These correspond with ParamEnums and entries in parameter_values&lt;br /&gt;
        const enum Datatypes PROGMEM parameter_dtypes[NUM_PARAMS] = {&lt;br /&gt;
            /*PAR_NONE*/                         DTYPE_0B127,                                                        // 0&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM1*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM2*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM3*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_SNARE*/  DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
        ....&lt;br /&gt;
&lt;br /&gt;
* Place your parameter at a special place, right after the section:&lt;br /&gt;
&lt;br /&gt;
            /*PAR_MIDI_NOTE1*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE2*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE3*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE4*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE5*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE6*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE7*/                DTYPE_NOTE_NAME,&lt;br /&gt;
           &lt;br /&gt;
            // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
            /*PAR_LOOP*/                      DTYPE_1B16, // Values goes from 1 to 16 steps&lt;br /&gt;
            &lt;br /&gt;
            /*PAR_ROLL*/                         DTYPE_MENU | (MENU_ROLL_RATES&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_MORPH*/                         DTYPE_0B255,&lt;br /&gt;
            ...&lt;br /&gt;
                &lt;br /&gt;
&lt;br /&gt;
Here the list of parameters you can choose from...&lt;br /&gt;
&lt;br /&gt;
        Type of parameters:&lt;br /&gt;
        //-----------------------------------------------------------------&lt;br /&gt;
        enum Datatypes&lt;br /&gt;
        {&lt;br /&gt;
        DTYPE_0B255,        //0:255&lt;br /&gt;
        DTYPE_0B127,        //0-127&lt;br /&gt;
        DTYPE_PM100,        //-100:100&lt;br /&gt;
        DTYPE_MENU,                //text type outputs &lt;br /&gt;
        DTYPE_PM63,                //-63 &amp;lt;-&amp;gt; 63&lt;br /&gt;
        DTYPE_1B16,                //1-16&lt;br /&gt;
        DTYPE_ON_OFF,        //0-1&lt;br /&gt;
        DTYPE_MIX_FM,        //0-1&lt;br /&gt;
        DTYPE_TARGET_SELECTION_LFO,&lt;br /&gt;
        DTYPE_TARGET_SELECTION_VELO,        &lt;br /&gt;
        DTYPE_VOICE_LFO,&lt;br /&gt;
        DTYPE_AUTOM_TARGET,&lt;br /&gt;
        DTYPE_0b1,&lt;br /&gt;
        DTYPE_NOTE_NAME, // --AS eg C#0, D 1 for note name&lt;br /&gt;
        DTYPE_0B15,                //0-15&lt;br /&gt;
        /*15*/&lt;br /&gt;
        /*16*/&lt;br /&gt;
        // --AS warning, we can only have 16 on this list the way things are laid out&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
* oki, once this done, we need to fill other information in the code&lt;br /&gt;
&lt;br /&gt;
* Open the file &amp;#039;&amp;#039;&amp;#039;menuPages.h&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
* 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&lt;br /&gt;
&lt;br /&gt;
* in the section: const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM ... add your MENU (we want that our knob display a name &amp;#039;LEN&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
* in our case, we have:&lt;br /&gt;
&lt;br /&gt;
        const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM =&lt;br /&gt;
        {&lt;br /&gt;
        //page 1 - Voice 1&lt;br /&gt;
        {&lt;br /&gt;
        //sub page 1 - Oscillator&lt;br /&gt;
        {&lt;br /&gt;
        TEXT_COARSE,        TEXT_FINE,        TEXT_WAVEFORM,                TEXT_RND_VOICE,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,&lt;br /&gt;
        PAR_COARSE1,        PAR_FINE1,        PAR_OSC_WAVE_DRUM1,        PAR_RND_VOICE1,PAR_NONE,PAR_NONE,PAR_NONE,PAR_NONE&lt;br /&gt;
                },        &lt;br /&gt;
        ...&lt;br /&gt;
        //Page 10&lt;br /&gt;
        //---------------- Performance Mode Menu pages ---------------------------&lt;br /&gt;
        //These pages are shown when the selected mode is the &amp;quot;mute/pattern select&amp;quot; page&lt;br /&gt;
        //there is only one page with subpages shown for the whole mode&lt;br /&gt;
        {&lt;br /&gt;
        {		&lt;br /&gt;
        TEXT_SHUFFLE,	TEXT_ROLL_SPEED,	TEXT_X_FADE,	TEXT_SAMPLE_RATE,		 &amp;#039;&amp;#039;&amp;#039;TEXT_LOOP&amp;#039;&amp;#039;&amp;#039;,	TEXT_EMPTY,&lt;br /&gt;
        PAR_SHUFFLE,	&amp;#039;&amp;#039;&amp;#039;PAR_ROLL&amp;#039;&amp;#039;&amp;#039;,			PAR_MORPH,		PAR_VOICE_DECIMATION_ALL,		PAR_LOOP,&lt;br /&gt;
        },&lt;br /&gt;
        ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* We need now to declare the TEXT_LOOP and PAR_LOOP in other files :-)&lt;br /&gt;
&lt;br /&gt;
* Open file &amp;#039;&amp;#039;&amp;#039;menu.h&amp;#039;&amp;#039;&amp;#039;, and go to section &lt;br /&gt;
&lt;br /&gt;
        enum NamesEnum&lt;br /&gt;
        {&lt;br /&gt;
        TEXT_EMPTY = 0,                                        //0&lt;br /&gt;
        TEXT_COARSE,&lt;br /&gt;
        TEXT_FINE,&lt;br /&gt;
        TEXT_ATTACK,&lt;br /&gt;
        TEXT_DECAY,&lt;br /&gt;
        TEXT_PITCH_DECAY,&lt;br /&gt;
        TEXT_MOD_AMOUNT,                &lt;br /&gt;
        ....&lt;br /&gt;
&lt;br /&gt;
* Add at the end, the text &amp;#039;TEXT_LOOP&amp;quot; : &lt;br /&gt;
        &lt;br /&gt;
        ....&lt;br /&gt;
        TEXT_BAR_RESET_MODE,&lt;br /&gt;
        TEXT_MIDI_CHAN_GLOBAL,&lt;br /&gt;
        &amp;#039;&amp;#039;&amp;#039;TEXT_LOOP&amp;#039;&amp;#039;&amp;#039;,        // rstephane: LOOP text &lt;br /&gt;
        NUM_NAMES&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
* Open &amp;#039;&amp;#039;&amp;#039;Cc2Text.c&amp;#039;&amp;#039;&amp;#039; file and under the section (i need to explain and complete this section)&lt;br /&gt;
&lt;br /&gt;
       {TEXT_COARSE, PAR_COARSE1},                         //2&lt;br /&gt;
       {TEXT_FINE, PAR_FINE1},&lt;br /&gt;
       {TEXT_WAVEFORM, PAR_OSC_WAVE_DRUM1},&lt;br /&gt;
       {TEXT_LOOP, PAR_LOOP}, // rstephane : added LOOP button &amp;lt;- no really needed, well pass trough this step                                   &lt;br /&gt;
                                        &lt;br /&gt;
&lt;br /&gt;
* Open the &amp;#039;&amp;#039;&amp;#039;menu.c&amp;#039;&amp;#039;&amp;#039; file, go to section &amp;#039;&amp;#039;&amp;#039;valueNames&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
        const Name valueNames[NUM_NAMES] PROGMEM =&lt;br /&gt;
        {&lt;br /&gt;
                {SHORT_EMPTY,CAT_EMPTY,LONG_EMPTY},&lt;br /&gt;
                ....&lt;br /&gt;
&lt;br /&gt;
* Add the following information:&lt;br /&gt;
                ....&lt;br /&gt;
                {SHORT_BAR_RESET_MODE, CAT_SEQUENCER, LONG_BAR_RESET_MODE}, // TEXT_BAR_RESET_MODE&lt;br /&gt;
                {SHORT_CHANNEL, CAT_MIDI, LONG_MIDI_CHANNEL}, // TEXT_MIDI_CHAN_GLOBAL&lt;br /&gt;
                {SHORT_LOOP, CAT_SEQUENCER, LONG_LOOP}, // rstephane: TEXT_LOOP&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
* We NEED declare it at the end of the section :-)&lt;br /&gt;
* now, open the &amp;#039;&amp;#039;&amp;#039;MenuText.h&amp;#039;&amp;#039;&amp;#039; file to declare the &amp;#039;&amp;#039;&amp;#039;short and long version of the TEXT&amp;#039;&amp;#039;&amp;#039; (TEXT_LOOP)&lt;br /&gt;
* go to section &amp;#039;const char longNames[][16] PROGMEM = &amp;#039; and &amp;#039;const char shortNames[][4] PROGMEM  = &amp;#039;&lt;br /&gt;
* add the parameters:&lt;br /&gt;
&lt;br /&gt;
        const char shortNames[][4] PROGMEM  = &lt;br /&gt;
        {&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        {&amp;quot;coa&amp;quot;},&lt;br /&gt;
        {&amp;quot;fin&amp;quot;},&lt;br /&gt;
        {&amp;quot;atk&amp;quot;},&lt;br /&gt;
        {&amp;quot;dec&amp;quot;},&lt;br /&gt;
        {&amp;quot;eg2&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        &lt;br /&gt;
        {&amp;quot;co2&amp;quot;},  // trigger clock out2 ppq&lt;br /&gt;
        {&amp;quot;pcr&amp;quot;}, // pattern change resets bar counter&lt;br /&gt;
        {&amp;quot;LEN&amp;quot;}, // rstephane: LEN for LOOP :-)&lt;br /&gt;
        &lt;br /&gt;
        };        &lt;br /&gt;
&lt;br /&gt;
        const char longNames[][16] PROGMEM = &lt;br /&gt;
        {&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        //01234567&lt;br /&gt;
        {&amp;quot;Coarse&amp;quot;},&lt;br /&gt;
        {&amp;quot;Fine&amp;quot;},&lt;br /&gt;
        {&amp;quot;Attack&amp;quot;},&lt;br /&gt;
        {&amp;quot;Decay&amp;quot;},&lt;br /&gt;
        {&amp;quot;Amount&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        {&amp;quot;Out2 PPQ&amp;quot;},&lt;br /&gt;
        {&amp;quot;Gate Mode&amp;quot;},&lt;br /&gt;
        {&amp;quot;PCReset&amp;quot; }, // reset bar counter on manual pattern change&lt;br /&gt;
        {&amp;quot;Loop&amp;quot;}, // rstephane: LOOP LONG text&lt;br /&gt;
        };&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
* If you want you can already compile and see the results under the menu PERF menu (normally under the second page, your should see &amp;#039;LEN&amp;#039; on the first knob).&lt;br /&gt;
&lt;br /&gt;
* Now, &amp;#039;&amp;#039;&amp;#039;we will create our function&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* We will add a link between this function and our knob.&lt;br /&gt;
&lt;br /&gt;
* open &amp;#039;&amp;#039;&amp;#039;midimessage.h&amp;#039;&amp;#039;&amp;#039; file&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        //for all parameters above 127 &amp;lt;- our case&lt;br /&gt;
        enum&lt;br /&gt;
        {&lt;br /&gt;
        ....&lt;br /&gt;
        // Again, place your parameter at a special place, right after the section:&lt;br /&gt;
        CC2_MIDI_NOTE1,&lt;br /&gt;
        CC2_MIDI_NOTE2,&lt;br /&gt;
        CC2_MIDI_NOTE3,&lt;br /&gt;
        CC2_MIDI_NOTE4,&lt;br /&gt;
        CC2_MIDI_NOTE5,&lt;br /&gt;
        CC2_MIDI_NOTE6,&lt;br /&gt;
        CC2_MIDI_NOTE7, // s/b 111 i think&lt;br /&gt;
        &lt;br /&gt;
        // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
        CC2_LOOP,&lt;br /&gt;
        ....&lt;br /&gt;
        }&lt;br /&gt;
        Param2Enums;&lt;br /&gt;
&lt;br /&gt;
* open  &amp;#039;&amp;#039;&amp;#039;MidiParser.c&amp;#039;&amp;#039;&amp;#039; file &lt;br /&gt;
&lt;br /&gt;
        //-----------------------------------------------------------&lt;br /&gt;
        /** handle all incoming CCs and invoke action*/&lt;br /&gt;
        void midiParser_ccHandler(MidiMsg msg, uint8_t updateOriginalValue)&lt;br /&gt;
        {&lt;br /&gt;
        &lt;br /&gt;
        ...&lt;br /&gt;
        &lt;br /&gt;
        else //MIDI_CC2&lt;br /&gt;
        {&lt;br /&gt;
                const uint16_t paramNr = msg.data1+1 + 127;&lt;br /&gt;
&lt;br /&gt;
                if(updateOriginalValue) {&lt;br /&gt;
                        midiParser_originalCcValues[paramNr] = msg.data2;&lt;br /&gt;
                }&lt;br /&gt;
                switch(msg.data1)&lt;br /&gt;
                {&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_WAVE:&lt;br /&gt;
                                        voiceArray[0].transGen.waveform = msg.data2;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_VOL:&lt;br /&gt;
                                voiceArray[0].transGen.volume = msg.data2/127.f;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
        ...&lt;br /&gt;
                        case CC2_MUTE_1:&lt;br /&gt;
                        case CC2_MUTE_2:&lt;br /&gt;
                        case CC2_MUTE_3:&lt;br /&gt;
                        case CC2_MUTE_4:&lt;br /&gt;
                        case CC2_MUTE_5:&lt;br /&gt;
                        case CC2_MUTE_6:&lt;br /&gt;
                        case CC2_MUTE_7:&lt;br /&gt;
                        {&lt;br /&gt;
                                const uint8_t voiceNr = msg.data1 - CC2_MUTE_1;&lt;br /&gt;
                                if(msg.data2 == 0)&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,0);&lt;br /&gt;
                                }&lt;br /&gt;
                                else&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,1);&lt;br /&gt;
                                }&lt;br /&gt;
&lt;br /&gt;
                        }&lt;br /&gt;
                                break;&lt;br /&gt;
                            //&lt;br /&gt;
                            // rstephane MY FUNCTIONS&lt;br /&gt;
                            case CC2_LOOP:&lt;br /&gt;
                                   if(msg.data2 == 16)  // reset the loop ! &lt;br /&gt;
                                   {	// we stop the loop effect and&lt;br /&gt;
                                          // go back to prevoious track lenght&lt;br /&gt;
                                          seq_setLoopLength(16);&lt;br /&gt;
                                   }&lt;br /&gt;
                                   else&lt;br /&gt;
                                   {	// we change the tracks lenght&lt;br /&gt;
                                          seq_setLoopLength(msg.data2);&lt;br /&gt;
                                   }&lt;br /&gt;
                                   break;			&lt;br /&gt;
                                       &lt;br /&gt;
                        default:&lt;br /&gt;
                                break;&lt;br /&gt;
                                &lt;br /&gt;
                        ....&lt;br /&gt;
                        &lt;br /&gt;
                        &lt;br /&gt;
&lt;br /&gt;
* open &amp;#039;&amp;#039;&amp;#039;sequencer.h&amp;#039;&amp;#039;&amp;#039; file&lt;br /&gt;
* add the function  &lt;br /&gt;
        void seq_setLoopLength(uint8_t length);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* open &amp;#039;&amp;#039;&amp;#039;sequencer.c&amp;#039;&amp;#039;&amp;#039; file, add:&lt;br /&gt;
        void seq_setLoopLength(uint8_t length)&lt;br /&gt;
        {&lt;br /&gt;
        uint8_t i;&lt;br /&gt;
        // we set the new Loop Track Lenght&lt;br /&gt;
        for(i=0;i&amp;lt;NUM_TRACKS;i++) {&lt;br /&gt;
                seq_setTrackLength(i, length);	&lt;br /&gt;
        }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
* compile !&lt;br /&gt;
* upload on the machine with the new firmware&lt;br /&gt;
* test!&lt;/div&gt;</summary>
		<author><name>Rstephane</name></author>
		
	</entry>
	<entry>
		<id>http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=241</id>
		<title>How to create and add a new function to the LXR</title>
		<link rel="alternate" type="text/html" href="http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=241"/>
		<updated>2014-05-11T21:18:13Z</updated>

		<summary type="html">&lt;p&gt;Rstephane: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a DRAFT !!!! I will correct it during the next days :-)&lt;br /&gt;
&lt;br /&gt;
* GOAL:&lt;br /&gt;
* 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 :-)&lt;br /&gt;
* 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 :-)&lt;br /&gt;
&lt;br /&gt;
* First step, we start by adding a new knob &amp;#039;LEN&amp;#039; (for Length) in  the PERF menu on the LCD display.&lt;br /&gt;
&lt;br /&gt;
* Open the file &amp;#039;&amp;#039;&amp;#039;&amp;#039;Parameters.h&amp;#039;&amp;#039;&amp;#039;&amp;#039;, we first declare our parameter and its type.&lt;br /&gt;
&lt;br /&gt;
* Add in the section: &amp;#039;enum ParamEnums&amp;#039; your new parameter. In our case we will add the parameter : PAR_LOOP&lt;br /&gt;
&lt;br /&gt;
* 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):&lt;br /&gt;
&lt;br /&gt;
        example: &lt;br /&gt;
        &lt;br /&gt;
        enum ParamEnums = {&lt;br /&gt;
        ...&lt;br /&gt;
        PAR_MIDI_NOTE1,&lt;br /&gt;
        PAR_MIDI_NOTE2,&lt;br /&gt;
        PAR_MIDI_NOTE3,&lt;br /&gt;
        PAR_MIDI_NOTE4,&lt;br /&gt;
        PAR_MIDI_NOTE5,&lt;br /&gt;
        PAR_MIDI_NOTE6,&lt;br /&gt;
        PAR_MIDI_NOTE7,&lt;br /&gt;
        // YOUR parameters comes right after thoses lines...&lt;br /&gt;
                   &lt;br /&gt;
        // rstephane MY VALUES ADDED FOR LOOP FUNCTION&lt;br /&gt;
        PAR_LOOP,     &lt;br /&gt;
        ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* We need to open the &amp;#039;&amp;#039;&amp;#039;menu.c&amp;#039;&amp;#039;&amp;#039; file. we want that our knob display a name &amp;#039;LEN&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        menu.c&lt;br /&gt;
        //---------------------------------------------------------------&lt;br /&gt;
        // Parameter types. These correspond with ParamEnums and entries in parameter_values&lt;br /&gt;
        const enum Datatypes PROGMEM parameter_dtypes[NUM_PARAMS] = {&lt;br /&gt;
            /*PAR_NONE*/                         DTYPE_0B127,                                                        // 0&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM1*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM2*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM3*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_SNARE*/  DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
        ....&lt;br /&gt;
&lt;br /&gt;
* Place your parameter at a special place, right after the section:&lt;br /&gt;
&lt;br /&gt;
            /*PAR_MIDI_NOTE1*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE2*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE3*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE4*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE5*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE6*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE7*/                DTYPE_NOTE_NAME,&lt;br /&gt;
           &lt;br /&gt;
            // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
            /*PAR_LOOP*/                      DTYPE_1B16, // Values goes from 1 to 16 steps&lt;br /&gt;
            &lt;br /&gt;
            /*PAR_ROLL*/                         DTYPE_MENU | (MENU_ROLL_RATES&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_MORPH*/                         DTYPE_0B255,&lt;br /&gt;
            ...&lt;br /&gt;
                &lt;br /&gt;
&lt;br /&gt;
Here the list of parameters you can choose from...&lt;br /&gt;
&lt;br /&gt;
        Type of parameters:&lt;br /&gt;
        //-----------------------------------------------------------------&lt;br /&gt;
        enum Datatypes&lt;br /&gt;
        {&lt;br /&gt;
        DTYPE_0B255,        //0:255&lt;br /&gt;
        DTYPE_0B127,        //0-127&lt;br /&gt;
        DTYPE_PM100,        //-100:100&lt;br /&gt;
        DTYPE_MENU,                //text type outputs &lt;br /&gt;
        DTYPE_PM63,                //-63 &amp;lt;-&amp;gt; 63&lt;br /&gt;
        DTYPE_1B16,                //1-16&lt;br /&gt;
        DTYPE_ON_OFF,        //0-1&lt;br /&gt;
        DTYPE_MIX_FM,        //0-1&lt;br /&gt;
        DTYPE_TARGET_SELECTION_LFO,&lt;br /&gt;
        DTYPE_TARGET_SELECTION_VELO,        &lt;br /&gt;
        DTYPE_VOICE_LFO,&lt;br /&gt;
        DTYPE_AUTOM_TARGET,&lt;br /&gt;
        DTYPE_0b1,&lt;br /&gt;
        DTYPE_NOTE_NAME, // --AS eg C#0, D 1 for note name&lt;br /&gt;
        DTYPE_0B15,                //0-15&lt;br /&gt;
        /*15*/&lt;br /&gt;
        /*16*/&lt;br /&gt;
        // --AS warning, we can only have 16 on this list the way things are laid out&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
* oki, once this done, we need to fill other information in the code&lt;br /&gt;
&lt;br /&gt;
* Open the file &amp;#039;&amp;#039;&amp;#039;menuPages.h&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
* 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&lt;br /&gt;
&lt;br /&gt;
* in the section: const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM ... add your MENU &lt;br /&gt;
&lt;br /&gt;
* in our case, we have:&lt;br /&gt;
&lt;br /&gt;
        const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM =&lt;br /&gt;
        {&lt;br /&gt;
        //page 1 - Voice 1&lt;br /&gt;
        {&lt;br /&gt;
        //sub page 1 - Oscillator&lt;br /&gt;
        {&lt;br /&gt;
        TEXT_COARSE,        TEXT_FINE,        TEXT_WAVEFORM,                TEXT_RND_VOICE,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,&lt;br /&gt;
        PAR_COARSE1,        PAR_FINE1,        PAR_OSC_WAVE_DRUM1,        PAR_RND_VOICE1,PAR_NONE,PAR_NONE,PAR_NONE,PAR_NONE&lt;br /&gt;
                },        &lt;br /&gt;
        ...&lt;br /&gt;
        //Page 10&lt;br /&gt;
        //---------------- Performance Mode Menu pages ---------------------------&lt;br /&gt;
        //These pages are shown when the selected mode is the &amp;quot;mute/pattern select&amp;quot; page&lt;br /&gt;
        //there is only one page with subpages shown for the whole mode&lt;br /&gt;
        {&lt;br /&gt;
        {		&lt;br /&gt;
        TEXT_SHUFFLE,	TEXT_ROLL_SPEED,	TEXT_X_FADE,	TEXT_SAMPLE_RATE,		 &amp;#039;&amp;#039;&amp;#039;TEXT_LOOP&amp;#039;&amp;#039;&amp;#039;,	TEXT_EMPTY,&lt;br /&gt;
        PAR_SHUFFLE,	&amp;#039;&amp;#039;&amp;#039;PAR_ROLL&amp;#039;&amp;#039;&amp;#039;,			PAR_MORPH,		PAR_VOICE_DECIMATION_ALL,		PAR_LOOP,&lt;br /&gt;
        },&lt;br /&gt;
        ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* We need now to declare the TEXT_LOOP and PAR_LOOP in other files :-)&lt;br /&gt;
&lt;br /&gt;
* Open file &amp;#039;&amp;#039;&amp;#039;menu.h&amp;#039;&amp;#039;&amp;#039;, and go to section &lt;br /&gt;
&lt;br /&gt;
        enum NamesEnum&lt;br /&gt;
        {&lt;br /&gt;
        TEXT_EMPTY = 0,                                        //0&lt;br /&gt;
        TEXT_COARSE,&lt;br /&gt;
        TEXT_FINE,&lt;br /&gt;
        TEXT_ATTACK,&lt;br /&gt;
        TEXT_DECAY,&lt;br /&gt;
        TEXT_PITCH_DECAY,&lt;br /&gt;
        TEXT_MOD_AMOUNT,                &lt;br /&gt;
        ....&lt;br /&gt;
&lt;br /&gt;
* Add at the end, the text &amp;#039;TEXT_LOOP&amp;quot; : &lt;br /&gt;
        &lt;br /&gt;
        ....&lt;br /&gt;
        TEXT_BAR_RESET_MODE,&lt;br /&gt;
        TEXT_MIDI_CHAN_GLOBAL,&lt;br /&gt;
        &amp;#039;&amp;#039;&amp;#039;TEXT_LOOP&amp;#039;&amp;#039;&amp;#039;,        // rstephane: LOOP text &lt;br /&gt;
        NUM_NAMES&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
* Open &amp;#039;&amp;#039;&amp;#039;Cc2Text.c&amp;#039;&amp;#039;&amp;#039; file and under the section (i need to explain and complete this section)&lt;br /&gt;
&lt;br /&gt;
       {TEXT_COARSE, PAR_COARSE1},                         //2&lt;br /&gt;
       {TEXT_FINE, PAR_FINE1},&lt;br /&gt;
       {TEXT_WAVEFORM, PAR_OSC_WAVE_DRUM1},&lt;br /&gt;
       {TEXT_LOOP, PAR_LOOP}, // rstephane : added LOOP button &amp;lt;- no really needed, well pass trough this step                                   &lt;br /&gt;
                                        &lt;br /&gt;
&lt;br /&gt;
* Open the &amp;#039;&amp;#039;&amp;#039;menu.c&amp;#039;&amp;#039;&amp;#039; file, go to section &amp;#039;&amp;#039;&amp;#039;valueNames&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
        const Name valueNames[NUM_NAMES] PROGMEM =&lt;br /&gt;
        {&lt;br /&gt;
                {SHORT_EMPTY,CAT_EMPTY,LONG_EMPTY},&lt;br /&gt;
                ....&lt;br /&gt;
&lt;br /&gt;
* Add the following information:&lt;br /&gt;
                ....&lt;br /&gt;
                {SHORT_BAR_RESET_MODE, CAT_SEQUENCER, LONG_BAR_RESET_MODE}, // TEXT_BAR_RESET_MODE&lt;br /&gt;
                {SHORT_CHANNEL, CAT_MIDI, LONG_MIDI_CHANNEL}, // TEXT_MIDI_CHAN_GLOBAL&lt;br /&gt;
                {SHORT_LOOP, CAT_SEQUENCER, LONG_LOOP}, // rstephane: TEXT_LOOP&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
* We NEED declare it at the end of the section :-)&lt;br /&gt;
* now, open the &amp;#039;&amp;#039;&amp;#039;MenuText.h&amp;#039;&amp;#039;&amp;#039; file to declare the &amp;#039;&amp;#039;&amp;#039;short and long version of the TEXT&amp;#039;&amp;#039;&amp;#039; (TEXT_LOOP)&lt;br /&gt;
* go to section &amp;#039;const char longNames[][16] PROGMEM = &amp;#039; and &amp;#039;const char shortNames[][4] PROGMEM  = &amp;#039;&lt;br /&gt;
* add the parameters:&lt;br /&gt;
&lt;br /&gt;
        const char shortNames[][4] PROGMEM  = &lt;br /&gt;
        {&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        {&amp;quot;coa&amp;quot;},&lt;br /&gt;
        {&amp;quot;fin&amp;quot;},&lt;br /&gt;
        {&amp;quot;atk&amp;quot;},&lt;br /&gt;
        {&amp;quot;dec&amp;quot;},&lt;br /&gt;
        {&amp;quot;eg2&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        &lt;br /&gt;
        {&amp;quot;co2&amp;quot;},  // trigger clock out2 ppq&lt;br /&gt;
        {&amp;quot;pcr&amp;quot;}, // pattern change resets bar counter&lt;br /&gt;
        {&amp;quot;LEN&amp;quot;}, // rstephane: LEN for LOOP :-)&lt;br /&gt;
        &lt;br /&gt;
        };        &lt;br /&gt;
&lt;br /&gt;
        const char longNames[][16] PROGMEM = &lt;br /&gt;
        {&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        //01234567&lt;br /&gt;
        {&amp;quot;Coarse&amp;quot;},&lt;br /&gt;
        {&amp;quot;Fine&amp;quot;},&lt;br /&gt;
        {&amp;quot;Attack&amp;quot;},&lt;br /&gt;
        {&amp;quot;Decay&amp;quot;},&lt;br /&gt;
        {&amp;quot;Amount&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        {&amp;quot;Out2 PPQ&amp;quot;},&lt;br /&gt;
        {&amp;quot;Gate Mode&amp;quot;},&lt;br /&gt;
        {&amp;quot;PCReset&amp;quot; }, // reset bar counter on manual pattern change&lt;br /&gt;
        {&amp;quot;Loop&amp;quot;}, // rstephane: LOOP LONG text&lt;br /&gt;
        };&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
* If you want you can already compile and see the results under the menu PERF menu (normally under the second page, your should see &amp;#039;LEN&amp;#039; on the first knob).&lt;br /&gt;
&lt;br /&gt;
* Now, &amp;#039;&amp;#039;&amp;#039;we will create our function&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* We will add a link between this function and our knob.&lt;br /&gt;
&lt;br /&gt;
* open &amp;#039;&amp;#039;&amp;#039;midimessage.h&amp;#039;&amp;#039;&amp;#039; file&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        //for all parameters above 127 &amp;lt;- our case&lt;br /&gt;
        enum&lt;br /&gt;
        {&lt;br /&gt;
        ....&lt;br /&gt;
        // Again, place your parameter at a special place, right after the section:&lt;br /&gt;
        CC2_MIDI_NOTE1,&lt;br /&gt;
        CC2_MIDI_NOTE2,&lt;br /&gt;
        CC2_MIDI_NOTE3,&lt;br /&gt;
        CC2_MIDI_NOTE4,&lt;br /&gt;
        CC2_MIDI_NOTE5,&lt;br /&gt;
        CC2_MIDI_NOTE6,&lt;br /&gt;
        CC2_MIDI_NOTE7, // s/b 111 i think&lt;br /&gt;
        &lt;br /&gt;
        // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
        CC2_LOOP,&lt;br /&gt;
        ....&lt;br /&gt;
        }&lt;br /&gt;
        Param2Enums;&lt;br /&gt;
&lt;br /&gt;
* open  &amp;#039;&amp;#039;&amp;#039;MidiParser.c&amp;#039;&amp;#039;&amp;#039; file &lt;br /&gt;
&lt;br /&gt;
        //-----------------------------------------------------------&lt;br /&gt;
        /** handle all incoming CCs and invoke action*/&lt;br /&gt;
        void midiParser_ccHandler(MidiMsg msg, uint8_t updateOriginalValue)&lt;br /&gt;
        {&lt;br /&gt;
        &lt;br /&gt;
        ...&lt;br /&gt;
        &lt;br /&gt;
        else //MIDI_CC2&lt;br /&gt;
        {&lt;br /&gt;
                const uint16_t paramNr = msg.data1+1 + 127;&lt;br /&gt;
&lt;br /&gt;
                if(updateOriginalValue) {&lt;br /&gt;
                        midiParser_originalCcValues[paramNr] = msg.data2;&lt;br /&gt;
                }&lt;br /&gt;
                switch(msg.data1)&lt;br /&gt;
                {&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_WAVE:&lt;br /&gt;
                                        voiceArray[0].transGen.waveform = msg.data2;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_VOL:&lt;br /&gt;
                                voiceArray[0].transGen.volume = msg.data2/127.f;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
        ...&lt;br /&gt;
        case CC2_MUTE_1:&lt;br /&gt;
                        case CC2_MUTE_2:&lt;br /&gt;
                        case CC2_MUTE_3:&lt;br /&gt;
                        case CC2_MUTE_4:&lt;br /&gt;
                        case CC2_MUTE_5:&lt;br /&gt;
                        case CC2_MUTE_6:&lt;br /&gt;
                        case CC2_MUTE_7:&lt;br /&gt;
                        {&lt;br /&gt;
                                const uint8_t voiceNr = msg.data1 - CC2_MUTE_1;&lt;br /&gt;
                                if(msg.data2 == 0)&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,0);&lt;br /&gt;
                                }&lt;br /&gt;
                                else&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,1);&lt;br /&gt;
                                }&lt;br /&gt;
&lt;br /&gt;
                        }&lt;br /&gt;
                                break;&lt;br /&gt;
                        // rstephane MY FUNCTIONS&lt;br /&gt;
                            case CC2_LOOP:&lt;br /&gt;
                                   if(msg.data2 == 16)  // reset the loop ! &lt;br /&gt;
                                   {	// we stop the loop effect and&lt;br /&gt;
                                          // go back to prevoious track lenght&lt;br /&gt;
                                          seq_setLoopLength(16);&lt;br /&gt;
                                   }&lt;br /&gt;
                                   else&lt;br /&gt;
                                   {	// we change the tracks lenght&lt;br /&gt;
                                          seq_setLoopLength(msg.data2);&lt;br /&gt;
                                   }&lt;br /&gt;
                                   break;			&lt;br /&gt;
                                       &lt;br /&gt;
                        default:&lt;br /&gt;
                                break;&lt;br /&gt;
                                &lt;br /&gt;
                        ....&lt;br /&gt;
                        &lt;br /&gt;
                        &lt;br /&gt;
&lt;br /&gt;
* open &amp;#039;&amp;#039;&amp;#039;sequencer.h&amp;#039;&amp;#039;&amp;#039; file&lt;br /&gt;
* add the function  void randomDrumVoice123(const uint8_t voiceNr);  &lt;br /&gt;
        void seq_setLoopLength(uint8_t length);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* open &amp;#039;&amp;#039;&amp;#039;sequencer.c&amp;#039;&amp;#039;&amp;#039; file&lt;br /&gt;
        void seq_setLoopLength(uint8_t length)&lt;br /&gt;
        {&lt;br /&gt;
        uint8_t i;&lt;br /&gt;
        // we set the new Loop Track Lenght&lt;br /&gt;
        for(i=0;i&amp;lt;NUM_TRACKS;i++) {&lt;br /&gt;
                seq_setTrackLength(i, length);	&lt;br /&gt;
        }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
* compile !&lt;br /&gt;
* upload on the machine the new firmware&lt;br /&gt;
* test!&lt;/div&gt;</summary>
		<author><name>Rstephane</name></author>
		
	</entry>
	<entry>
		<id>http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=236</id>
		<title>How to create and add a new function to the LXR</title>
		<link rel="alternate" type="text/html" href="http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=236"/>
		<updated>2014-05-09T21:58:02Z</updated>

		<summary type="html">&lt;p&gt;Rstephane: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a DRAFT !!!! I will correct it during the next days :-)&lt;br /&gt;
&lt;br /&gt;
* GOAL:&lt;br /&gt;
* 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 :-)&lt;br /&gt;
* 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 :-)&lt;br /&gt;
&lt;br /&gt;
* First step, we start by adding a new knob &amp;#039;LEN&amp;#039; (for Length) in  the PERF menu on the LCD display.&lt;br /&gt;
&lt;br /&gt;
* Open the file &amp;#039;&amp;#039;&amp;#039;&amp;#039;Parameters.h&amp;#039;&amp;#039;&amp;#039;&amp;#039;, we first declare our parameter and its type.&lt;br /&gt;
&lt;br /&gt;
* Add in the section: &amp;#039;enum ParamEnums&amp;#039; your new parameter. In our case we will add the parameter : PAR_LOOP&lt;br /&gt;
&lt;br /&gt;
* 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):&lt;br /&gt;
&lt;br /&gt;
        example: &lt;br /&gt;
        &lt;br /&gt;
        enum ParamEnums = {&lt;br /&gt;
        ...&lt;br /&gt;
        PAR_MIDI_NOTE1,&lt;br /&gt;
        PAR_MIDI_NOTE2,&lt;br /&gt;
        PAR_MIDI_NOTE3,&lt;br /&gt;
        PAR_MIDI_NOTE4,&lt;br /&gt;
        PAR_MIDI_NOTE5,&lt;br /&gt;
        PAR_MIDI_NOTE6,&lt;br /&gt;
        PAR_MIDI_NOTE7,&lt;br /&gt;
        // YOUR parameters comes right after thoses lines...&lt;br /&gt;
                   &lt;br /&gt;
        // rstephane MY VALUES ADDED FOR LOOP FUNCTION&lt;br /&gt;
        PAR_LOOP,     &lt;br /&gt;
        ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* We need to open the &amp;#039;&amp;#039;&amp;#039;menu.c&amp;#039;&amp;#039;&amp;#039; file. we want that our knob display a name &amp;#039;LEN&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        menu.c&lt;br /&gt;
        //---------------------------------------------------------------&lt;br /&gt;
        // Parameter types. These correspond with ParamEnums and entries in parameter_values&lt;br /&gt;
        const enum Datatypes PROGMEM parameter_dtypes[NUM_PARAMS] = {&lt;br /&gt;
            /*PAR_NONE*/                         DTYPE_0B127,                                                        // 0&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM1*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM2*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM3*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_SNARE*/  DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
        ....&lt;br /&gt;
&lt;br /&gt;
* Place your parameter at a special place, right after the section:&lt;br /&gt;
&lt;br /&gt;
            /*PAR_MIDI_NOTE1*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE2*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE3*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE4*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE5*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE6*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE7*/                DTYPE_NOTE_NAME,&lt;br /&gt;
           &lt;br /&gt;
            // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
            /*PAR_LOOP*/                      DTYPE_1B16, // Values goes from 1 to 16 steps&lt;br /&gt;
            &lt;br /&gt;
            /*PAR_ROLL*/                         DTYPE_MENU | (MENU_ROLL_RATES&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_MORPH*/                         DTYPE_0B255,&lt;br /&gt;
            ...&lt;br /&gt;
                &lt;br /&gt;
&lt;br /&gt;
Here the list of parameters you can choose from...&lt;br /&gt;
&lt;br /&gt;
        Type of parameters:&lt;br /&gt;
        //-----------------------------------------------------------------&lt;br /&gt;
        enum Datatypes&lt;br /&gt;
        {&lt;br /&gt;
        DTYPE_0B255,        //0:255&lt;br /&gt;
        DTYPE_0B127,        //0-127&lt;br /&gt;
        DTYPE_PM100,        //-100:100&lt;br /&gt;
        DTYPE_MENU,                //text type outputs &lt;br /&gt;
        DTYPE_PM63,                //-63 &amp;lt;-&amp;gt; 63&lt;br /&gt;
        DTYPE_1B16,                //1-16&lt;br /&gt;
        DTYPE_ON_OFF,        //0-1&lt;br /&gt;
        DTYPE_MIX_FM,        //0-1&lt;br /&gt;
        DTYPE_TARGET_SELECTION_LFO,&lt;br /&gt;
        DTYPE_TARGET_SELECTION_VELO,        &lt;br /&gt;
        DTYPE_VOICE_LFO,&lt;br /&gt;
        DTYPE_AUTOM_TARGET,&lt;br /&gt;
        DTYPE_0b1,&lt;br /&gt;
        DTYPE_NOTE_NAME, // --AS eg C#0, D 1 for note name&lt;br /&gt;
        DTYPE_0B15,                //0-15&lt;br /&gt;
        /*15*/&lt;br /&gt;
        /*16*/&lt;br /&gt;
        // --AS warning, we can only have 16 on this list the way things are laid out&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
* oki, once this done, we need to fill other information in the code&lt;br /&gt;
&lt;br /&gt;
* Open the file &amp;#039;&amp;#039;&amp;#039;menuPages.h&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
* 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&lt;br /&gt;
&lt;br /&gt;
* in the section: const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM ... add your MENU &lt;br /&gt;
&lt;br /&gt;
* in our case, we have:&lt;br /&gt;
&lt;br /&gt;
        const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM =&lt;br /&gt;
        {&lt;br /&gt;
        //page 1 - Voice 1&lt;br /&gt;
        {&lt;br /&gt;
        //sub page 1 - Oscillator&lt;br /&gt;
        {&lt;br /&gt;
        TEXT_COARSE,        TEXT_FINE,        TEXT_WAVEFORM,                TEXT_RND_VOICE,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,&lt;br /&gt;
        PAR_COARSE1,        PAR_FINE1,        PAR_OSC_WAVE_DRUM1,        PAR_RND_VOICE1,PAR_NONE,PAR_NONE,PAR_NONE,PAR_NONE&lt;br /&gt;
                },        &lt;br /&gt;
        ...&lt;br /&gt;
        //Page 10&lt;br /&gt;
        //---------------- Performance Mode Menu pages ---------------------------&lt;br /&gt;
        //These pages are shown when the selected mode is the &amp;quot;mute/pattern select&amp;quot; page&lt;br /&gt;
        //there is only one page with subpages shown for the whole mode&lt;br /&gt;
        {&lt;br /&gt;
        {		&lt;br /&gt;
        TEXT_SHUFFLE,	TEXT_ROLL_SPEED,	TEXT_X_FADE,	TEXT_SAMPLE_RATE,		 &amp;#039;&amp;#039;&amp;#039;TEXT_LOOP&amp;#039;&amp;#039;&amp;#039;,	TEXT_EMPTY,&lt;br /&gt;
        PAR_SHUFFLE,	&amp;#039;&amp;#039;&amp;#039;PAR_ROLL&amp;#039;&amp;#039;&amp;#039;,			PAR_MORPH,		PAR_VOICE_DECIMATION_ALL,		PAR_LOOP,&lt;br /&gt;
        },&lt;br /&gt;
        ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* We need now to declare the TEXT_LOOP and PAR_LOOP in other files :-)&lt;br /&gt;
&lt;br /&gt;
* Open file &amp;#039;&amp;#039;&amp;#039;menu.h&amp;#039;&amp;#039;&amp;#039;, and go to section &lt;br /&gt;
&lt;br /&gt;
        enum NamesEnum&lt;br /&gt;
        {&lt;br /&gt;
        TEXT_EMPTY = 0,                                        //0&lt;br /&gt;
        TEXT_COARSE,&lt;br /&gt;
        TEXT_FINE,&lt;br /&gt;
        TEXT_ATTACK,&lt;br /&gt;
        TEXT_DECAY,&lt;br /&gt;
        TEXT_PITCH_DECAY,&lt;br /&gt;
        TEXT_MOD_AMOUNT,                &lt;br /&gt;
        ....&lt;br /&gt;
&lt;br /&gt;
* Add at the end, the text &amp;#039;TEXT_LOOP&amp;quot; : &lt;br /&gt;
        &lt;br /&gt;
        ....&lt;br /&gt;
        TEXT_BAR_RESET_MODE,&lt;br /&gt;
        TEXT_MIDI_CHAN_GLOBAL,&lt;br /&gt;
        &amp;#039;&amp;#039;&amp;#039;TEXT_LOOP&amp;#039;&amp;#039;&amp;#039;,        // rstephane: LOOP text &lt;br /&gt;
        NUM_NAMES&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
* Open &amp;#039;&amp;#039;&amp;#039;Cc2Text.c&amp;#039;&amp;#039;&amp;#039; file and under the section (i need to explain and complete this section)&lt;br /&gt;
&lt;br /&gt;
{TEXT_COARSE, PAR_COARSE1},                         //2&lt;br /&gt;
{TEXT_FINE, PAR_FINE1},&lt;br /&gt;
{TEXT_WAVEFORM, PAR_OSC_WAVE_DRUM1},&lt;br /&gt;
{TEXT_LOOP, PAR_LOOP}, // rstephane : added LOOP button &amp;lt;- no needed, weelll pass trough this step                                   &lt;br /&gt;
                                        &lt;br /&gt;
&lt;br /&gt;
* Open the &amp;#039;&amp;#039;&amp;#039;menu.c&amp;#039;&amp;#039;&amp;#039; file, go to section &amp;#039;&amp;#039;&amp;#039;valueNames&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
        const Name valueNames[NUM_NAMES] PROGMEM =&lt;br /&gt;
        {&lt;br /&gt;
                {SHORT_EMPTY,CAT_EMPTY,LONG_EMPTY},&lt;br /&gt;
                ....&lt;br /&gt;
&lt;br /&gt;
* Add the following information:&lt;br /&gt;
                ....&lt;br /&gt;
                {SHORT_BAR_RESET_MODE, CAT_SEQUENCER, LONG_BAR_RESET_MODE}, // TEXT_BAR_RESET_MODE&lt;br /&gt;
                {SHORT_CHANNEL, CAT_MIDI, LONG_MIDI_CHANNEL}, // TEXT_MIDI_CHAN_GLOBAL&lt;br /&gt;
                {SHORT_LOOP, CAT_SEQUENCER, LONG_LOOP}, // rstephane: TEXT_LOOP&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
* We NEED declare it at the end of the section :-)&lt;br /&gt;
* now, open the &amp;#039;&amp;#039;&amp;#039;MenuText.h&amp;#039;&amp;#039;&amp;#039; file to declare the &amp;#039;&amp;#039;&amp;#039;short and long version of the TEXT&amp;#039;&amp;#039;&amp;#039; (TEXT_LOOP)&lt;br /&gt;
* go to section &amp;#039;const char longNames[][16] PROGMEM = &amp;#039; and &amp;#039;const char shortNames[][4] PROGMEM  = &amp;#039;&lt;br /&gt;
* add the parameters:&lt;br /&gt;
&lt;br /&gt;
        const char shortNames[][4] PROGMEM  = &lt;br /&gt;
        {&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        {&amp;quot;coa&amp;quot;},&lt;br /&gt;
        {&amp;quot;fin&amp;quot;},&lt;br /&gt;
        {&amp;quot;atk&amp;quot;},&lt;br /&gt;
        {&amp;quot;dec&amp;quot;},&lt;br /&gt;
        {&amp;quot;eg2&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        &lt;br /&gt;
        {&amp;quot;co2&amp;quot;},  // trigger clock out2 ppq&lt;br /&gt;
        {&amp;quot;pcr&amp;quot;}, // pattern change resets bar counter&lt;br /&gt;
        {&amp;quot;LEN&amp;quot;}, // rstephane: LEN for LOOP :-)&lt;br /&gt;
        &lt;br /&gt;
        };        &lt;br /&gt;
&lt;br /&gt;
        const char longNames[][16] PROGMEM = &lt;br /&gt;
        {&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        //01234567&lt;br /&gt;
        {&amp;quot;Coarse&amp;quot;},&lt;br /&gt;
        {&amp;quot;Fine&amp;quot;},&lt;br /&gt;
        {&amp;quot;Attack&amp;quot;},&lt;br /&gt;
        {&amp;quot;Decay&amp;quot;},&lt;br /&gt;
        {&amp;quot;Amount&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        {&amp;quot;Out2 PPQ&amp;quot;},&lt;br /&gt;
        {&amp;quot;Gate Mode&amp;quot;},&lt;br /&gt;
        {&amp;quot;PCReset&amp;quot; }, // reset bar counter on manual pattern change&lt;br /&gt;
        {&amp;quot;Loop&amp;quot;}, // rstephane: LOOP LONG text&lt;br /&gt;
        };&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
* If you want you can already compile and see the results under the menu PERF menu (normally under the second page, your should see &amp;#039;LEN&amp;#039; on the first knob).&lt;br /&gt;
&lt;br /&gt;
* Now, &amp;#039;&amp;#039;&amp;#039;we will create our function&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* We will add a link between this function and our knob.&lt;br /&gt;
&lt;br /&gt;
* open &amp;#039;&amp;#039;&amp;#039;midimessage.h&amp;#039;&amp;#039;&amp;#039; file&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        //for all parameters above 127 &amp;lt;- our case&lt;br /&gt;
        enum&lt;br /&gt;
        {&lt;br /&gt;
        ....&lt;br /&gt;
        // Again, place your parameter at a special place, right after the section:&lt;br /&gt;
        CC2_MIDI_NOTE1,&lt;br /&gt;
        CC2_MIDI_NOTE2,&lt;br /&gt;
        CC2_MIDI_NOTE3,&lt;br /&gt;
        CC2_MIDI_NOTE4,&lt;br /&gt;
        CC2_MIDI_NOTE5,&lt;br /&gt;
        CC2_MIDI_NOTE6,&lt;br /&gt;
        CC2_MIDI_NOTE7, // s/b 111 i think&lt;br /&gt;
        &lt;br /&gt;
        // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
        CC2_LOOP,&lt;br /&gt;
        ....&lt;br /&gt;
        }&lt;br /&gt;
        Param2Enums;&lt;br /&gt;
&lt;br /&gt;
* open  &amp;#039;&amp;#039;&amp;#039;MidiParser.c&amp;#039;&amp;#039;&amp;#039; file &lt;br /&gt;
&lt;br /&gt;
        //-----------------------------------------------------------&lt;br /&gt;
        /** handle all incoming CCs and invoke action*/&lt;br /&gt;
        void midiParser_ccHandler(MidiMsg msg, uint8_t updateOriginalValue)&lt;br /&gt;
        {&lt;br /&gt;
        &lt;br /&gt;
        ...&lt;br /&gt;
        &lt;br /&gt;
        else //MIDI_CC2&lt;br /&gt;
        {&lt;br /&gt;
                const uint16_t paramNr = msg.data1+1 + 127;&lt;br /&gt;
&lt;br /&gt;
                if(updateOriginalValue) {&lt;br /&gt;
                        midiParser_originalCcValues[paramNr] = msg.data2;&lt;br /&gt;
                }&lt;br /&gt;
                switch(msg.data1)&lt;br /&gt;
                {&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_WAVE:&lt;br /&gt;
                                        voiceArray[0].transGen.waveform = msg.data2;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_VOL:&lt;br /&gt;
                                voiceArray[0].transGen.volume = msg.data2/127.f;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
        ...&lt;br /&gt;
        case CC2_MUTE_1:&lt;br /&gt;
                        case CC2_MUTE_2:&lt;br /&gt;
                        case CC2_MUTE_3:&lt;br /&gt;
                        case CC2_MUTE_4:&lt;br /&gt;
                        case CC2_MUTE_5:&lt;br /&gt;
                        case CC2_MUTE_6:&lt;br /&gt;
                        case CC2_MUTE_7:&lt;br /&gt;
                        {&lt;br /&gt;
                                const uint8_t voiceNr = msg.data1 - CC2_MUTE_1;&lt;br /&gt;
                                if(msg.data2 == 0)&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,0);&lt;br /&gt;
                                }&lt;br /&gt;
                                else&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,1);&lt;br /&gt;
                                }&lt;br /&gt;
&lt;br /&gt;
                        }&lt;br /&gt;
                                break;&lt;br /&gt;
                        // rstephane MY FUNCTIONS&lt;br /&gt;
                            case CC2_LOOP:&lt;br /&gt;
                                   if(msg.data2 == 16)  // reset the loop ! &lt;br /&gt;
                                   {	// we stop the loop effect and&lt;br /&gt;
                                          // go back to prevoious track lenght&lt;br /&gt;
                                          seq_setLoopLength(16);&lt;br /&gt;
                                   }&lt;br /&gt;
                                   else&lt;br /&gt;
                                   {	// we change the tracks lenght&lt;br /&gt;
                                          seq_setLoopLength(msg.data2);&lt;br /&gt;
                                   }&lt;br /&gt;
                                   break;			&lt;br /&gt;
                                       &lt;br /&gt;
                        default:&lt;br /&gt;
                                break;&lt;br /&gt;
                                &lt;br /&gt;
                        ....&lt;br /&gt;
                        &lt;br /&gt;
                        &lt;br /&gt;
&lt;br /&gt;
* open &amp;#039;&amp;#039;&amp;#039;sequencer.h&amp;#039;&amp;#039;&amp;#039; file&lt;br /&gt;
* add the function  void randomDrumVoice123(const uint8_t voiceNr);  &lt;br /&gt;
        void seq_setLoopLength(uint8_t length);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* open &amp;#039;&amp;#039;&amp;#039;sequencer.c&amp;#039;&amp;#039;&amp;#039; file&lt;br /&gt;
        void seq_setLoopLength(uint8_t length)&lt;br /&gt;
        {&lt;br /&gt;
        uint8_t i;&lt;br /&gt;
        // we set the new Loop Track Lenght&lt;br /&gt;
        for(i=0;i&amp;lt;NUM_TRACKS;i++) {&lt;br /&gt;
                seq_setTrackLength(i, length);	&lt;br /&gt;
        }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
* compile !&lt;br /&gt;
* upload on the machine the new firmware&lt;br /&gt;
* test!&lt;/div&gt;</summary>
		<author><name>Rstephane</name></author>
		
	</entry>
	<entry>
		<id>http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=235</id>
		<title>How to create and add a new function to the LXR</title>
		<link rel="alternate" type="text/html" href="http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=235"/>
		<updated>2014-05-09T21:54:43Z</updated>

		<summary type="html">&lt;p&gt;Rstephane: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a DRAFT !!!! I will correct it during the next days :-)&lt;br /&gt;
&lt;br /&gt;
* GOAL:&lt;br /&gt;
* 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 :-)&lt;br /&gt;
* 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 :-)&lt;br /&gt;
&lt;br /&gt;
* First step, we start by adding a new knob &amp;#039;LEN&amp;#039; (for Length) in  the PERF menu on the LCD display.&lt;br /&gt;
&lt;br /&gt;
* Open the file &amp;#039;&amp;#039;&amp;#039;&amp;#039;Parameters.h&amp;#039;&amp;#039;&amp;#039;&amp;#039;, we first declare our parameter and its type.&lt;br /&gt;
&lt;br /&gt;
* Add in the section: &amp;#039;enum ParamEnums&amp;#039; your new parameter. In our case we will add the parameter : PAR_LOOP&lt;br /&gt;
&lt;br /&gt;
* 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):&lt;br /&gt;
&lt;br /&gt;
        example: &lt;br /&gt;
        &lt;br /&gt;
        enum ParamEnums = {&lt;br /&gt;
        ...&lt;br /&gt;
        PAR_MIDI_NOTE1,&lt;br /&gt;
        PAR_MIDI_NOTE2,&lt;br /&gt;
        PAR_MIDI_NOTE3,&lt;br /&gt;
        PAR_MIDI_NOTE4,&lt;br /&gt;
        PAR_MIDI_NOTE5,&lt;br /&gt;
        PAR_MIDI_NOTE6,&lt;br /&gt;
        PAR_MIDI_NOTE7,&lt;br /&gt;
        // YOUR parameters comes right after thoses lines...&lt;br /&gt;
                   &lt;br /&gt;
        // rstephane MY VALUES ADDED FOR LOOP FUNCTION&lt;br /&gt;
        PAR_LOOP,     &lt;br /&gt;
        ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* We need to open the &amp;#039;&amp;#039;&amp;#039;menu.c&amp;#039;&amp;#039;&amp;#039; file. we want that our knob display a name &amp;#039;LEN&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        menu.c&lt;br /&gt;
        //---------------------------------------------------------------&lt;br /&gt;
        // Parameter types. These correspond with ParamEnums and entries in parameter_values&lt;br /&gt;
        const enum Datatypes PROGMEM parameter_dtypes[NUM_PARAMS] = {&lt;br /&gt;
            /*PAR_NONE*/                         DTYPE_0B127,                                                        // 0&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM1*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM2*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM3*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_SNARE*/  DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
        ....&lt;br /&gt;
&lt;br /&gt;
* Place your parameter at a special place, right after the section:&lt;br /&gt;
&lt;br /&gt;
            /*PAR_MIDI_NOTE1*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE2*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE3*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE4*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE5*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE6*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE7*/                DTYPE_NOTE_NAME,&lt;br /&gt;
           &lt;br /&gt;
            // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
            /*PAR_LOOP*/                      DTYPE_1B16, // Values goes from 1 to 16 steps&lt;br /&gt;
            &lt;br /&gt;
            /*PAR_ROLL*/                         DTYPE_MENU | (MENU_ROLL_RATES&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_MORPH*/                         DTYPE_0B255,&lt;br /&gt;
            ...&lt;br /&gt;
                &lt;br /&gt;
&lt;br /&gt;
Here the list of parameters you can choose from...&lt;br /&gt;
&lt;br /&gt;
        Type of parameters:&lt;br /&gt;
        //-----------------------------------------------------------------&lt;br /&gt;
        enum Datatypes&lt;br /&gt;
        {&lt;br /&gt;
        DTYPE_0B255,        //0:255&lt;br /&gt;
        DTYPE_0B127,        //0-127&lt;br /&gt;
        DTYPE_PM100,        //-100:100&lt;br /&gt;
        DTYPE_MENU,                //text type outputs &lt;br /&gt;
        DTYPE_PM63,                //-63 &amp;lt;-&amp;gt; 63&lt;br /&gt;
        DTYPE_1B16,                //1-16&lt;br /&gt;
        DTYPE_ON_OFF,        //0-1&lt;br /&gt;
        DTYPE_MIX_FM,        //0-1&lt;br /&gt;
        DTYPE_TARGET_SELECTION_LFO,&lt;br /&gt;
        DTYPE_TARGET_SELECTION_VELO,        &lt;br /&gt;
        DTYPE_VOICE_LFO,&lt;br /&gt;
        DTYPE_AUTOM_TARGET,&lt;br /&gt;
        DTYPE_0b1,&lt;br /&gt;
        DTYPE_NOTE_NAME, // --AS eg C#0, D 1 for note name&lt;br /&gt;
        DTYPE_0B15,                //0-15&lt;br /&gt;
        /*15*/&lt;br /&gt;
        /*16*/&lt;br /&gt;
        // --AS warning, we can only have 16 on this list the way things are laid out&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
* oki, once this done, we need to fill other information in the code&lt;br /&gt;
&lt;br /&gt;
* Open the file &amp;#039;&amp;#039;&amp;#039;menuPages.h&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
* 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&lt;br /&gt;
&lt;br /&gt;
* in the section: const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM ... add your MENU &lt;br /&gt;
&lt;br /&gt;
* in our case, we have:&lt;br /&gt;
&lt;br /&gt;
        const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM =&lt;br /&gt;
        {&lt;br /&gt;
        //page 1 - Voice 1&lt;br /&gt;
        {&lt;br /&gt;
        //sub page 1 - Oscillator&lt;br /&gt;
        {&lt;br /&gt;
        TEXT_COARSE,        TEXT_FINE,        TEXT_WAVEFORM,                TEXT_RND_VOICE,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,&lt;br /&gt;
        PAR_COARSE1,        PAR_FINE1,        PAR_OSC_WAVE_DRUM1,        PAR_RND_VOICE1,PAR_NONE,PAR_NONE,PAR_NONE,PAR_NONE&lt;br /&gt;
                },        &lt;br /&gt;
        ...&lt;br /&gt;
        //Page 10&lt;br /&gt;
	//---------------- Performance Mode Menu pages ---------------------------&lt;br /&gt;
	//These pages are shown when the selected mode is the &amp;quot;mute/pattern select&amp;quot; page&lt;br /&gt;
	//there is only one page with subpages shown for the whole mode&lt;br /&gt;
	{&lt;br /&gt;
	{		&lt;br /&gt;
	TEXT_SHUFFLE,	TEXT_ROLL_SPEED,	TEXT_X_FADE,	TEXT_SAMPLE_RATE,		 &amp;#039;&amp;#039;&amp;#039;TEXT_LOOP&amp;#039;&amp;#039;&amp;#039;,	TEXT_EMPTY,&lt;br /&gt;
	PAR_SHUFFLE,	&amp;#039;&amp;#039;&amp;#039;PAR_ROLL&amp;#039;&amp;#039;&amp;#039;,			PAR_MORPH,		PAR_VOICE_DECIMATION_ALL,		PAR_LOOP,&lt;br /&gt;
	},&lt;br /&gt;
        ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* We need now to declare the TEXT_LOOP and PAR_LOOP in other files :-)&lt;br /&gt;
&lt;br /&gt;
* Open file &amp;#039;&amp;#039;&amp;#039;menu.h&amp;#039;&amp;#039;&amp;#039;, and go to section &lt;br /&gt;
&lt;br /&gt;
        enum NamesEnum&lt;br /&gt;
        {&lt;br /&gt;
        TEXT_EMPTY = 0,                                        //0&lt;br /&gt;
        TEXT_COARSE,&lt;br /&gt;
        TEXT_FINE,&lt;br /&gt;
        TEXT_ATTACK,&lt;br /&gt;
        TEXT_DECAY,&lt;br /&gt;
        TEXT_PITCH_DECAY,&lt;br /&gt;
        TEXT_MOD_AMOUNT,                &lt;br /&gt;
        ....&lt;br /&gt;
&lt;br /&gt;
* Add at the end, the text &amp;#039;TEXT_LOOP&amp;quot; : &lt;br /&gt;
        &lt;br /&gt;
        ....&lt;br /&gt;
        TEXT_BAR_RESET_MODE,&lt;br /&gt;
        TEXT_MIDI_CHAN_GLOBAL,&lt;br /&gt;
        &amp;#039;&amp;#039;&amp;#039;TEXT_LOOP&amp;#039;&amp;#039;&amp;#039;,        // rstephane: LOOP text &lt;br /&gt;
        NUM_NAMES&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
* Open &amp;#039;&amp;#039;&amp;#039;Cc2Text.c&amp;#039;&amp;#039;&amp;#039; file and under the section (i need to explain and complete this section)&lt;br /&gt;
&lt;br /&gt;
{TEXT_COARSE, PAR_COARSE1},                         //2&lt;br /&gt;
{TEXT_FINE, PAR_FINE1},&lt;br /&gt;
{TEXT_WAVEFORM, PAR_OSC_WAVE_DRUM1},&lt;br /&gt;
{TEXT_LOOP, PAR_LOOP}, // rstephane : added LOOP button &amp;lt;- no needed, weelll pass trough this step                                   &lt;br /&gt;
                                        &lt;br /&gt;
&lt;br /&gt;
* Open the &amp;#039;&amp;#039;&amp;#039;menu.c&amp;#039;&amp;#039;&amp;#039; file, go to section &amp;#039;&amp;#039;&amp;#039;valueNames&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
        const Name valueNames[NUM_NAMES] PROGMEM =&lt;br /&gt;
        {&lt;br /&gt;
                {SHORT_EMPTY,CAT_EMPTY,LONG_EMPTY},&lt;br /&gt;
                ....&lt;br /&gt;
&lt;br /&gt;
* Add the following information:&lt;br /&gt;
                ....&lt;br /&gt;
                {SHORT_BAR_RESET_MODE, CAT_SEQUENCER, LONG_BAR_RESET_MODE}, // TEXT_BAR_RESET_MODE&lt;br /&gt;
                {SHORT_CHANNEL, CAT_MIDI, LONG_MIDI_CHANNEL}, // TEXT_MIDI_CHAN_GLOBAL&lt;br /&gt;
                {SHORT_LOOP, CAT_SEQUENCER, LONG_LOOP}, // rstephane: TEXT_LOOP&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
* We NEED declare it at the end of the section :-)&lt;br /&gt;
* now, open the &amp;#039;&amp;#039;&amp;#039;MenuText.h&amp;#039;&amp;#039;&amp;#039; file to declare the &amp;#039;&amp;#039;&amp;#039;short and long version of the TEXT&amp;#039;&amp;#039;&amp;#039; (TEXT_LOOP)&lt;br /&gt;
* go to section &amp;#039;const char longNames[][16] PROGMEM = &amp;#039; and &amp;#039;const char shortNames[][4] PROGMEM  = &amp;#039;&lt;br /&gt;
* add the parameters:&lt;br /&gt;
&lt;br /&gt;
        const char shortNames[][4] PROGMEM  = &lt;br /&gt;
        {&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        {&amp;quot;coa&amp;quot;},&lt;br /&gt;
        {&amp;quot;fin&amp;quot;},&lt;br /&gt;
        {&amp;quot;atk&amp;quot;},&lt;br /&gt;
        {&amp;quot;dec&amp;quot;},&lt;br /&gt;
        {&amp;quot;eg2&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        &lt;br /&gt;
        {&amp;quot;co2&amp;quot;},  // trigger clock out2 ppq&lt;br /&gt;
        {&amp;quot;pcr&amp;quot;}, // pattern change resets bar counter&lt;br /&gt;
        {&amp;quot;LEN&amp;quot;}, // rstephane: LEN for LOOP :-)&lt;br /&gt;
        &lt;br /&gt;
        };        &lt;br /&gt;
&lt;br /&gt;
        const char longNames[][16] PROGMEM = &lt;br /&gt;
        {&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        //01234567&lt;br /&gt;
        {&amp;quot;Coarse&amp;quot;},&lt;br /&gt;
        {&amp;quot;Fine&amp;quot;},&lt;br /&gt;
        {&amp;quot;Attack&amp;quot;},&lt;br /&gt;
        {&amp;quot;Decay&amp;quot;},&lt;br /&gt;
        {&amp;quot;Amount&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        {&amp;quot;Out2 PPQ&amp;quot;},&lt;br /&gt;
        {&amp;quot;Gate Mode&amp;quot;},&lt;br /&gt;
        {&amp;quot;PCReset&amp;quot; }, // reset bar counter on manual pattern change&lt;br /&gt;
        {&amp;quot;Loop&amp;quot;}, // rstephane: LOOP LONG text&lt;br /&gt;
        };&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
* If you want you can already compile and see the results under the menu PERF menu (normally under the second page, your should see &amp;#039;LEN&amp;#039; on the first knob).&lt;br /&gt;
&lt;br /&gt;
* Now, &amp;#039;&amp;#039;&amp;#039;we will create our function&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* We will add a link between this function and our knob.&lt;br /&gt;
&lt;br /&gt;
* open &amp;#039;&amp;#039;&amp;#039;midimessage.h&amp;#039;&amp;#039;&amp;#039; file&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//for all parameters above 127 &amp;lt;- our case&lt;br /&gt;
enum&lt;br /&gt;
{&lt;br /&gt;
        ....&lt;br /&gt;
        // Again, place your parameter at a special place, right after the section:&lt;br /&gt;
        CC2_MIDI_NOTE1,&lt;br /&gt;
        CC2_MIDI_NOTE2,&lt;br /&gt;
        CC2_MIDI_NOTE3,&lt;br /&gt;
        CC2_MIDI_NOTE4,&lt;br /&gt;
        CC2_MIDI_NOTE5,&lt;br /&gt;
        CC2_MIDI_NOTE6,&lt;br /&gt;
        CC2_MIDI_NOTE7, // s/b 111 i think&lt;br /&gt;
        &lt;br /&gt;
        // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
        CC2_LOOP,&lt;br /&gt;
        ....&lt;br /&gt;
        }&lt;br /&gt;
        Param2Enums;&lt;br /&gt;
&lt;br /&gt;
* open  &amp;#039;&amp;#039;&amp;#039;MidiParser.c&amp;#039;&amp;#039;&amp;#039; file &lt;br /&gt;
&lt;br /&gt;
        //-----------------------------------------------------------&lt;br /&gt;
        /** handle all incoming CCs and invoke action*/&lt;br /&gt;
        void midiParser_ccHandler(MidiMsg msg, uint8_t updateOriginalValue)&lt;br /&gt;
        {&lt;br /&gt;
        &lt;br /&gt;
        ...&lt;br /&gt;
        &lt;br /&gt;
        else //MIDI_CC2&lt;br /&gt;
        {&lt;br /&gt;
                const uint16_t paramNr = msg.data1+1 + 127;&lt;br /&gt;
&lt;br /&gt;
                if(updateOriginalValue) {&lt;br /&gt;
                        midiParser_originalCcValues[paramNr] = msg.data2;&lt;br /&gt;
                }&lt;br /&gt;
                switch(msg.data1)&lt;br /&gt;
                {&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_WAVE:&lt;br /&gt;
                                        voiceArray[0].transGen.waveform = msg.data2;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_VOL:&lt;br /&gt;
                                voiceArray[0].transGen.volume = msg.data2/127.f;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
        ...&lt;br /&gt;
        case CC2_MUTE_1:&lt;br /&gt;
                        case CC2_MUTE_2:&lt;br /&gt;
                        case CC2_MUTE_3:&lt;br /&gt;
                        case CC2_MUTE_4:&lt;br /&gt;
                        case CC2_MUTE_5:&lt;br /&gt;
                        case CC2_MUTE_6:&lt;br /&gt;
                        case CC2_MUTE_7:&lt;br /&gt;
                        {&lt;br /&gt;
                                const uint8_t voiceNr = msg.data1 - CC2_MUTE_1;&lt;br /&gt;
                                if(msg.data2 == 0)&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,0);&lt;br /&gt;
                                }&lt;br /&gt;
                                else&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,1);&lt;br /&gt;
                                }&lt;br /&gt;
&lt;br /&gt;
                        }&lt;br /&gt;
                                break;&lt;br /&gt;
                        // rstephane MY FUNCTIONS&lt;br /&gt;
                        // rstephane : Handle the RND button&lt;br /&gt;
                                                        &lt;br /&gt;
                        default:&lt;br /&gt;
                                break;&lt;br /&gt;
                                &lt;br /&gt;
                        ....&lt;br /&gt;
                        &lt;br /&gt;
                        &lt;br /&gt;
&lt;br /&gt;
* open &amp;#039;&amp;#039;&amp;#039;sequencer.h&amp;#039;&amp;#039;&amp;#039; file&lt;br /&gt;
* add the function  void randomDrumVoice123(const uint8_t voiceNr);  &lt;br /&gt;
        void seq_setLoopLength(uint8_t length);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* open &amp;#039;&amp;#039;&amp;#039;sequencer.c&amp;#039;&amp;#039;&amp;#039; file&lt;br /&gt;
        void seq_setLoopLength(uint8_t length)&lt;br /&gt;
        {&lt;br /&gt;
        uint8_t i;&lt;br /&gt;
        // we set the new Loop Track Lenght&lt;br /&gt;
        for(i=0;i&amp;lt;NUM_TRACKS;i++) {&lt;br /&gt;
                seq_setTrackLength(i, length);	&lt;br /&gt;
        }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
* compile !&lt;br /&gt;
* upload on the machine the new firmware&lt;br /&gt;
* test!&lt;/div&gt;</summary>
		<author><name>Rstephane</name></author>
		
	</entry>
	<entry>
		<id>http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=234</id>
		<title>How to create and add a new function to the LXR</title>
		<link rel="alternate" type="text/html" href="http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=234"/>
		<updated>2014-05-09T15:48:17Z</updated>

		<summary type="html">&lt;p&gt;Rstephane: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a DRAFT !!!! I will correct it during the next days :-)&lt;br /&gt;
&lt;br /&gt;
* 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 :-)&lt;br /&gt;
&lt;br /&gt;
* We start by adding a new knob &amp;#039;LEN&amp;#039; (for Length) in  the PERF menu on the LCD display.&lt;br /&gt;
&lt;br /&gt;
* Open the file &amp;#039;&amp;#039;&amp;#039;&amp;#039;Parameters.h&amp;#039;&amp;#039;&amp;#039;&amp;#039;, we first declare our parameter and its type.&lt;br /&gt;
&lt;br /&gt;
* Add in the section: &amp;#039;enum ParamEnums&amp;#039; your new parameter. In our case we will add the parameter : PAR_LOOP&lt;br /&gt;
&lt;br /&gt;
* 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):&lt;br /&gt;
&lt;br /&gt;
        example: &lt;br /&gt;
        &lt;br /&gt;
        enum ParamEnums = {&lt;br /&gt;
        ...&lt;br /&gt;
        PAR_MIDI_NOTE1,&lt;br /&gt;
        PAR_MIDI_NOTE2,&lt;br /&gt;
        PAR_MIDI_NOTE3,&lt;br /&gt;
        PAR_MIDI_NOTE4,&lt;br /&gt;
        PAR_MIDI_NOTE5,&lt;br /&gt;
        PAR_MIDI_NOTE6,&lt;br /&gt;
        PAR_MIDI_NOTE7,&lt;br /&gt;
        // YOUR parameters comes right after thoses lines...&lt;br /&gt;
                   &lt;br /&gt;
        // rstephane MY VALUES ADDED FOR LOOP FUNCTION&lt;br /&gt;
        PAR_LOOP,     &lt;br /&gt;
        ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* We need to open the &amp;#039;&amp;#039;&amp;#039;menu.c&amp;#039;&amp;#039;&amp;#039; file. we want that our knob display a name &amp;#039;LEN&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        menu.c&lt;br /&gt;
        //---------------------------------------------------------------&lt;br /&gt;
        // Parameter types. These correspond with ParamEnums and entries in parameter_values&lt;br /&gt;
        const enum Datatypes PROGMEM parameter_dtypes[NUM_PARAMS] = {&lt;br /&gt;
            /*PAR_NONE*/                         DTYPE_0B127,                                                        // 0&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM1*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM2*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM3*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_SNARE*/  DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
        ....&lt;br /&gt;
&lt;br /&gt;
* Place your parameter at a special place, right after the section:&lt;br /&gt;
&lt;br /&gt;
            /*PAR_MIDI_NOTE1*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE2*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE3*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE4*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE5*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE6*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE7*/                DTYPE_NOTE_NAME,&lt;br /&gt;
           &lt;br /&gt;
            // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
            /*PAR_LOOP*/                      DTYPE_1B16, // Values goes from 1 to 16 steps&lt;br /&gt;
            &lt;br /&gt;
            /*PAR_ROLL*/                         DTYPE_MENU | (MENU_ROLL_RATES&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_MORPH*/                         DTYPE_0B255,&lt;br /&gt;
            ...&lt;br /&gt;
                &lt;br /&gt;
&lt;br /&gt;
Here the list of parameters you can choose from...&lt;br /&gt;
&lt;br /&gt;
        Type of parameters:&lt;br /&gt;
        //-----------------------------------------------------------------&lt;br /&gt;
        enum Datatypes&lt;br /&gt;
        {&lt;br /&gt;
        DTYPE_0B255,        //0:255&lt;br /&gt;
        DTYPE_0B127,        //0-127&lt;br /&gt;
        DTYPE_PM100,        //-100:100&lt;br /&gt;
        DTYPE_MENU,                //text type outputs &lt;br /&gt;
        DTYPE_PM63,                //-63 &amp;lt;-&amp;gt; 63&lt;br /&gt;
        DTYPE_1B16,                //1-16&lt;br /&gt;
        DTYPE_ON_OFF,        //0-1&lt;br /&gt;
        DTYPE_MIX_FM,        //0-1&lt;br /&gt;
        DTYPE_TARGET_SELECTION_LFO,&lt;br /&gt;
        DTYPE_TARGET_SELECTION_VELO,        &lt;br /&gt;
        DTYPE_VOICE_LFO,&lt;br /&gt;
        DTYPE_AUTOM_TARGET,&lt;br /&gt;
        DTYPE_0b1,&lt;br /&gt;
        DTYPE_NOTE_NAME, // --AS eg C#0, D 1 for note name&lt;br /&gt;
        DTYPE_0B15,                //0-15&lt;br /&gt;
        /*15*/&lt;br /&gt;
        /*16*/&lt;br /&gt;
        // --AS warning, we can only have 16 on this list the way things are laid out&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
* oki, once this done, we need to fill other information in the code&lt;br /&gt;
&lt;br /&gt;
* Open the file &amp;#039;&amp;#039;&amp;#039;menuPages.h&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
* 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&lt;br /&gt;
&lt;br /&gt;
* in the section: const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM ... add your MENU &lt;br /&gt;
&lt;br /&gt;
* in our case, we have:&lt;br /&gt;
&lt;br /&gt;
        const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM =&lt;br /&gt;
        {&lt;br /&gt;
        //page 1 - Voice 1&lt;br /&gt;
        {&lt;br /&gt;
        //sub page 1 - Oscillator&lt;br /&gt;
        {&lt;br /&gt;
        TEXT_COARSE,        TEXT_FINE,        TEXT_WAVEFORM,                TEXT_RND_VOICE,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,&lt;br /&gt;
        PAR_COARSE1,        PAR_FINE1,        PAR_OSC_WAVE_DRUM1,        PAR_RND_VOICE1,PAR_NONE,PAR_NONE,PAR_NONE,PAR_NONE&lt;br /&gt;
                },        &lt;br /&gt;
        ...&lt;br /&gt;
        //Page 10&lt;br /&gt;
	//---------------- Performance Mode Menu pages ---------------------------&lt;br /&gt;
	//These pages are shown when the selected mode is the &amp;quot;mute/pattern select&amp;quot; page&lt;br /&gt;
	//there is only one page with subpages shown for the whole mode&lt;br /&gt;
	{&lt;br /&gt;
	{		&lt;br /&gt;
	TEXT_SHUFFLE,	TEXT_ROLL_SPEED,	TEXT_X_FADE,	TEXT_SAMPLE_RATE,		 &amp;#039;&amp;#039;&amp;#039;TEXT_LOOP&amp;#039;&amp;#039;&amp;#039;,	TEXT_EMPTY,&lt;br /&gt;
	PAR_SHUFFLE,	&amp;#039;&amp;#039;&amp;#039;PAR_ROLL&amp;#039;&amp;#039;&amp;#039;,			PAR_MORPH,		PAR_VOICE_DECIMATION_ALL,		PAR_LOOP,&lt;br /&gt;
	},&lt;br /&gt;
        ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* We need now to declare the TEXT_LOOP and PAR_LOOP in other files :-)&lt;br /&gt;
&lt;br /&gt;
* Open file &amp;#039;&amp;#039;&amp;#039;menu.h&amp;#039;&amp;#039;&amp;#039;, and go to section &lt;br /&gt;
&lt;br /&gt;
        enum NamesEnum&lt;br /&gt;
        {&lt;br /&gt;
        TEXT_EMPTY = 0,                                        //0&lt;br /&gt;
        TEXT_COARSE,&lt;br /&gt;
        TEXT_FINE,&lt;br /&gt;
        TEXT_ATTACK,&lt;br /&gt;
        TEXT_DECAY,&lt;br /&gt;
        TEXT_PITCH_DECAY,&lt;br /&gt;
        TEXT_MOD_AMOUNT,                &lt;br /&gt;
        ....&lt;br /&gt;
&lt;br /&gt;
* Add at the end, the text &amp;#039;TEXT_LOOP&amp;quot; : &lt;br /&gt;
        &lt;br /&gt;
        ....&lt;br /&gt;
        TEXT_BAR_RESET_MODE,&lt;br /&gt;
        TEXT_MIDI_CHAN_GLOBAL,&lt;br /&gt;
        &amp;#039;&amp;#039;&amp;#039;TEXT_LOOP&amp;#039;&amp;#039;&amp;#039;,        // rstephane: LOOP text &lt;br /&gt;
        NUM_NAMES&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
* Open &amp;#039;&amp;#039;&amp;#039;Cc2Text.c&amp;#039;&amp;#039;&amp;#039; file and under the section &lt;br /&gt;
&lt;br /&gt;
//Voice 1 - Drum 1&lt;br /&gt;
//  1 Oscillator&lt;br /&gt;
{TEXT_COARSE, PAR_COARSE1},                         //2&lt;br /&gt;
{TEXT_FINE, PAR_FINE1},&lt;br /&gt;
{TEXT_WAVEFORM, PAR_OSC_WAVE_DRUM1},&lt;br /&gt;
{TEXT_RND_VOICE, PAR_RND_VOICE1}, // rstephane : added random button                                        &lt;br /&gt;
                                        &lt;br /&gt;
&lt;br /&gt;
* Open the &amp;#039;&amp;#039;&amp;#039;menu.c&amp;#039;&amp;#039;&amp;#039; file, go to section &amp;#039;&amp;#039;&amp;#039;valueNames&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
        const Name valueNames[NUM_NAMES] PROGMEM =&lt;br /&gt;
        {&lt;br /&gt;
                {SHORT_EMPTY,CAT_EMPTY,LONG_EMPTY},&lt;br /&gt;
                ....&lt;br /&gt;
&lt;br /&gt;
* Add the following information:&lt;br /&gt;
                ....&lt;br /&gt;
                {SHORT_BAR_RESET_MODE, CAT_SEQUENCER, LONG_BAR_RESET_MODE}, // TEXT_BAR_RESET_MODE&lt;br /&gt;
                {SHORT_CHANNEL, CAT_MIDI, LONG_MIDI_CHANNEL}, // TEXT_MIDI_CHAN_GLOBAL&lt;br /&gt;
                {SHORT_LOOP, CAT_SEQUENCER, LONG_LOOP}, // rstephane: TEXT_LOOP&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
* We NEED declare it at the end of the section :-)&lt;br /&gt;
* now, open the &amp;#039;&amp;#039;&amp;#039;MenuText.h&amp;#039;&amp;#039;&amp;#039; file to declare the &amp;#039;&amp;#039;&amp;#039;short and long version of the TEXT&amp;#039;&amp;#039;&amp;#039; (TEXT_LOOP)&lt;br /&gt;
* go to section &amp;#039;const char longNames[][16] PROGMEM = &amp;#039; and &amp;#039;const char shortNames[][4] PROGMEM  = &amp;#039;&lt;br /&gt;
* add the parameters:&lt;br /&gt;
&lt;br /&gt;
        const char shortNames[][4] PROGMEM  = &lt;br /&gt;
        {&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        {&amp;quot;coa&amp;quot;},&lt;br /&gt;
        {&amp;quot;fin&amp;quot;},&lt;br /&gt;
        {&amp;quot;atk&amp;quot;},&lt;br /&gt;
        {&amp;quot;dec&amp;quot;},&lt;br /&gt;
        {&amp;quot;eg2&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        &lt;br /&gt;
        {&amp;quot;co2&amp;quot;},  // trigger clock out2 ppq&lt;br /&gt;
        {&amp;quot;pcr&amp;quot;}, // pattern change resets bar counter&lt;br /&gt;
        {&amp;quot;LEN&amp;quot;}, // rstephane: LEN for LOOP :-)&lt;br /&gt;
        &lt;br /&gt;
        };        &lt;br /&gt;
&lt;br /&gt;
        const char longNames[][16] PROGMEM = &lt;br /&gt;
        {&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        //01234567&lt;br /&gt;
        {&amp;quot;Coarse&amp;quot;},&lt;br /&gt;
        {&amp;quot;Fine&amp;quot;},&lt;br /&gt;
        {&amp;quot;Attack&amp;quot;},&lt;br /&gt;
        {&amp;quot;Decay&amp;quot;},&lt;br /&gt;
        {&amp;quot;Amount&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        {&amp;quot;Out2 PPQ&amp;quot;},&lt;br /&gt;
        {&amp;quot;Gate Mode&amp;quot;},&lt;br /&gt;
        {&amp;quot;PCReset&amp;quot; }, // reset bar counter on manual pattern change&lt;br /&gt;
        {&amp;quot;Loop&amp;quot;}, // rstephane: LOOP LONG text&lt;br /&gt;
        };&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
* If you want you can already compile and see the results under the menu PERF menu (normally under the second page, your should see &amp;#039;LEN&amp;#039; on the first knob).&lt;br /&gt;
&lt;br /&gt;
* Now, &amp;#039;&amp;#039;&amp;#039;we will create our function&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* We will add a link between this function and our knob.&lt;br /&gt;
&lt;br /&gt;
* open &amp;#039;&amp;#039;&amp;#039;midimessage.h&amp;#039;&amp;#039;&amp;#039; file&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//for all parameters above 127 &amp;lt;- our case&lt;br /&gt;
enum&lt;br /&gt;
{&lt;br /&gt;
        ....&lt;br /&gt;
        // Again, place your parameter at a special place, right after the section:&lt;br /&gt;
        CC2_MIDI_NOTE1,&lt;br /&gt;
        CC2_MIDI_NOTE2,&lt;br /&gt;
        CC2_MIDI_NOTE3,&lt;br /&gt;
        CC2_MIDI_NOTE4,&lt;br /&gt;
        CC2_MIDI_NOTE5,&lt;br /&gt;
        CC2_MIDI_NOTE6,&lt;br /&gt;
        CC2_MIDI_NOTE7, // s/b 111 i think&lt;br /&gt;
        &lt;br /&gt;
        // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
        // rstephane MY VALUES ADDED FOR RANDOM FUNCTION&lt;br /&gt;
        // rstephane : RND button :-) for CASE switch in MidiParser.C&lt;br /&gt;
        CC2_RND_VOICE1,&lt;br /&gt;
        ....&lt;br /&gt;
}Param2Enums;&lt;br /&gt;
&lt;br /&gt;
open &lt;br /&gt;
* MidiParser.c&lt;br /&gt;
//-----------------------------------------------------------&lt;br /&gt;
/** handle all incoming CCs and invoke action*/&lt;br /&gt;
void midiParser_ccHandler(MidiMsg msg, uint8_t updateOriginalValue)&lt;br /&gt;
{&lt;br /&gt;
        &lt;br /&gt;
        ...&lt;br /&gt;
        &lt;br /&gt;
        else //MIDI_CC2&lt;br /&gt;
        {&lt;br /&gt;
                const uint16_t paramNr = msg.data1+1 + 127;&lt;br /&gt;
&lt;br /&gt;
                if(updateOriginalValue) {&lt;br /&gt;
                        midiParser_originalCcValues[paramNr] = msg.data2;&lt;br /&gt;
                }&lt;br /&gt;
                switch(msg.data1)&lt;br /&gt;
                {&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_WAVE:&lt;br /&gt;
                                        voiceArray[0].transGen.waveform = msg.data2;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_VOL:&lt;br /&gt;
                                voiceArray[0].transGen.volume = msg.data2/127.f;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
        ...&lt;br /&gt;
        case CC2_MUTE_1:&lt;br /&gt;
                        case CC2_MUTE_2:&lt;br /&gt;
                        case CC2_MUTE_3:&lt;br /&gt;
                        case CC2_MUTE_4:&lt;br /&gt;
                        case CC2_MUTE_5:&lt;br /&gt;
                        case CC2_MUTE_6:&lt;br /&gt;
                        case CC2_MUTE_7:&lt;br /&gt;
                        {&lt;br /&gt;
                                const uint8_t voiceNr = msg.data1 - CC2_MUTE_1;&lt;br /&gt;
                                if(msg.data2 == 0)&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,0);&lt;br /&gt;
                                }&lt;br /&gt;
                                else&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,1);&lt;br /&gt;
                                }&lt;br /&gt;
&lt;br /&gt;
                        }&lt;br /&gt;
                                break;&lt;br /&gt;
                        // rstephane MY FUNCTIONS&lt;br /&gt;
                        // rstephane : Handle the RND button&lt;br /&gt;
                        case CC2_RND_VOICE1:&lt;br /&gt;
                                if(msg.data2 == 1)&lt;br /&gt;
                                {&lt;br /&gt;
                                        // RND is ON&lt;br /&gt;
                                        randomDrumVoice123(0); //voice1 = 0, voice2 = 1 etc...&lt;br /&gt;
                                }&lt;br /&gt;
                                break;        &lt;br /&gt;
                                                        &lt;br /&gt;
                        default:&lt;br /&gt;
                                break;&lt;br /&gt;
                                &lt;br /&gt;
                        ....&lt;br /&gt;
                        &lt;br /&gt;
                        &lt;br /&gt;
+ &lt;br /&gt;
open drumvoice.h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// rstephane : my functions&lt;br /&gt;
//random all the parameters for voice 1 2 and 3&lt;br /&gt;
void randomDrumVoice123(const uint8_t voiceNr);  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+&lt;br /&gt;
open drumvoice.c&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// rstephane : pour random functions&lt;br /&gt;
#include &amp;quot;valueShaper.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
+&lt;br /&gt;
&lt;br /&gt;
//---------------------------------------------------&lt;br /&gt;
// rstephane : my functions&lt;br /&gt;
//random all the parameters for voice 1 2 and 3&lt;br /&gt;
//---------------------------------------------------&lt;br /&gt;
void randomDrumVoice123(const uint8_t voiceNr)&lt;br /&gt;
{&lt;br /&gt;
                uint8_t rndData; // , new_min, new_max;&lt;br /&gt;
                // uint32_t rndDataTemp, old_min, old_max;&lt;br /&gt;
                // COARSE&lt;br /&gt;
                rndData = (uint8_t) GetRngValue();&lt;br /&gt;
                //clear upper nibble&lt;br /&gt;
                voiceArray[voiceNr].osc.midiFreq &amp;amp;= 0x00ff;&lt;br /&gt;
                //set upper nibble&lt;br /&gt;
                voiceArray[voiceNr].osc.midiFreq |= rndData &amp;lt;&amp;lt; 8;&lt;br /&gt;
                osc_recalcFreq(&amp;amp;voiceArray[voiceNr].osc);&lt;br /&gt;
                //OSC1_DIST:&lt;br /&gt;
                rndData = (uint8_t) GetRngValue();&lt;br /&gt;
#if USE_FILTER_DRIVE&lt;br /&gt;
                voiceArray[voiceNr].filter.drive = 0.5f + (rndData/127.f) *6;&lt;br /&gt;
#else&lt;br /&gt;
                setDistortionShape(&amp;amp;voiceArray[voiceNr].distortion,rndData);&lt;br /&gt;
#endif                        &lt;br /&gt;
                &lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Rstephane</name></author>
		
	</entry>
	<entry>
		<id>http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=233</id>
		<title>How to create and add a new function to the LXR</title>
		<link rel="alternate" type="text/html" href="http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=233"/>
		<updated>2014-05-09T15:46:39Z</updated>

		<summary type="html">&lt;p&gt;Rstephane: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a DRAFT !!!! I will correct it during the next days :-)&lt;br /&gt;
&lt;br /&gt;
* 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 :-)&lt;br /&gt;
&lt;br /&gt;
* We start by adding a new knob &amp;#039;LEN&amp;#039; (for Length) in  the PERF menu on the LCD display.&lt;br /&gt;
&lt;br /&gt;
* Open the file &amp;#039;&amp;#039;&amp;#039;&amp;#039;Parameters.h&amp;#039;&amp;#039;&amp;#039;&amp;#039;, we first declare our parameter and its type.&lt;br /&gt;
&lt;br /&gt;
* Add in the section: &amp;#039;enum ParamEnums&amp;#039; your new parameter. In our case we will add the parameter : PAR_LOOP&lt;br /&gt;
&lt;br /&gt;
* 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):&lt;br /&gt;
&lt;br /&gt;
        example: &lt;br /&gt;
        &lt;br /&gt;
        enum ParamEnums = {&lt;br /&gt;
        ...&lt;br /&gt;
        PAR_MIDI_NOTE1,&lt;br /&gt;
        PAR_MIDI_NOTE2,&lt;br /&gt;
        PAR_MIDI_NOTE3,&lt;br /&gt;
        PAR_MIDI_NOTE4,&lt;br /&gt;
        PAR_MIDI_NOTE5,&lt;br /&gt;
        PAR_MIDI_NOTE6,&lt;br /&gt;
        PAR_MIDI_NOTE7,&lt;br /&gt;
        // YOUR parameters comes right after thoses lines...&lt;br /&gt;
                   &lt;br /&gt;
        // rstephane MY VALUES ADDED FOR LOOP FUNCTION&lt;br /&gt;
        PAR_LOOP,     &lt;br /&gt;
        ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* We need to open the &amp;#039;&amp;#039;&amp;#039;menu.c&amp;#039;&amp;#039;&amp;#039; file. we want that our knob display a name &amp;#039;LEN&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        menu.c&lt;br /&gt;
        //---------------------------------------------------------------&lt;br /&gt;
        // Parameter types. These correspond with ParamEnums and entries in parameter_values&lt;br /&gt;
        const enum Datatypes PROGMEM parameter_dtypes[NUM_PARAMS] = {&lt;br /&gt;
            /*PAR_NONE*/                         DTYPE_0B127,                                                        // 0&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM1*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM2*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM3*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_SNARE*/  DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
        ....&lt;br /&gt;
&lt;br /&gt;
* Place your parameter at a special place, right after the section:&lt;br /&gt;
&lt;br /&gt;
            /*PAR_MIDI_NOTE1*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE2*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE3*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE4*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE5*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE6*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE7*/                DTYPE_NOTE_NAME,&lt;br /&gt;
           &lt;br /&gt;
            // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
            /*PAR_LOOP*/                      DTYPE_1B16, // Values goes from 1 to 16 steps&lt;br /&gt;
            &lt;br /&gt;
            /*PAR_ROLL*/                         DTYPE_MENU | (MENU_ROLL_RATES&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_MORPH*/                         DTYPE_0B255,&lt;br /&gt;
            ...&lt;br /&gt;
                &lt;br /&gt;
&lt;br /&gt;
Here the list of parameters you can choose from...&lt;br /&gt;
&lt;br /&gt;
        Type of parameters:&lt;br /&gt;
        //-----------------------------------------------------------------&lt;br /&gt;
        enum Datatypes&lt;br /&gt;
        {&lt;br /&gt;
        DTYPE_0B255,        //0:255&lt;br /&gt;
        DTYPE_0B127,        //0-127&lt;br /&gt;
        DTYPE_PM100,        //-100:100&lt;br /&gt;
        DTYPE_MENU,                //text type outputs &lt;br /&gt;
        DTYPE_PM63,                //-63 &amp;lt;-&amp;gt; 63&lt;br /&gt;
        DTYPE_1B16,                //1-16&lt;br /&gt;
        DTYPE_ON_OFF,        //0-1&lt;br /&gt;
        DTYPE_MIX_FM,        //0-1&lt;br /&gt;
        DTYPE_TARGET_SELECTION_LFO,&lt;br /&gt;
        DTYPE_TARGET_SELECTION_VELO,        &lt;br /&gt;
        DTYPE_VOICE_LFO,&lt;br /&gt;
        DTYPE_AUTOM_TARGET,&lt;br /&gt;
        DTYPE_0b1,&lt;br /&gt;
        DTYPE_NOTE_NAME, // --AS eg C#0, D 1 for note name&lt;br /&gt;
        DTYPE_0B15,                //0-15&lt;br /&gt;
        /*15*/&lt;br /&gt;
        /*16*/&lt;br /&gt;
        // --AS warning, we can only have 16 on this list the way things are laid out&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
* oki, once this done, we need to fill other information in the code&lt;br /&gt;
&lt;br /&gt;
* Open the file &amp;#039;&amp;#039;&amp;#039;menuPages.h&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
* 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&lt;br /&gt;
&lt;br /&gt;
* in the section: const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM ... add your MENU &lt;br /&gt;
&lt;br /&gt;
* in our case, we have:&lt;br /&gt;
&lt;br /&gt;
        const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM =&lt;br /&gt;
        {&lt;br /&gt;
        //page 1 - Voice 1&lt;br /&gt;
        {&lt;br /&gt;
        //sub page 1 - Oscillator&lt;br /&gt;
        {&lt;br /&gt;
        TEXT_COARSE,        TEXT_FINE,        TEXT_WAVEFORM,                TEXT_RND_VOICE,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,&lt;br /&gt;
        PAR_COARSE1,        PAR_FINE1,        PAR_OSC_WAVE_DRUM1,        PAR_RND_VOICE1,PAR_NONE,PAR_NONE,PAR_NONE,PAR_NONE&lt;br /&gt;
                },        &lt;br /&gt;
        ...&lt;br /&gt;
        //Page 10&lt;br /&gt;
	//---------------- Performance Mode Menu pages ---------------------------&lt;br /&gt;
	//These pages are shown when the selected mode is the &amp;quot;mute/pattern select&amp;quot; page&lt;br /&gt;
	//there is only one page with subpages shown for the whole mode&lt;br /&gt;
	{&lt;br /&gt;
	{		&lt;br /&gt;
	TEXT_SHUFFLE,	TEXT_ROLL_SPEED,	TEXT_X_FADE,	TEXT_SAMPLE_RATE,		 &amp;#039;&amp;#039;&amp;#039;TEXT_LOOP&amp;#039;&amp;#039;&amp;#039;,	TEXT_EMPTY,&lt;br /&gt;
	PAR_SHUFFLE,	&amp;#039;&amp;#039;&amp;#039;PAR_ROLL&amp;#039;&amp;#039;&amp;#039;,			PAR_MORPH,		PAR_VOICE_DECIMATION_ALL,		PAR_LOOP,&lt;br /&gt;
	},&lt;br /&gt;
        ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* We need now to declare the TEXT_LOOP and PAR_LOOP in other files :-)&lt;br /&gt;
&lt;br /&gt;
* Open file &amp;#039;&amp;#039;&amp;#039;menu.h&amp;#039;&amp;#039;&amp;#039;, and go to section &lt;br /&gt;
&lt;br /&gt;
        enum NamesEnum&lt;br /&gt;
        {&lt;br /&gt;
        TEXT_EMPTY = 0,                                        //0&lt;br /&gt;
        TEXT_COARSE,&lt;br /&gt;
        TEXT_FINE,&lt;br /&gt;
        TEXT_ATTACK,&lt;br /&gt;
        TEXT_DECAY,&lt;br /&gt;
        TEXT_PITCH_DECAY,&lt;br /&gt;
        TEXT_MOD_AMOUNT,                &lt;br /&gt;
        ....&lt;br /&gt;
&lt;br /&gt;
* Add at the end, the text &amp;#039;TEXT_LOOP&amp;quot; : &lt;br /&gt;
        &lt;br /&gt;
        ....&lt;br /&gt;
        TEXT_BAR_RESET_MODE,&lt;br /&gt;
        TEXT_MIDI_CHAN_GLOBAL,&lt;br /&gt;
        &amp;#039;&amp;#039;&amp;#039;TEXT_LOOP&amp;#039;&amp;#039;&amp;#039;,        // rstephane: LOOP text &lt;br /&gt;
        NUM_NAMES&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
* Open &amp;#039;&amp;#039;&amp;#039;Cc2Text.c&amp;#039;&amp;#039;&amp;#039; file and under the section &lt;br /&gt;
&lt;br /&gt;
//Voice 1 - Drum 1&lt;br /&gt;
//  1 Oscillator&lt;br /&gt;
{TEXT_COARSE, PAR_COARSE1},                         //2&lt;br /&gt;
{TEXT_FINE, PAR_FINE1},&lt;br /&gt;
{TEXT_WAVEFORM, PAR_OSC_WAVE_DRUM1},&lt;br /&gt;
{TEXT_RND_VOICE, PAR_RND_VOICE1}, // rstephane : added random button                                        &lt;br /&gt;
                                        &lt;br /&gt;
&lt;br /&gt;
* Open the &amp;#039;&amp;#039;&amp;#039;menu.c&amp;#039;&amp;#039;&amp;#039; file, go to section &amp;#039;&amp;#039;&amp;#039;valueNames&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
        const Name valueNames[NUM_NAMES] PROGMEM =&lt;br /&gt;
        {&lt;br /&gt;
                {SHORT_EMPTY,CAT_EMPTY,LONG_EMPTY},&lt;br /&gt;
                ....&lt;br /&gt;
&lt;br /&gt;
* Add the following information:&lt;br /&gt;
                ....&lt;br /&gt;
                {SHORT_BAR_RESET_MODE, CAT_SEQUENCER, LONG_BAR_RESET_MODE}, // TEXT_BAR_RESET_MODE&lt;br /&gt;
                {SHORT_CHANNEL, CAT_MIDI, LONG_MIDI_CHANNEL}, // TEXT_MIDI_CHAN_GLOBAL&lt;br /&gt;
                {SHORT_LOOP, CAT_SEQUENCER, LONG_LOOP}, // rstephane: TEXT_LOOP&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
* We NEED declare it at the end of the section :-)&lt;br /&gt;
&lt;br /&gt;
* now, open the &amp;#039;&amp;#039;&amp;#039;MenuText.h&amp;#039;&amp;#039;&amp;#039; file to declare the &amp;#039;&amp;#039;&amp;#039;short and long version of the TEXT&amp;#039;&amp;#039;&amp;#039; (TEXT_LOOP)&lt;br /&gt;
* go to section &amp;#039;const char longNames[][16] PROGMEM = &amp;#039; and &amp;#039;const char shortNames[][4] PROGMEM  = &amp;#039;&lt;br /&gt;
* add the parameters:&lt;br /&gt;
&lt;br /&gt;
        const char shortNames[][4] PROGMEM  = &lt;br /&gt;
        {&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        {&amp;quot;coa&amp;quot;},&lt;br /&gt;
        {&amp;quot;fin&amp;quot;},&lt;br /&gt;
        {&amp;quot;atk&amp;quot;},&lt;br /&gt;
        {&amp;quot;dec&amp;quot;},&lt;br /&gt;
        {&amp;quot;eg2&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        &lt;br /&gt;
        {&amp;quot;co2&amp;quot;},  // trigger clock out2 ppq&lt;br /&gt;
        {&amp;quot;pcr&amp;quot;}, // pattern change resets bar counter&lt;br /&gt;
        {&amp;quot;LEN&amp;quot;}, // rstephane: LEN for LOOP :-)&lt;br /&gt;
        &lt;br /&gt;
        };        &lt;br /&gt;
&lt;br /&gt;
        const char longNames[][16] PROGMEM = &lt;br /&gt;
        {&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        //01234567&lt;br /&gt;
        {&amp;quot;Coarse&amp;quot;},&lt;br /&gt;
        {&amp;quot;Fine&amp;quot;},&lt;br /&gt;
        {&amp;quot;Attack&amp;quot;},&lt;br /&gt;
        {&amp;quot;Decay&amp;quot;},&lt;br /&gt;
        {&amp;quot;Amount&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        {&amp;quot;Out2 PPQ&amp;quot;},&lt;br /&gt;
        {&amp;quot;Gate Mode&amp;quot;},&lt;br /&gt;
        {&amp;quot;PCReset&amp;quot; }, // reset bar counter on manual pattern change&lt;br /&gt;
        {&amp;quot;Loop&amp;quot;}, // rstephane: LOOP LONG text&lt;br /&gt;
        };&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
* If you want you can already compile and see the results under the menu PERF menu (normally under the second page, your should see &amp;#039;LEN&amp;#039; on the first knob).&lt;br /&gt;
&lt;br /&gt;
* Now, we will create our function&lt;br /&gt;
* We will add a link between this function and our knob.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/////&lt;br /&gt;
&lt;br /&gt;
 call the function relative to the encoder:&lt;br /&gt;
&lt;br /&gt;
open midimessage.h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//for all parameters above 127 &amp;lt;- our case&lt;br /&gt;
enum&lt;br /&gt;
{&lt;br /&gt;
        ....&lt;br /&gt;
        // Again, place your parameter at a special place, right after the section:&lt;br /&gt;
        CC2_MIDI_NOTE1,&lt;br /&gt;
        CC2_MIDI_NOTE2,&lt;br /&gt;
        CC2_MIDI_NOTE3,&lt;br /&gt;
        CC2_MIDI_NOTE4,&lt;br /&gt;
        CC2_MIDI_NOTE5,&lt;br /&gt;
        CC2_MIDI_NOTE6,&lt;br /&gt;
        CC2_MIDI_NOTE7, // s/b 111 i think&lt;br /&gt;
        &lt;br /&gt;
        // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
        // rstephane MY VALUES ADDED FOR RANDOM FUNCTION&lt;br /&gt;
        // rstephane : RND button :-) for CASE switch in MidiParser.C&lt;br /&gt;
        CC2_RND_VOICE1,&lt;br /&gt;
        ....&lt;br /&gt;
}Param2Enums;&lt;br /&gt;
&lt;br /&gt;
open &lt;br /&gt;
* MidiParser.c&lt;br /&gt;
//-----------------------------------------------------------&lt;br /&gt;
/** handle all incoming CCs and invoke action*/&lt;br /&gt;
void midiParser_ccHandler(MidiMsg msg, uint8_t updateOriginalValue)&lt;br /&gt;
{&lt;br /&gt;
        &lt;br /&gt;
        ...&lt;br /&gt;
        &lt;br /&gt;
        else //MIDI_CC2&lt;br /&gt;
        {&lt;br /&gt;
                const uint16_t paramNr = msg.data1+1 + 127;&lt;br /&gt;
&lt;br /&gt;
                if(updateOriginalValue) {&lt;br /&gt;
                        midiParser_originalCcValues[paramNr] = msg.data2;&lt;br /&gt;
                }&lt;br /&gt;
                switch(msg.data1)&lt;br /&gt;
                {&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_WAVE:&lt;br /&gt;
                                        voiceArray[0].transGen.waveform = msg.data2;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_VOL:&lt;br /&gt;
                                voiceArray[0].transGen.volume = msg.data2/127.f;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
        ...&lt;br /&gt;
        case CC2_MUTE_1:&lt;br /&gt;
                        case CC2_MUTE_2:&lt;br /&gt;
                        case CC2_MUTE_3:&lt;br /&gt;
                        case CC2_MUTE_4:&lt;br /&gt;
                        case CC2_MUTE_5:&lt;br /&gt;
                        case CC2_MUTE_6:&lt;br /&gt;
                        case CC2_MUTE_7:&lt;br /&gt;
                        {&lt;br /&gt;
                                const uint8_t voiceNr = msg.data1 - CC2_MUTE_1;&lt;br /&gt;
                                if(msg.data2 == 0)&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,0);&lt;br /&gt;
                                }&lt;br /&gt;
                                else&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,1);&lt;br /&gt;
                                }&lt;br /&gt;
&lt;br /&gt;
                        }&lt;br /&gt;
                                break;&lt;br /&gt;
                        // rstephane MY FUNCTIONS&lt;br /&gt;
                        // rstephane : Handle the RND button&lt;br /&gt;
                        case CC2_RND_VOICE1:&lt;br /&gt;
                                if(msg.data2 == 1)&lt;br /&gt;
                                {&lt;br /&gt;
                                        // RND is ON&lt;br /&gt;
                                        randomDrumVoice123(0); //voice1 = 0, voice2 = 1 etc...&lt;br /&gt;
                                }&lt;br /&gt;
                                break;        &lt;br /&gt;
                                                        &lt;br /&gt;
                        default:&lt;br /&gt;
                                break;&lt;br /&gt;
                                &lt;br /&gt;
                        ....&lt;br /&gt;
                        &lt;br /&gt;
                        &lt;br /&gt;
+ &lt;br /&gt;
open drumvoice.h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// rstephane : my functions&lt;br /&gt;
//random all the parameters for voice 1 2 and 3&lt;br /&gt;
void randomDrumVoice123(const uint8_t voiceNr);  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+&lt;br /&gt;
open drumvoice.c&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// rstephane : pour random functions&lt;br /&gt;
#include &amp;quot;valueShaper.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
+&lt;br /&gt;
&lt;br /&gt;
//---------------------------------------------------&lt;br /&gt;
// rstephane : my functions&lt;br /&gt;
//random all the parameters for voice 1 2 and 3&lt;br /&gt;
//---------------------------------------------------&lt;br /&gt;
void randomDrumVoice123(const uint8_t voiceNr)&lt;br /&gt;
{&lt;br /&gt;
                uint8_t rndData; // , new_min, new_max;&lt;br /&gt;
                // uint32_t rndDataTemp, old_min, old_max;&lt;br /&gt;
                // COARSE&lt;br /&gt;
                rndData = (uint8_t) GetRngValue();&lt;br /&gt;
                //clear upper nibble&lt;br /&gt;
                voiceArray[voiceNr].osc.midiFreq &amp;amp;= 0x00ff;&lt;br /&gt;
                //set upper nibble&lt;br /&gt;
                voiceArray[voiceNr].osc.midiFreq |= rndData &amp;lt;&amp;lt; 8;&lt;br /&gt;
                osc_recalcFreq(&amp;amp;voiceArray[voiceNr].osc);&lt;br /&gt;
                //OSC1_DIST:&lt;br /&gt;
                rndData = (uint8_t) GetRngValue();&lt;br /&gt;
#if USE_FILTER_DRIVE&lt;br /&gt;
                voiceArray[voiceNr].filter.drive = 0.5f + (rndData/127.f) *6;&lt;br /&gt;
#else&lt;br /&gt;
                setDistortionShape(&amp;amp;voiceArray[voiceNr].distortion,rndData);&lt;br /&gt;
#endif                        &lt;br /&gt;
                &lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Rstephane</name></author>
		
	</entry>
	<entry>
		<id>http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=232</id>
		<title>How to create and add a new function to the LXR</title>
		<link rel="alternate" type="text/html" href="http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=232"/>
		<updated>2014-05-09T15:33:49Z</updated>

		<summary type="html">&lt;p&gt;Rstephane: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a DRAFT !!!! I will correct it during the next days :-)&lt;br /&gt;
&lt;br /&gt;
* 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 :-)&lt;br /&gt;
&lt;br /&gt;
* We start by adding a new knob &amp;#039;LEN&amp;#039; (for Length) in  the PERF menu on the LCD display.&lt;br /&gt;
&lt;br /&gt;
* Open the file &amp;#039;Parameters.h&amp;#039;, we first declare our parameter and its type.&lt;br /&gt;
&lt;br /&gt;
* Add in the section: &amp;#039;enum ParamEnums&amp;#039; your new parameter. In our case we will add the parameter : PAR_LOOP&lt;br /&gt;
&lt;br /&gt;
* 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):&lt;br /&gt;
&lt;br /&gt;
example: &lt;br /&gt;
enum ParamEnums ...&lt;br /&gt;
        PAR_MIDI_NOTE1,&lt;br /&gt;
        PAR_MIDI_NOTE2,&lt;br /&gt;
        PAR_MIDI_NOTE3,&lt;br /&gt;
        PAR_MIDI_NOTE4,&lt;br /&gt;
        PAR_MIDI_NOTE5,&lt;br /&gt;
        PAR_MIDI_NOTE6,&lt;br /&gt;
        PAR_MIDI_NOTE7,&lt;br /&gt;
        // YOUR parameters comes right after thoses lines...&lt;br /&gt;
                   &lt;br /&gt;
        // rstephane MY VALUES ADDED FOR LOOP FUNCTION&lt;br /&gt;
        PAR_LOOP,     &lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
Now, let&amp;#039;s go the the menu text, we want that our knob display a name &amp;#039;FILTER&amp;#039; or in our case &amp;#039;RANDOM&amp;#039; .. well we will set it to &amp;#039;RND&amp;#039; to make it short on the LCD screen.&lt;br /&gt;
&lt;br /&gt;
We need to open the menu.c file.&lt;br /&gt;
&lt;br /&gt;
menu.c&lt;br /&gt;
//---------------------------------------------------------------&lt;br /&gt;
// Parameter types. These correspond with ParamEnums and entries in parameter_values&lt;br /&gt;
const enum Datatypes PROGMEM parameter_dtypes[NUM_PARAMS] = {&lt;br /&gt;
            /*PAR_NONE*/                         DTYPE_0B127,                                                        // 0&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM1*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM2*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM3*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_SNARE*/  DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
....&lt;br /&gt;
&lt;br /&gt;
Again, place your parameter at a special place, right after the section:&lt;br /&gt;
/*PAR_MIDI_NOTE1*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE2*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE3*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE4*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE5*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE6*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE7*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
            &lt;br /&gt;
            // rstephane MY VALUES ADDED FOR RANDOM FUNCTION&lt;br /&gt;
            /*PAR_RND_VOICE1*/        DTYPE_ON_OFF,  // choose the type of your parameter, a definition of the parameter type is shown right after....&lt;br /&gt;
            &lt;br /&gt;
            /*PAR_ROLL*/                         DTYPE_MENU | (MENU_ROLL_RATES&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_MORPH*/                         DTYPE_0B255,&lt;br /&gt;
                ....&lt;br /&gt;
                &lt;br /&gt;
Type of parameters:&lt;br /&gt;
//-----------------------------------------------------------------&lt;br /&gt;
enum Datatypes&lt;br /&gt;
{&lt;br /&gt;
        DTYPE_0B255,        //0:255&lt;br /&gt;
        DTYPE_0B127,        //0-127&lt;br /&gt;
        DTYPE_PM100,        //-100:100&lt;br /&gt;
        DTYPE_MENU,                //text type outputs &lt;br /&gt;
        DTYPE_PM63,                //-63 &amp;lt;-&amp;gt; 63&lt;br /&gt;
        DTYPE_1B16,                //1-16&lt;br /&gt;
        DTYPE_ON_OFF,        //0-1&lt;br /&gt;
        DTYPE_MIX_FM,        //0-1&lt;br /&gt;
        DTYPE_TARGET_SELECTION_LFO,&lt;br /&gt;
        DTYPE_TARGET_SELECTION_VELO,        &lt;br /&gt;
        DTYPE_VOICE_LFO,&lt;br /&gt;
        DTYPE_AUTOM_TARGET,&lt;br /&gt;
        DTYPE_0b1,&lt;br /&gt;
        DTYPE_NOTE_NAME, // --AS eg C#0, D 1 for note name&lt;br /&gt;
        DTYPE_0B15,                //0-15&lt;br /&gt;
        /*15*/&lt;br /&gt;
        /*16*/&lt;br /&gt;
        // --AS warning, we can only have 16 on this list the way things are laid out&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
oki, once this done, we need to fill other infformation in the code&lt;br /&gt;
&lt;br /&gt;
Open the* menuPages.h&lt;br /&gt;
&lt;br /&gt;
/** This array hold the whole menu structure.&lt;br /&gt;
each voice has different pages. The pages hold the top and bottom enums to indicate which values and desriptors to show&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
in the section: &lt;br /&gt;
const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM =&lt;br /&gt;
                ....&lt;br /&gt;
add your MENU ! &lt;br /&gt;
&lt;br /&gt;
in our case: we want to create an random knob for its voice. this new button/parameter will appear when we have selected  the &amp;#039;OSC&amp;#039; menu&lt;br /&gt;
&lt;br /&gt;
so we have:&lt;br /&gt;
&lt;br /&gt;
const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM =&lt;br /&gt;
{&lt;br /&gt;
        //page 1 - Voice 1&lt;br /&gt;
        {&lt;br /&gt;
                //sub page 1 - Oscillator&lt;br /&gt;
                {&lt;br /&gt;
                        TEXT_COARSE,        TEXT_FINE,        TEXT_WAVEFORM,                TEXT_RND_VOICE,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,&lt;br /&gt;
                        PAR_COARSE1,        PAR_FINE1,        PAR_OSC_WAVE_DRUM1,        PAR_RND_VOICE1,PAR_NONE,PAR_NONE,PAR_NONE,PAR_NONE&lt;br /&gt;
                },&lt;br /&gt;
                &lt;br /&gt;
&lt;br /&gt;
you will noticed two parameters:&lt;br /&gt;
TEXT_RND_VOICE and PAR_RND_VOICE1&lt;br /&gt;
&lt;br /&gt;
those parameter are important as the program will display on the LCD the menu names that appears in this section, so if we want to show a new menu or function, we need to add it in this section/file.&lt;br /&gt;
&lt;br /&gt;
but we need now to declare the TEXT_RND_VOICE1 and PAR_RND_VOICE1 in other files :-)&lt;br /&gt;
&lt;br /&gt;
Open file menu.h&lt;br /&gt;
go to section &lt;br /&gt;
&lt;br /&gt;
enum NamesEnum&lt;br /&gt;
{&lt;br /&gt;
        TEXT_EMPTY = 0,                                        //0&lt;br /&gt;
        TEXT_COARSE,&lt;br /&gt;
        TEXT_FINE,&lt;br /&gt;
        TEXT_ATTACK,&lt;br /&gt;
        TEXT_DECAY,&lt;br /&gt;
        TEXT_PITCH_DECAY,&lt;br /&gt;
        TEXT_MOD_AMOUNT,                &lt;br /&gt;
        ....&lt;br /&gt;
&lt;br /&gt;
add at the end, the text &amp;#039;TEXT_RND_VOICE1&amp;quot; : &lt;br /&gt;
        ....&lt;br /&gt;
        TEXT_BAR_RESET_MODE,&lt;br /&gt;
        TEXT_MIDI_CHAN_GLOBAL,&lt;br /&gt;
        TEXT_RND_VOICE,        // rstephane: random text &lt;br /&gt;
        NUM_NAMES&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
+&lt;br /&gt;
&lt;br /&gt;
Open Cc2Text.c&lt;br /&gt;
&lt;br /&gt;
//Voice 1 - Drum 1&lt;br /&gt;
//  1 Oscillator&lt;br /&gt;
{TEXT_COARSE, PAR_COARSE1},                         //2&lt;br /&gt;
{TEXT_FINE, PAR_FINE1},&lt;br /&gt;
{TEXT_WAVEFORM, PAR_OSC_WAVE_DRUM1},&lt;br /&gt;
{TEXT_RND_VOICE, PAR_RND_VOICE1}, // rstephane : added random button                                        &lt;br /&gt;
                                        &lt;br /&gt;
Now,&lt;br /&gt;
Open the menu.c file&lt;br /&gt;
go to section valueNames:&lt;br /&gt;
&lt;br /&gt;
const Name valueNames[NUM_NAMES] PROGMEM =&lt;br /&gt;
{&lt;br /&gt;
                {SHORT_EMPTY,CAT_EMPTY,LONG_EMPTY},&lt;br /&gt;
                ....&lt;br /&gt;
add the following information:&lt;br /&gt;
                ....&lt;br /&gt;
                {SHORT_BAR_RESET_MODE, CAT_SEQUENCER, LONG_BAR_RESET_MODE}, // TEXT_BAR_RESET_MODE&lt;br /&gt;
                {SHORT_CHANNEL, CAT_MIDI, LONG_MIDI_CHANNEL}, // TEXT_MIDI_CHAN_GLOBAL&lt;br /&gt;
                {SHORT_RND, CAT_OSC, LONG_RND_VOICE}, // rstephane: TEXT_RND_VOICE&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
we declare it at the end of the section :-)&lt;br /&gt;
&lt;br /&gt;
now, open the * MenuText.h file to declare the short and long version of the TEXT (TEXT_RND_VOICE1)&lt;br /&gt;
go to section&lt;br /&gt;
 &lt;br /&gt;
 const char longNames[][16] PROGMEM = &lt;br /&gt;
 et const char shortNames[][4] PROGMEM  = &lt;br /&gt;
&lt;br /&gt;
add the parameters:&lt;br /&gt;
&lt;br /&gt;
const char shortNames[][4] PROGMEM  = &lt;br /&gt;
{&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        {&amp;quot;coa&amp;quot;},&lt;br /&gt;
        {&amp;quot;fin&amp;quot;},&lt;br /&gt;
        {&amp;quot;atk&amp;quot;},&lt;br /&gt;
        {&amp;quot;dec&amp;quot;},&lt;br /&gt;
        {&amp;quot;eg2&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        &lt;br /&gt;
        {&amp;quot;co2&amp;quot;},  // trigger clock out2 ppq&lt;br /&gt;
        {&amp;quot;pcr&amp;quot;}, // pattern change resets bar counter&lt;br /&gt;
        {&amp;quot;RND&amp;quot;}, // rstephane: RND VOice&lt;br /&gt;
        &lt;br /&gt;
};        &lt;br /&gt;
&lt;br /&gt;
const char longNames[][16] PROGMEM = &lt;br /&gt;
{&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        //01234567&lt;br /&gt;
        {&amp;quot;Coarse&amp;quot;},&lt;br /&gt;
        {&amp;quot;Fine&amp;quot;},&lt;br /&gt;
        {&amp;quot;Attack&amp;quot;},&lt;br /&gt;
        {&amp;quot;Decay&amp;quot;},&lt;br /&gt;
        {&amp;quot;Amount&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        {&amp;quot;Out2 PPQ&amp;quot;},&lt;br /&gt;
        {&amp;quot;Gate Mode&amp;quot;},&lt;br /&gt;
        {&amp;quot;PCReset&amp;quot; }, // reset bar counter on manual pattern change&lt;br /&gt;
        {&amp;quot;Random&amp;quot;}, // rstephane: RND VOice LONG text&lt;br /&gt;
};&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
Now, we will create our function&lt;br /&gt;
and will add a link between this function and our knob.&lt;br /&gt;
&lt;br /&gt;
If you want you can already compile and see the results under the menu OSC of the VOICE1, normally right after COARSE, FINE, WAV, should appear RND.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/////&lt;br /&gt;
&lt;br /&gt;
 call the function relative to the encoder:&lt;br /&gt;
&lt;br /&gt;
open midimessage.h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//for all parameters above 127 &amp;lt;- our case&lt;br /&gt;
enum&lt;br /&gt;
{&lt;br /&gt;
        ....&lt;br /&gt;
        // Again, place your parameter at a special place, right after the section:&lt;br /&gt;
        CC2_MIDI_NOTE1,&lt;br /&gt;
        CC2_MIDI_NOTE2,&lt;br /&gt;
        CC2_MIDI_NOTE3,&lt;br /&gt;
        CC2_MIDI_NOTE4,&lt;br /&gt;
        CC2_MIDI_NOTE5,&lt;br /&gt;
        CC2_MIDI_NOTE6,&lt;br /&gt;
        CC2_MIDI_NOTE7, // s/b 111 i think&lt;br /&gt;
        &lt;br /&gt;
        // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
        // rstephane MY VALUES ADDED FOR RANDOM FUNCTION&lt;br /&gt;
        // rstephane : RND button :-) for CASE switch in MidiParser.C&lt;br /&gt;
        CC2_RND_VOICE1,&lt;br /&gt;
        ....&lt;br /&gt;
}Param2Enums;&lt;br /&gt;
&lt;br /&gt;
open &lt;br /&gt;
* MidiParser.c&lt;br /&gt;
//-----------------------------------------------------------&lt;br /&gt;
/** handle all incoming CCs and invoke action*/&lt;br /&gt;
void midiParser_ccHandler(MidiMsg msg, uint8_t updateOriginalValue)&lt;br /&gt;
{&lt;br /&gt;
        &lt;br /&gt;
        ...&lt;br /&gt;
        &lt;br /&gt;
        else //MIDI_CC2&lt;br /&gt;
        {&lt;br /&gt;
                const uint16_t paramNr = msg.data1+1 + 127;&lt;br /&gt;
&lt;br /&gt;
                if(updateOriginalValue) {&lt;br /&gt;
                        midiParser_originalCcValues[paramNr] = msg.data2;&lt;br /&gt;
                }&lt;br /&gt;
                switch(msg.data1)&lt;br /&gt;
                {&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_WAVE:&lt;br /&gt;
                                        voiceArray[0].transGen.waveform = msg.data2;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_VOL:&lt;br /&gt;
                                voiceArray[0].transGen.volume = msg.data2/127.f;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
        ...&lt;br /&gt;
        case CC2_MUTE_1:&lt;br /&gt;
                        case CC2_MUTE_2:&lt;br /&gt;
                        case CC2_MUTE_3:&lt;br /&gt;
                        case CC2_MUTE_4:&lt;br /&gt;
                        case CC2_MUTE_5:&lt;br /&gt;
                        case CC2_MUTE_6:&lt;br /&gt;
                        case CC2_MUTE_7:&lt;br /&gt;
                        {&lt;br /&gt;
                                const uint8_t voiceNr = msg.data1 - CC2_MUTE_1;&lt;br /&gt;
                                if(msg.data2 == 0)&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,0);&lt;br /&gt;
                                }&lt;br /&gt;
                                else&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,1);&lt;br /&gt;
                                }&lt;br /&gt;
&lt;br /&gt;
                        }&lt;br /&gt;
                                break;&lt;br /&gt;
                        // rstephane MY FUNCTIONS&lt;br /&gt;
                        // rstephane : Handle the RND button&lt;br /&gt;
                        case CC2_RND_VOICE1:&lt;br /&gt;
                                if(msg.data2 == 1)&lt;br /&gt;
                                {&lt;br /&gt;
                                        // RND is ON&lt;br /&gt;
                                        randomDrumVoice123(0); //voice1 = 0, voice2 = 1 etc...&lt;br /&gt;
                                }&lt;br /&gt;
                                break;        &lt;br /&gt;
                                                        &lt;br /&gt;
                        default:&lt;br /&gt;
                                break;&lt;br /&gt;
                                &lt;br /&gt;
                        ....&lt;br /&gt;
                        &lt;br /&gt;
                        &lt;br /&gt;
+ &lt;br /&gt;
open drumvoice.h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// rstephane : my functions&lt;br /&gt;
//random all the parameters for voice 1 2 and 3&lt;br /&gt;
void randomDrumVoice123(const uint8_t voiceNr);  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+&lt;br /&gt;
open drumvoice.c&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// rstephane : pour random functions&lt;br /&gt;
#include &amp;quot;valueShaper.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
+&lt;br /&gt;
&lt;br /&gt;
//---------------------------------------------------&lt;br /&gt;
// rstephane : my functions&lt;br /&gt;
//random all the parameters for voice 1 2 and 3&lt;br /&gt;
//---------------------------------------------------&lt;br /&gt;
void randomDrumVoice123(const uint8_t voiceNr)&lt;br /&gt;
{&lt;br /&gt;
                uint8_t rndData; // , new_min, new_max;&lt;br /&gt;
                // uint32_t rndDataTemp, old_min, old_max;&lt;br /&gt;
                // COARSE&lt;br /&gt;
                rndData = (uint8_t) GetRngValue();&lt;br /&gt;
                //clear upper nibble&lt;br /&gt;
                voiceArray[voiceNr].osc.midiFreq &amp;amp;= 0x00ff;&lt;br /&gt;
                //set upper nibble&lt;br /&gt;
                voiceArray[voiceNr].osc.midiFreq |= rndData &amp;lt;&amp;lt; 8;&lt;br /&gt;
                osc_recalcFreq(&amp;amp;voiceArray[voiceNr].osc);&lt;br /&gt;
                //OSC1_DIST:&lt;br /&gt;
                rndData = (uint8_t) GetRngValue();&lt;br /&gt;
#if USE_FILTER_DRIVE&lt;br /&gt;
                voiceArray[voiceNr].filter.drive = 0.5f + (rndData/127.f) *6;&lt;br /&gt;
#else&lt;br /&gt;
                setDistortionShape(&amp;amp;voiceArray[voiceNr].distortion,rndData);&lt;br /&gt;
#endif                        &lt;br /&gt;
                &lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Rstephane</name></author>
		
	</entry>
	<entry>
		<id>http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=231</id>
		<title>How to create and add a new function to the LXR</title>
		<link rel="alternate" type="text/html" href="http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=231"/>
		<updated>2014-05-09T15:33:09Z</updated>

		<summary type="html">&lt;p&gt;Rstephane: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a DRAFT !!!! I will correct it during the next days :-)&lt;br /&gt;
&lt;br /&gt;
* 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 :-)&lt;br /&gt;
&lt;br /&gt;
- We start by adding a new knob &amp;#039;LEN&amp;#039; (for Length) in  the PERF menu on the LCD display.&lt;br /&gt;
&lt;br /&gt;
* Open the file &amp;#039;Parameters.h&amp;#039;, we first declare our parameter and its type.&lt;br /&gt;
&lt;br /&gt;
add in the section: &amp;#039;enum ParamEnums&amp;#039; ... your new parameter. In our case we wil add the parameter : PAR_LOOP&lt;br /&gt;
&lt;br /&gt;
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):&lt;br /&gt;
&lt;br /&gt;
enum ParamEnums ...&lt;br /&gt;
        PAR_MIDI_NOTE1,&lt;br /&gt;
        PAR_MIDI_NOTE2,&lt;br /&gt;
        PAR_MIDI_NOTE3,&lt;br /&gt;
        PAR_MIDI_NOTE4,&lt;br /&gt;
        PAR_MIDI_NOTE5,&lt;br /&gt;
        PAR_MIDI_NOTE6,&lt;br /&gt;
        PAR_MIDI_NOTE7,&lt;br /&gt;
        // YOUR parameters comes right after thoses lines...&lt;br /&gt;
                   &lt;br /&gt;
        // rstephane MY VALUES ADDED FOR LOOP FUNCTION&lt;br /&gt;
        PAR_LOOP,     &lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
Now, let&amp;#039;s go the the menu text, we want that our knob display a name &amp;#039;FILTER&amp;#039; or in our case &amp;#039;RANDOM&amp;#039; .. well we will set it to &amp;#039;RND&amp;#039; to make it short on the LCD screen.&lt;br /&gt;
&lt;br /&gt;
We need to open the menu.c file.&lt;br /&gt;
&lt;br /&gt;
menu.c&lt;br /&gt;
//---------------------------------------------------------------&lt;br /&gt;
// Parameter types. These correspond with ParamEnums and entries in parameter_values&lt;br /&gt;
const enum Datatypes PROGMEM parameter_dtypes[NUM_PARAMS] = {&lt;br /&gt;
            /*PAR_NONE*/                         DTYPE_0B127,                                                        // 0&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM1*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM2*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM3*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_SNARE*/  DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
....&lt;br /&gt;
&lt;br /&gt;
Again, place your parameter at a special place, right after the section:&lt;br /&gt;
/*PAR_MIDI_NOTE1*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE2*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE3*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE4*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE5*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE6*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE7*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
            &lt;br /&gt;
            // rstephane MY VALUES ADDED FOR RANDOM FUNCTION&lt;br /&gt;
            /*PAR_RND_VOICE1*/        DTYPE_ON_OFF,  // choose the type of your parameter, a definition of the parameter type is shown right after....&lt;br /&gt;
            &lt;br /&gt;
            /*PAR_ROLL*/                         DTYPE_MENU | (MENU_ROLL_RATES&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_MORPH*/                         DTYPE_0B255,&lt;br /&gt;
                ....&lt;br /&gt;
                &lt;br /&gt;
Type of parameters:&lt;br /&gt;
//-----------------------------------------------------------------&lt;br /&gt;
enum Datatypes&lt;br /&gt;
{&lt;br /&gt;
        DTYPE_0B255,        //0:255&lt;br /&gt;
        DTYPE_0B127,        //0-127&lt;br /&gt;
        DTYPE_PM100,        //-100:100&lt;br /&gt;
        DTYPE_MENU,                //text type outputs &lt;br /&gt;
        DTYPE_PM63,                //-63 &amp;lt;-&amp;gt; 63&lt;br /&gt;
        DTYPE_1B16,                //1-16&lt;br /&gt;
        DTYPE_ON_OFF,        //0-1&lt;br /&gt;
        DTYPE_MIX_FM,        //0-1&lt;br /&gt;
        DTYPE_TARGET_SELECTION_LFO,&lt;br /&gt;
        DTYPE_TARGET_SELECTION_VELO,        &lt;br /&gt;
        DTYPE_VOICE_LFO,&lt;br /&gt;
        DTYPE_AUTOM_TARGET,&lt;br /&gt;
        DTYPE_0b1,&lt;br /&gt;
        DTYPE_NOTE_NAME, // --AS eg C#0, D 1 for note name&lt;br /&gt;
        DTYPE_0B15,                //0-15&lt;br /&gt;
        /*15*/&lt;br /&gt;
        /*16*/&lt;br /&gt;
        // --AS warning, we can only have 16 on this list the way things are laid out&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
oki, once this done, we need to fill other infformation in the code&lt;br /&gt;
&lt;br /&gt;
Open the* menuPages.h&lt;br /&gt;
&lt;br /&gt;
/** This array hold the whole menu structure.&lt;br /&gt;
each voice has different pages. The pages hold the top and bottom enums to indicate which values and desriptors to show&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
in the section: &lt;br /&gt;
const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM =&lt;br /&gt;
                ....&lt;br /&gt;
add your MENU ! &lt;br /&gt;
&lt;br /&gt;
in our case: we want to create an random knob for its voice. this new button/parameter will appear when we have selected  the &amp;#039;OSC&amp;#039; menu&lt;br /&gt;
&lt;br /&gt;
so we have:&lt;br /&gt;
&lt;br /&gt;
const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM =&lt;br /&gt;
{&lt;br /&gt;
        //page 1 - Voice 1&lt;br /&gt;
        {&lt;br /&gt;
                //sub page 1 - Oscillator&lt;br /&gt;
                {&lt;br /&gt;
                        TEXT_COARSE,        TEXT_FINE,        TEXT_WAVEFORM,                TEXT_RND_VOICE,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,&lt;br /&gt;
                        PAR_COARSE1,        PAR_FINE1,        PAR_OSC_WAVE_DRUM1,        PAR_RND_VOICE1,PAR_NONE,PAR_NONE,PAR_NONE,PAR_NONE&lt;br /&gt;
                },&lt;br /&gt;
                &lt;br /&gt;
&lt;br /&gt;
you will noticed two parameters:&lt;br /&gt;
TEXT_RND_VOICE and PAR_RND_VOICE1&lt;br /&gt;
&lt;br /&gt;
those parameter are important as the program will display on the LCD the menu names that appears in this section, so if we want to show a new menu or function, we need to add it in this section/file.&lt;br /&gt;
&lt;br /&gt;
but we need now to declare the TEXT_RND_VOICE1 and PAR_RND_VOICE1 in other files :-)&lt;br /&gt;
&lt;br /&gt;
Open file menu.h&lt;br /&gt;
go to section &lt;br /&gt;
&lt;br /&gt;
enum NamesEnum&lt;br /&gt;
{&lt;br /&gt;
        TEXT_EMPTY = 0,                                        //0&lt;br /&gt;
        TEXT_COARSE,&lt;br /&gt;
        TEXT_FINE,&lt;br /&gt;
        TEXT_ATTACK,&lt;br /&gt;
        TEXT_DECAY,&lt;br /&gt;
        TEXT_PITCH_DECAY,&lt;br /&gt;
        TEXT_MOD_AMOUNT,                &lt;br /&gt;
        ....&lt;br /&gt;
&lt;br /&gt;
add at the end, the text &amp;#039;TEXT_RND_VOICE1&amp;quot; : &lt;br /&gt;
        ....&lt;br /&gt;
        TEXT_BAR_RESET_MODE,&lt;br /&gt;
        TEXT_MIDI_CHAN_GLOBAL,&lt;br /&gt;
        TEXT_RND_VOICE,        // rstephane: random text &lt;br /&gt;
        NUM_NAMES&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
+&lt;br /&gt;
&lt;br /&gt;
Open Cc2Text.c&lt;br /&gt;
&lt;br /&gt;
//Voice 1 - Drum 1&lt;br /&gt;
//  1 Oscillator&lt;br /&gt;
{TEXT_COARSE, PAR_COARSE1},                         //2&lt;br /&gt;
{TEXT_FINE, PAR_FINE1},&lt;br /&gt;
{TEXT_WAVEFORM, PAR_OSC_WAVE_DRUM1},&lt;br /&gt;
{TEXT_RND_VOICE, PAR_RND_VOICE1}, // rstephane : added random button                                        &lt;br /&gt;
                                        &lt;br /&gt;
Now,&lt;br /&gt;
Open the menu.c file&lt;br /&gt;
go to section valueNames:&lt;br /&gt;
&lt;br /&gt;
const Name valueNames[NUM_NAMES] PROGMEM =&lt;br /&gt;
{&lt;br /&gt;
                {SHORT_EMPTY,CAT_EMPTY,LONG_EMPTY},&lt;br /&gt;
                ....&lt;br /&gt;
add the following information:&lt;br /&gt;
                ....&lt;br /&gt;
                {SHORT_BAR_RESET_MODE, CAT_SEQUENCER, LONG_BAR_RESET_MODE}, // TEXT_BAR_RESET_MODE&lt;br /&gt;
                {SHORT_CHANNEL, CAT_MIDI, LONG_MIDI_CHANNEL}, // TEXT_MIDI_CHAN_GLOBAL&lt;br /&gt;
                {SHORT_RND, CAT_OSC, LONG_RND_VOICE}, // rstephane: TEXT_RND_VOICE&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
we declare it at the end of the section :-)&lt;br /&gt;
&lt;br /&gt;
now, open the * MenuText.h file to declare the short and long version of the TEXT (TEXT_RND_VOICE1)&lt;br /&gt;
go to section&lt;br /&gt;
 &lt;br /&gt;
 const char longNames[][16] PROGMEM = &lt;br /&gt;
 et const char shortNames[][4] PROGMEM  = &lt;br /&gt;
&lt;br /&gt;
add the parameters:&lt;br /&gt;
&lt;br /&gt;
const char shortNames[][4] PROGMEM  = &lt;br /&gt;
{&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        {&amp;quot;coa&amp;quot;},&lt;br /&gt;
        {&amp;quot;fin&amp;quot;},&lt;br /&gt;
        {&amp;quot;atk&amp;quot;},&lt;br /&gt;
        {&amp;quot;dec&amp;quot;},&lt;br /&gt;
        {&amp;quot;eg2&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        &lt;br /&gt;
        {&amp;quot;co2&amp;quot;},  // trigger clock out2 ppq&lt;br /&gt;
        {&amp;quot;pcr&amp;quot;}, // pattern change resets bar counter&lt;br /&gt;
        {&amp;quot;RND&amp;quot;}, // rstephane: RND VOice&lt;br /&gt;
        &lt;br /&gt;
};        &lt;br /&gt;
&lt;br /&gt;
const char longNames[][16] PROGMEM = &lt;br /&gt;
{&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        //01234567&lt;br /&gt;
        {&amp;quot;Coarse&amp;quot;},&lt;br /&gt;
        {&amp;quot;Fine&amp;quot;},&lt;br /&gt;
        {&amp;quot;Attack&amp;quot;},&lt;br /&gt;
        {&amp;quot;Decay&amp;quot;},&lt;br /&gt;
        {&amp;quot;Amount&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        {&amp;quot;Out2 PPQ&amp;quot;},&lt;br /&gt;
        {&amp;quot;Gate Mode&amp;quot;},&lt;br /&gt;
        {&amp;quot;PCReset&amp;quot; }, // reset bar counter on manual pattern change&lt;br /&gt;
        {&amp;quot;Random&amp;quot;}, // rstephane: RND VOice LONG text&lt;br /&gt;
};&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
Now, we will create our function&lt;br /&gt;
and will add a link between this function and our knob.&lt;br /&gt;
&lt;br /&gt;
If you want you can already compile and see the results under the menu OSC of the VOICE1, normally right after COARSE, FINE, WAV, should appear RND.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/////&lt;br /&gt;
&lt;br /&gt;
 call the function relative to the encoder:&lt;br /&gt;
&lt;br /&gt;
open midimessage.h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//for all parameters above 127 &amp;lt;- our case&lt;br /&gt;
enum&lt;br /&gt;
{&lt;br /&gt;
        ....&lt;br /&gt;
        // Again, place your parameter at a special place, right after the section:&lt;br /&gt;
        CC2_MIDI_NOTE1,&lt;br /&gt;
        CC2_MIDI_NOTE2,&lt;br /&gt;
        CC2_MIDI_NOTE3,&lt;br /&gt;
        CC2_MIDI_NOTE4,&lt;br /&gt;
        CC2_MIDI_NOTE5,&lt;br /&gt;
        CC2_MIDI_NOTE6,&lt;br /&gt;
        CC2_MIDI_NOTE7, // s/b 111 i think&lt;br /&gt;
        &lt;br /&gt;
        // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
        // rstephane MY VALUES ADDED FOR RANDOM FUNCTION&lt;br /&gt;
        // rstephane : RND button :-) for CASE switch in MidiParser.C&lt;br /&gt;
        CC2_RND_VOICE1,&lt;br /&gt;
        ....&lt;br /&gt;
}Param2Enums;&lt;br /&gt;
&lt;br /&gt;
open &lt;br /&gt;
* MidiParser.c&lt;br /&gt;
//-----------------------------------------------------------&lt;br /&gt;
/** handle all incoming CCs and invoke action*/&lt;br /&gt;
void midiParser_ccHandler(MidiMsg msg, uint8_t updateOriginalValue)&lt;br /&gt;
{&lt;br /&gt;
        &lt;br /&gt;
        ...&lt;br /&gt;
        &lt;br /&gt;
        else //MIDI_CC2&lt;br /&gt;
        {&lt;br /&gt;
                const uint16_t paramNr = msg.data1+1 + 127;&lt;br /&gt;
&lt;br /&gt;
                if(updateOriginalValue) {&lt;br /&gt;
                        midiParser_originalCcValues[paramNr] = msg.data2;&lt;br /&gt;
                }&lt;br /&gt;
                switch(msg.data1)&lt;br /&gt;
                {&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_WAVE:&lt;br /&gt;
                                        voiceArray[0].transGen.waveform = msg.data2;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_VOL:&lt;br /&gt;
                                voiceArray[0].transGen.volume = msg.data2/127.f;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
        ...&lt;br /&gt;
        case CC2_MUTE_1:&lt;br /&gt;
                        case CC2_MUTE_2:&lt;br /&gt;
                        case CC2_MUTE_3:&lt;br /&gt;
                        case CC2_MUTE_4:&lt;br /&gt;
                        case CC2_MUTE_5:&lt;br /&gt;
                        case CC2_MUTE_6:&lt;br /&gt;
                        case CC2_MUTE_7:&lt;br /&gt;
                        {&lt;br /&gt;
                                const uint8_t voiceNr = msg.data1 - CC2_MUTE_1;&lt;br /&gt;
                                if(msg.data2 == 0)&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,0);&lt;br /&gt;
                                }&lt;br /&gt;
                                else&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,1);&lt;br /&gt;
                                }&lt;br /&gt;
&lt;br /&gt;
                        }&lt;br /&gt;
                                break;&lt;br /&gt;
                        // rstephane MY FUNCTIONS&lt;br /&gt;
                        // rstephane : Handle the RND button&lt;br /&gt;
                        case CC2_RND_VOICE1:&lt;br /&gt;
                                if(msg.data2 == 1)&lt;br /&gt;
                                {&lt;br /&gt;
                                        // RND is ON&lt;br /&gt;
                                        randomDrumVoice123(0); //voice1 = 0, voice2 = 1 etc...&lt;br /&gt;
                                }&lt;br /&gt;
                                break;        &lt;br /&gt;
                                                        &lt;br /&gt;
                        default:&lt;br /&gt;
                                break;&lt;br /&gt;
                                &lt;br /&gt;
                        ....&lt;br /&gt;
                        &lt;br /&gt;
                        &lt;br /&gt;
+ &lt;br /&gt;
open drumvoice.h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// rstephane : my functions&lt;br /&gt;
//random all the parameters for voice 1 2 and 3&lt;br /&gt;
void randomDrumVoice123(const uint8_t voiceNr);  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+&lt;br /&gt;
open drumvoice.c&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// rstephane : pour random functions&lt;br /&gt;
#include &amp;quot;valueShaper.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
+&lt;br /&gt;
&lt;br /&gt;
//---------------------------------------------------&lt;br /&gt;
// rstephane : my functions&lt;br /&gt;
//random all the parameters for voice 1 2 and 3&lt;br /&gt;
//---------------------------------------------------&lt;br /&gt;
void randomDrumVoice123(const uint8_t voiceNr)&lt;br /&gt;
{&lt;br /&gt;
                uint8_t rndData; // , new_min, new_max;&lt;br /&gt;
                // uint32_t rndDataTemp, old_min, old_max;&lt;br /&gt;
                // COARSE&lt;br /&gt;
                rndData = (uint8_t) GetRngValue();&lt;br /&gt;
                //clear upper nibble&lt;br /&gt;
                voiceArray[voiceNr].osc.midiFreq &amp;amp;= 0x00ff;&lt;br /&gt;
                //set upper nibble&lt;br /&gt;
                voiceArray[voiceNr].osc.midiFreq |= rndData &amp;lt;&amp;lt; 8;&lt;br /&gt;
                osc_recalcFreq(&amp;amp;voiceArray[voiceNr].osc);&lt;br /&gt;
                //OSC1_DIST:&lt;br /&gt;
                rndData = (uint8_t) GetRngValue();&lt;br /&gt;
#if USE_FILTER_DRIVE&lt;br /&gt;
                voiceArray[voiceNr].filter.drive = 0.5f + (rndData/127.f) *6;&lt;br /&gt;
#else&lt;br /&gt;
                setDistortionShape(&amp;amp;voiceArray[voiceNr].distortion,rndData);&lt;br /&gt;
#endif                        &lt;br /&gt;
                &lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Rstephane</name></author>
		
	</entry>
	<entry>
		<id>http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=230</id>
		<title>How to create and add a new function to the LXR</title>
		<link rel="alternate" type="text/html" href="http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=230"/>
		<updated>2014-05-09T14:51:17Z</updated>

		<summary type="html">&lt;p&gt;Rstephane: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a DRAFT !!!! I will correct it during the next days :-)&lt;br /&gt;
&lt;br /&gt;
We start with the LCD display menu part&lt;br /&gt;
&lt;br /&gt;
- we first declare our parameter and its type.&lt;br /&gt;
&lt;br /&gt;
open the file &amp;#039;Parameters.h&amp;#039;&lt;br /&gt;
&lt;br /&gt;
add in the section: &amp;#039;enum ParamEnums&amp;#039; ... your new parameter&lt;br /&gt;
&lt;br /&gt;
for instance, in our case we want to create an random knob for its voice. this new button/parameter will appear when we have selected  the &amp;#039;OSC&amp;#039; menu&lt;br /&gt;
so we open the &amp;#039;parameters.h&amp;#039; file and in the section &amp;#039;enum ParamEnums&amp;#039;, we add: &amp;#039;PAR_RND_VOICE1,&amp;#039;	&lt;br /&gt;
&lt;br /&gt;
you have to add all the new parameters right after the following declaration (otherwise you want link later the knob with the function you want to execute):&lt;br /&gt;
&lt;br /&gt;
enum ParamEnums ...&lt;br /&gt;
        PAR_MIDI_NOTE1,&lt;br /&gt;
        PAR_MIDI_NOTE2,&lt;br /&gt;
        PAR_MIDI_NOTE3,&lt;br /&gt;
        PAR_MIDI_NOTE4,&lt;br /&gt;
        PAR_MIDI_NOTE5,&lt;br /&gt;
        PAR_MIDI_NOTE6,&lt;br /&gt;
        PAR_MIDI_NOTE7,&lt;br /&gt;
        // YOUR parameters comes right after thoses lines...&lt;br /&gt;
                   &lt;br /&gt;
        // rstephane MY VALUES ADDED FOR RANDOM FUNCTION&lt;br /&gt;
        PAR_RND_VOICE1,        // rstephane: randomize drum1 / voice 1&lt;br /&gt;
&lt;br /&gt;
        //#########################################&lt;br /&gt;
        //######## End of sound Parameters ########&lt;br /&gt;
        //#########################################&lt;br /&gt;
        &lt;br /&gt;
        //all parameters in this section are only there to be referenced from the menu&lt;br /&gt;
        //they are not saved anywhere&lt;br /&gt;
        END_OF_SOUND_PARAMETERS,&lt;br /&gt;
        //the parameter declaration continues but don&amp;#039;t changed it, don&amp;#039;t add your parameters below... etc.&lt;br /&gt;
                ....&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
Now, let&amp;#039;s go the the menu text, we want that our knob display a name &amp;#039;FILTER&amp;#039; or in our case &amp;#039;RANDOM&amp;#039; .. well we will set it to &amp;#039;RND&amp;#039; to make it short on the LCD screen.&lt;br /&gt;
&lt;br /&gt;
We need to open the menu.c file.&lt;br /&gt;
&lt;br /&gt;
menu.c&lt;br /&gt;
//---------------------------------------------------------------&lt;br /&gt;
// Parameter types. These correspond with ParamEnums and entries in parameter_values&lt;br /&gt;
const enum Datatypes PROGMEM parameter_dtypes[NUM_PARAMS] = {&lt;br /&gt;
            /*PAR_NONE*/                         DTYPE_0B127,                                                        // 0&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM1*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM2*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM3*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_SNARE*/  DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
....&lt;br /&gt;
&lt;br /&gt;
Again, place your parameter at a special place, right after the section:&lt;br /&gt;
/*PAR_MIDI_NOTE1*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE2*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE3*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE4*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE5*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE6*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE7*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
            &lt;br /&gt;
            // rstephane MY VALUES ADDED FOR RANDOM FUNCTION&lt;br /&gt;
            /*PAR_RND_VOICE1*/        DTYPE_ON_OFF,  // choose the type of your parameter, a definition of the parameter type is shown right after....&lt;br /&gt;
            &lt;br /&gt;
            /*PAR_ROLL*/                         DTYPE_MENU | (MENU_ROLL_RATES&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_MORPH*/                         DTYPE_0B255,&lt;br /&gt;
                ....&lt;br /&gt;
                &lt;br /&gt;
Type of parameters:&lt;br /&gt;
//-----------------------------------------------------------------&lt;br /&gt;
enum Datatypes&lt;br /&gt;
{&lt;br /&gt;
        DTYPE_0B255,        //0:255&lt;br /&gt;
        DTYPE_0B127,        //0-127&lt;br /&gt;
        DTYPE_PM100,        //-100:100&lt;br /&gt;
        DTYPE_MENU,                //text type outputs &lt;br /&gt;
        DTYPE_PM63,                //-63 &amp;lt;-&amp;gt; 63&lt;br /&gt;
        DTYPE_1B16,                //1-16&lt;br /&gt;
        DTYPE_ON_OFF,        //0-1&lt;br /&gt;
        DTYPE_MIX_FM,        //0-1&lt;br /&gt;
        DTYPE_TARGET_SELECTION_LFO,&lt;br /&gt;
        DTYPE_TARGET_SELECTION_VELO,        &lt;br /&gt;
        DTYPE_VOICE_LFO,&lt;br /&gt;
        DTYPE_AUTOM_TARGET,&lt;br /&gt;
        DTYPE_0b1,&lt;br /&gt;
        DTYPE_NOTE_NAME, // --AS eg C#0, D 1 for note name&lt;br /&gt;
        DTYPE_0B15,                //0-15&lt;br /&gt;
        /*15*/&lt;br /&gt;
        /*16*/&lt;br /&gt;
        // --AS warning, we can only have 16 on this list the way things are laid out&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
oki, once this done, we need to fill other infformation in the code&lt;br /&gt;
&lt;br /&gt;
Open the* menuPages.h&lt;br /&gt;
&lt;br /&gt;
/** This array hold the whole menu structure.&lt;br /&gt;
each voice has different pages. The pages hold the top and bottom enums to indicate which values and desriptors to show&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
in the section: &lt;br /&gt;
const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM =&lt;br /&gt;
                ....&lt;br /&gt;
add your MENU ! &lt;br /&gt;
&lt;br /&gt;
in our case: we want to create an random knob for its voice. this new button/parameter will appear when we have selected  the &amp;#039;OSC&amp;#039; menu&lt;br /&gt;
&lt;br /&gt;
so we have:&lt;br /&gt;
&lt;br /&gt;
const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM =&lt;br /&gt;
{&lt;br /&gt;
        //page 1 - Voice 1&lt;br /&gt;
        {&lt;br /&gt;
                //sub page 1 - Oscillator&lt;br /&gt;
                {&lt;br /&gt;
                        TEXT_COARSE,        TEXT_FINE,        TEXT_WAVEFORM,                TEXT_RND_VOICE,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,&lt;br /&gt;
                        PAR_COARSE1,        PAR_FINE1,        PAR_OSC_WAVE_DRUM1,        PAR_RND_VOICE1,PAR_NONE,PAR_NONE,PAR_NONE,PAR_NONE&lt;br /&gt;
                },&lt;br /&gt;
                &lt;br /&gt;
&lt;br /&gt;
you will noticed two parameters:&lt;br /&gt;
TEXT_RND_VOICE and PAR_RND_VOICE1&lt;br /&gt;
&lt;br /&gt;
those parameter are important as the program will display on the LCD the menu names that appears in this section, so if we want to show a new menu or function, we need to add it in this section/file.&lt;br /&gt;
&lt;br /&gt;
but we need now to declare the TEXT_RND_VOICE1 and PAR_RND_VOICE1 in other files :-)&lt;br /&gt;
&lt;br /&gt;
Open file menu.h&lt;br /&gt;
go to section &lt;br /&gt;
&lt;br /&gt;
enum NamesEnum&lt;br /&gt;
{&lt;br /&gt;
        TEXT_EMPTY = 0,                                        //0&lt;br /&gt;
        TEXT_COARSE,&lt;br /&gt;
        TEXT_FINE,&lt;br /&gt;
        TEXT_ATTACK,&lt;br /&gt;
        TEXT_DECAY,&lt;br /&gt;
        TEXT_PITCH_DECAY,&lt;br /&gt;
        TEXT_MOD_AMOUNT,                &lt;br /&gt;
        ....&lt;br /&gt;
&lt;br /&gt;
add at the end, the text &amp;#039;TEXT_RND_VOICE1&amp;quot; : &lt;br /&gt;
        ....&lt;br /&gt;
        TEXT_BAR_RESET_MODE,&lt;br /&gt;
        TEXT_MIDI_CHAN_GLOBAL,&lt;br /&gt;
        TEXT_RND_VOICE,        // rstephane: random text &lt;br /&gt;
        NUM_NAMES&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
+&lt;br /&gt;
&lt;br /&gt;
Open Cc2Text.c&lt;br /&gt;
&lt;br /&gt;
//Voice 1 - Drum 1&lt;br /&gt;
//  1 Oscillator&lt;br /&gt;
{TEXT_COARSE, PAR_COARSE1},                         //2&lt;br /&gt;
{TEXT_FINE, PAR_FINE1},&lt;br /&gt;
{TEXT_WAVEFORM, PAR_OSC_WAVE_DRUM1},&lt;br /&gt;
{TEXT_RND_VOICE, PAR_RND_VOICE1}, // rstephane : added random button                                        &lt;br /&gt;
                                        &lt;br /&gt;
Now,&lt;br /&gt;
Open the menu.c file&lt;br /&gt;
go to section valueNames:&lt;br /&gt;
&lt;br /&gt;
const Name valueNames[NUM_NAMES] PROGMEM =&lt;br /&gt;
{&lt;br /&gt;
                {SHORT_EMPTY,CAT_EMPTY,LONG_EMPTY},&lt;br /&gt;
                ....&lt;br /&gt;
add the following information:&lt;br /&gt;
                ....&lt;br /&gt;
                {SHORT_BAR_RESET_MODE, CAT_SEQUENCER, LONG_BAR_RESET_MODE}, // TEXT_BAR_RESET_MODE&lt;br /&gt;
                {SHORT_CHANNEL, CAT_MIDI, LONG_MIDI_CHANNEL}, // TEXT_MIDI_CHAN_GLOBAL&lt;br /&gt;
                {SHORT_RND, CAT_OSC, LONG_RND_VOICE}, // rstephane: TEXT_RND_VOICE&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
we declare it at the end of the section :-)&lt;br /&gt;
&lt;br /&gt;
now, open the * MenuText.h file to declare the short and long version of the TEXT (TEXT_RND_VOICE1)&lt;br /&gt;
go to section&lt;br /&gt;
 &lt;br /&gt;
 const char longNames[][16] PROGMEM = &lt;br /&gt;
 et const char shortNames[][4] PROGMEM  = &lt;br /&gt;
&lt;br /&gt;
add the parameters:&lt;br /&gt;
&lt;br /&gt;
const char shortNames[][4] PROGMEM  = &lt;br /&gt;
{&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        {&amp;quot;coa&amp;quot;},&lt;br /&gt;
        {&amp;quot;fin&amp;quot;},&lt;br /&gt;
        {&amp;quot;atk&amp;quot;},&lt;br /&gt;
        {&amp;quot;dec&amp;quot;},&lt;br /&gt;
        {&amp;quot;eg2&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        &lt;br /&gt;
        {&amp;quot;co2&amp;quot;},  // trigger clock out2 ppq&lt;br /&gt;
        {&amp;quot;pcr&amp;quot;}, // pattern change resets bar counter&lt;br /&gt;
        {&amp;quot;RND&amp;quot;}, // rstephane: RND VOice&lt;br /&gt;
        &lt;br /&gt;
};        &lt;br /&gt;
&lt;br /&gt;
const char longNames[][16] PROGMEM = &lt;br /&gt;
{&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        //01234567&lt;br /&gt;
        {&amp;quot;Coarse&amp;quot;},&lt;br /&gt;
        {&amp;quot;Fine&amp;quot;},&lt;br /&gt;
        {&amp;quot;Attack&amp;quot;},&lt;br /&gt;
        {&amp;quot;Decay&amp;quot;},&lt;br /&gt;
        {&amp;quot;Amount&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        {&amp;quot;Out2 PPQ&amp;quot;},&lt;br /&gt;
        {&amp;quot;Gate Mode&amp;quot;},&lt;br /&gt;
        {&amp;quot;PCReset&amp;quot; }, // reset bar counter on manual pattern change&lt;br /&gt;
        {&amp;quot;Random&amp;quot;}, // rstephane: RND VOice LONG text&lt;br /&gt;
};&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
Now, we will create our function&lt;br /&gt;
and will add a link between this function and our knob.&lt;br /&gt;
&lt;br /&gt;
If you want you can already compile and see the results under the menu OSC of the VOICE1, normally right after COARSE, FINE, WAV, should appear RND.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/////&lt;br /&gt;
&lt;br /&gt;
 call the function relative to the encoder:&lt;br /&gt;
&lt;br /&gt;
open midimessage.h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//for all parameters above 127 &amp;lt;- our case&lt;br /&gt;
enum&lt;br /&gt;
{&lt;br /&gt;
        ....&lt;br /&gt;
        // Again, place your parameter at a special place, right after the section:&lt;br /&gt;
        CC2_MIDI_NOTE1,&lt;br /&gt;
        CC2_MIDI_NOTE2,&lt;br /&gt;
        CC2_MIDI_NOTE3,&lt;br /&gt;
        CC2_MIDI_NOTE4,&lt;br /&gt;
        CC2_MIDI_NOTE5,&lt;br /&gt;
        CC2_MIDI_NOTE6,&lt;br /&gt;
        CC2_MIDI_NOTE7, // s/b 111 i think&lt;br /&gt;
        &lt;br /&gt;
        // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
        // rstephane MY VALUES ADDED FOR RANDOM FUNCTION&lt;br /&gt;
        // rstephane : RND button :-) for CASE switch in MidiParser.C&lt;br /&gt;
        CC2_RND_VOICE1,&lt;br /&gt;
        ....&lt;br /&gt;
}Param2Enums;&lt;br /&gt;
&lt;br /&gt;
open &lt;br /&gt;
* MidiParser.c&lt;br /&gt;
//-----------------------------------------------------------&lt;br /&gt;
/** handle all incoming CCs and invoke action*/&lt;br /&gt;
void midiParser_ccHandler(MidiMsg msg, uint8_t updateOriginalValue)&lt;br /&gt;
{&lt;br /&gt;
        &lt;br /&gt;
        ...&lt;br /&gt;
        &lt;br /&gt;
        else //MIDI_CC2&lt;br /&gt;
        {&lt;br /&gt;
                const uint16_t paramNr = msg.data1+1 + 127;&lt;br /&gt;
&lt;br /&gt;
                if(updateOriginalValue) {&lt;br /&gt;
                        midiParser_originalCcValues[paramNr] = msg.data2;&lt;br /&gt;
                }&lt;br /&gt;
                switch(msg.data1)&lt;br /&gt;
                {&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_WAVE:&lt;br /&gt;
                                        voiceArray[0].transGen.waveform = msg.data2;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_VOL:&lt;br /&gt;
                                voiceArray[0].transGen.volume = msg.data2/127.f;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
        ...&lt;br /&gt;
        case CC2_MUTE_1:&lt;br /&gt;
                        case CC2_MUTE_2:&lt;br /&gt;
                        case CC2_MUTE_3:&lt;br /&gt;
                        case CC2_MUTE_4:&lt;br /&gt;
                        case CC2_MUTE_5:&lt;br /&gt;
                        case CC2_MUTE_6:&lt;br /&gt;
                        case CC2_MUTE_7:&lt;br /&gt;
                        {&lt;br /&gt;
                                const uint8_t voiceNr = msg.data1 - CC2_MUTE_1;&lt;br /&gt;
                                if(msg.data2 == 0)&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,0);&lt;br /&gt;
                                }&lt;br /&gt;
                                else&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,1);&lt;br /&gt;
                                }&lt;br /&gt;
&lt;br /&gt;
                        }&lt;br /&gt;
                                break;&lt;br /&gt;
                        // rstephane MY FUNCTIONS&lt;br /&gt;
                        // rstephane : Handle the RND button&lt;br /&gt;
                        case CC2_RND_VOICE1:&lt;br /&gt;
                                if(msg.data2 == 1)&lt;br /&gt;
                                {&lt;br /&gt;
                                        // RND is ON&lt;br /&gt;
                                        randomDrumVoice123(0); //voice1 = 0, voice2 = 1 etc...&lt;br /&gt;
                                }&lt;br /&gt;
                                break;        &lt;br /&gt;
                                                        &lt;br /&gt;
                        default:&lt;br /&gt;
                                break;&lt;br /&gt;
                                &lt;br /&gt;
                        ....&lt;br /&gt;
                        &lt;br /&gt;
                        &lt;br /&gt;
+ &lt;br /&gt;
open drumvoice.h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// rstephane : my functions&lt;br /&gt;
//random all the parameters for voice 1 2 and 3&lt;br /&gt;
void randomDrumVoice123(const uint8_t voiceNr);  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+&lt;br /&gt;
open drumvoice.c&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// rstephane : pour random functions&lt;br /&gt;
#include &amp;quot;valueShaper.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
+&lt;br /&gt;
&lt;br /&gt;
//---------------------------------------------------&lt;br /&gt;
// rstephane : my functions&lt;br /&gt;
//random all the parameters for voice 1 2 and 3&lt;br /&gt;
//---------------------------------------------------&lt;br /&gt;
void randomDrumVoice123(const uint8_t voiceNr)&lt;br /&gt;
{&lt;br /&gt;
                uint8_t rndData; // , new_min, new_max;&lt;br /&gt;
                // uint32_t rndDataTemp, old_min, old_max;&lt;br /&gt;
                // COARSE&lt;br /&gt;
                rndData = (uint8_t) GetRngValue();&lt;br /&gt;
                //clear upper nibble&lt;br /&gt;
                voiceArray[voiceNr].osc.midiFreq &amp;amp;= 0x00ff;&lt;br /&gt;
                //set upper nibble&lt;br /&gt;
                voiceArray[voiceNr].osc.midiFreq |= rndData &amp;lt;&amp;lt; 8;&lt;br /&gt;
                osc_recalcFreq(&amp;amp;voiceArray[voiceNr].osc);&lt;br /&gt;
                //OSC1_DIST:&lt;br /&gt;
                rndData = (uint8_t) GetRngValue();&lt;br /&gt;
#if USE_FILTER_DRIVE&lt;br /&gt;
                voiceArray[voiceNr].filter.drive = 0.5f + (rndData/127.f) *6;&lt;br /&gt;
#else&lt;br /&gt;
                setDistortionShape(&amp;amp;voiceArray[voiceNr].distortion,rndData);&lt;br /&gt;
#endif                        &lt;br /&gt;
                &lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Rstephane</name></author>
		
	</entry>
	<entry>
		<id>http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=222</id>
		<title>How to create and add a new function to the LXR</title>
		<link rel="alternate" type="text/html" href="http://wiki.sonic-potions.com/index.php?title=How_to_create_and_add_a_new_function_to_the_LXR&amp;diff=222"/>
		<updated>2014-05-08T21:56:54Z</updated>

		<summary type="html">&lt;p&gt;Rstephane: Created page with &amp;quot;This is a DRAFT !!!! I will correct it during the next days :-)  We start with the LCD display menu part  - we first declare our parameter and its type.  open the file &amp;#039;Parame...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a DRAFT !!!! I will correct it during the next days :-)&lt;br /&gt;
&lt;br /&gt;
We start with the LCD display menu part&lt;br /&gt;
&lt;br /&gt;
- we first declare our parameter and its type.&lt;br /&gt;
&lt;br /&gt;
open the file &amp;#039;Parameters.h&amp;#039;&lt;br /&gt;
&lt;br /&gt;
add in the section: &amp;#039;enum ParamEnums&amp;#039; ... your new parameter&lt;br /&gt;
&lt;br /&gt;
for instance, in our case we want to create an random knob for its voice. this new button/parameter will appear when we have selected  the &amp;#039;OSC&amp;#039; menu&lt;br /&gt;
so we open the &amp;#039;parameters.h&amp;#039; file and in the section &amp;#039;enum ParamEnums&amp;#039;, we add: &amp;#039;PAR_RND_VOICE1,&amp;#039;	&lt;br /&gt;
&lt;br /&gt;
you have to add all the new parameters right after the following declaration (otherwise you want link later the knob with the function you want to execute):&lt;br /&gt;
&lt;br /&gt;
enum ParamEnums ...&lt;br /&gt;
        PAR_MIDI_NOTE1,&lt;br /&gt;
        PAR_MIDI_NOTE2,&lt;br /&gt;
        PAR_MIDI_NOTE3,&lt;br /&gt;
        PAR_MIDI_NOTE4,&lt;br /&gt;
        PAR_MIDI_NOTE5,&lt;br /&gt;
        PAR_MIDI_NOTE6,&lt;br /&gt;
        PAR_MIDI_NOTE7,&lt;br /&gt;
        // YOUR parameters comes right after thoses lines...&lt;br /&gt;
                   &lt;br /&gt;
        // rstephane MY VALUES ADDED FOR RANDOM FUNCTION&lt;br /&gt;
        PAR_RND_VOICE1,        // rstephane: randomize drum1 / voice 1&lt;br /&gt;
&lt;br /&gt;
        //#########################################&lt;br /&gt;
        //######## End of sound Parameters ########&lt;br /&gt;
        //#########################################&lt;br /&gt;
        &lt;br /&gt;
        //all parameters in this section are only there to be referenced from the menu&lt;br /&gt;
        //they are not saved anywhere&lt;br /&gt;
        END_OF_SOUND_PARAMETERS,&lt;br /&gt;
        //the parameter declaration continues but don&amp;#039;t changed it, don&amp;#039;t add your parameters below... etc.&lt;br /&gt;
                ....&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
Now, let&amp;#039;s go the the menu text, we want that our knob display a name &amp;#039;FILTER&amp;#039; or in our case &amp;#039;RANDOM&amp;#039; .. well we will set it to &amp;#039;RND&amp;#039; to make it short on the LCD screen.&lt;br /&gt;
&lt;br /&gt;
We need to open the menu.c file.&lt;br /&gt;
&lt;br /&gt;
menu.c&lt;br /&gt;
//---------------------------------------------------------------&lt;br /&gt;
// Parameter types. These correspond with ParamEnums and entries in parameter_values&lt;br /&gt;
const enum Datatypes PROGMEM parameter_dtypes[NUM_PARAMS] = {&lt;br /&gt;
            /*PAR_NONE*/                         DTYPE_0B127,                                                        // 0&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM1*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM2*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_DRUM3*/         DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_OSC_WAVE_SNARE*/  DTYPE_MENU | (MENU_WAVEFORM&amp;lt;&amp;lt;4),&lt;br /&gt;
....&lt;br /&gt;
&lt;br /&gt;
Again, place your parameter at a special place, right after the section:&lt;br /&gt;
/*PAR_MIDI_NOTE1*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE2*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE3*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE4*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE5*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE6*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            /*PAR_MIDI_NOTE7*/                DTYPE_NOTE_NAME,&lt;br /&gt;
            // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
            &lt;br /&gt;
            // rstephane MY VALUES ADDED FOR RANDOM FUNCTION&lt;br /&gt;
            /*PAR_RND_VOICE1*/        DTYPE_ON_OFF,  // choose the type of your parameter, a definition of the parameter type is shown right after....&lt;br /&gt;
            &lt;br /&gt;
            /*PAR_ROLL*/                         DTYPE_MENU | (MENU_ROLL_RATES&amp;lt;&amp;lt;4),&lt;br /&gt;
            /*PAR_MORPH*/                         DTYPE_0B255,&lt;br /&gt;
                ....&lt;br /&gt;
                &lt;br /&gt;
Type of parameters:&lt;br /&gt;
//-----------------------------------------------------------------&lt;br /&gt;
enum Datatypes&lt;br /&gt;
{&lt;br /&gt;
        DTYPE_0B255,        //0:255&lt;br /&gt;
        DTYPE_0B127,        //0-127&lt;br /&gt;
        DTYPE_PM100,        //-100:100&lt;br /&gt;
        DTYPE_MENU,                //text type outputs &lt;br /&gt;
        DTYPE_PM63,                //-63 &amp;lt;-&amp;gt; 63&lt;br /&gt;
        DTYPE_1B16,                //1-16&lt;br /&gt;
        DTYPE_ON_OFF,        //0-1&lt;br /&gt;
        DTYPE_MIX_FM,        //0-1&lt;br /&gt;
        DTYPE_TARGET_SELECTION_LFO,&lt;br /&gt;
        DTYPE_TARGET_SELECTION_VELO,        &lt;br /&gt;
        DTYPE_VOICE_LFO,&lt;br /&gt;
        DTYPE_AUTOM_TARGET,&lt;br /&gt;
        DTYPE_0b1,&lt;br /&gt;
        DTYPE_NOTE_NAME, // --AS eg C#0, D 1 for note name&lt;br /&gt;
        DTYPE_0B15,                //0-15&lt;br /&gt;
        /*15*/&lt;br /&gt;
        /*16*/&lt;br /&gt;
        // --AS warning, we can only have 16 on this list the way things are laid out&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
oki, once this done, we need to fill other infformation in the code&lt;br /&gt;
&lt;br /&gt;
Open the* menuPages.h&lt;br /&gt;
&lt;br /&gt;
/** This array hold the whole menu structure.&lt;br /&gt;
each voice has different pages. The pages hold the top and bottom enums to indicate which values and desriptors to show&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
in the section: &lt;br /&gt;
const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM =&lt;br /&gt;
                ....&lt;br /&gt;
add your MENU ! &lt;br /&gt;
&lt;br /&gt;
in our case: we want to create an random knob for its voice. this new button/parameter will appear when we have selected  the &amp;#039;OSC&amp;#039; menu&lt;br /&gt;
&lt;br /&gt;
so we have:&lt;br /&gt;
&lt;br /&gt;
const Page menuPages[NUM_PAGES][NUM_SUB_PAGES] PROGMEM =&lt;br /&gt;
{&lt;br /&gt;
        //page 1 - Voice 1&lt;br /&gt;
        {&lt;br /&gt;
                //sub page 1 - Oscillator&lt;br /&gt;
                {&lt;br /&gt;
                        TEXT_COARSE,        TEXT_FINE,        TEXT_WAVEFORM,                TEXT_RND_VOICE,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,TEXT_EMPTY,&lt;br /&gt;
                        PAR_COARSE1,        PAR_FINE1,        PAR_OSC_WAVE_DRUM1,        PAR_RND_VOICE1,PAR_NONE,PAR_NONE,PAR_NONE,PAR_NONE&lt;br /&gt;
                },&lt;br /&gt;
                &lt;br /&gt;
&lt;br /&gt;
you will noticed two parameters:&lt;br /&gt;
TEXT_RND_VOICE and PAR_RND_VOICE1&lt;br /&gt;
&lt;br /&gt;
those parameter are important as the program will display on the LCD the menu names that appears in this section, so if we want to show a new menu or function, we need to add it in this section/file.&lt;br /&gt;
&lt;br /&gt;
but we need now to declare the TEXT_RND_VOICE1 and PAR_RND_VOICE1 in other files :-)&lt;br /&gt;
&lt;br /&gt;
Open file menu.h&lt;br /&gt;
go to section &lt;br /&gt;
&lt;br /&gt;
enum NamesEnum&lt;br /&gt;
{&lt;br /&gt;
        TEXT_EMPTY = 0,                                        //0&lt;br /&gt;
        TEXT_COARSE,&lt;br /&gt;
        TEXT_FINE,&lt;br /&gt;
        TEXT_ATTACK,&lt;br /&gt;
        TEXT_DECAY,&lt;br /&gt;
        TEXT_PITCH_DECAY,&lt;br /&gt;
        TEXT_MOD_AMOUNT,                &lt;br /&gt;
        ....&lt;br /&gt;
&lt;br /&gt;
add at the end, the text &amp;#039;TEXT_RND_VOICE1&amp;quot; : &lt;br /&gt;
        ....&lt;br /&gt;
        TEXT_BAR_RESET_MODE,&lt;br /&gt;
        TEXT_MIDI_CHAN_GLOBAL,&lt;br /&gt;
        TEXT_RND_VOICE,        // rstephane: random text &lt;br /&gt;
        NUM_NAMES&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
+&lt;br /&gt;
&lt;br /&gt;
Open CcNr2Text.c&lt;br /&gt;
&lt;br /&gt;
//Voice 1 - Drum 1&lt;br /&gt;
//  1 Oscillator&lt;br /&gt;
{TEXT_COARSE, PAR_COARSE1},                         //2&lt;br /&gt;
{TEXT_FINE, PAR_FINE1},&lt;br /&gt;
{TEXT_WAVEFORM, PAR_OSC_WAVE_DRUM1},&lt;br /&gt;
{TEXT_RND_VOICE, PAR_RND_VOICE1}, // rstephane : added random button                                        &lt;br /&gt;
                                        &lt;br /&gt;
Now,&lt;br /&gt;
Open the menu.c file&lt;br /&gt;
go to section valueNames:&lt;br /&gt;
&lt;br /&gt;
const Name valueNames[NUM_NAMES] PROGMEM =&lt;br /&gt;
{&lt;br /&gt;
                {SHORT_EMPTY,CAT_EMPTY,LONG_EMPTY},&lt;br /&gt;
                ....&lt;br /&gt;
add the following information:&lt;br /&gt;
                ....&lt;br /&gt;
                {SHORT_BAR_RESET_MODE, CAT_SEQUENCER, LONG_BAR_RESET_MODE}, // TEXT_BAR_RESET_MODE&lt;br /&gt;
                {SHORT_CHANNEL, CAT_MIDI, LONG_MIDI_CHANNEL}, // TEXT_MIDI_CHAN_GLOBAL&lt;br /&gt;
                {SHORT_RND, CAT_OSC, LONG_RND_VOICE}, // rstephane: TEXT_RND_VOICE&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
we declare it at the end of the section :-)&lt;br /&gt;
&lt;br /&gt;
now, open the * MenuText.h file to declare the short and long version of the TEXT (TEXT_RND_VOICE1)&lt;br /&gt;
go to section&lt;br /&gt;
 &lt;br /&gt;
 const char longNames[][16] PROGMEM = &lt;br /&gt;
 et const char shortNames[][4] PROGMEM  = &lt;br /&gt;
&lt;br /&gt;
add the parameters:&lt;br /&gt;
&lt;br /&gt;
const char shortNames[][4] PROGMEM  = &lt;br /&gt;
{&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        {&amp;quot;coa&amp;quot;},&lt;br /&gt;
        {&amp;quot;fin&amp;quot;},&lt;br /&gt;
        {&amp;quot;atk&amp;quot;},&lt;br /&gt;
        {&amp;quot;dec&amp;quot;},&lt;br /&gt;
        {&amp;quot;eg2&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        &lt;br /&gt;
        {&amp;quot;co2&amp;quot;},  // trigger clock out2 ppq&lt;br /&gt;
        {&amp;quot;pcr&amp;quot;}, // pattern change resets bar counter&lt;br /&gt;
        {&amp;quot;RND&amp;quot;}, // rstephane: RND VOice&lt;br /&gt;
        &lt;br /&gt;
};        &lt;br /&gt;
&lt;br /&gt;
const char longNames[][16] PROGMEM = &lt;br /&gt;
{&lt;br /&gt;
        {&amp;quot;&amp;quot;},&lt;br /&gt;
        //01234567&lt;br /&gt;
        {&amp;quot;Coarse&amp;quot;},&lt;br /&gt;
        {&amp;quot;Fine&amp;quot;},&lt;br /&gt;
        {&amp;quot;Attack&amp;quot;},&lt;br /&gt;
        {&amp;quot;Decay&amp;quot;},&lt;br /&gt;
        {&amp;quot;Amount&amp;quot;},&lt;br /&gt;
        ....&lt;br /&gt;
        {&amp;quot;Out2 PPQ&amp;quot;},&lt;br /&gt;
        {&amp;quot;Gate Mode&amp;quot;},&lt;br /&gt;
        {&amp;quot;PCReset&amp;quot; }, // reset bar counter on manual pattern change&lt;br /&gt;
        {&amp;quot;Random&amp;quot;}, // rstephane: RND VOice LONG text&lt;br /&gt;
};&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
Now, we will create our function&lt;br /&gt;
and will add a link between this function and our knob.&lt;br /&gt;
&lt;br /&gt;
If you want you can already compile and see the results under the menu OSC of the VOICE1, normally right after COARSE, FINE, WAV, should appear RND.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/////&lt;br /&gt;
&lt;br /&gt;
 call the function relative to the encoder:&lt;br /&gt;
&lt;br /&gt;
open midimessage.h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//for all parameters above 127 &amp;lt;- our case&lt;br /&gt;
enum&lt;br /&gt;
{&lt;br /&gt;
        ....&lt;br /&gt;
        // Again, place your parameter at a special place, right after the section:&lt;br /&gt;
        CC2_MIDI_NOTE1,&lt;br /&gt;
        CC2_MIDI_NOTE2,&lt;br /&gt;
        CC2_MIDI_NOTE3,&lt;br /&gt;
        CC2_MIDI_NOTE4,&lt;br /&gt;
        CC2_MIDI_NOTE5,&lt;br /&gt;
        CC2_MIDI_NOTE6,&lt;br /&gt;
        CC2_MIDI_NOTE7, // s/b 111 i think&lt;br /&gt;
        &lt;br /&gt;
        // YOUR PARAMETER comes right here and not elsewhere!!!!!&lt;br /&gt;
        // rstephane MY VALUES ADDED FOR RANDOM FUNCTION&lt;br /&gt;
        // rstephane : RND button :-) for CASE switch in MidiParser.C&lt;br /&gt;
        CC2_RND_VOICE1,&lt;br /&gt;
        ....&lt;br /&gt;
}Param2Enums;&lt;br /&gt;
&lt;br /&gt;
open &lt;br /&gt;
* MidiParser.c&lt;br /&gt;
//-----------------------------------------------------------&lt;br /&gt;
/** handle all incoming CCs and invoke action*/&lt;br /&gt;
void midiParser_ccHandler(MidiMsg msg, uint8_t updateOriginalValue)&lt;br /&gt;
{&lt;br /&gt;
        &lt;br /&gt;
        ...&lt;br /&gt;
        &lt;br /&gt;
        else //MIDI_CC2&lt;br /&gt;
        {&lt;br /&gt;
                const uint16_t paramNr = msg.data1+1 + 127;&lt;br /&gt;
&lt;br /&gt;
                if(updateOriginalValue) {&lt;br /&gt;
                        midiParser_originalCcValues[paramNr] = msg.data2;&lt;br /&gt;
                }&lt;br /&gt;
                switch(msg.data1)&lt;br /&gt;
                {&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_WAVE:&lt;br /&gt;
                                        voiceArray[0].transGen.waveform = msg.data2;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
                        case CC2_TRANS1_VOL:&lt;br /&gt;
                                voiceArray[0].transGen.volume = msg.data2/127.f;&lt;br /&gt;
                                break;&lt;br /&gt;
&lt;br /&gt;
        ...&lt;br /&gt;
        case CC2_MUTE_1:&lt;br /&gt;
                        case CC2_MUTE_2:&lt;br /&gt;
                        case CC2_MUTE_3:&lt;br /&gt;
                        case CC2_MUTE_4:&lt;br /&gt;
                        case CC2_MUTE_5:&lt;br /&gt;
                        case CC2_MUTE_6:&lt;br /&gt;
                        case CC2_MUTE_7:&lt;br /&gt;
                        {&lt;br /&gt;
                                const uint8_t voiceNr = msg.data1 - CC2_MUTE_1;&lt;br /&gt;
                                if(msg.data2 == 0)&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,0);&lt;br /&gt;
                                }&lt;br /&gt;
                                else&lt;br /&gt;
                                {&lt;br /&gt;
                                        seq_setMute(voiceNr,1);&lt;br /&gt;
                                }&lt;br /&gt;
&lt;br /&gt;
                        }&lt;br /&gt;
                                break;&lt;br /&gt;
                        // rstephane MY FUNCTIONS&lt;br /&gt;
                        // rstephane : Handle the RND button&lt;br /&gt;
                        case CC2_RND_VOICE1:&lt;br /&gt;
                                if(msg.data2 == 1)&lt;br /&gt;
                                {&lt;br /&gt;
                                        // RND is ON&lt;br /&gt;
                                        randomDrumVoice123(0); //voice1 = 0, voice2 = 1 etc...&lt;br /&gt;
                                }&lt;br /&gt;
                                break;        &lt;br /&gt;
                                                        &lt;br /&gt;
                        default:&lt;br /&gt;
                                break;&lt;br /&gt;
                                &lt;br /&gt;
                        ....&lt;br /&gt;
                        &lt;br /&gt;
                        &lt;br /&gt;
+ &lt;br /&gt;
open drumvoice.h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// rstephane : my functions&lt;br /&gt;
//random all the parameters for voice 1 2 and 3&lt;br /&gt;
void randomDrumVoice123(const uint8_t voiceNr);  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+&lt;br /&gt;
open drumvoice.c&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// rstephane : pour random functions&lt;br /&gt;
#include &amp;quot;valueShaper.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
+&lt;br /&gt;
&lt;br /&gt;
//---------------------------------------------------&lt;br /&gt;
// rstephane : my functions&lt;br /&gt;
//random all the parameters for voice 1 2 and 3&lt;br /&gt;
//---------------------------------------------------&lt;br /&gt;
void randomDrumVoice123(const uint8_t voiceNr)&lt;br /&gt;
{&lt;br /&gt;
                uint8_t rndData; // , new_min, new_max;&lt;br /&gt;
                // uint32_t rndDataTemp, old_min, old_max;&lt;br /&gt;
                // COARSE&lt;br /&gt;
                rndData = (uint8_t) GetRngValue();&lt;br /&gt;
                //clear upper nibble&lt;br /&gt;
                voiceArray[voiceNr].osc.midiFreq &amp;amp;= 0x00ff;&lt;br /&gt;
                //set upper nibble&lt;br /&gt;
                voiceArray[voiceNr].osc.midiFreq |= rndData &amp;lt;&amp;lt; 8;&lt;br /&gt;
                osc_recalcFreq(&amp;amp;voiceArray[voiceNr].osc);&lt;br /&gt;
                //OSC1_DIST:&lt;br /&gt;
                rndData = (uint8_t) GetRngValue();&lt;br /&gt;
#if USE_FILTER_DRIVE&lt;br /&gt;
                voiceArray[voiceNr].filter.drive = 0.5f + (rndData/127.f) *6;&lt;br /&gt;
#else&lt;br /&gt;
                setDistortionShape(&amp;amp;voiceArray[voiceNr].distortion,rndData);&lt;br /&gt;
#endif                        &lt;br /&gt;
                &lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Rstephane</name></author>
		
	</entry>
	<entry>
		<id>http://wiki.sonic-potions.com/index.php?title=Main_Page&amp;diff=221</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="http://wiki.sonic-potions.com/index.php?title=Main_Page&amp;diff=221"/>
		<updated>2014-05-08T21:50:00Z</updated>

		<summary type="html">&lt;p&gt;Rstephane: /* Users contributions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Welcome to the Sonic Potions Wiki.&lt;br /&gt;
&lt;br /&gt;
== LXR ==&lt;br /&gt;
===Manual===&lt;br /&gt;
* [[LXR Owners Manual]]&lt;br /&gt;
&lt;br /&gt;
===Sourcing parts===&lt;br /&gt;
* [[BOMs for LXR projects]]&lt;br /&gt;
&lt;br /&gt;
===Firmware updates===&lt;br /&gt;
* [[Updating the firmware]]&lt;br /&gt;
* [[Changelog]]&lt;br /&gt;
&lt;br /&gt;
=== Troubleshooting ===&lt;br /&gt;
* [[LXR Troubleshooting]]&lt;br /&gt;
&lt;br /&gt;
=== Design Files ===&lt;br /&gt;
* [[Enclosure SVG]]&lt;br /&gt;
&lt;br /&gt;
=== Building the firmware from source ===&lt;br /&gt;
* [[LXR Linux build instructions]]&lt;br /&gt;
* [[LXR Windows build instructions]]&lt;br /&gt;
* [[LXR OSX build instructions]]&lt;br /&gt;
&lt;br /&gt;
=== Users contributions ===&lt;br /&gt;
* [[Demos]]&lt;br /&gt;
* [[Compilations]]&lt;br /&gt;
* [[How to create and add a new function to the LXR ]]&lt;br /&gt;
&lt;br /&gt;
== Wiki help ==&lt;br /&gt;
* [//www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]&lt;/div&gt;</summary>
		<author><name>Rstephane</name></author>
		
	</entry>
	<entry>
		<id>http://wiki.sonic-potions.com/index.php?title=LXR_OSX_build_instructions&amp;diff=215</id>
		<title>LXR OSX build instructions</title>
		<link rel="alternate" type="text/html" href="http://wiki.sonic-potions.com/index.php?title=LXR_OSX_build_instructions&amp;diff=215"/>
		<updated>2014-05-07T17:27:38Z</updated>

		<summary type="html">&lt;p&gt;Rstephane: /* Compile */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Tested on 10.8.x and 10.9.2; likely needs Xcode installed also (https://developer.apple.com/xcode/downloads/)&lt;br /&gt;
&lt;br /&gt;
== General steps == &lt;br /&gt;
The LXR code is divided into two mains code parts that we will compile &amp;quot;separately&amp;quot; using two different tools&lt;br /&gt;
*the AVR Atmel CODE (LCD, front panel control, USB, SD card)&lt;br /&gt;
*the ARM CODE (main LXR code for the voices / sounds)&lt;br /&gt;
&lt;br /&gt;
- We need &amp;quot;specific compilers and librairies&amp;quot; for each CODE. We need to change the PATH in your .bash_profile, we need MAKEFILES to build the firmware, and, finally, we will compile the code :)&lt;br /&gt;
&lt;br /&gt;
Let&amp;#039;s do it! &lt;br /&gt;
&lt;br /&gt;
== AVR COMPILER &amp;amp; LIBS == &lt;br /&gt;
* Download of Atmel AVR 8-bit toolchain from http://www.obdev.at/products/crosspack/download.html&lt;br /&gt;
* You will get a .dmg file that you should extract and install (CrossPack-AVR-20131216.dmg is the most recent as of 2015/05/02)&lt;br /&gt;
* The compiler and libs are installed under /usr/local/CrossPack-AVR-20131216/&lt;br /&gt;
* Note that you will also find a folder like /usr/local/CrossPack-AVR/ (this folder is an alias to the previous folder - symlink).&lt;br /&gt;
&lt;br /&gt;
== GNU ARM COMPILER AND LIBS == &lt;br /&gt;
* Download of GNU bare metal ARM toolchain from https://launchpad.net/gcc-arm-embedded (v4.8)&lt;br /&gt;
* Take the MAC version (something like : gcc-arm-none-eabi-4_8-2014q1-20140314-mac.tar.bz2 )&lt;br /&gt;
* Extract the compressed/tar file.&lt;br /&gt;
* Copy the extracted folder under /usr/local/&lt;br /&gt;
* Nothing else to do !&lt;br /&gt;
&lt;br /&gt;
== Change your PATH == &lt;br /&gt;
* We need to add a specific PATH for both compilers (and libs) for the MAC. Here is mine...&lt;br /&gt;
&lt;br /&gt;
    export PATH=$PATH:/usr/local/CrossPack-AVR-20131216/bin:/usr/local/CrossPack-AVR-20131216/:/usr/include:/usr/local/CrossPack-AVR-20131216/avr/include:/usr/local/gcc-arm-none-eabi-4_8-2014q1/bin&lt;br /&gt;
    export ARM_TOOLKIT_ROOT=/usr/local/gcc-arm-none-eabi-4_8-2014q1&lt;br /&gt;
    export AVR_TOOLKIT_ROOT=/usr/local/CrossPack-AVR-20131216&lt;br /&gt;
&lt;br /&gt;
* in a terminal window, execute &amp;quot;source ./.bash_profile&amp;quot; to update the PATH to your system.&lt;br /&gt;
* for the moment, don&amp;#039;t try to understand what are ARM_TOOLKIT / AVR_TOLLKIT variables, we will explain why we need this later.&lt;br /&gt;
&lt;br /&gt;
== Grab the LXR Code == &lt;br /&gt;
We advice you to grab the code either from :&lt;br /&gt;
&lt;br /&gt;
    Julian repository on GITHUB (https://github.com/SonicPotions/LXR)&lt;br /&gt;
    PLD repository (https://github.com/patrickdowling/LXR)&lt;br /&gt;
    rudeog repository (https://github.com/rudeog/LXR) -&amp;gt; extra features compared to Julian code.&lt;br /&gt;
    rstephane repository (https://github.com/rstephane/LXR) -&amp;gt; equivalent to Julian CODE. &lt;br /&gt;
&lt;br /&gt;
- of course once downloaded, you should extract the code and copy it to any folder you like.&lt;br /&gt;
On our side we copied it under: /Users/music/Documents/workspace/LXR/&lt;br /&gt;
&lt;br /&gt;
== MACOS specific makefiles == &lt;br /&gt;
We advice you to grab the makefiles either from :&lt;br /&gt;
&lt;br /&gt;
    PLD repository (https://github.com/patrickdowling/LXR) &lt;br /&gt;
    rstephane (@egnouf) repository (https://github.com/rstephane/LXR)&lt;br /&gt;
    RUDEOG repository https://github.com/patrickdowling/LXR&lt;br /&gt;
&lt;br /&gt;
- You will find on the root path of both repository a file called MAKEFILE. You will also need the other makefiles:&lt;br /&gt;
&lt;br /&gt;
    https://github.com/patrickdowling/LXR/blob/makefiles/Makefile&lt;br /&gt;
    https://github.com/patrickdowling/LXR/blob/makefiles/front/AVR/Makefile&lt;br /&gt;
    https://github.com/patrickdowling/LXR/blob/makefiles/mainboard/firmware/DrumSynth_FPU/Makefile&lt;br /&gt;
    https://github.com/patrickdowling/LXR/blob/makefiles/tools/FirmwareImageBuilder/Makefile&lt;br /&gt;
&lt;br /&gt;
* Once downloaded, copy them at the root PATH of the code (1) and in subfolders (2,3,4) you dowloaded in STEP 4.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;If you have taken the whole LXR code from @PLD or rstephane or @RUDEOG you don&amp;#039;t need to download once more the Makefiles, they are provided within !&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Now, let&amp;#039;s go back to the .bash_profile file:&lt;br /&gt;
&lt;br /&gt;
    export PATH=$PATH:/usr/local/CrossPack-AVR-20131216/bin:/usr/local/CrossPack-AVR-20131216/:/usr/include:/usr/local/CrossPack-AVR-20131216/avr/include:/usr/local/gcc-arm-none-eabi-4_8-2014q1/bin&lt;br /&gt;
    export ARM_TOOLKIT_ROOT=/usr/local/gcc-arm-none-eabi-4_8-2014q1&lt;br /&gt;
    export AVR_TOOLKIT_ROOT=/usr/local/CrossPack-AVR-20131216&lt;br /&gt;
&lt;br /&gt;
* You can notice the two variables &amp;#039;&amp;#039;&amp;#039;ARM_TOOLKIT_ROOT&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;AVR_TOOLKIT_ROOT&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
* They are used by the MAKEFILE that has created @PLD (and also used by rstephane).&lt;br /&gt;
* Change their values appropriately, according to your system path, where you installed the libs... etc.&lt;br /&gt;
&lt;br /&gt;
== Compile == &lt;br /&gt;
&lt;br /&gt;
* Open a terminal window, go under your LXR code root path i.e cd /Users/music/Documents/workspace/LXR/&lt;br /&gt;
* Launch the command &amp;quot;make firmware&amp;quot; from a MAC terminal window. To clean the &amp;quot;code&amp;quot; you can execute &amp;quot;make clean&amp;quot;.&lt;br /&gt;
* You will get a FIRMWARE.BIN image (in fact, we compiled two programs and the makefile combine both to one single file !), copy this file on your SD CARD and follow instruction to upload your new firmware.&lt;br /&gt;
&lt;br /&gt;
If you have downloaded rstephane code, similar to @Julian and @PLD, you will noticed that when you power on the machine, it displays &amp;quot;LXR-Drums-V&amp;quot; instead of &amp;quot;LXR Drums V&amp;quot;. If so, you have successfully loaded (and compiled) LXR CODE!!!!&lt;br /&gt;
&lt;br /&gt;
Well done and happy hacking!&lt;/div&gt;</summary>
		<author><name>Rstephane</name></author>
		
	</entry>
	<entry>
		<id>http://wiki.sonic-potions.com/index.php?title=LXR_OSX_build_instructions&amp;diff=214</id>
		<title>LXR OSX build instructions</title>
		<link rel="alternate" type="text/html" href="http://wiki.sonic-potions.com/index.php?title=LXR_OSX_build_instructions&amp;diff=214"/>
		<updated>2014-05-07T17:27:22Z</updated>

		<summary type="html">&lt;p&gt;Rstephane: /* Compile */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Tested on 10.8.x and 10.9.2; likely needs Xcode installed also (https://developer.apple.com/xcode/downloads/)&lt;br /&gt;
&lt;br /&gt;
== General steps == &lt;br /&gt;
The LXR code is divided into two mains code parts that we will compile &amp;quot;separately&amp;quot; using two different tools&lt;br /&gt;
*the AVR Atmel CODE (LCD, front panel control, USB, SD card)&lt;br /&gt;
*the ARM CODE (main LXR code for the voices / sounds)&lt;br /&gt;
&lt;br /&gt;
- We need &amp;quot;specific compilers and librairies&amp;quot; for each CODE. We need to change the PATH in your .bash_profile, we need MAKEFILES to build the firmware, and, finally, we will compile the code :)&lt;br /&gt;
&lt;br /&gt;
Let&amp;#039;s do it! &lt;br /&gt;
&lt;br /&gt;
== AVR COMPILER &amp;amp; LIBS == &lt;br /&gt;
* Download of Atmel AVR 8-bit toolchain from http://www.obdev.at/products/crosspack/download.html&lt;br /&gt;
* You will get a .dmg file that you should extract and install (CrossPack-AVR-20131216.dmg is the most recent as of 2015/05/02)&lt;br /&gt;
* The compiler and libs are installed under /usr/local/CrossPack-AVR-20131216/&lt;br /&gt;
* Note that you will also find a folder like /usr/local/CrossPack-AVR/ (this folder is an alias to the previous folder - symlink).&lt;br /&gt;
&lt;br /&gt;
== GNU ARM COMPILER AND LIBS == &lt;br /&gt;
* Download of GNU bare metal ARM toolchain from https://launchpad.net/gcc-arm-embedded (v4.8)&lt;br /&gt;
* Take the MAC version (something like : gcc-arm-none-eabi-4_8-2014q1-20140314-mac.tar.bz2 )&lt;br /&gt;
* Extract the compressed/tar file.&lt;br /&gt;
* Copy the extracted folder under /usr/local/&lt;br /&gt;
* Nothing else to do !&lt;br /&gt;
&lt;br /&gt;
== Change your PATH == &lt;br /&gt;
* We need to add a specific PATH for both compilers (and libs) for the MAC. Here is mine...&lt;br /&gt;
&lt;br /&gt;
    export PATH=$PATH:/usr/local/CrossPack-AVR-20131216/bin:/usr/local/CrossPack-AVR-20131216/:/usr/include:/usr/local/CrossPack-AVR-20131216/avr/include:/usr/local/gcc-arm-none-eabi-4_8-2014q1/bin&lt;br /&gt;
    export ARM_TOOLKIT_ROOT=/usr/local/gcc-arm-none-eabi-4_8-2014q1&lt;br /&gt;
    export AVR_TOOLKIT_ROOT=/usr/local/CrossPack-AVR-20131216&lt;br /&gt;
&lt;br /&gt;
* in a terminal window, execute &amp;quot;source ./.bash_profile&amp;quot; to update the PATH to your system.&lt;br /&gt;
* for the moment, don&amp;#039;t try to understand what are ARM_TOOLKIT / AVR_TOLLKIT variables, we will explain why we need this later.&lt;br /&gt;
&lt;br /&gt;
== Grab the LXR Code == &lt;br /&gt;
We advice you to grab the code either from :&lt;br /&gt;
&lt;br /&gt;
    Julian repository on GITHUB (https://github.com/SonicPotions/LXR)&lt;br /&gt;
    PLD repository (https://github.com/patrickdowling/LXR)&lt;br /&gt;
    rudeog repository (https://github.com/rudeog/LXR) -&amp;gt; extra features compared to Julian code.&lt;br /&gt;
    rstephane repository (https://github.com/rstephane/LXR) -&amp;gt; equivalent to Julian CODE. &lt;br /&gt;
&lt;br /&gt;
- of course once downloaded, you should extract the code and copy it to any folder you like.&lt;br /&gt;
On our side we copied it under: /Users/music/Documents/workspace/LXR/&lt;br /&gt;
&lt;br /&gt;
== MACOS specific makefiles == &lt;br /&gt;
We advice you to grab the makefiles either from :&lt;br /&gt;
&lt;br /&gt;
    PLD repository (https://github.com/patrickdowling/LXR) &lt;br /&gt;
    rstephane (@egnouf) repository (https://github.com/rstephane/LXR)&lt;br /&gt;
    RUDEOG repository https://github.com/patrickdowling/LXR&lt;br /&gt;
&lt;br /&gt;
- You will find on the root path of both repository a file called MAKEFILE. You will also need the other makefiles:&lt;br /&gt;
&lt;br /&gt;
    https://github.com/patrickdowling/LXR/blob/makefiles/Makefile&lt;br /&gt;
    https://github.com/patrickdowling/LXR/blob/makefiles/front/AVR/Makefile&lt;br /&gt;
    https://github.com/patrickdowling/LXR/blob/makefiles/mainboard/firmware/DrumSynth_FPU/Makefile&lt;br /&gt;
    https://github.com/patrickdowling/LXR/blob/makefiles/tools/FirmwareImageBuilder/Makefile&lt;br /&gt;
&lt;br /&gt;
* Once downloaded, copy them at the root PATH of the code (1) and in subfolders (2,3,4) you dowloaded in STEP 4.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;If you have taken the whole LXR code from @PLD or rstephane or @RUDEOG you don&amp;#039;t need to download once more the Makefiles, they are provided within !&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Now, let&amp;#039;s go back to the .bash_profile file:&lt;br /&gt;
&lt;br /&gt;
    export PATH=$PATH:/usr/local/CrossPack-AVR-20131216/bin:/usr/local/CrossPack-AVR-20131216/:/usr/include:/usr/local/CrossPack-AVR-20131216/avr/include:/usr/local/gcc-arm-none-eabi-4_8-2014q1/bin&lt;br /&gt;
    export ARM_TOOLKIT_ROOT=/usr/local/gcc-arm-none-eabi-4_8-2014q1&lt;br /&gt;
    export AVR_TOOLKIT_ROOT=/usr/local/CrossPack-AVR-20131216&lt;br /&gt;
&lt;br /&gt;
* You can notice the two variables &amp;#039;&amp;#039;&amp;#039;ARM_TOOLKIT_ROOT&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;AVR_TOOLKIT_ROOT&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
* They are used by the MAKEFILE that has created @PLD (and also used by rstephane).&lt;br /&gt;
* Change their values appropriately, according to your system path, where you installed the libs... etc.&lt;br /&gt;
&lt;br /&gt;
== Compile == &lt;br /&gt;
&lt;br /&gt;
* Open a terminal window, go under your LXR code root path i.e cd /Users/music/Documents/workspace/LXR/)&lt;br /&gt;
* Launch the command &amp;quot;make firmware&amp;quot; from a MAC terminal window. To clean the &amp;quot;code&amp;quot; you can execute &amp;quot;make clean&amp;quot;.&lt;br /&gt;
* You will get a FIRMWARE.BIN image (in fact, we compiled two programs and the makefile combine both to one single file !), copy this file on your SD CARD and follow instruction to upload your new firmware.&lt;br /&gt;
&lt;br /&gt;
If you have downloaded rstephane code, similar to @Julian and @PLD, you will noticed that when you power on the machine, it displays &amp;quot;LXR-Drums-V&amp;quot; instead of &amp;quot;LXR Drums V&amp;quot;. If so, you have successfully loaded (and compiled) LXR CODE!!!!&lt;br /&gt;
&lt;br /&gt;
Well done and happy hacking!&lt;/div&gt;</summary>
		<author><name>Rstephane</name></author>
		
	</entry>
	<entry>
		<id>http://wiki.sonic-potions.com/index.php?title=LXR_OSX_build_instructions&amp;diff=213</id>
		<title>LXR OSX build instructions</title>
		<link rel="alternate" type="text/html" href="http://wiki.sonic-potions.com/index.php?title=LXR_OSX_build_instructions&amp;diff=213"/>
		<updated>2014-05-07T17:25:58Z</updated>

		<summary type="html">&lt;p&gt;Rstephane: /* Compile */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Tested on 10.8.x and 10.9.2; likely needs Xcode installed also (https://developer.apple.com/xcode/downloads/)&lt;br /&gt;
&lt;br /&gt;
== General steps == &lt;br /&gt;
The LXR code is divided into two mains code parts that we will compile &amp;quot;separately&amp;quot; using two different tools&lt;br /&gt;
*the AVR Atmel CODE (LCD, front panel control, USB, SD card)&lt;br /&gt;
*the ARM CODE (main LXR code for the voices / sounds)&lt;br /&gt;
&lt;br /&gt;
- We need &amp;quot;specific compilers and librairies&amp;quot; for each CODE. We need to change the PATH in your .bash_profile, we need MAKEFILES to build the firmware, and, finally, we will compile the code :)&lt;br /&gt;
&lt;br /&gt;
Let&amp;#039;s do it! &lt;br /&gt;
&lt;br /&gt;
== AVR COMPILER &amp;amp; LIBS == &lt;br /&gt;
* Download of Atmel AVR 8-bit toolchain from http://www.obdev.at/products/crosspack/download.html&lt;br /&gt;
* You will get a .dmg file that you should extract and install (CrossPack-AVR-20131216.dmg is the most recent as of 2015/05/02)&lt;br /&gt;
* The compiler and libs are installed under /usr/local/CrossPack-AVR-20131216/&lt;br /&gt;
* Note that you will also find a folder like /usr/local/CrossPack-AVR/ (this folder is an alias to the previous folder - symlink).&lt;br /&gt;
&lt;br /&gt;
== GNU ARM COMPILER AND LIBS == &lt;br /&gt;
* Download of GNU bare metal ARM toolchain from https://launchpad.net/gcc-arm-embedded (v4.8)&lt;br /&gt;
* Take the MAC version (something like : gcc-arm-none-eabi-4_8-2014q1-20140314-mac.tar.bz2 )&lt;br /&gt;
* Extract the compressed/tar file.&lt;br /&gt;
* Copy the extracted folder under /usr/local/&lt;br /&gt;
* Nothing else to do !&lt;br /&gt;
&lt;br /&gt;
== Change your PATH == &lt;br /&gt;
* We need to add a specific PATH for both compilers (and libs) for the MAC. Here is mine...&lt;br /&gt;
&lt;br /&gt;
    export PATH=$PATH:/usr/local/CrossPack-AVR-20131216/bin:/usr/local/CrossPack-AVR-20131216/:/usr/include:/usr/local/CrossPack-AVR-20131216/avr/include:/usr/local/gcc-arm-none-eabi-4_8-2014q1/bin&lt;br /&gt;
    export ARM_TOOLKIT_ROOT=/usr/local/gcc-arm-none-eabi-4_8-2014q1&lt;br /&gt;
    export AVR_TOOLKIT_ROOT=/usr/local/CrossPack-AVR-20131216&lt;br /&gt;
&lt;br /&gt;
* in a terminal window, execute &amp;quot;source ./.bash_profile&amp;quot; to update the PATH to your system.&lt;br /&gt;
* for the moment, don&amp;#039;t try to understand what are ARM_TOOLKIT / AVR_TOLLKIT variables, we will explain why we need this later.&lt;br /&gt;
&lt;br /&gt;
== Grab the LXR Code == &lt;br /&gt;
We advice you to grab the code either from :&lt;br /&gt;
&lt;br /&gt;
    Julian repository on GITHUB (https://github.com/SonicPotions/LXR)&lt;br /&gt;
    PLD repository (https://github.com/patrickdowling/LXR)&lt;br /&gt;
    rudeog repository (https://github.com/rudeog/LXR) -&amp;gt; extra features compared to Julian code.&lt;br /&gt;
    rstephane repository (https://github.com/rstephane/LXR) -&amp;gt; equivalent to Julian CODE. &lt;br /&gt;
&lt;br /&gt;
- of course once downloaded, you should extract the code and copy it to any folder you like.&lt;br /&gt;
On our side we copied it under: /Users/music/Documents/workspace/LXR/&lt;br /&gt;
&lt;br /&gt;
== MACOS specific makefiles == &lt;br /&gt;
We advice you to grab the makefiles either from :&lt;br /&gt;
&lt;br /&gt;
    PLD repository (https://github.com/patrickdowling/LXR) &lt;br /&gt;
    rstephane (@egnouf) repository (https://github.com/rstephane/LXR)&lt;br /&gt;
    RUDEOG repository https://github.com/patrickdowling/LXR&lt;br /&gt;
&lt;br /&gt;
- You will find on the root path of both repository a file called MAKEFILE. You will also need the other makefiles:&lt;br /&gt;
&lt;br /&gt;
    https://github.com/patrickdowling/LXR/blob/makefiles/Makefile&lt;br /&gt;
    https://github.com/patrickdowling/LXR/blob/makefiles/front/AVR/Makefile&lt;br /&gt;
    https://github.com/patrickdowling/LXR/blob/makefiles/mainboard/firmware/DrumSynth_FPU/Makefile&lt;br /&gt;
    https://github.com/patrickdowling/LXR/blob/makefiles/tools/FirmwareImageBuilder/Makefile&lt;br /&gt;
&lt;br /&gt;
* Once downloaded, copy them at the root PATH of the code (1) and in subfolders (2,3,4) you dowloaded in STEP 4.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;If you have taken the whole LXR code from @PLD or rstephane or @RUDEOG you don&amp;#039;t need to download once more the Makefiles, they are provided within !&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Now, let&amp;#039;s go back to the .bash_profile file:&lt;br /&gt;
&lt;br /&gt;
    export PATH=$PATH:/usr/local/CrossPack-AVR-20131216/bin:/usr/local/CrossPack-AVR-20131216/:/usr/include:/usr/local/CrossPack-AVR-20131216/avr/include:/usr/local/gcc-arm-none-eabi-4_8-2014q1/bin&lt;br /&gt;
    export ARM_TOOLKIT_ROOT=/usr/local/gcc-arm-none-eabi-4_8-2014q1&lt;br /&gt;
    export AVR_TOOLKIT_ROOT=/usr/local/CrossPack-AVR-20131216&lt;br /&gt;
&lt;br /&gt;
* You can notice the two variables &amp;#039;&amp;#039;&amp;#039;ARM_TOOLKIT_ROOT&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;AVR_TOOLKIT_ROOT&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
* They are used by the MAKEFILE that has created @PLD (and also used by rstephane).&lt;br /&gt;
* Change their values appropriately, according to your system path, where you installed the libs... etc.&lt;br /&gt;
&lt;br /&gt;
== Compile == &lt;br /&gt;
&lt;br /&gt;
* You just have to launch the command &amp;quot;make firmware&amp;quot; from a MAC terminal window (under your LXR code root path i.e /Users/music/Documents/workspace/LXR/)&lt;br /&gt;
). To clean the code you can execute &amp;quot;make clean&amp;quot;.&lt;br /&gt;
* You will get a FIRMWARE.BIN image (in fact, we compiled two programs and the makefile combine both to one single file !), copy this file on your SD CARD and follow instruction to upload your new firmware.&lt;br /&gt;
&lt;br /&gt;
If you have downloaded rstephane code, similar to @Julian and @PLD, you will noticed that when you power on the machine, it displays &amp;quot;LXR-Drums-V&amp;quot; instead of &amp;quot;LXR Drums V&amp;quot;. If so, you have successfully loaded (and compiled) LXR CODE!!!!&lt;br /&gt;
&lt;br /&gt;
Well done and happy hacking!&lt;/div&gt;</summary>
		<author><name>Rstephane</name></author>
		
	</entry>
	<entry>
		<id>http://wiki.sonic-potions.com/index.php?title=LXR_OSX_build_instructions&amp;diff=212</id>
		<title>LXR OSX build instructions</title>
		<link rel="alternate" type="text/html" href="http://wiki.sonic-potions.com/index.php?title=LXR_OSX_build_instructions&amp;diff=212"/>
		<updated>2014-05-07T17:23:36Z</updated>

		<summary type="html">&lt;p&gt;Rstephane: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Tested on 10.8.x and 10.9.2; likely needs Xcode installed also (https://developer.apple.com/xcode/downloads/)&lt;br /&gt;
&lt;br /&gt;
== General steps == &lt;br /&gt;
The LXR code is divided into two mains code parts that we will compile &amp;quot;separately&amp;quot; using two different tools&lt;br /&gt;
*the AVR Atmel CODE (LCD, front panel control, USB, SD card)&lt;br /&gt;
*the ARM CODE (main LXR code for the voices / sounds)&lt;br /&gt;
&lt;br /&gt;
- We need &amp;quot;specific compilers and librairies&amp;quot; for each CODE. We need to change the PATH in your .bash_profile, we need MAKEFILES to build the firmware, and, finally, we will compile the code :)&lt;br /&gt;
&lt;br /&gt;
Let&amp;#039;s do it! &lt;br /&gt;
&lt;br /&gt;
== AVR COMPILER &amp;amp; LIBS == &lt;br /&gt;
* Download of Atmel AVR 8-bit toolchain from http://www.obdev.at/products/crosspack/download.html&lt;br /&gt;
* You will get a .dmg file that you should extract and install (CrossPack-AVR-20131216.dmg is the most recent as of 2015/05/02)&lt;br /&gt;
* The compiler and libs are installed under /usr/local/CrossPack-AVR-20131216/&lt;br /&gt;
* Note that you will also find a folder like /usr/local/CrossPack-AVR/ (this folder is an alias to the previous folder - symlink).&lt;br /&gt;
&lt;br /&gt;
== GNU ARM COMPILER AND LIBS == &lt;br /&gt;
* Download of GNU bare metal ARM toolchain from https://launchpad.net/gcc-arm-embedded (v4.8)&lt;br /&gt;
* Take the MAC version (something like : gcc-arm-none-eabi-4_8-2014q1-20140314-mac.tar.bz2 )&lt;br /&gt;
* Extract the compressed/tar file.&lt;br /&gt;
* Copy the extracted folder under /usr/local/&lt;br /&gt;
* Nothing else to do !&lt;br /&gt;
&lt;br /&gt;
== Change your PATH == &lt;br /&gt;
* We need to add a specific PATH for both compilers (and libs) for the MAC. Here is mine...&lt;br /&gt;
&lt;br /&gt;
    export PATH=$PATH:/usr/local/CrossPack-AVR-20131216/bin:/usr/local/CrossPack-AVR-20131216/:/usr/include:/usr/local/CrossPack-AVR-20131216/avr/include:/usr/local/gcc-arm-none-eabi-4_8-2014q1/bin&lt;br /&gt;
    export ARM_TOOLKIT_ROOT=/usr/local/gcc-arm-none-eabi-4_8-2014q1&lt;br /&gt;
    export AVR_TOOLKIT_ROOT=/usr/local/CrossPack-AVR-20131216&lt;br /&gt;
&lt;br /&gt;
* in a terminal window, execute &amp;quot;source ./.bash_profile&amp;quot; to update the PATH to your system.&lt;br /&gt;
* for the moment, don&amp;#039;t try to understand what are ARM_TOOLKIT / AVR_TOLLKIT variables, we will explain why we need this later.&lt;br /&gt;
&lt;br /&gt;
== Grab the LXR Code == &lt;br /&gt;
We advice you to grab the code either from :&lt;br /&gt;
&lt;br /&gt;
    Julian repository on GITHUB (https://github.com/SonicPotions/LXR)&lt;br /&gt;
    PLD repository (https://github.com/patrickdowling/LXR)&lt;br /&gt;
    rudeog repository (https://github.com/rudeog/LXR) -&amp;gt; extra features compared to Julian code.&lt;br /&gt;
    rstephane repository (https://github.com/rstephane/LXR) -&amp;gt; equivalent to Julian CODE. &lt;br /&gt;
&lt;br /&gt;
- of course once downloaded, you should extract the code and copy it to any folder you like.&lt;br /&gt;
On our side we copied it under: /Users/music/Documents/workspace/LXR/&lt;br /&gt;
&lt;br /&gt;
== MACOS specific makefiles == &lt;br /&gt;
We advice you to grab the makefiles either from :&lt;br /&gt;
&lt;br /&gt;
    PLD repository (https://github.com/patrickdowling/LXR) &lt;br /&gt;
    rstephane (@egnouf) repository (https://github.com/rstephane/LXR)&lt;br /&gt;
    RUDEOG repository https://github.com/patrickdowling/LXR&lt;br /&gt;
&lt;br /&gt;
- You will find on the root path of both repository a file called MAKEFILE. You will also need the other makefiles:&lt;br /&gt;
&lt;br /&gt;
    https://github.com/patrickdowling/LXR/blob/makefiles/Makefile&lt;br /&gt;
    https://github.com/patrickdowling/LXR/blob/makefiles/front/AVR/Makefile&lt;br /&gt;
    https://github.com/patrickdowling/LXR/blob/makefiles/mainboard/firmware/DrumSynth_FPU/Makefile&lt;br /&gt;
    https://github.com/patrickdowling/LXR/blob/makefiles/tools/FirmwareImageBuilder/Makefile&lt;br /&gt;
&lt;br /&gt;
* Once downloaded, copy them at the root PATH of the code (1) and in subfolders (2,3,4) you dowloaded in STEP 4.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;If you have taken the whole LXR code from @PLD or rstephane or @RUDEOG you don&amp;#039;t need to download once more the Makefiles, they are provided within !&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Now, let&amp;#039;s go back to the .bash_profile file:&lt;br /&gt;
&lt;br /&gt;
    export PATH=$PATH:/usr/local/CrossPack-AVR-20131216/bin:/usr/local/CrossPack-AVR-20131216/:/usr/include:/usr/local/CrossPack-AVR-20131216/avr/include:/usr/local/gcc-arm-none-eabi-4_8-2014q1/bin&lt;br /&gt;
    export ARM_TOOLKIT_ROOT=/usr/local/gcc-arm-none-eabi-4_8-2014q1&lt;br /&gt;
    export AVR_TOOLKIT_ROOT=/usr/local/CrossPack-AVR-20131216&lt;br /&gt;
&lt;br /&gt;
* You can notice the two variables &amp;#039;&amp;#039;&amp;#039;ARM_TOOLKIT_ROOT&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;AVR_TOOLKIT_ROOT&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
* They are used by the MAKEFILE that has created @PLD (and also used by rstephane).&lt;br /&gt;
* Change their values appropriately, according to your system path, where you installed the libs... etc.&lt;br /&gt;
&lt;br /&gt;
== Compile == &lt;br /&gt;
&lt;br /&gt;
* You just have to launch the command &amp;quot;make firmware&amp;quot; from a MAC terminal window. To clean the code you can execute &amp;quot;make clean&amp;quot;.&lt;br /&gt;
* You will get a FIRMWARE.BIN image (in fact, we compiled two programs and the makefile combine both to one single file !), copy this file on your SD CARD and follow instruction to upload your new firmware.&lt;br /&gt;
&lt;br /&gt;
If you have downloaded rstephane code, similar to @Julian and @PLD, you will noticed that when you power on the machine, it displays &amp;quot;LXR-Drums-V&amp;quot; instead of &amp;quot;LXR Drums V&amp;quot;. If so, you have successfully loaded (and compiled) LXR CODE!!!!&lt;br /&gt;
&lt;br /&gt;
Well done and happy hacking!&lt;/div&gt;</summary>
		<author><name>Rstephane</name></author>
		
	</entry>
</feed>