Skip to content

Extending sol

puss edited this page Jul 11, 2017 · 3 revisions

this section describes sol's structure and how to extend sol

overview

            database
              ^ |
              | v
 inputs ->  control -> gui
            (magi)  <- 
              | ^   
              v |
            model 
  • control aka MAGI

    • the brains
    • gets input from
      • inputs - midi or osc
      • its own state (for example, when to loop)
      • the gui
  • database

    • the data
    • abstractions of clips
    • collections to store clips
    • methods to update or query database
    • save/load
  • gui

    • what's happening right now
    • what can be changed
    • multiple views
      1. performance
      2. library organization
      3. clip collection organization
  • models

    • provide compatible api(s)
    • translates info coming in so that it can go out

magi

magi controls everything, instead of writing out everything i will list the osc addresses magi uses. note that anywhere you see {}, that means each layer is assigned its own address eg /magi/layer0/playback/play would play on layer 0.

inputs/outputs that are model specific are specified within the model ie addresses for current clip positions or playback control.

address description
- timeline control
/magi/control{}/start start control
/magi/control{}/stop stop control
/magi/control{}/do do control
/magi/control{}/sens modify control sensitivity
/magi/fft/control{} fft control
- playback control
/magi/layer{}/playback/play play
/magi/layer{}/playback/pause pause
/magi/layer{}/playback/reverse reverse
/magi/layer{}/playback/random random
/magi/layer{}/playback/seek seek
/magi/layer{}/playback/clear clear
/magi/layer{}/playback/speed speed
/magi/layer{}/playback/speed/adjust adjust speed
/magi/layer{}/playback/speed/adjust/factor adjust speed by a factor
- clip control
/magi/layer{}/cue set/activate cue point
/magi/layer{}/cue/clear clear cue point
/magi/layer{}/loop/on_off de/activate looping
/magi/layer{}/loop/type change loop type
/magi/layer{}/loop/select select loop range
/magi/layer{}/loop/select/move select a loop range relatively
/magi/layer{}/loop/set/ set the loop range
/magi/layer{}/loop/set/a set the loop range's beginning
/magi/layer{}/loop/set/b set the loop range's end
/magi/layer{}/loop/set/ab set both beginning and end
/magi/layer{}/loop/set/cur/a set the beginning to current position
/magi/layer{}/loop/set/cur/b set the end to currrent position
/magi/layer{}/loop/clear reset the loop range
- clip collection manipulation
/magi/cur_col/select_clip/layer{} select a clip from current collection
/magi/cur_col/add add a collection
/magi/cur_col/delete delete a collection
/magi/cur_col/select select a collection
/magi/cur_col/select_left select collection to the left
/magi/cur_col/select_right select collection to the right
/magi/cur_col/swap swap collections
/magi/cur_col/swap_left swap left
/magi/cur_col/swap_right swap right
- search
/magi/search perform a search
/magi/search/select/layer{} select a search result
- midi / associated gui things
/midi used for midi control
/magi/gui/layer{}/qp_lp_toggle toggle whether pads affect qp or lp
/magi/gui/layer{}/pads_toggle toggle whether pads activate or delete on press
/magi/gui/layer{}/pad/activate activate pad
/magi/gui/layer{}/pad/deactivate deactivate pad
/magi/gui/layer{}/pad_press press pad (depends on state of pads_toggle)
/magi/gui/layer{}/pad/press_qp press qp pad
/magi/gui/layer{}/pad/press_lp press lp pad

database

the database contains all information about clips including parameters, cue points, loop points, last playback state, etc.

if you want to modify this, you can always add more params

within the database submodule are methods for searching, saving/loading savedata, thumbnail generation etc.

gui

to write your own gui create a new class and pass magi the gui as follows

from sol import Magi

magi = Magi()
magi.gui = MyCoolGui(magi)
magi.start()

a gui that you pass to magi directly requires the following functions to be implemented

def update_clip(self,layer,clip):
    """ update a layer with new clip. or if clip is none clear it """

def update_clip_params(self,layer,clip,param):
    """ dispatch a new clip parameter """

def update_cur_pos(self,layer,pos):
    """ update current playback position for a layer """

def update_search(self):
    """ do something when a search has occured """

def update_cols(self,what,ij=None):
    """ update clip collections
    what - select, add, remove, swap
    ij - what index (swap uses a tuple..) """

def update_clip_names(self):
    """ clip names have changed """

def update_gui_directly(self, layer, what, n=-1):
    """ added for midi control 
    what - qp_lp_toggle, pads_toggle, pad_activate, pad_deactivate, pad_press, qp_pad_press, lp_pad_press 
    n - what index (optional) """

sol_mt

sol_mt works like any other gui except it sends some extra information to a potentially external client.

if you wish to write your own client, you need to send the correct osc commands to magi as above

a sol_mt client will receive messages at the following addresses

address description
/modvj/sol_mt/layer{}/cur_pos current clip position
/modvj/sol_mt/layer{}/cur_col_clip_i index of current clip within clip collection
/modvj/sol_mt/layer{}/qp cue points status
/modvj/sol_mt/layer{}/loop/cur_range loop current range
/modvj/sol_mt/layer{}/loop/on_off loop status
/modvj/sol_mt/layer{}/loop/type loop type
/modvj/sol_mt/layer{}/loop/lp loop ranges
/modvj/sol_mt/layer{}/loop/lp_i index of loop selection
/modvj/sol_mt/layer{}/spd playback speed
/modvj/sol_mt/layer{}/sens control sensitivity
/modvj/sol_mt/update_thumbs update clip thumbnails

the tricky points are:

  • /qp and /lp will send comma separated lists of whether or not a cue point/loop range is set per bucket
  • /update_thumbs will send a comma separated list of thumbnail numbers, it's up to you to generate these thumbnails by running sol_mt -g and copying the files to a place where your client can read them.

models

each model specifies input/output osc addresses for external players.

each model needs to have the following fields

self.clip_pos_addr[n] # addresses for each layer where the player will send current clip position to
self.external_looping # true or false, whether you want to use the external player's looping functionality

and the following functions

play
pause
reverse
random
set_clip_pos
select_clip
clear_clip
set_playback_speed
# only if self.external_looping is True
set_loop_a
set_loop_b
set_loop_type
Clone this wiki locally