Showing posts with label modul8. Show all posts
Showing posts with label modul8. Show all posts

Saturday, June 13, 2020

Modul8 / Modul8 Module Best Practices

Best Practices for Writing Modul8 Modules:

  • Variables are camelCase
  • Put all your code in Init(). Define functions like handleKeyword(keyword, param, layer) and the only code in the KeywordEvent() block should be to call your handleKeyword() function. Keeping all the code on one screen makes it easy to audit, rename variables, and understand what the code is doing. You can also use "return" to skip code, instead of indenting the rest of the method.
  • Add a "module active" toggle button which defaults to off and auto-serializes. If this button is off, your module does nothing. Modul8 does not save which modules are active on a per-project basis. So if users have a lot of different projects using different modules, it is a common problem that an old project won't work until they figure out which modules to turn on and off. Adding an active toggle to your module lets them save that information as part of the project and there is no need to actually turn off the modules at the modul8 level. This is especially important for modules that have periodical, direct event, or keyword actions, because those might screw up someone's project. But it is also nice for performance reasons, if your module does a lot of GUI updates, to be able to skip them when the module is turned off.
  • Use versions on your modules, and put a changelog in the description. You can use option-Enter to add newlines to the description box.
  • Use the names of GUI elements rather then the messages. Specifically, in MessageEvent() ignore 'msg' and use param['NAME'] instead. The names are easier to find in the GUI editor, and you have to use name when modifying the GUI from the code. Having different values for the message in the "Script Connect" area, or having to keep the messages and names in sync is bothersome and an easy source of bugs. You do have to put something in the "script connect" box, but as long as you ignore the 'msg' variable in your code it doesn't matter what it is.
  • Logging script output is very CPU-intensive, so comment out all your debug message when done. If your module outputs to console as part of its feature, then it should have a "module active" button that defaults to False
  • If your module will have a (global) and (layer) version, define a variable "global = False" and write your code to handle both modes. Anytime you update the code, copy it from the (layer) module into the (global) module and change the value to True. Alternately, copy the .m8m file on disk which will include the layout as well as the code. Then you only need to update the 'global' variable to True.
  • Consider ignoring GUI changes during startup. If you have a fader that drives some keywords, but might be out of sync because the user changed those keywords through the main modul8 GUI, then you should ignore the fader position on load. Otherwise, you will override the values in the stored project: "hey, why are these values different than I left them??". This is especially important if your module doesn't have an [active] button which defaults to off. Define "finishedInit = False" in Init() and then set it true in PeriodicalEvent(); empirically, MessageEvent of saved state will run before PeriodicalEvent, so if not finishedInit you know it is due to project load and not an explicit user interaction. Turning off auto-serialize for certain GUI elements is another way to address this, although you will then lose the information about that element's value at time of save.
Best Practices for Modul8:
  • Use LB Notes and write down how your projects are structured, which modules are being used, and which MIDI and keyboard bindings you use.

Thursday, June 14, 2018

Control Modul8 From Reaper

Modul8 is VJ software for the Mac. Reaper is a full-featured and inexpensive DAW (with an unrestricted free demo).

Modul8 has no timeline, Reaper has a decent one.

To control Modul8 via MIDI from other software, I recommend my modules "LB - Control From MIDI CC" and "LB - Media from MIDI Notes" (available in the public library). With these modules installed and activated, you get direct control over nearly all layer and global parameters, and the ability to set media in layers, without having to mess around with interactive MIDI bindings.

For Reaper, I have created two files which will label the MIDI notes and CCs in Reaper's MIDI editor according to the Modul8 functions they will control. Install these in ~/Library/Application\ Support/REAPER/MIDINoteNames/ and load them via File -> Custom Note Names if you are editing a MIDI object and don't see the Modul8 parameter names.



There is also a sample Reaper project with tracks set up for each of the 10 Modul8 layers, and one more for control of global params. All MIDI from these track is forced onto the appropriate channel, so that you don't have to worry about setting the MIDI channel of each bit of MIDI data; just focus on which CCs and what values you are sending. If you prefer, you could have a single track containing MIDI data for multiple channels.



Download the files from Reaper Modul8 Control.zip

For this to work, you need to set up Reaper to enable MIDI output to M8. For most people this will be

  1. Use OSX's Audio MIDI Setup, in the IAC Driver, create a MIDI port called "Reaper to M8"
  2. Select "Reaper to M8" as a MIDI input in M8
  3. Enable "Reaper to M8" for output in Reaper's preferences
  4. In the Reaper project, adjust the routing for the topmost track and add MIDI hardware output to "Reaper to M8"
  5. In Modul8, double check that my modules are active
Play the timeline in Reaper, and see the Modul8 parameters respond.

Saturday, October 14, 2017

Modul8: "LB - Macro" module



Macro is an alternative to the "preset" concept.  Macro does not record the state of the modul8 parameters; rather, it records any number of changes to those parameters, and allows all those changes to be repeated by the press of a single button.




Modul8: LB Macro Module from Geoff Matters on Vimeo.


To start, turn on Learn for one of the macros, then take a few actions in modul8 such as toggling layer visibility, changing colorize and scale.  Turn off Learn.  Now, any time Play is pressed, it will return exactly those parameters modified, to the exact values they were when "learn" was turned off.  To test it, mess with the layer visibility / colorize / scale then press the Play button.  Note that unless a parameter was modified while Learn was on, it will not be adjusted when the macro is played back.  Note that the macro does not remember every intermediate value, only the most recent value for each parameter.  Note that some unwanted changes, such as layer focus, may be remembered as a side effect of a Macro eg if layer focus was changed during Learn.... this can interact with other parts of modul8.  Note that using another module during Learn does not record the use of the module, but records the actions the module takes.  For instance, if you use a random color module, the macro will not produce a random color each time but will always return to the color set during Learn.

Macros are a convenient way to bundle multiple predetermined actions into a single button, without having to write a module.  They are also useful to work around interface restrictions, eg use a Note On to enable something without the Note Off also disabling it (as it would with a direct MIDI mapping).

Version 1.0: store as dict rather than array
Version 0.8: use keywordsLB system, it can now learn keywords from other modules that also use the system

Note: "LB-Macro" (no spaces) was an early version of this uploaded 10 years ago. Obsolete, do not use.

Donate by Paypal