mozaic_tips_and_tricks

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Next revisionBoth sides next revision
mozaic_tips_and_tricks [2020/02/04 19:19] – Changed overview links to local links _kimozaic_tips_and_tricks [2020/07/30 19:01] – [Mozaic: Scripting Tips & Tricks] Added link to ‚Dynamic Letters for Labeling‚ section _ki
Line 1: Line 1:
 ====== Mozaic: Scripting Tips & Tricks ====== ====== Mozaic: Scripting Tips & Tricks ======
 +~~NOTOC~~ {{tag>Mozaic midi_scripting tips_and_tricks}}
  
 This wiki page contains programming tips & tricks for [[mozaic_plugin_engine|Mozaic]] This wiki page contains programming tips & tricks for [[mozaic_plugin_engine|Mozaic]]
Line 10: Line 11:
   * [[#Some Best Practice Tips]]   * [[#Some Best Practice Tips]]
   * [[#Multi-Line Pad Labels]]   * [[#Multi-Line Pad Labels]]
 +  * [[#Dynamic Letters for Labeling]]
   * [[#Use the SHIFT Button to toggle to HELP View]]   * [[#Use the SHIFT Button to toggle to HELP View]]
   * [[#Use a Knob to toggle 16 Pads View to HELP View]]   * [[#Use a Knob to toggle 16 Pads View to HELP View]]
 +  * [[#Knob double-tap Support]]
 +  * [[#Using Logic Operators in Expressions instead of IF cases]]
 +  * [[#Using Inc and Dec in Expressions]]
 +  * [[#Calculate Standard Chords from a Root Note]]
 +  * [[#Include Snippets]]
  
 ===== Two dimensional Arrays ===== ===== Two dimensional Arrays =====
Line 155: Line 162:
  
 \\  \\ 
 +===== Dynamic Letters for Labeling =====
 +<html><p align = "right"><small><i>From -ki</i></small></p></html>
 +The NoteName function of Moazic can be used to dynamically output the letters A-G inside the label string definitions of Knobs, Pads or Logs. This allows to construct labels like ‚Bank A‘ to ‚Bank D‘, or ‚Preset A-1‘ to ‚Preset F-8‘.
 +
 +<code>
 +@OnLoad
 +  ShowLayout 2
 +  ABCDEFG   = [9,11,0,2,4,5,7]
 +
 +  for i = 0 to 15
 +    row = 1 + (i>7)
 +    id  = i%8
 +    if (id < 7)
 +      LabelPad i, {Pad },(NoteName ABCDEFG[id],NO),    },{Row },row
 +    endif
 +  endfor
 +@End
 +</code>
 +
 ===== Use the SHIFT Button to toggle to HELP View ===== ===== Use the SHIFT Button to toggle to HELP View =====
 <html><p align = "right"><small><i>From -ki</i></small></p></html> <html><p align = "right"><small><i>From -ki</i></small></p></html>
Line 212: Line 238:
 @End @End
 </code> </code>
-{{tag>Mozaic midi_scripting}}+ 
 +\\  
 +===== Knob double-tap Support =====  
 +<html><p align = "right"><small><i>From -ki</i></small></p></html> 
 + 
 +The value returned from //**GetKnobValue**// is a floating point number, usually it will contain non-zero decimal places when the knob is turned manually. If double tapped the knob-value is set to 64 exactly.  
 +This tip exploits the fact, that is very unlikely to manually dial in exactly 64.0000 - if such a knob value is returned, then the knob has probably been double-tapped. 
 + 
 + 
 +If a knob is only used to toggle between two states like a switch (like the variable //isOn// in the example), the code for double-tap detection would look like: 
 +<code> 
 +@OnKnobChange 
 +  _knob = LastKnob 
 +  _val  = GetKnobValue _knob 
 +   
 +  if _knob = TOGGLE_KNOB 
 +    if _val = 64 
 +      isOn = not isOn 
 +      SetKnobValue TOGGLE_KNOB,48 + 32*isOn 
 +    else 
 +      isOn = _val > 64   
 +    endif 
 +     
 +    if isOn 
 +      LabelKnob TOGGLE_KNOB,  {ON} 
 +    else 
 +      LabelKnob TOGGLE_KNOB,  {OFF} 
 +    endif 
 +  endif 
 +@End 
 + 
 +@OnLoad 
 +  ShowLayout 2 
 +  LabelPads {Knob Double-Tap Demo } 
 +  LabelKnobs {Toggle with Double-Tap} 
 +  for _knob = 0 to 3 
 +    SetKnobValue _knob,0 
 +    LabelKnob _knob,  { } 
 +  endfor 
 +   
 +  if Unassigned isOn 
 +    isOn = NO   
 +  endif 
 +   
 +  TOGGLE_KNOB = 1 
 +   
 +  SetKnobValue TOGGLE_KNOB,48 + 32*isOn 
 +  if isOn 
 +    LabelKnob TOGGLE_KNOB,  {ON} 
 +  else 
 +    LabelKnob TOGGLE_KNOB,  {OFF} 
 +  endif 
 +@End 
 +</code> 
 +The script snippet also features 
 +  * State saving of the toggle variable isOn 
 +  * Conditional expressions:  
 +    * //48 + 32*isOn// is either 48 or 80 depending on the state of //isOn// 
 +    * //isOn = _val > 64// assigns either 0 or 1 to //isOn// depending on _val 
 + 
 + 
 + 
 +\\  
 +=====  Using Logic Operators in Expressions instead of IF cases =====  
 +<html><p align = "right"><small><i>From -ki</i></small></p></html> 
 + 
 +Boolean expressions compute to either 1 or 0, which are the internal values for TRUE/FALSE or YES/NO. 
 +Using this behavior in expressions allows to get rid of some IFs, but on the other hand makes the script a bit more complicated to read and understand for novices. 
 + 
 +Instead of the lengthy 
 +<code> 
 +  // showHelp  is a boolean with the values YES/NO or TRUE/FALSE 
 + 
 +  If showHelp 
 +    ShowLayout 4 
 +  Else 
 +    ShowLayout 2 
 +  Endif 
 +</code> 
 + 
 +On can write  
 +<code> 
 +  ShowLayout 2 + 2*showHelp 
 +</code> 
 + 
 +
 + 
 +Here second example where in the 22 knob layout the left most 8 knobs of both rows are used as channel knobs for channels 1 to 16. Since there are 11 knobs per row, the channel computed for the lower row needs to be adjusted: 
 +<code> 
 +  chan = LastKnob + 1 
 +  If LastKnob >= 8 
 +    chan = chan - 3 
 +  Endif 
 +</code> 
 + 
 +This can be written shorter as: 
 +<code> 
 +  chan = LastKnob +1 - 3*(LastKnob>=8) 
 +</code> 
 + 
 +\\  
 +===== Using Inc and Dec in Expressions =====  
 +<html><p align = "right"><small><i>From -ki</i></small></p></html> 
 + 
 +TheOriginalPaulB discovered that Inc and Dec are working as functions. Both Inc and Dec are ‚pre-increment‘ operations like ++var  in C, as the function returns the already incremented value. This allows for several interesting language constructs: 
 + 
 +In case of a ring buffer index, one could use 
 +<code> 
 +  index = (Inc index) % 64 
 +</code> 
 +instead of the longer construct 
 + 
 +<code> 
 +  Inc index 
 +  index = index % 64 
 +</code> 
 + 
 +\\  
 +Sometimes this trick is also applicable in array initialization, but one has to compensate for the pre-increment. 
 +<code> 
 +  idx = -1 
 +  for i = 10 to 19 
 +    array[Inc idx] = 2*i 
 +  endfor 
 +</code> 
 +The example fills array[0] to array[9] with the values 20 to 38. To compensate for pre-increment, idx needs to start at -1 since it will be incremented to zero on first usage 
 + 
 +\\  
 +It is also possible to construct a post-increment operation by using the inc in the expression itself, but discarding it using multiplication with 0: 
 + 
 +<code> 
 +  idx = 0 
 +  for i = 10 to 19 
 +    array[idx] = 2*i  + 0*(Inc idx) 
 +  endfor 
 +</code> 
 + 
 +\\  
 +===== Calculate Standard Chords from a Root Note ==== 
 +<html><p align = "right"><small><i>From wim</i></small></p></html> 
 + 
 +This is a compact way to build standard chords from just a root note. It turns out that for standard western scales such as Major, Minor, Dorian, Phrygian, etc, normal chord notes can be found by starting at the root and counting up in steps of three semitones then quantizing up to the next scale tone. Repeat this for the number of notes you want in the chord (triad (3), seventh (4), ninth (5), eleventh (6), 13th (7). 
 + 
 +Here’s a code snippet that efficiently creates a chord of “notes” degree from an incoming MIDI Note. Code to do something with that array would obviously have to be added. 
 + 
 +<code> 
 +@OnMIDINote 
 +  //set “notes” to the number of notes wanted in the chord before this event triggers! 
 +  chordNotes[0] = ScaleQuantize MIDINote 
 +  for i = 1 to (notes - 1) 
 +    chordNotes[i] = ScaleQuantize chordNotes[i-1] + 3 
 +  endfor 
 +@End 
 +</code> 
 + 
 + 
 +\\  
 +===== Include Snippets ===== 
 +<html><p align = "right"><small><i>From -ki</i></small></p></html> 
 + 
 +On PatchStorage you can find several 'Include Snippets' that cover specific programming problems and that are intended to be appended your own scipt code. 
 + 
 +The snippets can be seen as 'well tested library functions'. For the current available include snippets, you copy their main code to the end of you script and call one or two initialization event functions in your @OnLoad.  
 +The snippet in turn will later call event that you need to define in your code (callbacks).  
 +All of the current available snippets need a timer event to do their work, the snippets are coded in a way that allows to also to work with a timer event that you defined in your script.  
 + 
 +I tried to make them as 'developer-friendly' as possible and also did extensive testing on each of them. The documentation wiki pages show the snippets source at the bottom since its easier to read on the wiki than inside Mozaic. 
 + 
 +^PatchStorage  ^Wiki ^OnLoad ^Other ^Callbacks ^Info ^ 
 +| [[https://patchstorage.com/pad-manager-include/|Pad & Shift Manager]] | [[mozaic_include_pad_and_shift_manager|Documentation]]| optional vars \\ one call| - | 2 | Detect single-/double-/triple-tap and hold interactions for pads or shift| 
 +| [[https://patchstorage.com/active-notes-tracker/|Active Notes Tracker]] | [[mozaic_include_active_notes_tracker|Documentation]] | optional var \\ one call | note-on / note-off \\ events | - | Manages a list of active notes, velocities and durations for each channel | 
 +| [[https://patchstorage.com/migration-manager-include/|Migration Manager]] | [[mozaic_include_migration_mananger|Documentation]] | two calls| - | 4 | Migrate script parameters between different script versions |
  • mozaic_tips_and_tricks.txt
  • Last modified: 2021/07/01 21:41
  • by _ki