Saturday, July 2, 2011

MIDI Remote Script Design Challenges

I have been spending free or non-music time I have had on programming something similar to Hans Petrov's MIDI Remote Script for the Akai APC40, but for Native Instruments' Maschine. The Maschine did come with it's own script and controller template for Ableton Live, but I guess I want to create a better one. I want it to integrate the two workflows more, specifically during live performance.

_Framework is a component set, written at Ableton, that can be composed and extended to make Live interact with the different parts of midi controllers. The script could plausibly be simple combinations of these classes in one file or if you want more complex controller interaction, split up over multiple files in folders. So in my vision for VoidMaschine, there are multiple functions for different groups of elements on it, so there will need to be states or modes built into the way the elements work. That could possibly be over-architected to become more work than I need to so for the script, though. Someone might be drinking cool-aid, saying "Always use a design pattern, or beware the wrath of [insert cool-aid drinker's preferred language progenitor or platform demi-god's name here]!!! But, don't worry, be happy with shitty code, "it works, doesn't it?" "But is it scalable?" "I'll scale you, dude, how's that?" JK about that drama, I intend on building states into the script in whatever way such thatit'll be easier to modify later and that is appropriate for each mode/element combination.

I have confusion about the APC40_* script, particularly in the code doing something like what I want to do. For instance, some of the classes in the APC40_* source are prefixed by 'shiftable', e.g. 'ShiftableTransportComponent' and 'ShiftableSelectorComponent'. These both extend different classes. 'TransportComponent' and 'ModeSelectorComponent', respectively. This confuses me a little. I know that these are for toggle behavior for a component(pressing a modifier or 'shift' button to complete an action) AND for a 'mode' component. The second looks more like a traditional state machine, but without too much documentation, I want the class naming to be self-documenting at least, yet I also think I need to study the code more.

The VoidMaschine script has a has very similar behavior to the APC40_* script. The functionalities of Live that they control are represented by component classes that combine groups of control elements:

1 row of 8 buttons,
2 displays,
1 row of 8 knobs,
7 miscellaneous buttons,
8 group buttons,
8 transport control buttons,
3 master section knobs,
8 'mode' buttons ('scene', 'pattern', 'pad mode', etc next to the pads)
16 velocity sensitive pads

The current script does these things:

The transport controls are mapped so:
'restart' : play/restart
'play' : stop (yeah)
'rec' : record
'erase' : back to arrangement
'<' & '>' : time-line navigation
Note Repeat is mapped to tap-tempo
Master Volume is mapped to the Volume knob
Master Tempo is mapped to the Tempo knob (that's nice, it says what it is mapped to, whew)

I have 6 Group buttons blocked out for up(B) down(F) left(E) right(G) navigation of the infamous session box. While the last 2 are up(D) & down(H) for vertical scene navigation. The 'scene' mode button triggers the currently selected scene. A & C stay dark (for now...).

The pads trigger clip slots, but they don't light up to show you that they have a clip in them. I am not sure I can use Hanz' APC script as a model for setting up the launch buttons. The button class that he created utilizes different midi note values which correspond with the lights in the APC40's buttons. Maschine doesn't seem to expose any internal color or blinking state for it's buttons, so I am working on a timer-based blinking state for the clip buttons in the script. Par for the course, but the APC script has a scrolling behavior that is triggered if you hold the navigation buttons for a second or so. My experience with timers has been to use them or events that they trigger to create animation frame loops, in just about every other language I know, just not Python yet(go figure).

Finally, I have basic identification of the project name and authorship displaying on the two screens upon initialization of the script. This was an amazing epiphany for me when I discovered how to use the screens in Controller mode. I am pretty sure I was the first to do this, but it depends on how you look at it. I am simply sending messages via sysex to a certain knob and it is showing up on the screen. I created simple constants with 14, 15, and 30 spaces in order to crudely format the lcds. I want to eventually integrate this behavior into the functionality of the various components, so that I can simply trigger events to display messages, both a persistent display explaining the states and names of the parameters being controlled toast messages(quick interruptions, like the name of a mode when you press that button). I would like the persistent display to be uncluttered and only show numbers or abbreviations of the param names, but to get both the number and the full name of a parameter, you need to hold some shift button and turn the knob. When doing this sort of identification, the knobs (continuous rotaries) would not transmit their messages.