├── media ├── updown.svg ├── square.svg ├── sine.svg └── line4.svg ├── max-midi-learn.maxproj ├── patchers ├── two-deep.maxpat ├── bpatcher-test.maxpat ├── bpatcher-test2.maxpat ├── midilearn.maxpat └── max-midi-learn.maxpat ├── README.md └── code └── midilearn.js /media/updown.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /media/square.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /media/sine.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /max-midi-learn.maxproj: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "max-midi-learn", 3 | "version" : 1, 4 | "creationdate" : 3508289107, 5 | "modificationdate" : 3508289107, 6 | "viewrect" : [ 0.0, 0.0, 300.0, 500.0 ], 7 | "autoorganize" : 1, 8 | "hideprojectwindow" : 0, 9 | "showdependencies" : 1, 10 | "autolocalize" : 0, 11 | "contents" : { 12 | "patchers" : { 13 | "max-midi-learn.maxpat" : { 14 | "kind" : "patcher", 15 | "local" : 1, 16 | "toplevel" : 1 17 | } 18 | 19 | } 20 | , 21 | "media" : { 22 | 23 | } 24 | , 25 | "code" : { 26 | 27 | } 28 | 29 | } 30 | , 31 | "layout" : { 32 | 33 | } 34 | , 35 | "searchpath" : { 36 | 37 | } 38 | , 39 | "detailsvisible" : 0, 40 | "amxdtype" : 1633771873, 41 | "readonly" : 0 42 | } 43 | -------------------------------------------------------------------------------- /media/line4.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Layer 2 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /patchers/two-deep.maxpat: -------------------------------------------------------------------------------- 1 | { 2 | "patcher" : { 3 | "fileversion" : 1, 4 | "appversion" : { 5 | "major" : 7, 6 | "minor" : 0, 7 | "revision" : 1, 8 | "architecture" : "x64", 9 | "modernui" : 1 10 | } 11 | , 12 | "rect" : [ 1135.0, 583.0, 68.0, 51.0 ], 13 | "bgcolor" : [ 0.095481, 0.100396, 0.100293, 1.0 ], 14 | "editing_bgcolor" : [ 0.095481, 0.100396, 0.100293, 1.0 ], 15 | "bglocked" : 0, 16 | "openinpresentation" : 1, 17 | "default_fontsize" : 12.0, 18 | "default_fontface" : 0, 19 | "default_fontname" : "Arial", 20 | "gridonopen" : 1, 21 | "gridsize" : [ 15.0, 15.0 ], 22 | "gridsnaponopen" : 1, 23 | "objectsnaponopen" : 1, 24 | "statusbarvisible" : 2, 25 | "toolbarvisible" : 1, 26 | "lefttoolbarpinned" : 0, 27 | "toptoolbarpinned" : 0, 28 | "righttoolbarpinned" : 0, 29 | "bottomtoolbarpinned" : 0, 30 | "toolbars_unpinned_last_save" : 0, 31 | "tallnewobj" : 0, 32 | "boxanimatetime" : 200, 33 | "enablehscroll" : 1, 34 | "enablevscroll" : 1, 35 | "devicewidth" : 0.0, 36 | "description" : "", 37 | "digest" : "", 38 | "tags" : "", 39 | "style" : "dark-night-patch", 40 | "subpatcher_template" : "", 41 | "boxes" : [ { 42 | "box" : { 43 | "bgmode" : 0, 44 | "border" : 0, 45 | "clickthrough" : 0, 46 | "enablehscroll" : 0, 47 | "enablevscroll" : 0, 48 | "id" : "obj-1", 49 | "lockeddragscroll" : 0, 50 | "maxclass" : "bpatcher", 51 | "name" : "bpatcher-test2.maxpat", 52 | "numinlets" : 1, 53 | "numoutlets" : 1, 54 | "offset" : [ 0.0, 0.0 ], 55 | "outlettype" : [ "" ], 56 | "patching_rect" : [ 39.0, 35.0, 128.0, 128.0 ], 57 | "presentation" : 1, 58 | "presentation_rect" : [ 4.0, 2.0, 77.0, 62.0 ], 59 | "varname" : "bpatcher-test2", 60 | "viewvisibility" : 1 61 | } 62 | 63 | } 64 | ], 65 | "lines" : [ ], 66 | "styles" : [ { 67 | "name" : "dark-night-patch", 68 | "default" : { 69 | "bgfillcolor" : { 70 | "type" : "gradient", 71 | "color1" : [ 0.376471, 0.384314, 0.4, 1.0 ], 72 | "color2" : [ 0.290196, 0.309804, 0.301961, 1.0 ], 73 | "color" : [ 0.290196, 0.309804, 0.301961, 1.0 ], 74 | "angle" : 270.0, 75 | "proportion" : 0.39 76 | } 77 | , 78 | "textcolor" : [ 0.862745, 0.870588, 0.878431, 1.0 ], 79 | "patchlinecolor" : [ 0.439216, 0.74902, 0.254902, 0.898039 ], 80 | "accentcolor" : [ 0.952941, 0.564706, 0.098039, 1.0 ] 81 | } 82 | , 83 | "parentstyle" : "", 84 | "multi" : 0 85 | } 86 | ] 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # max-midi-learn # 2 | 3 | A simple to use - plug-n-play - MIDI learning system for Max/MSP projects. 4 | 5 | ![max-midi-learn](http://i.imgur.com/jE7fVHi.png) 6 | 7 | ## Features 8 | 9 | * Supports all enabled MIDI devices 10 | * Supports routing of multiple MIDI controllers to a single object in Max/MSP 11 | * Supports single MIDI controller to control multiple objects in Max/MSP 12 | * Intuitive graphical interface for hiliting objects in Max to arm them for learning 13 | * Supports persistent storage of learned assignments 14 | 15 | 16 | ## How to use from a user's perspective ## 17 | 18 | * Enable MIDI learn mode 19 | * Mouse-click on an object in your Max/MSP GUI to hilite the object and arm it for MIDI learn. 20 | * An item hilited pink has no current assignments 21 | * An item hilited green has a current assignment 22 | * Items can have multiple assignments 23 | 24 | **Example of an item hilited and ready for controller input** 25 | ![max-midi-learn](http://i.imgur.com/JBFr6JI.png) 26 | 27 | * Once an item is hilited and recieves MIDI controller input, this assignment is saved and the item is unhilited. 28 | * An item that is hilited with green already has a controller assigned to it, however, it is possible to assign multiple controllers to a single object. 29 | 30 | ![max-midi-learn](http://i.imgur.com/QrQRY86.png) 31 | 32 | * If multiple items are hilited and a MIDI controller value is registered, this object will respond to multiple MIDI controllers 33 | 34 | ![max-midi-learn](http://i.imgur.com/13RuMjn.png) 35 | 36 | 37 | * Shift clicking on any green hilited object will remove all currently stored assignments 38 | 39 | 40 | *Note: Persistance is automatic (i.e., saving to disk is automatic)* 41 | 42 | 43 | ## How to use from a developer's perspective ## 44 | 45 | ![max-midi-learn](http://i.imgur.com/Pbkr6HH.png) 46 | 47 | The MIDI learn system is encapsulated into a single Max patcher and a javascript file. The included project shows an example of how this patcher can be used. 48 | 49 | This implementation requires that your project use the Max/MSP pattr system, specifically the pattrstorage system. All objects that are recognized by the pattstorage system are automatically included in the midi learn system. 50 | 51 | The inputs of the midilearn object inputs are as follows: 52 | 53 | * MIDI learn mode on/off (0/1) 54 | * MIDI on/off (0/1) 55 | * Output of your pattrstorage object 56 | * Assigned hilite color 57 | * Unassigned hilite color 58 | * logging mode on/off 59 | 60 | The output of the midilearn object must be connected to the input of your pattrstorage object 61 | -------------------------------------------------------------------------------- /patchers/bpatcher-test.maxpat: -------------------------------------------------------------------------------- 1 | { 2 | "patcher" : { 3 | "fileversion" : 1, 4 | "appversion" : { 5 | "major" : 7, 6 | "minor" : 0, 7 | "revision" : 1, 8 | "architecture" : "x64", 9 | "modernui" : 1 10 | } 11 | , 12 | "rect" : [ 1028.0, 583.0, 68.0, 51.0 ], 13 | "bgcolor" : [ 0.095481, 0.100396, 0.100293, 1.0 ], 14 | "editing_bgcolor" : [ 0.095481, 0.100396, 0.100293, 1.0 ], 15 | "bglocked" : 0, 16 | "openinpresentation" : 1, 17 | "default_fontsize" : 12.0, 18 | "default_fontface" : 0, 19 | "default_fontname" : "Arial", 20 | "gridonopen" : 1, 21 | "gridsize" : [ 15.0, 15.0 ], 22 | "gridsnaponopen" : 1, 23 | "objectsnaponopen" : 1, 24 | "statusbarvisible" : 2, 25 | "toolbarvisible" : 1, 26 | "lefttoolbarpinned" : 0, 27 | "toptoolbarpinned" : 0, 28 | "righttoolbarpinned" : 0, 29 | "bottomtoolbarpinned" : 0, 30 | "toolbars_unpinned_last_save" : 0, 31 | "tallnewobj" : 0, 32 | "boxanimatetime" : 200, 33 | "enablehscroll" : 1, 34 | "enablevscroll" : 1, 35 | "devicewidth" : 0.0, 36 | "description" : "", 37 | "digest" : "", 38 | "tags" : "", 39 | "style" : "dark-night-patch", 40 | "subpatcher_template" : "bigpatcher", 41 | "boxes" : [ { 42 | "box" : { 43 | "id" : "obj-3", 44 | "maxclass" : "newobj", 45 | "numinlets" : 1, 46 | "numoutlets" : 4, 47 | "outlettype" : [ "", "", "", "" ], 48 | "patching_rect" : [ 216.0, 133.5, 58.0, 22.0 ], 49 | "restore" : { 50 | "obj5" : [ 0.0 ] 51 | } 52 | , 53 | "style" : "", 54 | "text" : "autopattr", 55 | "varname" : "u947000351" 56 | } 57 | 58 | } 59 | , { 60 | "box" : { 61 | "comment" : "", 62 | "id" : "obj-2", 63 | "maxclass" : "outlet", 64 | "numinlets" : 1, 65 | "numoutlets" : 0, 66 | "patching_rect" : [ 95.0, 206.0, 30.0, 30.0 ], 67 | "style" : "" 68 | } 69 | 70 | } 71 | , { 72 | "box" : { 73 | "comment" : "", 74 | "id" : "obj-1", 75 | "maxclass" : "inlet", 76 | "numinlets" : 0, 77 | "numoutlets" : 1, 78 | "outlettype" : [ "" ], 79 | "patching_rect" : [ 95.0, 58.0, 30.0, 30.0 ], 80 | "style" : "" 81 | } 82 | 83 | } 84 | , { 85 | "box" : { 86 | "activedialcolor" : [ 0.317647, 0.654902, 0.976471, 1.0 ], 87 | "activeneedlecolor" : [ 0.65098, 0.666667, 0.662745, 1.0 ], 88 | "focusbordercolor" : [ 0.960784, 0.827451, 0.156863, 1.0 ], 89 | "fontface" : 0, 90 | "fontsize" : 9.0, 91 | "id" : "obj-1789", 92 | "maxclass" : "live.dial", 93 | "numinlets" : 1, 94 | "numoutlets" : 2, 95 | "outlettype" : [ "", "float" ], 96 | "parameter_enable" : 1, 97 | "patching_rect" : [ 95.0, 131.0, 34.0, 27.0 ], 98 | "presentation" : 1, 99 | "presentation_rect" : [ 11.199951, 11.291656, 34.0, 27.0 ], 100 | "saved_attribute_attributes" : { 101 | "valueof" : { 102 | "parameter_longname" : "scale1[1]", 103 | "parameter_shortname" : "phase mod", 104 | "parameter_type" : 0, 105 | "parameter_mmin" : -1.0, 106 | "parameter_mmax" : 1.0, 107 | "parameter_modmode" : 1, 108 | "parameter_initial_enable" : 1, 109 | "parameter_initial" : [ 0.0 ], 110 | "parameter_unitstyle" : 1 111 | } 112 | 113 | } 114 | , 115 | "showname" : 0, 116 | "shownumber" : 0, 117 | "textcolor" : [ 0.862745, 0.870588, 0.878431, 1.0 ], 118 | "tribordercolor" : [ 0.701961, 0.415686, 0.886275, 1.0 ], 119 | "varname" : "obj5" 120 | } 121 | 122 | } 123 | ], 124 | "lines" : [ { 125 | "patchline" : { 126 | "destination" : [ "obj-1789", 0 ], 127 | "disabled" : 0, 128 | "hidden" : 0, 129 | "source" : [ "obj-1", 0 ] 130 | } 131 | 132 | } 133 | , { 134 | "patchline" : { 135 | "destination" : [ "obj-2", 0 ], 136 | "disabled" : 0, 137 | "hidden" : 0, 138 | "source" : [ "obj-1789", 0 ] 139 | } 140 | 141 | } 142 | ], 143 | "styles" : [ { 144 | "name" : "dark-night-patch", 145 | "default" : { 146 | "bgfillcolor" : { 147 | "type" : "gradient", 148 | "color1" : [ 0.376471, 0.384314, 0.4, 1.0 ], 149 | "color2" : [ 0.290196, 0.309804, 0.301961, 1.0 ], 150 | "color" : [ 0.290196, 0.309804, 0.301961, 1.0 ], 151 | "angle" : 270.0, 152 | "proportion" : 0.39 153 | } 154 | , 155 | "textcolor" : [ 0.862745, 0.870588, 0.878431, 1.0 ], 156 | "patchlinecolor" : [ 0.439216, 0.74902, 0.254902, 0.898039 ], 157 | "accentcolor" : [ 0.952941, 0.564706, 0.098039, 1.0 ] 158 | } 159 | , 160 | "parentstyle" : "", 161 | "multi" : 0 162 | } 163 | ] 164 | } 165 | 166 | } 167 | -------------------------------------------------------------------------------- /patchers/bpatcher-test2.maxpat: -------------------------------------------------------------------------------- 1 | { 2 | "patcher" : { 3 | "fileversion" : 1, 4 | "appversion" : { 5 | "major" : 7, 6 | "minor" : 0, 7 | "revision" : 1, 8 | "architecture" : "x64", 9 | "modernui" : 1 10 | } 11 | , 12 | "rect" : [ 1139.0, 585.0, 77.0, 62.0 ], 13 | "bgcolor" : [ 0.095481, 0.100396, 0.100293, 1.0 ], 14 | "editing_bgcolor" : [ 0.095481, 0.100396, 0.100293, 1.0 ], 15 | "bglocked" : 0, 16 | "openinpresentation" : 1, 17 | "default_fontsize" : 12.0, 18 | "default_fontface" : 0, 19 | "default_fontname" : "Arial", 20 | "gridonopen" : 1, 21 | "gridsize" : [ 15.0, 15.0 ], 22 | "gridsnaponopen" : 1, 23 | "objectsnaponopen" : 1, 24 | "statusbarvisible" : 2, 25 | "toolbarvisible" : 1, 26 | "lefttoolbarpinned" : 0, 27 | "toptoolbarpinned" : 0, 28 | "righttoolbarpinned" : 0, 29 | "bottomtoolbarpinned" : 0, 30 | "toolbars_unpinned_last_save" : 0, 31 | "tallnewobj" : 0, 32 | "boxanimatetime" : 200, 33 | "enablehscroll" : 1, 34 | "enablevscroll" : 1, 35 | "devicewidth" : 0.0, 36 | "description" : "", 37 | "digest" : "", 38 | "tags" : "", 39 | "style" : "dark-night-patch", 40 | "subpatcher_template" : "bigpatcher", 41 | "boxes" : [ { 42 | "box" : { 43 | "id" : "obj-3", 44 | "maxclass" : "newobj", 45 | "numinlets" : 1, 46 | "numoutlets" : 4, 47 | "outlettype" : [ "", "", "", "" ], 48 | "patching_rect" : [ 216.0, 133.5, 58.0, 22.0 ], 49 | "restore" : { 50 | "obj6" : [ 0.0 ] 51 | } 52 | , 53 | "style" : "", 54 | "text" : "autopattr", 55 | "varname" : "u894000352" 56 | } 57 | 58 | } 59 | , { 60 | "box" : { 61 | "comment" : "", 62 | "id" : "obj-2", 63 | "maxclass" : "outlet", 64 | "numinlets" : 1, 65 | "numoutlets" : 0, 66 | "patching_rect" : [ 95.0, 206.0, 30.0, 30.0 ], 67 | "style" : "" 68 | } 69 | 70 | } 71 | , { 72 | "box" : { 73 | "comment" : "", 74 | "id" : "obj-1", 75 | "maxclass" : "inlet", 76 | "numinlets" : 0, 77 | "numoutlets" : 1, 78 | "outlettype" : [ "" ], 79 | "patching_rect" : [ 95.0, 58.0, 30.0, 30.0 ], 80 | "style" : "" 81 | } 82 | 83 | } 84 | , { 85 | "box" : { 86 | "activedialcolor" : [ 0.317647, 0.654902, 0.976471, 1.0 ], 87 | "activeneedlecolor" : [ 0.65098, 0.666667, 0.662745, 1.0 ], 88 | "focusbordercolor" : [ 0.960784, 0.827451, 0.156863, 1.0 ], 89 | "fontface" : 0, 90 | "fontsize" : 9.0, 91 | "id" : "obj-1789", 92 | "maxclass" : "live.dial", 93 | "numinlets" : 1, 94 | "numoutlets" : 2, 95 | "outlettype" : [ "", "float" ], 96 | "parameter_enable" : 1, 97 | "patching_rect" : [ 95.0, 131.0, 34.0, 27.0 ], 98 | "presentation" : 1, 99 | "presentation_rect" : [ 11.199951, 11.291656, 34.0, 27.0 ], 100 | "saved_attribute_attributes" : { 101 | "valueof" : { 102 | "parameter_longname" : "scale1[2]", 103 | "parameter_shortname" : "phase mod", 104 | "parameter_type" : 0, 105 | "parameter_mmin" : -1.0, 106 | "parameter_mmax" : 1.0, 107 | "parameter_modmode" : 1, 108 | "parameter_initial_enable" : 1, 109 | "parameter_initial" : [ 0.0 ], 110 | "parameter_unitstyle" : 1 111 | } 112 | 113 | } 114 | , 115 | "showname" : 0, 116 | "shownumber" : 0, 117 | "textcolor" : [ 0.862745, 0.870588, 0.878431, 1.0 ], 118 | "tribordercolor" : [ 0.701961, 0.415686, 0.886275, 1.0 ], 119 | "varname" : "obj6" 120 | } 121 | 122 | } 123 | ], 124 | "lines" : [ { 125 | "patchline" : { 126 | "destination" : [ "obj-1789", 0 ], 127 | "disabled" : 0, 128 | "hidden" : 0, 129 | "source" : [ "obj-1", 0 ] 130 | } 131 | 132 | } 133 | , { 134 | "patchline" : { 135 | "destination" : [ "obj-2", 0 ], 136 | "disabled" : 0, 137 | "hidden" : 0, 138 | "source" : [ "obj-1789", 0 ] 139 | } 140 | 141 | } 142 | ], 143 | "styles" : [ { 144 | "name" : "dark-night-patch", 145 | "default" : { 146 | "bgfillcolor" : { 147 | "type" : "gradient", 148 | "color1" : [ 0.376471, 0.384314, 0.4, 1.0 ], 149 | "color2" : [ 0.290196, 0.309804, 0.301961, 1.0 ], 150 | "color" : [ 0.290196, 0.309804, 0.301961, 1.0 ], 151 | "angle" : 270.0, 152 | "proportion" : 0.39 153 | } 154 | , 155 | "textcolor" : [ 0.862745, 0.870588, 0.878431, 1.0 ], 156 | "patchlinecolor" : [ 0.439216, 0.74902, 0.254902, 0.898039 ], 157 | "accentcolor" : [ 0.952941, 0.564706, 0.098039, 1.0 ] 158 | } 159 | , 160 | "parentstyle" : "", 161 | "multi" : 0 162 | } 163 | ] 164 | } 165 | 166 | } 167 | -------------------------------------------------------------------------------- /code/midilearn.js: -------------------------------------------------------------------------------- 1 | autowatch = 1; 2 | inlets = 1; 3 | 4 | 5 | var midilearnobjs = []; 6 | var midiobjects = []; 7 | var mididevices = []; 8 | var toggleList = {}; 9 | 10 | // these are the two maps which are persisted to disk 11 | var controlList = {}; 12 | var midiRouter = {}; 13 | 14 | // is the shift key down 15 | var shift = false; 16 | 17 | // is logging enabled 18 | var logenabled = 0; 19 | 20 | // constants 21 | var padding = 2; 22 | var colorAssigned = [0.590803, 1., 0.102193, 0.65]; 23 | var colorNotAssinged = [1.0, 0.023504, 0.64687, 0.55]; 24 | 25 | 26 | /**************************************************************** 27 | Message Handlers 28 | ****************************************************************/ 29 | 30 | function init() { 31 | 32 | clear_midilearnobjs(); 33 | 34 | controlList = {}; 35 | midiRouter = {}; 36 | mididevices = []; 37 | midiobjects = []; 38 | 39 | readmidimap(); 40 | } 41 | 42 | function logging(val) { 43 | logenabled = val; 44 | } 45 | 46 | function assignedcolor(r,g,b,a) { 47 | colorAssigned = [r,g,b,a]; 48 | logmsg("assigned color = " + JSON.stringify(colorAssigned)); 49 | } 50 | 51 | function unassignedcolor(r,g,b,a) { 52 | colorNotAssinged = [r,g,b,a]; 53 | logmsg("unassigned color = " + JSON.stringify(colorNotAssinged)); 54 | } 55 | 56 | function shiftkey(val) { 57 | shift = (val == 1); 58 | } 59 | 60 | function mididevice(name) { 61 | mididevices.push(name); 62 | } 63 | 64 | function togglelistener(name, val) { 65 | toggleList[name] = val; 66 | 67 | // check to see if control is already assigned 68 | if (val == 1) { 69 | var ub = controlList[name].ub; 70 | ub.message("hltcolor", isassigned(name) ? colorAssigned : colorNotAssinged); 71 | } 72 | if (val == 0 && shift) { 73 | unassign(name); 74 | } 75 | } 76 | 77 | function learnmode(val) { 78 | if (val == 0) { 79 | learnmodeoff(); 80 | } else { 81 | learnmodedeep(); 82 | } 83 | } 84 | 85 | function ctlassign(device, chan, cc, val) { 86 | 87 | var needupdate = false; 88 | if (arguments.length > 0) { 89 | for (key in toggleList) { 90 | if (toggleList.hasOwnProperty(key)) { 91 | var item = toggleList[key]; 92 | if (item === 1) { 93 | 94 | var midi = { 95 | "device": device, 96 | "channel": chan, 97 | "cc": cc 98 | } 99 | 100 | if (!controlList[key].midi) { 101 | controlList[key].midi = []; 102 | } 103 | 104 | controlList[key].midi.push(midi); 105 | 106 | var chanStr = "c-" + chan; 107 | var ccStr = "cc-" + cc; 108 | 109 | if (!midiRouter[device]) { 110 | midiRouter[device] = {}; 111 | } 112 | if (!midiRouter[device][chanStr]) { 113 | midiRouter[device][chanStr] = {}; 114 | } 115 | 116 | if (!midiRouter[device][chanStr][ccStr]) { 117 | midiRouter[device][chanStr][ccStr] = []; 118 | } 119 | 120 | var objArray = midiRouter[device][chanStr][ccStr]; 121 | 122 | if (objArray.indexOf(key) === -1) { 123 | 124 | // support multiple assignments per midi control - just because someone might want to 125 | midiRouter[device][chanStr][ccStr].push(key); 126 | 127 | // lets turn learn-mode hilite off for this control once we get an assignment 128 | var ub = controlList[key].ub; 129 | if (ub) { 130 | ub.message("bang"); 131 | } 132 | needupdate = true; 133 | } 134 | } 135 | } 136 | } 137 | } 138 | 139 | if (needupdate) { 140 | writemidimap(); 141 | } 142 | } 143 | 144 | function routemidi(device, chan, cc, val) { 145 | 146 | var chanStr = "c-" + chan; 147 | var ccStr = "cc-" + cc; 148 | if (midiRouter[device].hasOwnProperty(chanStr) && midiRouter[device][chanStr].hasOwnProperty(ccStr)) { 149 | 150 | var objList = midiRouter[device][chanStr][ccStr]; 151 | if (objList) { 152 | for (var i = 0; i < objList.length; i++) { 153 | // calling getnameddeep seems to crash max if called to frequently/quickly.... wtf? 154 | var task = new Task(routeMidiTask, this, objList[i], val); 155 | task.schedule((i + 1) * 20); 156 | } 157 | } 158 | } 159 | } 160 | 161 | 162 | function midimode(val) { 163 | if (val) { 164 | midion(); 165 | } 166 | else { 167 | midioff(); 168 | } 169 | } 170 | 171 | 172 | function clientlist(name) { 173 | if (name !== "done") { 174 | if (!controlList[name]) { 175 | controlList[name] = {}; 176 | } 177 | toggleList[name] = 0; 178 | } 179 | } 180 | 181 | 182 | /**************************************************************** 183 | workers 184 | ****************************************************************/ 185 | 186 | function midion() { 187 | 188 | logmsg("creating midi objects"); 189 | for (var i = 0; i < mididevices.length; i++) { 190 | var x = 100 + 250 * i; 191 | var y = 100; 192 | 193 | var gate = this.patcher.getnamed("prepgate"); 194 | 195 | // can't figure out how to make a string out of a name with spaces that prepend can understand 196 | // so we will replace spaces in MIDI device names with delimiter 197 | var device = mididevices[i].replace(/\s+/g, "$"); 198 | 199 | logmsg("midi in device found: " + device); 200 | 201 | var cin = this.patcher.newdefault(x, y, "ctlin"); 202 | cin.message(mididevices[i]); 203 | 204 | var midichan = this.patcher.newdefault(x, y + 15, "prepend", "set"); 205 | var tbi = this.patcher.newdefault(x, y + 25, "trigger", "b", "i"); 206 | var pack = this.patcher.newdefault(x, y + 50, "pack", 1, 1, 1); 207 | 208 | this.patcher.connect(cin, 0, tbi, 0); 209 | this.patcher.connect(cin, 1, pack, 1); 210 | this.patcher.connect(cin, 2, midichan, 0); 211 | this.patcher.connect(tbi, 1, pack, 2); 212 | this.patcher.connect(tbi, 0, pack, 0); 213 | this.patcher.connect(midichan, 0, pack, 0); 214 | 215 | var prep = this.patcher.newdefault(x, y + 100, "prepend", device); 216 | this.patcher.connect(pack, 0, prep, 0); 217 | 218 | var msg = this.patcher.newdefault(x, y + 150, "message"); 219 | this.patcher.connect(prep, 0, msg, 1); 220 | this.patcher.connect(prep, 0, gate, 1); 221 | midiobjects.push([cin, midichan, tbi, pack, prep, msg]); 222 | 223 | if (!midiRouter[device]) 224 | midiRouter[device] = {}; 225 | } 226 | } 227 | 228 | 229 | function midioff() { 230 | 231 | logmsg("cleaning up midi objects"); 232 | if (midiobjects.length) { 233 | for (var i = 0; i < midiobjects.length; i++) { 234 | var objlist = midiobjects[i]; 235 | for (var k = 0; k < objlist.length; k++) { 236 | this.patcher.remove(objlist[k]); 237 | } 238 | } 239 | } 240 | } 241 | 242 | 243 | function routeMidiTask(objname, val) { 244 | 245 | //wtf... this crashes max if called too frequently so we have to move to a js task 246 | var obj = getnameddeep(objname); 247 | var thispatcher = obj.patcher; 248 | // if it is a m4l object - then we can just send it a normalized value 249 | // and it will scale accordingly ( I whidh max objects did the same) 250 | if (obj.understands("rawfloat")) { 251 | obj.message("rawfloat", val / 127.0); 252 | } 253 | else if (obj.maxclass === "live.togle") { 254 | obj.message("int", val > 63 ? 1 : 0); 255 | } else { 256 | var maxclass = obj.maxclass; 257 | 258 | // are we dealing with a live. object 259 | if (maxclass.indexOf("live.") > -1) { 260 | obj.message("float", val / 127.0); 261 | } 262 | // if not, lets try to find the min/max values so we can scale accordingly 263 | else { 264 | var min = obj.getattr("min"); 265 | var range = obj.getattr("size"); 266 | var n = min + ((val / 127.0) * range); 267 | obj.message("float", n); 268 | } 269 | } 270 | } 271 | 272 | 273 | function learnmodedeep() { 274 | 275 | logmsg("learn mode deep ON"); 276 | if (controlList) { 277 | for (key in controlList) { 278 | if (controlList.hasOwnProperty(key)) { 279 | var name = key; 280 | var mobj = getnameddeep(name); 281 | var assigned = false; 282 | var clickSender = null; 283 | var togSender = null; 284 | if (mobj) { 285 | var r = mobj.rect; 286 | var x, y, w, h; 287 | 288 | var thispatcher = mobj.patcher; 289 | 290 | x = r[0]; 291 | y = r[1]; 292 | w = r[2] - r[0]; 293 | h = r[3] - r[1]; 294 | 295 | togSender = thispatcher.newdefault(x, r[2] + 75, "send", "toglstnr"); 296 | clickSender = thispatcher.newdefault(x + 25, r[2] + 25, "send", "clicklstnr"); 297 | 298 | var ub = thispatcher.newdefault(x, y, "ubutton", 299 | "@varname", "learn-" + name, 300 | "@presentation_rect", x - padding, y - padding, w + padding * 2, h + padding * 2, 301 | "@orderfront", 1, 302 | "@hltcolor", isassigned(key) ? colorAssigned : colorNotAssinged, 303 | "@toggle", 1, 304 | "@presentation", 1, 305 | "@ignoreclick", 0); 306 | 307 | var tg = thispatcher.newdefault(r[0], r[2] + 25, "toggle", 308 | "@ignoreclick:", 1); 309 | 310 | var prep = thispatcher.newdefault(r[0], r[2] + 50, "prepend", name); 311 | 312 | thispatcher.connect(ub, 0, tg, 0); 313 | thispatcher.connect(ub, 1, tg, 0); 314 | thispatcher.connect(tg, 0, prep, 0); 315 | thispatcher.connect(prep, 0, togSender, 0); 316 | thispatcher.connect(ub, 0, clickSender, 0); 317 | 318 | midilearnobjs.push([ub, tg, prep, togSender, clickSender]); 319 | controlList[key].ub = ub; 320 | } else { 321 | logmsg("could not find obj named " + name); 322 | } 323 | 324 | } 325 | } 326 | } 327 | } 328 | 329 | function unassign(objName) { 330 | 331 | var midiList = controlList[objName].midi; 332 | var needupate = false; 333 | 334 | if (midiList) { 335 | 336 | while(midiList.length > 0) { 337 | var midi = midiList[0]; 338 | var device = midi.device; 339 | var chanStr = "c-" + midi.channel; 340 | var ccStr = "cc-" + midi.cc; 341 | 342 | var itemList = midiRouter[device][chanStr][ccStr]; 343 | if (itemList) { 344 | var ind = itemList.indexOf(objName); 345 | if (ind > -1) { 346 | itemList.splice(ind, 1); 347 | } 348 | } 349 | midiList.splice(0, 1); 350 | needupdate = true; 351 | } 352 | } 353 | if (needupdate) { 354 | writemidimap(); 355 | } 356 | } 357 | 358 | function learnmodeoff() { 359 | logmsg("midi learn mode OFF"); 360 | clear_midilearnobjs(); 361 | toggleList = {}; 362 | } 363 | 364 | function clear_midilearnobjs() { 365 | 366 | logmsg("cleaning up learn-mode objects"); 367 | if (midilearnobjs && midilearnobjs.length > 0) { 368 | for (var i = 0; i < midilearnobjs.length; i++) { 369 | var items = midilearnobjs[i]; 370 | for (var k = 0; k < items.length; k++) { 371 | var thispatcher = items[k].patcher; 372 | 373 | thispatcher.remove(items[k]); 374 | } 375 | } 376 | } 377 | midilearnobjs = []; 378 | } 379 | 380 | 381 | function writemidimap() { 382 | 383 | var f = new File("midimap.json", "write", "TEXT"); 384 | 385 | if (f.isopen) { 386 | f.position = 0; 387 | f.eof = 0; 388 | logmsg("writing midimap.json - parent folder = " + f.foldername); 389 | f.writestring(JSON.stringify(midiRouter)); 390 | f.close(); 391 | } 392 | 393 | f = new File("controllist.json", "write", "TEXT"); 394 | if (f.isopen) { 395 | f.position = 0; 396 | f.eof = 0; 397 | logmsg("writing controllist.json - parent folder = " + f.foldername); 398 | f.writestring(JSON.stringify(controlList)); 399 | f.close(); 400 | } 401 | } 402 | 403 | function readmidimap() { 404 | var f = new File("midimap.json", "read"); 405 | if (f.isopen) { 406 | var size = f.eof; 407 | var temp = f.readstring(size); 408 | if (temp) { 409 | 410 | midiRouter = JSON.parse(temp); 411 | logmsg("loaded midimap successfully: " + JSON.stringify(midiRouter)); 412 | } 413 | } 414 | f = new File("controllist.json", "read"); 415 | if (f.isopen) { 416 | var size = f.eof; 417 | var temp = f.readstring(size); 418 | if (temp) { 419 | controlList = JSON.parse(temp); 420 | logmsg("loaded controlList successfully: " + JSON.stringify(controlList)); 421 | } 422 | } 423 | } 424 | 425 | 426 | /**************************************************************** 427 | utils 428 | ****************************************************************/ 429 | 430 | function findroot() { 431 | var thispatcher = this.patcher; 432 | while (thispatcher.parentpatcher) { 433 | thispatcher = thispatcher.parentpatcher; 434 | } 435 | return thispatcher; 436 | } 437 | 438 | 439 | function getnameddeep(name) { 440 | var tree = name.split("::"); 441 | var thispatcher = findroot(); 442 | for (var i = 0; i < tree.length - 1; i++) { 443 | thispatcher = thispatcher.getnamed(tree[i]).subpatcher(); 444 | } 445 | return thispatcher.getnamed(tree[tree.length - 1]); 446 | } 447 | 448 | function isassigned(name) { 449 | return (controlList[name].midi && controlList[name].midi.length); 450 | } 451 | 452 | 453 | function printlists() { 454 | logmsg("midiRouter = " + JSON.stringify(midiRouter)); 455 | logmsg("controlList = " + JSON.stringify(controlList)); 456 | } 457 | 458 | function logmsg(msg) { 459 | if (logenabled) { 460 | post(msg + "\n"); 461 | } 462 | } -------------------------------------------------------------------------------- /patchers/midilearn.maxpat: -------------------------------------------------------------------------------- 1 | { 2 | "patcher" : { 3 | "fileversion" : 1, 4 | "appversion" : { 5 | "major" : 7, 6 | "minor" : 0, 7 | "revision" : 1, 8 | "architecture" : "x64", 9 | "modernui" : 1 10 | } 11 | , 12 | "rect" : [ 461.0, 79.0, 1460.0, 1257.0 ], 13 | "bgcolor" : [ 0.095481, 0.100396, 0.100293, 1.0 ], 14 | "editing_bgcolor" : [ 0.095481, 0.100396, 0.100293, 1.0 ], 15 | "bglocked" : 0, 16 | "openinpresentation" : 0, 17 | "default_fontsize" : 12.0, 18 | "default_fontface" : 0, 19 | "default_fontname" : "Arial", 20 | "gridonopen" : 1, 21 | "gridsize" : [ 15.0, 15.0 ], 22 | "gridsnaponopen" : 1, 23 | "objectsnaponopen" : 1, 24 | "statusbarvisible" : 2, 25 | "toolbarvisible" : 1, 26 | "lefttoolbarpinned" : 0, 27 | "toptoolbarpinned" : 0, 28 | "righttoolbarpinned" : 0, 29 | "bottomtoolbarpinned" : 0, 30 | "toolbars_unpinned_last_save" : 0, 31 | "tallnewobj" : 0, 32 | "boxanimatetime" : 200, 33 | "enablehscroll" : 1, 34 | "enablevscroll" : 1, 35 | "devicewidth" : 0.0, 36 | "description" : "", 37 | "digest" : "", 38 | "tags" : "", 39 | "style" : "dark-night-patch", 40 | "subpatcher_template" : "bigpatcher", 41 | "boxes" : [ { 42 | "box" : { 43 | "id" : "obj-19", 44 | "maxclass" : "newobj", 45 | "numinlets" : 1, 46 | "numoutlets" : 1, 47 | "outlettype" : [ "" ], 48 | "patching_rect" : [ 592.5, 722.0, 110.0, 22.0 ], 49 | "style" : "", 50 | "text" : "prepend midimode" 51 | } 52 | 53 | } 54 | , { 55 | "box" : { 56 | "id" : "obj-10", 57 | "maxclass" : "newobj", 58 | "numinlets" : 1, 59 | "numoutlets" : 1, 60 | "outlettype" : [ "" ], 61 | "patching_rect" : [ 1644.0, 424.0, 97.0, 22.0 ], 62 | "style" : "", 63 | "text" : "prepend logging" 64 | } 65 | 66 | } 67 | , { 68 | "box" : { 69 | "comment" : "turn logging on/off", 70 | "id" : "obj-9", 71 | "maxclass" : "inlet", 72 | "numinlets" : 0, 73 | "numoutlets" : 1, 74 | "outlettype" : [ "" ], 75 | "patching_rect" : [ 1644.0, 326.0, 30.0, 30.0 ], 76 | "style" : "" 77 | } 78 | 79 | } 80 | , { 81 | "box" : { 82 | "comment" : "unassigned hilite color (rgba)", 83 | "id" : "obj-17", 84 | "maxclass" : "inlet", 85 | "numinlets" : 0, 86 | "numoutlets" : 1, 87 | "outlettype" : [ "" ], 88 | "patching_rect" : [ 1499.0, 326.0, 30.0, 30.0 ], 89 | "style" : "" 90 | } 91 | 92 | } 93 | , { 94 | "box" : { 95 | "comment" : "assigned hilite color (rgba)", 96 | "id" : "obj-15", 97 | "maxclass" : "inlet", 98 | "numinlets" : 0, 99 | "numoutlets" : 1, 100 | "outlettype" : [ "" ], 101 | "patching_rect" : [ 1345.0, 326.0, 30.0, 30.0 ], 102 | "style" : "" 103 | } 104 | 105 | } 106 | , { 107 | "box" : { 108 | "id" : "obj-14", 109 | "maxclass" : "newobj", 110 | "numinlets" : 1, 111 | "numoutlets" : 1, 112 | "outlettype" : [ "" ], 113 | "patching_rect" : [ 1499.0, 1071.0, 145.0, 22.0 ], 114 | "style" : "", 115 | "text" : "prepend unassignedcolor" 116 | } 117 | 118 | } 119 | , { 120 | "box" : { 121 | "id" : "obj-16", 122 | "maxclass" : "newobj", 123 | "numinlets" : 1, 124 | "numoutlets" : 1, 125 | "outlettype" : [ "" ], 126 | "patching_rect" : [ 1345.0, 1071.0, 132.0, 22.0 ], 127 | "style" : "", 128 | "text" : "prepend assignedcolor" 129 | } 130 | 131 | } 132 | , { 133 | "box" : { 134 | "id" : "obj-7", 135 | "maxclass" : "newobj", 136 | "numinlets" : 2, 137 | "numoutlets" : 2, 138 | "outlettype" : [ "", "" ], 139 | "patching_rect" : [ 896.666626, 278.0, 135.0, 22.0 ], 140 | "style" : "", 141 | "text" : "routepass clientlist" 142 | } 143 | 144 | } 145 | , { 146 | "box" : { 147 | "id" : "obj-20", 148 | "maxclass" : "newobj", 149 | "numinlets" : 1, 150 | "numoutlets" : 1, 151 | "outlettype" : [ "" ], 152 | "patching_rect" : [ 951.0, 1025.0, 99.0, 22.0 ], 153 | "style" : "", 154 | "text" : "prepend shiftkey" 155 | } 156 | 157 | } 158 | , { 159 | "box" : { 160 | "id" : "obj-13", 161 | "maxclass" : "newobj", 162 | "numinlets" : 1, 163 | "numoutlets" : 5, 164 | "outlettype" : [ "int", "int", "int", "int", "int" ], 165 | "patching_rect" : [ 951.0, 954.0, 117.0, 22.0 ], 166 | "style" : "", 167 | "text" : "modifiers" 168 | } 169 | 170 | } 171 | , { 172 | "box" : { 173 | "id" : "obj-12", 174 | "maxclass" : "newobj", 175 | "numinlets" : 0, 176 | "numoutlets" : 1, 177 | "outlettype" : [ "" ], 178 | "patching_rect" : [ 951.0, 897.0, 64.0, 22.0 ], 179 | "style" : "", 180 | "text" : "r clicklstnr" 181 | } 182 | 183 | } 184 | , { 185 | "box" : { 186 | "id" : "obj-6", 187 | "maxclass" : "newobj", 188 | "numinlets" : 1, 189 | "numoutlets" : 1, 190 | "outlettype" : [ "" ], 191 | "patching_rect" : [ 130.0, 563.5, 72.0, 22.0 ], 192 | "style" : "", 193 | "text" : "loadmess 1" 194 | } 195 | 196 | } 197 | , { 198 | "box" : { 199 | "id" : "obj-227", 200 | "maxclass" : "newobj", 201 | "numinlets" : 1, 202 | "numoutlets" : 1, 203 | "outlettype" : [ "bang" ], 204 | "patching_rect" : [ 744.5, 428.0, 24.0, 22.0 ], 205 | "style" : "", 206 | "text" : "t b" 207 | } 208 | 209 | } 210 | , { 211 | "box" : { 212 | "id" : "obj-175", 213 | "maxclass" : "newobj", 214 | "numinlets" : 2, 215 | "numoutlets" : 1, 216 | "outlettype" : [ "" ], 217 | "patching_rect" : [ 390.5, 491.0, 56.0, 22.0 ], 218 | "style" : "", 219 | "text" : "gate" 220 | } 221 | 222 | } 223 | , { 224 | "box" : { 225 | "id" : "obj-172", 226 | "maxclass" : "message", 227 | "numinlets" : 2, 228 | "numoutlets" : 1, 229 | "outlettype" : [ "" ], 230 | "patching_rect" : [ 592.5, 595.5, 29.5, 22.0 ], 231 | "style" : "", 232 | "text" : "0" 233 | } 234 | 235 | } 236 | , { 237 | "box" : { 238 | "id" : "obj-170", 239 | "maxclass" : "newobj", 240 | "numinlets" : 2, 241 | "numoutlets" : 2, 242 | "outlettype" : [ "bang", "" ], 243 | "patching_rect" : [ 691.5, 386.0, 52.0, 22.0 ], 244 | "style" : "", 245 | "text" : "select 0" 246 | } 247 | 248 | } 249 | , { 250 | "box" : { 251 | "id" : "obj-87", 252 | "maxclass" : "newobj", 253 | "numinlets" : 0, 254 | "numoutlets" : 1, 255 | "outlettype" : [ "" ], 256 | "patching_rect" : [ 48.0, 1170.0, 57.0, 22.0 ], 257 | "style" : "", 258 | "text" : "r toglstnr" 259 | } 260 | 261 | } 262 | , { 263 | "box" : { 264 | "id" : "obj-452", 265 | "maxclass" : "newobj", 266 | "numinlets" : 1, 267 | "numoutlets" : 1, 268 | "outlettype" : [ "" ], 269 | "patching_rect" : [ 184.75, 736.0, 107.0, 22.0 ], 270 | "style" : "", 271 | "text" : "prepend routemidi" 272 | } 273 | 274 | } 275 | , { 276 | "box" : { 277 | "id" : "obj-196", 278 | "maxclass" : "newobj", 279 | "numinlets" : 2, 280 | "numoutlets" : 1, 281 | "outlettype" : [ "int" ], 282 | "patching_rect" : [ 223.5, 563.5, 29.5, 22.0 ], 283 | "style" : "", 284 | "text" : "+ 1" 285 | } 286 | 287 | } 288 | , { 289 | "box" : { 290 | "id" : "obj-195", 291 | "maxclass" : "newobj", 292 | "numinlets" : 2, 293 | "numoutlets" : 2, 294 | "outlettype" : [ "", "" ], 295 | "patching_rect" : [ 223.5, 621.5, 94.0, 22.0 ], 296 | "style" : "", 297 | "text" : "gate 2", 298 | "varname" : "prepgate" 299 | } 300 | 301 | } 302 | , { 303 | "box" : { 304 | "id" : "obj-75", 305 | "maxclass" : "newobj", 306 | "numinlets" : 1, 307 | "numoutlets" : 1, 308 | "outlettype" : [ "" ], 309 | "patching_rect" : [ 226.5, 1071.0, 105.0, 22.0 ], 310 | "style" : "", 311 | "text" : "prepend ctlassign", 312 | "varname" : "ctlassign" 313 | } 314 | 315 | } 316 | , { 317 | "box" : { 318 | "id" : "obj-173", 319 | "maxclass" : "newobj", 320 | "numinlets" : 1, 321 | "numoutlets" : 1, 322 | "outlettype" : [ "" ], 323 | "patching_rect" : [ 48.0, 1219.0, 129.0, 22.0 ], 324 | "style" : "", 325 | "text" : "prepend togglelistener", 326 | "varname" : "togglelistener" 327 | } 328 | 329 | } 330 | , { 331 | "box" : { 332 | "id" : "obj-164", 333 | "maxclass" : "message", 334 | "numinlets" : 2, 335 | "numoutlets" : 1, 336 | "outlettype" : [ "" ], 337 | "patching_rect" : [ 644.5, 567.0, 29.5, 22.0 ], 338 | "style" : "", 339 | "text" : "1" 340 | } 341 | 342 | } 343 | , { 344 | "box" : { 345 | "id" : "obj-160", 346 | "maxclass" : "newobj", 347 | "numinlets" : 1, 348 | "numoutlets" : 1, 349 | "outlettype" : [ "" ], 350 | "patching_rect" : [ 1079.5, 1190.0, 115.0, 22.0 ], 351 | "style" : "", 352 | "text" : "prepend mididevice" 353 | } 354 | 355 | } 356 | , { 357 | "box" : { 358 | "id" : "obj-156", 359 | "maxclass" : "newobj", 360 | "numinlets" : 2, 361 | "numoutlets" : 2, 362 | "outlettype" : [ "", "" ], 363 | "patching_rect" : [ 1079.5, 1136.333374, 81.0, 22.0 ], 364 | "style" : "", 365 | "text" : "route append" 366 | } 367 | 368 | } 369 | , { 370 | "box" : { 371 | "id" : "obj-155", 372 | "maxclass" : "message", 373 | "numinlets" : 2, 374 | "numoutlets" : 1, 375 | "outlettype" : [ "" ], 376 | "patching_rect" : [ 1076.5, 611.0, 66.0, 22.0 ], 377 | "style" : "", 378 | "text" : "controllers" 379 | } 380 | 381 | } 382 | , { 383 | "box" : { 384 | "id" : "obj-149", 385 | "maxclass" : "newobj", 386 | "numinlets" : 2, 387 | "numoutlets" : 1, 388 | "outlettype" : [ "" ], 389 | "patching_rect" : [ 1079.5, 1071.0, 114.0, 22.0 ], 390 | "style" : "", 391 | "text" : "midiinfo" 392 | } 393 | 394 | } 395 | , { 396 | "box" : { 397 | "id" : "obj-111", 398 | "maxclass" : "message", 399 | "numinlets" : 2, 400 | "numoutlets" : 1, 401 | "outlettype" : [ "" ], 402 | "patching_rect" : [ 823.666626, 514.0, 29.5, 22.0 ], 403 | "style" : "", 404 | "text" : "init" 405 | } 406 | 407 | } 408 | , { 409 | "box" : { 410 | "id" : "obj-8", 411 | "maxclass" : "number", 412 | "numinlets" : 1, 413 | "numoutlets" : 2, 414 | "outlettype" : [ "", "bang" ], 415 | "parameter_enable" : 0, 416 | "patching_rect" : [ 390.5, 563.5, 50.0, 22.0 ], 417 | "style" : "" 418 | } 419 | 420 | } 421 | , { 422 | "box" : { 423 | "id" : "obj-102", 424 | "maxclass" : "newobj", 425 | "numinlets" : 1, 426 | "numoutlets" : 1, 427 | "outlettype" : [ "" ], 428 | "patching_rect" : [ 393.5, 1071.0, 115.0, 22.0 ], 429 | "style" : "", 430 | "text" : "prepend learnmode" 431 | } 432 | 433 | } 434 | , { 435 | "box" : { 436 | "id" : "obj-18", 437 | "maxclass" : "newobj", 438 | "numinlets" : 1, 439 | "numoutlets" : 3, 440 | "outlettype" : [ "bang", "bang", "bang" ], 441 | "patching_rect" : [ 749.5, 461.0, 44.0, 22.0 ], 442 | "style" : "", 443 | "text" : "t b b b" 444 | } 445 | 446 | } 447 | , { 448 | "box" : { 449 | "id" : "obj-11", 450 | "maxclass" : "message", 451 | "numinlets" : 2, 452 | "numoutlets" : 1, 453 | "outlettype" : [ "" ], 454 | "patching_rect" : [ 1266.0, 614.0, 70.0, 22.0 ], 455 | "style" : "", 456 | "text" : "getclientlist" 457 | } 458 | 459 | } 460 | , { 461 | "box" : { 462 | "id" : "obj-5", 463 | "maxclass" : "newobj", 464 | "numinlets" : 1, 465 | "numoutlets" : 1, 466 | "outlettype" : [ "" ], 467 | "patching_rect" : [ 830.666626, 1435.166748, 83.0, 22.0 ], 468 | "saved_object_attributes" : { 469 | "filename" : "midilearn.js", 470 | "parameter_enable" : 0 471 | } 472 | , 473 | "style" : "", 474 | "text" : "js midilearn.js" 475 | } 476 | 477 | } 478 | , { 479 | "box" : { 480 | "comment" : "midi enable (0/1)", 481 | "id" : "obj-1", 482 | "maxclass" : "inlet", 483 | "numinlets" : 0, 484 | "numoutlets" : 1, 485 | "outlettype" : [ "int" ], 486 | "patching_rect" : [ 537.0, 40.0, 30.0, 30.0 ], 487 | "style" : "" 488 | } 489 | 490 | } 491 | , { 492 | "box" : { 493 | "comment" : "midi learn mode on/off (0/1)", 494 | "id" : "obj-2", 495 | "maxclass" : "inlet", 496 | "numinlets" : 0, 497 | "numoutlets" : 1, 498 | "outlettype" : [ "int" ], 499 | "patching_rect" : [ 429.5, 40.0, 30.0, 30.0 ], 500 | "style" : "" 501 | } 502 | 503 | } 504 | , { 505 | "box" : { 506 | "comment" : "pattrstorage output", 507 | "id" : "obj-3", 508 | "maxclass" : "inlet", 509 | "numinlets" : 0, 510 | "numoutlets" : 1, 511 | "outlettype" : [ "" ], 512 | "patching_rect" : [ 896.666626, 40.0, 30.0, 30.0 ], 513 | "style" : "" 514 | } 515 | 516 | } 517 | , { 518 | "box" : { 519 | "comment" : "pattrstorage input", 520 | "id" : "obj-4", 521 | "maxclass" : "outlet", 522 | "numinlets" : 1, 523 | "numoutlets" : 0, 524 | "patching_rect" : [ 1266.0, 1517.166748, 30.0, 30.0 ], 525 | "style" : "" 526 | } 527 | 528 | } 529 | ], 530 | "lines" : [ { 531 | "patchline" : { 532 | "destination" : [ "obj-170", 0 ], 533 | "disabled" : 0, 534 | "hidden" : 0, 535 | "midpoints" : [ 546.5, 333.5, 701.0, 333.5 ], 536 | "source" : [ "obj-1", 0 ] 537 | } 538 | 539 | } 540 | , { 541 | "patchline" : { 542 | "destination" : [ "obj-175", 0 ], 543 | "disabled" : 0, 544 | "hidden" : 0, 545 | "midpoints" : [ 546.5, 330.0, 400.0, 330.0 ], 546 | "source" : [ "obj-1", 0 ] 547 | } 548 | 549 | } 550 | , { 551 | "patchline" : { 552 | "destination" : [ "obj-5", 0 ], 553 | "disabled" : 0, 554 | "hidden" : 0, 555 | "midpoints" : [ 1653.5, 1318.0, 840.166626, 1318.0 ], 556 | "source" : [ "obj-10", 0 ] 557 | } 558 | 559 | } 560 | , { 561 | "patchline" : { 562 | "destination" : [ "obj-5", 0 ], 563 | "disabled" : 0, 564 | "hidden" : 0, 565 | "midpoints" : [ 403.0, 1308.083344, 840.166626, 1308.083344 ], 566 | "source" : [ "obj-102", 0 ] 567 | } 568 | 569 | } 570 | , { 571 | "patchline" : { 572 | "destination" : [ "obj-4", 0 ], 573 | "disabled" : 0, 574 | "hidden" : 0, 575 | "source" : [ "obj-11", 0 ] 576 | } 577 | 578 | } 579 | , { 580 | "patchline" : { 581 | "destination" : [ "obj-5", 0 ], 582 | "disabled" : 0, 583 | "hidden" : 0, 584 | "source" : [ "obj-111", 0 ] 585 | } 586 | 587 | } 588 | , { 589 | "patchline" : { 590 | "destination" : [ "obj-13", 0 ], 591 | "disabled" : 0, 592 | "hidden" : 0, 593 | "source" : [ "obj-12", 0 ] 594 | } 595 | 596 | } 597 | , { 598 | "patchline" : { 599 | "destination" : [ "obj-20", 0 ], 600 | "disabled" : 0, 601 | "hidden" : 0, 602 | "source" : [ "obj-13", 0 ] 603 | } 604 | 605 | } 606 | , { 607 | "patchline" : { 608 | "destination" : [ "obj-5", 0 ], 609 | "disabled" : 0, 610 | "hidden" : 0, 611 | "midpoints" : [ 1508.5, 1263.583374, 840.166626, 1263.583374 ], 612 | "source" : [ "obj-14", 0 ] 613 | } 614 | 615 | } 616 | , { 617 | "patchline" : { 618 | "destination" : [ "obj-156", 0 ], 619 | "disabled" : 0, 620 | "hidden" : 0, 621 | "source" : [ "obj-149", 0 ] 622 | } 623 | 624 | } 625 | , { 626 | "patchline" : { 627 | "destination" : [ "obj-16", 0 ], 628 | "disabled" : 0, 629 | "hidden" : 0, 630 | "source" : [ "obj-15", 0 ] 631 | } 632 | 633 | } 634 | , { 635 | "patchline" : { 636 | "destination" : [ "obj-149", 0 ], 637 | "disabled" : 0, 638 | "hidden" : 0, 639 | "source" : [ "obj-155", 0 ] 640 | } 641 | 642 | } 643 | , { 644 | "patchline" : { 645 | "destination" : [ "obj-160", 0 ], 646 | "disabled" : 0, 647 | "hidden" : 0, 648 | "source" : [ "obj-156", 0 ] 649 | } 650 | 651 | } 652 | , { 653 | "patchline" : { 654 | "destination" : [ "obj-5", 0 ], 655 | "disabled" : 0, 656 | "hidden" : 0, 657 | "midpoints" : [ 1354.5, 1263.583374, 840.166626, 1263.583374 ], 658 | "source" : [ "obj-16", 0 ] 659 | } 660 | 661 | } 662 | , { 663 | "patchline" : { 664 | "destination" : [ "obj-5", 0 ], 665 | "disabled" : 0, 666 | "hidden" : 0, 667 | "midpoints" : [ 1089.0, 1231.0, 840.166626, 1231.0 ], 668 | "source" : [ "obj-160", 0 ] 669 | } 670 | 671 | } 672 | , { 673 | "patchline" : { 674 | "destination" : [ "obj-19", 0 ], 675 | "disabled" : 0, 676 | "hidden" : 0, 677 | "midpoints" : [ 654.0, 661.0, 602.0, 661.0 ], 678 | "source" : [ "obj-164", 0 ] 679 | } 680 | 681 | } 682 | , { 683 | "patchline" : { 684 | "destination" : [ "obj-14", 0 ], 685 | "disabled" : 0, 686 | "hidden" : 0, 687 | "source" : [ "obj-17", 0 ] 688 | } 689 | 690 | } 691 | , { 692 | "patchline" : { 693 | "destination" : [ "obj-172", 0 ], 694 | "disabled" : 0, 695 | "hidden" : 0, 696 | "midpoints" : [ 701.0, 498.0, 602.0, 498.0 ], 697 | "source" : [ "obj-170", 0 ] 698 | } 699 | 700 | } 701 | , { 702 | "patchline" : { 703 | "destination" : [ "obj-227", 0 ], 704 | "disabled" : 0, 705 | "hidden" : 0, 706 | "source" : [ "obj-170", 1 ] 707 | } 708 | 709 | } 710 | , { 711 | "patchline" : { 712 | "destination" : [ "obj-19", 0 ], 713 | "disabled" : 0, 714 | "hidden" : 0, 715 | "source" : [ "obj-172", 0 ] 716 | } 717 | 718 | } 719 | , { 720 | "patchline" : { 721 | "destination" : [ "obj-5", 0 ], 722 | "disabled" : 0, 723 | "hidden" : 0, 724 | "midpoints" : [ 57.5, 1385.0, 840.166626, 1385.0 ], 725 | "source" : [ "obj-173", 0 ] 726 | } 727 | 728 | } 729 | , { 730 | "patchline" : { 731 | "destination" : [ "obj-8", 0 ], 732 | "disabled" : 0, 733 | "hidden" : 0, 734 | "source" : [ "obj-175", 0 ] 735 | } 736 | 737 | } 738 | , { 739 | "patchline" : { 740 | "destination" : [ "obj-11", 0 ], 741 | "disabled" : 0, 742 | "hidden" : 0, 743 | "midpoints" : [ 771.5, 585.0, 1275.5, 585.0 ], 744 | "source" : [ "obj-18", 1 ] 745 | } 746 | 747 | } 748 | , { 749 | "patchline" : { 750 | "destination" : [ "obj-111", 0 ], 751 | "disabled" : 0, 752 | "hidden" : 0, 753 | "source" : [ "obj-18", 2 ] 754 | } 755 | 756 | } 757 | , { 758 | "patchline" : { 759 | "destination" : [ "obj-155", 0 ], 760 | "disabled" : 0, 761 | "hidden" : 0, 762 | "midpoints" : [ 759.0, 542.0, 1086.0, 542.0 ], 763 | "source" : [ "obj-18", 0 ] 764 | } 765 | 766 | } 767 | , { 768 | "patchline" : { 769 | "destination" : [ "obj-164", 0 ], 770 | "disabled" : 0, 771 | "hidden" : 0, 772 | "midpoints" : [ 759.0, 522.0, 654.0, 522.0 ], 773 | "source" : [ "obj-18", 0 ] 774 | } 775 | 776 | } 777 | , { 778 | "patchline" : { 779 | "destination" : [ "obj-5", 0 ], 780 | "disabled" : 0, 781 | "hidden" : 0, 782 | "midpoints" : [ 602.0, 1231.0, 840.166626, 1231.0 ], 783 | "source" : [ "obj-19", 0 ] 784 | } 785 | 786 | } 787 | , { 788 | "patchline" : { 789 | "destination" : [ "obj-452", 0 ], 790 | "disabled" : 0, 791 | "hidden" : 0, 792 | "midpoints" : [ 233.0, 689.25, 194.25, 689.25 ], 793 | "source" : [ "obj-195", 0 ] 794 | } 795 | 796 | } 797 | , { 798 | "patchline" : { 799 | "destination" : [ "obj-75", 0 ], 800 | "disabled" : 0, 801 | "hidden" : 0, 802 | "midpoints" : [ 308.0, 1020.75, 236.0, 1020.75 ], 803 | "source" : [ "obj-195", 1 ] 804 | } 805 | 806 | } 807 | , { 808 | "patchline" : { 809 | "destination" : [ "obj-195", 0 ], 810 | "disabled" : 0, 811 | "hidden" : 0, 812 | "source" : [ "obj-196", 0 ] 813 | } 814 | 815 | } 816 | , { 817 | "patchline" : { 818 | "destination" : [ "obj-175", 1 ], 819 | "disabled" : 0, 820 | "hidden" : 0, 821 | "source" : [ "obj-2", 0 ] 822 | } 823 | 824 | } 825 | , { 826 | "patchline" : { 827 | "destination" : [ "obj-5", 0 ], 828 | "disabled" : 0, 829 | "hidden" : 0, 830 | "midpoints" : [ 960.5, 1361.0, 840.166626, 1361.0 ], 831 | "source" : [ "obj-20", 0 ] 832 | } 833 | 834 | } 835 | , { 836 | "patchline" : { 837 | "destination" : [ "obj-18", 0 ], 838 | "disabled" : 0, 839 | "hidden" : 0, 840 | "source" : [ "obj-227", 0 ] 841 | } 842 | 843 | } 844 | , { 845 | "patchline" : { 846 | "destination" : [ "obj-7", 0 ], 847 | "disabled" : 0, 848 | "hidden" : 0, 849 | "source" : [ "obj-3", 0 ] 850 | } 851 | 852 | } 853 | , { 854 | "patchline" : { 855 | "destination" : [ "obj-5", 0 ], 856 | "disabled" : 0, 857 | "hidden" : 0, 858 | "midpoints" : [ 194.25, 1385.0, 840.166626, 1385.0 ], 859 | "source" : [ "obj-452", 0 ] 860 | } 861 | 862 | } 863 | , { 864 | "patchline" : { 865 | "destination" : [ "obj-195", 0 ], 866 | "disabled" : 0, 867 | "hidden" : 0, 868 | "midpoints" : [ 139.5, 606.25, 233.0, 606.25 ], 869 | "source" : [ "obj-6", 0 ] 870 | } 871 | 872 | } 873 | , { 874 | "patchline" : { 875 | "destination" : [ "obj-5", 0 ], 876 | "disabled" : 0, 877 | "hidden" : 0, 878 | "midpoints" : [ 906.166626, 867.083374, 840.166626, 867.083374 ], 879 | "source" : [ "obj-7", 0 ] 880 | } 881 | 882 | } 883 | , { 884 | "patchline" : { 885 | "destination" : [ "obj-5", 0 ], 886 | "disabled" : 0, 887 | "hidden" : 0, 888 | "midpoints" : [ 236.0, 1343.0, 840.166626, 1343.0 ], 889 | "source" : [ "obj-75", 0 ] 890 | } 891 | 892 | } 893 | , { 894 | "patchline" : { 895 | "destination" : [ "obj-102", 0 ], 896 | "disabled" : 0, 897 | "hidden" : 0, 898 | "source" : [ "obj-8", 0 ] 899 | } 900 | 901 | } 902 | , { 903 | "patchline" : { 904 | "destination" : [ "obj-196", 0 ], 905 | "disabled" : 0, 906 | "hidden" : 0, 907 | "midpoints" : [ 400.0, 609.0, 357.5, 609.0, 357.5, 547.0, 233.0, 547.0 ], 908 | "source" : [ "obj-8", 0 ] 909 | } 910 | 911 | } 912 | , { 913 | "patchline" : { 914 | "destination" : [ "obj-173", 0 ], 915 | "disabled" : 0, 916 | "hidden" : 0, 917 | "source" : [ "obj-87", 0 ] 918 | } 919 | 920 | } 921 | , { 922 | "patchline" : { 923 | "destination" : [ "obj-10", 0 ], 924 | "disabled" : 0, 925 | "hidden" : 0, 926 | "source" : [ "obj-9", 0 ] 927 | } 928 | 929 | } 930 | ], 931 | "styles" : [ { 932 | "name" : "dark-night-patch", 933 | "default" : { 934 | "bgfillcolor" : { 935 | "type" : "gradient", 936 | "color1" : [ 0.376471, 0.384314, 0.4, 1.0 ], 937 | "color2" : [ 0.290196, 0.309804, 0.301961, 1.0 ], 938 | "color" : [ 0.290196, 0.309804, 0.301961, 1.0 ], 939 | "angle" : 270.0, 940 | "proportion" : 0.39 941 | } 942 | , 943 | "textcolor" : [ 0.862745, 0.870588, 0.878431, 1.0 ], 944 | "patchlinecolor" : [ 0.439216, 0.74902, 0.254902, 0.898039 ], 945 | "accentcolor" : [ 0.952941, 0.564706, 0.098039, 1.0 ] 946 | } 947 | , 948 | "parentstyle" : "", 949 | "multi" : 0 950 | } 951 | ] 952 | } 953 | 954 | } 955 | -------------------------------------------------------------------------------- /patchers/max-midi-learn.maxpat: -------------------------------------------------------------------------------- 1 | { 2 | "patcher" : { 3 | "fileversion" : 1, 4 | "appversion" : { 5 | "major" : 7, 6 | "minor" : 0, 7 | "revision" : 1, 8 | "architecture" : "x64", 9 | "modernui" : 1 10 | } 11 | , 12 | "openrect" : [ 348.0, 79.0, 1059.0, 644.0 ], 13 | "bgcolor" : [ 0.095481, 0.100396, 0.100293, 1.0 ], 14 | "editing_bgcolor" : [ 0.095481, 0.100396, 0.100293, 1.0 ], 15 | "bglocked" : 0, 16 | "openinpresentation" : 1, 17 | "default_fontsize" : 12.0, 18 | "default_fontface" : 0, 19 | "default_fontname" : "Arial", 20 | "gridonopen" : 1, 21 | "gridsize" : [ 15.0, 15.0 ], 22 | "gridsnaponopen" : 1, 23 | "objectsnaponopen" : 1, 24 | "statusbarvisible" : 2, 25 | "toolbarvisible" : 1, 26 | "lefttoolbarpinned" : 0, 27 | "toptoolbarpinned" : 0, 28 | "righttoolbarpinned" : 0, 29 | "bottomtoolbarpinned" : 0, 30 | "toolbars_unpinned_last_save" : 0, 31 | "tallnewobj" : 0, 32 | "boxanimatetime" : 200, 33 | "enablehscroll" : 1, 34 | "enablevscroll" : 1, 35 | "devicewidth" : 1059.0, 36 | "description" : "", 37 | "digest" : "", 38 | "tags" : "", 39 | "style" : "", 40 | "subpatcher_template" : "bigpatcher", 41 | "boxes" : [ { 42 | "box" : { 43 | "id" : "obj-21", 44 | "maxclass" : "comment", 45 | "numinlets" : 1, 46 | "numoutlets" : 0, 47 | "patching_rect" : [ 1173.199951, 127.0, 105.0, 20.0 ], 48 | "presentation" : 1, 49 | "presentation_rect" : [ 878.75, 482.166626, 118.5, 20.0 ], 50 | "style" : "", 51 | "text" : "auto scaling", 52 | "textjustification" : 1 53 | } 54 | 55 | } 56 | , { 57 | "box" : { 58 | "format" : 6, 59 | "id" : "obj-335", 60 | "maxclass" : "flonum", 61 | "numinlets" : 1, 62 | "numoutlets" : 2, 63 | "outlettype" : [ "", "bang" ], 64 | "parameter_enable" : 0, 65 | "patching_rect" : [ 1060.0, 226.0, 50.0, 22.0 ], 66 | "presentation" : 1, 67 | "presentation_rect" : [ 913.0, 572.833374, 50.0, 22.0 ], 68 | "style" : "" 69 | } 70 | 71 | } 72 | , { 73 | "box" : { 74 | "clip" : 0, 75 | "floatoutput" : 1, 76 | "id" : "obj-58", 77 | "maxclass" : "dial", 78 | "numinlets" : 1, 79 | "numoutlets" : 1, 80 | "outlettype" : [ "float" ], 81 | "parameter_enable" : 0, 82 | "patching_rect" : [ 1060.0, 139.0, 40.0, 40.0 ], 83 | "presentation" : 1, 84 | "presentation_rect" : [ 918.0, 510.291626, 40.0, 40.0 ], 85 | "size" : 4.0, 86 | "style" : "", 87 | "varname" : "dialobj" 88 | } 89 | 90 | } 91 | , { 92 | "box" : { 93 | "angle" : 270.0, 94 | "bgcolor" : [ 0.290196, 0.309804, 0.301961, 0.0 ], 95 | "border" : 1, 96 | "bordercolor" : [ 1.0, 1.0, 1.0, 0.14902 ], 97 | "id" : "obj-20", 98 | "maxclass" : "panel", 99 | "mode" : 0, 100 | "numinlets" : 1, 101 | "numoutlets" : 0, 102 | "patching_rect" : [ 171.0, 701.0, 128.0, 128.0 ], 103 | "presentation" : 1, 104 | "presentation_rect" : [ 878.75, 473.833374, 118.5, 91.0 ], 105 | "proportion" : 0.39, 106 | "style" : "" 107 | } 108 | 109 | } 110 | , { 111 | "box" : { 112 | "id" : "obj-19", 113 | "maxclass" : "comment", 114 | "numinlets" : 1, 115 | "numoutlets" : 0, 116 | "patching_rect" : [ 1158.199951, 112.0, 105.0, 20.0 ], 117 | "presentation" : 1, 118 | "presentation_rect" : [ 404.75, 482.166626, 127.0, 20.0 ], 119 | "style" : "", 120 | "text" : "top level controls", 121 | "textjustification" : 1 122 | } 123 | 124 | } 125 | , { 126 | "box" : { 127 | "angle" : 270.0, 128 | "bgcolor" : [ 0.290196, 0.309804, 0.301961, 0.0 ], 129 | "border" : 1, 130 | "bordercolor" : [ 1.0, 1.0, 1.0, 0.14902 ], 131 | "id" : "obj-18", 132 | "maxclass" : "panel", 133 | "mode" : 0, 134 | "numinlets" : 1, 135 | "numoutlets" : 0, 136 | "patching_rect" : [ 171.0, 701.0, 128.0, 128.0 ], 137 | "presentation" : 1, 138 | "presentation_rect" : [ 231.0, 473.833374, 424.0, 91.0 ], 139 | "proportion" : 0.39, 140 | "style" : "" 141 | } 142 | 143 | } 144 | , { 145 | "box" : { 146 | "fontsize" : 16.0, 147 | "id" : "obj-15", 148 | "maxclass" : "comment", 149 | "numinlets" : 1, 150 | "numoutlets" : 0, 151 | "patching_rect" : [ 1029.0, 724.0, 112.0, 24.0 ], 152 | "presentation" : 1, 153 | "presentation_rect" : [ 67.5, 325.833374, 82.0, 24.0 ], 154 | "style" : "", 155 | "text" : "Try it out!" 156 | } 157 | 158 | } 159 | , { 160 | "box" : { 161 | "bgcolor" : [ 1.0, 0.788235, 0.470588, 1.0 ], 162 | "fontname" : "Arial Bold", 163 | "hint" : "", 164 | "id" : "obj-12", 165 | "ignoreclick" : 1, 166 | "legacytextcolor" : 1, 167 | "maxclass" : "textbutton", 168 | "numinlets" : 1, 169 | "numoutlets" : 3, 170 | "outlettype" : [ "", "", "int" ], 171 | "parameter_enable" : 0, 172 | "patching_rect" : [ 421.366638, 794.0, 20.0, 20.0 ], 173 | "presentation" : 1, 174 | "presentation_rect" : [ 26.0, 325.833374, 20.0, 20.0 ], 175 | "rounded" : 60.0, 176 | "style" : "", 177 | "text" : "3", 178 | "textcolor" : [ 0.34902, 0.34902, 0.34902, 1.0 ] 179 | } 180 | 181 | } 182 | , { 183 | "box" : { 184 | "id" : "obj-11", 185 | "linecount" : 2, 186 | "maxclass" : "comment", 187 | "numinlets" : 1, 188 | "numoutlets" : 0, 189 | "patching_rect" : [ 1139.0, 38.0, 150.0, 33.0 ], 190 | "style" : "", 191 | "text" : "example controls connected to pattr system" 192 | } 193 | 194 | } 195 | , { 196 | "box" : { 197 | "id" : "obj-8", 198 | "maxclass" : "comment", 199 | "numinlets" : 1, 200 | "numoutlets" : 0, 201 | "patching_rect" : [ 566.166626, 459.0, 142.0, 20.0 ], 202 | "style" : "", 203 | "text" : "turn logging on/off" 204 | } 205 | 206 | } 207 | , { 208 | "box" : { 209 | "id" : "obj-7", 210 | "maxclass" : "newobj", 211 | "numinlets" : 1, 212 | "numoutlets" : 1, 213 | "outlettype" : [ "bang" ], 214 | "patching_rect" : [ 601.166626, 281.0, 60.0, 22.0 ], 215 | "style" : "", 216 | "text" : "loadbang" 217 | } 218 | 219 | } 220 | , { 221 | "box" : { 222 | "id" : "obj-2", 223 | "maxclass" : "newobj", 224 | "numinlets" : 1, 225 | "numoutlets" : 1, 226 | "outlettype" : [ "" ], 227 | "patching_rect" : [ 396.0, 95.0, 72.0, 22.0 ], 228 | "style" : "", 229 | "text" : "loadmess 0" 230 | } 231 | 232 | } 233 | , { 234 | "box" : { 235 | "id" : "obj-1", 236 | "maxclass" : "newobj", 237 | "numinlets" : 1, 238 | "numoutlets" : 1, 239 | "outlettype" : [ "" ], 240 | "patching_rect" : [ 483.0, 459.0, 72.0, 22.0 ], 241 | "style" : "", 242 | "text" : "loadmess 0" 243 | } 244 | 245 | } 246 | , { 247 | "box" : { 248 | "fontsize" : 14.0, 249 | "id" : "obj-57", 250 | "linecount" : 13, 251 | "maxclass" : "comment", 252 | "numinlets" : 1, 253 | "numoutlets" : 0, 254 | "patching_rect" : [ 472.0, 729.0, 354.0, 210.0 ], 255 | "presentation" : 1, 256 | "presentation_linecount" : 6, 257 | "presentation_rect" : [ 231.0, 323.833374, 712.0, 100.0 ], 258 | "style" : "", 259 | "text" : "Any control which is part of the pattr system is automatically added to the midi-learn system\n - with midi learn mode on, click on any of the controls below with your mouse\n - a pink hilited control is a control that currently is not assigned\n - a green hilited control is a control that is currently assigned to a controller\n - with a control hilited, simply twiddle a knob on any of your midi controllers to assign that controller to the object\n - turn midi learn mode off to start using the assigned controls", 260 | "textcolor" : [ 0.65098, 0.666667, 0.662745, 1.0 ] 261 | } 262 | 263 | } 264 | , { 265 | "box" : { 266 | "angle" : 270.0, 267 | "bgcolor" : [ 0.290196, 0.309804, 0.301961, 0.0 ], 268 | "border" : 1, 269 | "bordercolor" : [ 1.0, 1.0, 1.0, 0.14902 ], 270 | "id" : "obj-55", 271 | "maxclass" : "panel", 272 | "mode" : 0, 273 | "numinlets" : 1, 274 | "numoutlets" : 0, 275 | "patching_rect" : [ 171.0, 701.0, 128.0, 128.0 ], 276 | "presentation" : 1, 277 | "presentation_rect" : [ 770.25, 473.833374, 101.5, 91.0 ], 278 | "proportion" : 0.39, 279 | "style" : "" 280 | } 281 | 282 | } 283 | , { 284 | "box" : { 285 | "id" : "obj-54", 286 | "maxclass" : "comment", 287 | "numinlets" : 1, 288 | "numoutlets" : 0, 289 | "patching_rect" : [ 1274.0, 97.0, 116.0, 20.0 ], 290 | "presentation" : 1, 291 | "presentation_rect" : [ 776.5, 482.166626, 89.0, 20.0 ], 292 | "style" : "", 293 | "text" : "2 levels deep", 294 | "textjustification" : 1 295 | } 296 | 297 | } 298 | , { 299 | "box" : { 300 | "id" : "obj-53", 301 | "maxclass" : "comment", 302 | "numinlets" : 1, 303 | "numoutlets" : 0, 304 | "patching_rect" : [ 1143.199951, 97.0, 105.0, 20.0 ], 305 | "presentation" : 1, 306 | "presentation_rect" : [ 667.75, 482.166626, 89.0, 20.0 ], 307 | "style" : "", 308 | "text" : "1 level deep", 309 | "textjustification" : 1 310 | } 311 | 312 | } 313 | , { 314 | "box" : { 315 | "angle" : 270.0, 316 | "bgcolor" : [ 0.290196, 0.309804, 0.301961, 0.0 ], 317 | "border" : 1, 318 | "bordercolor" : [ 1.0, 1.0, 1.0, 0.14902 ], 319 | "id" : "obj-50", 320 | "maxclass" : "panel", 321 | "mode" : 0, 322 | "numinlets" : 1, 323 | "numoutlets" : 0, 324 | "patching_rect" : [ 156.0, 686.0, 128.0, 128.0 ], 325 | "presentation" : 1, 326 | "presentation_rect" : [ 661.5, 473.833374, 101.5, 91.0 ], 327 | "proportion" : 0.39, 328 | "style" : "" 329 | } 330 | 331 | } 332 | , { 333 | "box" : { 334 | "activedialcolor" : [ 0.317647, 0.654902, 0.976471, 1.0 ], 335 | "activeneedlecolor" : [ 0.65098, 0.666667, 0.662745, 1.0 ], 336 | "focusbordercolor" : [ 0.960784, 0.827451, 0.156863, 1.0 ], 337 | "fontface" : 0, 338 | "fontsize" : 9.0, 339 | "id" : "obj-48", 340 | "maxclass" : "live.dial", 341 | "numinlets" : 1, 342 | "numoutlets" : 2, 343 | "outlettype" : [ "", "float" ], 344 | "parameter_enable" : 1, 345 | "patching_rect" : [ 1151.699951, 314.583313, 34.0, 27.0 ], 346 | "presentation" : 1, 347 | "presentation_rect" : [ 437.0, 514.416626, 34.0, 27.0 ], 348 | "saved_attribute_attributes" : { 349 | "valueof" : { 350 | "parameter_longname" : "scale1[6]", 351 | "parameter_shortname" : "phase mod", 352 | "parameter_type" : 0, 353 | "parameter_mmin" : -1.0, 354 | "parameter_mmax" : 1.0, 355 | "parameter_modmode" : 1, 356 | "parameter_initial_enable" : 1, 357 | "parameter_initial" : [ 0.0 ], 358 | "parameter_unitstyle" : 1 359 | } 360 | 361 | } 362 | , 363 | "showname" : 0, 364 | "shownumber" : 0, 365 | "textcolor" : [ 0.862745, 0.870588, 0.878431, 1.0 ], 366 | "tribordercolor" : [ 0.701961, 0.415686, 0.886275, 1.0 ], 367 | "varname" : "obj8" 368 | } 369 | 370 | } 371 | , { 372 | "box" : { 373 | "activedialcolor" : [ 0.317647, 0.654902, 0.976471, 1.0 ], 374 | "activeneedlecolor" : [ 0.65098, 0.666667, 0.662745, 1.0 ], 375 | "focusbordercolor" : [ 0.960784, 0.827451, 0.156863, 1.0 ], 376 | "fontface" : 0, 377 | "fontsize" : 9.0, 378 | "id" : "obj-47", 379 | "maxclass" : "live.dial", 380 | "numinlets" : 1, 381 | "numoutlets" : 2, 382 | "outlettype" : [ "", "float" ], 383 | "parameter_enable" : 1, 384 | "patching_rect" : [ 1243.133301, 314.583313, 34.0, 27.0 ], 385 | "presentation" : 1, 386 | "presentation_rect" : [ 385.0, 514.416626, 34.0, 27.0 ], 387 | "saved_attribute_attributes" : { 388 | "valueof" : { 389 | "parameter_longname" : "scale1[3]", 390 | "parameter_shortname" : "phase mod", 391 | "parameter_type" : 0, 392 | "parameter_mmin" : -1.0, 393 | "parameter_mmax" : 1.0, 394 | "parameter_modmode" : 1, 395 | "parameter_initial_enable" : 1, 396 | "parameter_initial" : [ 0.0 ], 397 | "parameter_unitstyle" : 1 398 | } 399 | 400 | } 401 | , 402 | "showname" : 0, 403 | "shownumber" : 0, 404 | "textcolor" : [ 0.862745, 0.870588, 0.878431, 1.0 ], 405 | "tribordercolor" : [ 0.701961, 0.415686, 0.886275, 1.0 ], 406 | "varname" : "obj7" 407 | } 408 | 409 | } 410 | , { 411 | "box" : { 412 | "id" : "obj-255", 413 | "maxclass" : "newobj", 414 | "numinlets" : 1, 415 | "numoutlets" : 1, 416 | "outlettype" : [ "bang" ], 417 | "patching_rect" : [ 427.400024, 281.0, 60.0, 22.0 ], 418 | "style" : "", 419 | "text" : "loadbang" 420 | } 421 | 422 | } 423 | , { 424 | "box" : { 425 | "id" : "obj-254", 426 | "maxclass" : "comment", 427 | "numinlets" : 1, 428 | "numoutlets" : 0, 429 | "patching_rect" : [ 631.166626, 321.0, 142.0, 20.0 ], 430 | "style" : "", 431 | "text" : "unassigned hilite color" 432 | } 433 | 434 | } 435 | , { 436 | "box" : { 437 | "id" : "obj-253", 438 | "maxclass" : "comment", 439 | "numinlets" : 1, 440 | "numoutlets" : 0, 441 | "patching_rect" : [ 450.400024, 321.0, 127.0, 20.0 ], 442 | "style" : "", 443 | "text" : "assigned hilite color" 444 | } 445 | 446 | } 447 | , { 448 | "box" : { 449 | "id" : "obj-251", 450 | "maxclass" : "message", 451 | "numinlets" : 2, 452 | "numoutlets" : 1, 453 | "outlettype" : [ "" ], 454 | "patching_rect" : [ 601.166626, 350.0, 147.0, 22.0 ], 455 | "style" : "", 456 | "text" : "1. 0.023504 0.64687 0.55" 457 | } 458 | 459 | } 460 | , { 461 | "box" : { 462 | "id" : "obj-250", 463 | "maxclass" : "message", 464 | "numinlets" : 2, 465 | "numoutlets" : 1, 466 | "outlettype" : [ "" ], 467 | "patching_rect" : [ 427.400024, 350.0, 154.0, 22.0 ], 468 | "style" : "", 469 | "text" : "0.590803 1. 0.102193 0.65" 470 | } 471 | 472 | } 473 | , { 474 | "box" : { 475 | "fontsize" : 14.0, 476 | "id" : "obj-247", 477 | "linecount" : 9, 478 | "maxclass" : "comment", 479 | "numinlets" : 1, 480 | "numoutlets" : 0, 481 | "patching_rect" : [ 456.0, 769.0, 727.0, 147.0 ], 482 | "presentation" : 1, 483 | "presentation_linecount" : 9, 484 | "presentation_rect" : [ 231.0, 104.833374, 715.0, 147.0 ], 485 | "style" : "", 486 | "text" : "Turns midi learn mode on/off\n - midi must be enabled (step 1) for this to have any effect\n - click on an object to arm the object for midi learn\n - if the object is hilited pink, it does not currently have any controller assignment\n - if the object is hilited green, it is currently assigned to one or more controllers\n - shift-click on a green hilited object to remove all controller assignments\n - objects can be controlled by multiple midi controls\n - a single midi control can control multiple objects\n - midi controller assignments are persisted through two json files: \"controllist.json\" and \"midimap.json\"", 487 | "textcolor" : [ 0.65098, 0.666667, 0.662745, 1.0 ] 488 | } 489 | 490 | } 491 | , { 492 | "box" : { 493 | "fontsize" : 16.0, 494 | "id" : "obj-246", 495 | "linecount" : 3, 496 | "maxclass" : "comment", 497 | "numinlets" : 1, 498 | "numoutlets" : 0, 499 | "patching_rect" : [ 457.0, 714.0, 355.0, 60.0 ], 500 | "presentation" : 1, 501 | "presentation_linecount" : 2, 502 | "presentation_rect" : [ 231.0, 20.833374, 491.0, 42.0 ], 503 | "style" : "", 504 | "text" : "Turns midi on/off \n - midi must be enabled prior to any control input being analyzed", 505 | "textcolor" : [ 0.65098, 0.666667, 0.662745, 1.0 ] 506 | } 507 | 508 | } 509 | , { 510 | "box" : { 511 | "id" : "obj-71", 512 | "maxclass" : "newobj", 513 | "numinlets" : 1, 514 | "numoutlets" : 1, 515 | "outlettype" : [ "" ], 516 | "patching_rect" : [ 122.166626, 99.0, 72.0, 22.0 ], 517 | "style" : "", 518 | "text" : "loadmess 0" 519 | } 520 | 521 | } 522 | , { 523 | "box" : { 524 | "id" : "obj-70", 525 | "maxclass" : "toggle", 526 | "numinlets" : 1, 527 | "numoutlets" : 1, 528 | "outlettype" : [ "int" ], 529 | "parameter_enable" : 0, 530 | "patching_rect" : [ 371.799988, 142.0, 24.0, 24.0 ], 531 | "presentation" : 1, 532 | "presentation_rect" : [ 67.5, 27.333374, 24.0, 24.0 ], 533 | "style" : "", 534 | "varname" : "toggle[1]" 535 | } 536 | 537 | } 538 | , { 539 | "box" : { 540 | "id" : "obj-69", 541 | "maxclass" : "toggle", 542 | "numinlets" : 1, 543 | "numoutlets" : 1, 544 | "outlettype" : [ "int" ], 545 | "parameter_enable" : 0, 546 | "patching_rect" : [ 87.333328, 140.0, 24.0, 24.0 ], 547 | "presentation" : 1, 548 | "presentation_rect" : [ 67.5, 110.333374, 24.0, 24.0 ], 549 | "style" : "", 550 | "varname" : "toggle" 551 | } 552 | 553 | } 554 | , { 555 | "box" : { 556 | "bgmode" : 0, 557 | "border" : 0, 558 | "clickthrough" : 0, 559 | "enablehscroll" : 0, 560 | "enablevscroll" : 0, 561 | "id" : "obj-6", 562 | "lockeddragscroll" : 0, 563 | "maxclass" : "bpatcher", 564 | "name" : "two-deep.maxpat", 565 | "numinlets" : 0, 566 | "numoutlets" : 0, 567 | "offset" : [ 0.0, 0.0 ], 568 | "patching_rect" : [ 1274.0, 131.0, 120.0, 90.0 ], 569 | "presentation" : 1, 570 | "presentation_rect" : [ 787.0, 504.166626, 68.0, 51.0 ], 571 | "varname" : "two-deep", 572 | "viewvisibility" : 1 573 | } 574 | 575 | } 576 | , { 577 | "box" : { 578 | "bgcolor" : [ 1.0, 0.788235, 0.470588, 1.0 ], 579 | "fontname" : "Arial Bold", 580 | "hint" : "", 581 | "id" : "obj-4", 582 | "ignoreclick" : 1, 583 | "legacytextcolor" : 1, 584 | "maxclass" : "textbutton", 585 | "numinlets" : 1, 586 | "numoutlets" : 3, 587 | "outlettype" : [ "", "", "int" ], 588 | "parameter_enable" : 0, 589 | "patching_rect" : [ 406.366638, 779.0, 20.0, 20.0 ], 590 | "presentation" : 1, 591 | "presentation_rect" : [ 26.0, 110.333374, 20.0, 20.0 ], 592 | "rounded" : 60.0, 593 | "style" : "", 594 | "text" : "2", 595 | "textcolor" : [ 0.34902, 0.34902, 0.34902, 1.0 ] 596 | } 597 | 598 | } 599 | , { 600 | "box" : { 601 | "bgcolor" : [ 1.0, 0.788235, 0.470588, 1.0 ], 602 | "fontname" : "Arial Bold", 603 | "hint" : "", 604 | "id" : "obj-3", 605 | "ignoreclick" : 1, 606 | "legacytextcolor" : 1, 607 | "maxclass" : "textbutton", 608 | "numinlets" : 1, 609 | "numoutlets" : 3, 610 | "outlettype" : [ "", "", "int" ], 611 | "parameter_enable" : 0, 612 | "patching_rect" : [ 406.366638, 725.0, 20.0, 20.0 ], 613 | "presentation" : 1, 614 | "presentation_rect" : [ 26.0, 29.333374, 20.0, 20.0 ], 615 | "rounded" : 60.0, 616 | "style" : "", 617 | "text" : "1", 618 | "textcolor" : [ 0.34902, 0.34902, 0.34902, 1.0 ] 619 | } 620 | 621 | } 622 | , { 623 | "box" : { 624 | "id" : "obj-5", 625 | "maxclass" : "newobj", 626 | "numinlets" : 6, 627 | "numoutlets" : 1, 628 | "outlettype" : [ "" ], 629 | "patching_rect" : [ 344.0, 545.0, 158.0, 22.0 ], 630 | "style" : "", 631 | "text" : "midilearn" 632 | } 633 | 634 | } 635 | , { 636 | "box" : { 637 | "bgmode" : 0, 638 | "border" : 0, 639 | "clickthrough" : 0, 640 | "enablehscroll" : 0, 641 | "enablevscroll" : 0, 642 | "id" : "obj-397", 643 | "lockeddragscroll" : 0, 644 | "maxclass" : "bpatcher", 645 | "name" : "bpatcher-test.maxpat", 646 | "numinlets" : 1, 647 | "numoutlets" : 1, 648 | "offset" : [ 0.0, 0.0 ], 649 | "outlettype" : [ "" ], 650 | "patching_rect" : [ 1143.199951, 131.0, 121.93335, 90.0 ], 651 | "presentation" : 1, 652 | "presentation_rect" : [ 680.0, 504.166626, 68.0, 51.0 ], 653 | "varname" : "bpatcher-test", 654 | "viewvisibility" : 1 655 | } 656 | 657 | } 658 | , { 659 | "box" : { 660 | "id" : "obj-52", 661 | "maxclass" : "comment", 662 | "numinlets" : 1, 663 | "numoutlets" : 0, 664 | "patching_rect" : [ 419.0, 142.0, 150.0, 20.0 ], 665 | "presentation" : 1, 666 | "presentation_rect" : [ 105.0, 27.333374, 86.0, 20.0 ], 667 | "style" : "", 668 | "text" : "MIDI ON/OFF" 669 | } 670 | 671 | } 672 | , { 673 | "box" : { 674 | "id" : "obj-49", 675 | "maxclass" : "comment", 676 | "numinlets" : 1, 677 | "numoutlets" : 0, 678 | "patching_rect" : [ 126.166626, 142.0, 150.0, 20.0 ], 679 | "presentation" : 1, 680 | "presentation_rect" : [ 105.0, 108.333374, 110.0, 20.0 ], 681 | "style" : "", 682 | "text" : "MIDI Learn Mode" 683 | } 684 | 685 | } 686 | , { 687 | "box" : { 688 | "id" : "obj-16", 689 | "maxclass" : "newobj", 690 | "numinlets" : 1, 691 | "numoutlets" : 4, 692 | "outlettype" : [ "", "", "", "" ], 693 | "patching_rect" : [ 65.0, 37.0, 86.0, 22.0 ], 694 | "restore" : { 695 | "dialobj" : [ 0.0 ], 696 | "obj1" : [ 1.0 ], 697 | "obj2" : [ -0.606299 ], 698 | "obj3" : [ 1.0 ], 699 | "obj4" : [ 1.0 ], 700 | "obj7" : [ -0.433071 ], 701 | "obj8" : [ -0.19685 ] 702 | } 703 | , 704 | "style" : "", 705 | "text" : "autopattr", 706 | "varname" : "u836000353" 707 | } 708 | 709 | } 710 | , { 711 | "box" : { 712 | "id" : "obj-9", 713 | "maxclass" : "newobj", 714 | "numinlets" : 1, 715 | "numoutlets" : 1, 716 | "outlettype" : [ "" ], 717 | "patching_rect" : [ 601.166626, 545.0, 220.0, 22.0 ], 718 | "saved_object_attributes" : { 719 | "client_rect" : [ 1843, 45, 2325, 279 ], 720 | "parameter_enable" : 0, 721 | "storage_rect" : [ 766, 44, 1220, 302 ] 722 | } 723 | , 724 | "style" : "", 725 | "text" : "pattrstorage midipresets @savemode 3", 726 | "varname" : "midipresets" 727 | } 728 | 729 | } 730 | , { 731 | "box" : { 732 | "activebgcolor" : [ 0.317647, 0.654902, 0.976471, 1.0 ], 733 | "hltcolor" : [ 0.960784, 0.827451, 0.156863, 1.0 ], 734 | "id" : "obj-13", 735 | "maxclass" : "live.menu", 736 | "numinlets" : 1, 737 | "numoutlets" : 3, 738 | "outlettype" : [ "", "", "float" ], 739 | "parameter_enable" : 1, 740 | "patching_rect" : [ 1284.0, 251.416626, 100.0, 15.0 ], 741 | "presentation" : 1, 742 | "presentation_rect" : [ 505.366577, 520.416626, 68.666641, 15.0 ], 743 | "saved_attribute_attributes" : { 744 | "valueof" : { 745 | "parameter_longname" : "live.menu[1]", 746 | "parameter_shortname" : "live.menu", 747 | "parameter_type" : 2, 748 | "parameter_enum" : [ "linear", "sin" ] 749 | } 750 | 751 | } 752 | , 753 | "varname" : "obj3" 754 | } 755 | 756 | } 757 | , { 758 | "box" : { 759 | "activedialcolor" : [ 0.317647, 0.654902, 0.976471, 1.0 ], 760 | "activeneedlecolor" : [ 0.65098, 0.666667, 0.662745, 1.0 ], 761 | "focusbordercolor" : [ 0.960784, 0.827451, 0.156863, 1.0 ], 762 | "fontface" : 0, 763 | "fontsize" : 9.0, 764 | "id" : "obj-14", 765 | "maxclass" : "live.dial", 766 | "numinlets" : 1, 767 | "numoutlets" : 2, 768 | "outlettype" : [ "", "float" ], 769 | "parameter_enable" : 1, 770 | "patching_rect" : [ 1313.133301, 314.583313, 34.0, 27.0 ], 771 | "presentation" : 1, 772 | "presentation_rect" : [ 337.199951, 514.416626, 34.0, 27.0 ], 773 | "saved_attribute_attributes" : { 774 | "valueof" : { 775 | "parameter_longname" : "scale1[5]", 776 | "parameter_shortname" : "phase mod", 777 | "parameter_type" : 0, 778 | "parameter_mmin" : -1.0, 779 | "parameter_mmax" : 1.0, 780 | "parameter_modmode" : 1, 781 | "parameter_initial_enable" : 1, 782 | "parameter_initial" : [ 0.0 ], 783 | "parameter_unitstyle" : 1 784 | } 785 | 786 | } 787 | , 788 | "showname" : 0, 789 | "shownumber" : 0, 790 | "textcolor" : [ 0.862745, 0.870588, 0.878431, 1.0 ], 791 | "tribordercolor" : [ 0.701961, 0.415686, 0.886275, 1.0 ], 792 | "varname" : "obj2" 793 | } 794 | 795 | } 796 | , { 797 | "box" : { 798 | "activebgoncolor" : [ 0.317647, 0.654902, 0.976471, 1.0 ], 799 | "id" : "obj-43", 800 | "maxclass" : "live.tab", 801 | "num_lines_patching" : 2, 802 | "num_lines_presentation" : 2, 803 | "numinlets" : 1, 804 | "numoutlets" : 3, 805 | "outlettype" : [ "", "", "float" ], 806 | "parameter_enable" : 1, 807 | "patching_rect" : [ 1143.199951, 230.583313, 51.0, 35.833336 ], 808 | "pictures" : [ "sine.svg", "updown.svg", "square.svg", "line4.svg" ], 809 | "presentation" : 1, 810 | "presentation_rect" : [ 254.0, 510.291626, 48.616596, 35.25 ], 811 | "saved_attribute_attributes" : { 812 | "valueof" : { 813 | "parameter_longname" : "live.tab[1]", 814 | "parameter_shortname" : "live.tab[2]", 815 | "parameter_type" : 2, 816 | "parameter_enum" : [ "sin", "tri", "saw", "square" ], 817 | "parameter_unitstyle" : 0 818 | } 819 | 820 | } 821 | , 822 | "usepicture" : 1, 823 | "varname" : "obj1" 824 | } 825 | 826 | } 827 | , { 828 | "box" : { 829 | "activebgoncolor" : [ 0.952941, 0.564706, 0.098039, 1.0 ], 830 | "id" : "obj-44", 831 | "maxclass" : "live.toggle", 832 | "numinlets" : 1, 833 | "numoutlets" : 1, 834 | "outlettype" : [ "" ], 835 | "parameter_enable" : 1, 836 | "patching_rect" : [ 1219.533325, 236.5, 23.666668, 24.0 ], 837 | "presentation" : 1, 838 | "presentation_rect" : [ 612.583313, 520.416626, 19.333374, 18.5 ], 839 | "saved_attribute_attributes" : { 840 | "valueof" : { 841 | "parameter_longname" : "live.toggle[1]", 842 | "parameter_shortname" : "live.toggle", 843 | "parameter_type" : 2, 844 | "parameter_mmax" : 1.0, 845 | "parameter_enum" : [ "off", "on" ] 846 | } 847 | 848 | } 849 | , 850 | "varname" : "obj4" 851 | } 852 | 853 | } 854 | , { 855 | "box" : { 856 | "angle" : 270.0, 857 | "bgcolor" : [ 0.095481, 0.100396, 0.100293, 1.0 ], 858 | "border" : 1, 859 | "bordercolor" : [ 1.0, 1.0, 1.0, 0.25 ], 860 | "id" : "obj-56", 861 | "maxclass" : "panel", 862 | "mode" : 0, 863 | "numinlets" : 1, 864 | "numoutlets" : 0, 865 | "patching_rect" : [ 156.0, 686.0, 128.0, 128.0 ], 866 | "presentation" : 1, 867 | "presentation_rect" : [ 15.5, 308.833374, 1030.5, 319.0 ], 868 | "proportion" : 0.39, 869 | "style" : "" 870 | } 871 | 872 | } 873 | , { 874 | "box" : { 875 | "angle" : 270.0, 876 | "bgcolor" : [ 0.095481, 0.100396, 0.100293, 1.0 ], 877 | "border" : 1, 878 | "bordercolor" : [ 1.0, 1.0, 1.0, 0.25 ], 879 | "id" : "obj-46", 880 | "maxclass" : "panel", 881 | "mode" : 0, 882 | "numinlets" : 1, 883 | "numoutlets" : 0, 884 | "patching_rect" : [ 141.0, 671.0, 128.0, 128.0 ], 885 | "presentation" : 1, 886 | "presentation_rect" : [ 15.5, 86.833374, 1030.5, 203.0 ], 887 | "proportion" : 0.39, 888 | "style" : "" 889 | } 890 | 891 | } 892 | , { 893 | "box" : { 894 | "angle" : 270.0, 895 | "bgcolor" : [ 0.095481, 0.100396, 0.100293, 1.0 ], 896 | "border" : 1, 897 | "bordercolor" : [ 1.0, 1.0, 1.0, 0.25 ], 898 | "id" : "obj-45", 899 | "maxclass" : "panel", 900 | "mode" : 0, 901 | "numinlets" : 1, 902 | "numoutlets" : 0, 903 | "patching_rect" : [ 126.0, 656.0, 128.0, 128.0 ], 904 | "presentation" : 1, 905 | "presentation_rect" : [ 15.5, 12.0, 1030.5, 57.0 ], 906 | "proportion" : 0.39, 907 | "style" : "" 908 | } 909 | 910 | } 911 | , { 912 | "box" : { 913 | "angle" : 270.0, 914 | "background" : 1, 915 | "bgcolor" : [ 0.20254, 0.136656, 0.060667, 1.0 ], 916 | "id" : "obj-17", 917 | "maxclass" : "panel", 918 | "mode" : 0, 919 | "numinlets" : 1, 920 | "numoutlets" : 0, 921 | "patching_rect" : [ 853.0, 724.0, 128.0, 128.0 ], 922 | "presentation" : 1, 923 | "presentation_rect" : [ 0.0, -0.166626, 1158.0, 728.0 ], 924 | "proportion" : 0.39, 925 | "rounded" : 0, 926 | "style" : "" 927 | } 928 | 929 | } 930 | ], 931 | "lines" : [ { 932 | "patchline" : { 933 | "destination" : [ "obj-5", 5 ], 934 | "disabled" : 0, 935 | "hidden" : 0, 936 | "source" : [ "obj-1", 0 ] 937 | } 938 | 939 | } 940 | , { 941 | "patchline" : { 942 | "destination" : [ "obj-69", 0 ], 943 | "disabled" : 0, 944 | "hidden" : 0, 945 | "source" : [ "obj-16", 1 ] 946 | } 947 | 948 | } 949 | , { 950 | "patchline" : { 951 | "destination" : [ "obj-70", 0 ], 952 | "disabled" : 0, 953 | "hidden" : 0, 954 | "midpoints" : [ 96.833333, 80.0, 381.299988, 80.0 ], 955 | "source" : [ "obj-16", 1 ] 956 | } 957 | 958 | } 959 | , { 960 | "patchline" : { 961 | "destination" : [ "obj-70", 0 ], 962 | "disabled" : 0, 963 | "hidden" : 0, 964 | "source" : [ "obj-2", 0 ] 965 | } 966 | 967 | } 968 | , { 969 | "patchline" : { 970 | "destination" : [ "obj-5", 3 ], 971 | "disabled" : 0, 972 | "hidden" : 0, 973 | "source" : [ "obj-250", 0 ] 974 | } 975 | 976 | } 977 | , { 978 | "patchline" : { 979 | "destination" : [ "obj-5", 4 ], 980 | "disabled" : 0, 981 | "hidden" : 0, 982 | "midpoints" : [ 610.666626, 395.0, 464.7, 395.0 ], 983 | "source" : [ "obj-251", 0 ] 984 | } 985 | 986 | } 987 | , { 988 | "patchline" : { 989 | "destination" : [ "obj-250", 0 ], 990 | "disabled" : 0, 991 | "hidden" : 0, 992 | "source" : [ "obj-255", 0 ] 993 | } 994 | 995 | } 996 | , { 997 | "patchline" : { 998 | "destination" : [ "obj-9", 0 ], 999 | "disabled" : 0, 1000 | "hidden" : 0, 1001 | "midpoints" : [ 353.5, 589.0, 545.583313, 589.0, 545.583313, 522.0, 610.666626, 522.0 ], 1002 | "source" : [ "obj-5", 0 ] 1003 | } 1004 | 1005 | } 1006 | , { 1007 | "patchline" : { 1008 | "destination" : [ "obj-335", 0 ], 1009 | "disabled" : 0, 1010 | "hidden" : 0, 1011 | "source" : [ "obj-58", 0 ] 1012 | } 1013 | 1014 | } 1015 | , { 1016 | "patchline" : { 1017 | "destination" : [ "obj-5", 0 ], 1018 | "disabled" : 0, 1019 | "hidden" : 0, 1020 | "midpoints" : [ 96.833328, 354.0, 353.5, 354.0 ], 1021 | "source" : [ "obj-69", 0 ] 1022 | } 1023 | 1024 | } 1025 | , { 1026 | "patchline" : { 1027 | "destination" : [ "obj-251", 0 ], 1028 | "disabled" : 0, 1029 | "hidden" : 0, 1030 | "source" : [ "obj-7", 0 ] 1031 | } 1032 | 1033 | } 1034 | , { 1035 | "patchline" : { 1036 | "destination" : [ "obj-5", 1 ], 1037 | "disabled" : 0, 1038 | "hidden" : 0, 1039 | "source" : [ "obj-70", 0 ] 1040 | } 1041 | 1042 | } 1043 | , { 1044 | "patchline" : { 1045 | "destination" : [ "obj-69", 0 ], 1046 | "disabled" : 0, 1047 | "hidden" : 0, 1048 | "source" : [ "obj-71", 0 ] 1049 | } 1050 | 1051 | } 1052 | , { 1053 | "patchline" : { 1054 | "destination" : [ "obj-5", 2 ], 1055 | "disabled" : 0, 1056 | "hidden" : 0, 1057 | "midpoints" : [ 610.666626, 588.0, 547.083313, 588.0, 547.083313, 525.0, 409.1, 525.0 ], 1058 | "source" : [ "obj-9", 0 ] 1059 | } 1060 | 1061 | } 1062 | ], 1063 | "parameters" : { 1064 | "obj-14" : [ "scale1[5]", "phase mod", 0 ], 1065 | "obj-43" : [ "live.tab[1]", "live.tab[2]", 0 ], 1066 | "obj-6::obj-1::obj-1789" : [ "scale1[2]", "phase mod", 0 ], 1067 | "obj-397::obj-1789" : [ "scale1[1]", "phase mod", 0 ], 1068 | "obj-13" : [ "live.menu[1]", "live.menu", 0 ], 1069 | "obj-48" : [ "scale1[6]", "phase mod", 0 ], 1070 | "obj-47" : [ "scale1[3]", "phase mod", 0 ], 1071 | "obj-44" : [ "live.toggle[1]", "live.toggle", 0 ] 1072 | } 1073 | , 1074 | "dependency_cache" : [ { 1075 | "name" : "sine.svg", 1076 | "bootpath" : "~/Documents/Max 7/Projects/max-midi-learn/media", 1077 | "patcherrelativepath" : "../media", 1078 | "type" : "svg ", 1079 | "implicit" : 1 1080 | } 1081 | , { 1082 | "name" : "updown.svg", 1083 | "bootpath" : "~/Documents/Max 7/Projects/max-midi-learn/media", 1084 | "patcherrelativepath" : "../media", 1085 | "type" : "svg ", 1086 | "implicit" : 1 1087 | } 1088 | , { 1089 | "name" : "square.svg", 1090 | "bootpath" : "~/Documents/Max 7/Projects/max-midi-learn/media", 1091 | "patcherrelativepath" : "../media", 1092 | "type" : "svg ", 1093 | "implicit" : 1 1094 | } 1095 | , { 1096 | "name" : "line4.svg", 1097 | "bootpath" : "~/Documents/Max 7/Projects/max-midi-learn/media", 1098 | "patcherrelativepath" : "../media", 1099 | "type" : "svg ", 1100 | "implicit" : 1 1101 | } 1102 | , { 1103 | "name" : "bpatcher-test.maxpat", 1104 | "bootpath" : "~/Documents/Max 7/Projects/max-midi-learn/patchers", 1105 | "patcherrelativepath" : ".", 1106 | "type" : "JSON", 1107 | "implicit" : 1 1108 | } 1109 | , { 1110 | "name" : "midilearn.maxpat", 1111 | "bootpath" : "~/Documents/Max 7/Projects/max-midi-learn/patchers", 1112 | "patcherrelativepath" : ".", 1113 | "type" : "JSON", 1114 | "implicit" : 1 1115 | } 1116 | , { 1117 | "name" : "midilearn.js", 1118 | "bootpath" : "~/Documents/Max 7/Projects/max-midi-learn/code", 1119 | "patcherrelativepath" : "../code", 1120 | "type" : "TEXT", 1121 | "implicit" : 1 1122 | } 1123 | , { 1124 | "name" : "two-deep.maxpat", 1125 | "bootpath" : "~/Documents/Max 7/Projects/max-midi-learn/patchers", 1126 | "patcherrelativepath" : ".", 1127 | "type" : "JSON", 1128 | "implicit" : 1 1129 | } 1130 | , { 1131 | "name" : "bpatcher-test2.maxpat", 1132 | "bootpath" : "~/Documents/Max 7/Projects/max-midi-learn/patchers", 1133 | "patcherrelativepath" : ".", 1134 | "type" : "JSON", 1135 | "implicit" : 1 1136 | } 1137 | ], 1138 | "embedsnapshot" : 0, 1139 | "styles" : [ { 1140 | "name" : "AudioStatus_Menu", 1141 | "default" : { 1142 | "bgfillcolor" : { 1143 | "type" : "color", 1144 | "color" : [ 0.294118, 0.313726, 0.337255, 1 ], 1145 | "color1" : [ 0.454902, 0.462745, 0.482353, 0.0 ], 1146 | "color2" : [ 0.290196, 0.309804, 0.301961, 1.0 ], 1147 | "angle" : 270.0, 1148 | "proportion" : 0.39, 1149 | "autogradient" : 0 1150 | } 1151 | 1152 | } 1153 | , 1154 | "parentstyle" : "", 1155 | "multi" : 0 1156 | } 1157 | , { 1158 | "name" : "Luca", 1159 | "default" : { 1160 | "bgcolor" : [ 0.904179, 0.895477, 0.842975, 0.56 ], 1161 | "selectioncolor" : [ 0.720698, 0.16723, 0.080014, 1.0 ], 1162 | "fontname" : [ "Open Sans Semibold" ], 1163 | "textcolor_inverse" : [ 0.239216, 0.254902, 0.278431, 1.0 ], 1164 | "color" : [ 0.475135, 0.293895, 0.251069, 1.0 ], 1165 | "accentcolor" : [ 0.32549, 0.345098, 0.372549, 1.0 ], 1166 | "elementcolor" : [ 0.786675, 0.801885, 0.845022, 1.0 ], 1167 | "bgfillcolor" : { 1168 | "type" : "gradient", 1169 | "color" : [ 0.290196, 0.309804, 0.301961, 1.0 ], 1170 | "color1" : [ 0.862745, 0.870588, 0.878431, 1.0 ], 1171 | "color2" : [ 0.65098, 0.666667, 0.662745, 1.0 ], 1172 | "angle" : 270.0, 1173 | "proportion" : 0.39, 1174 | "autogradient" : 0 1175 | } 1176 | 1177 | } 1178 | , 1179 | "parentstyle" : "", 1180 | "multi" : 0 1181 | } 1182 | , { 1183 | "name" : "dark-night-patch", 1184 | "default" : { 1185 | "textcolor" : [ 0.862745, 0.870588, 0.878431, 1.0 ], 1186 | "patchlinecolor" : [ 0.439216, 0.74902, 0.254902, 0.898039 ], 1187 | "accentcolor" : [ 0.952941, 0.564706, 0.098039, 1.0 ], 1188 | "bgfillcolor" : { 1189 | "type" : "gradient", 1190 | "color1" : [ 0.376471, 0.384314, 0.4, 1.0 ], 1191 | "color2" : [ 0.290196, 0.309804, 0.301961, 1.0 ], 1192 | "color" : [ 0.290196, 0.309804, 0.301961, 1.0 ], 1193 | "angle" : 270.0, 1194 | "proportion" : 0.39 1195 | } 1196 | 1197 | } 1198 | , 1199 | "parentstyle" : "", 1200 | "multi" : 0 1201 | } 1202 | ], 1203 | "accentcolor" : [ 0.702269, 0.811747, 0.303388, 1.0 ], 1204 | "textcolor" : [ 0.862745, 0.870588, 0.878431, 1.0 ], 1205 | "patchlinecolor" : [ 0.439216, 0.74902, 0.254902, 0.898039 ], 1206 | "bgfillcolor_type" : "gradient", 1207 | "bgfillcolor_color1" : [ 0.376471, 0.384314, 0.4, 1.0 ], 1208 | "bgfillcolor_color2" : [ 0.290196, 0.309804, 0.301961, 1.0 ], 1209 | "bgfillcolor_color" : [ 0.290196, 0.309804, 0.301961, 1.0 ], 1210 | "bgfillcolor_angle" : 270.0, 1211 | "bgfillcolor_proportion" : 0.39 1212 | } 1213 | 1214 | } 1215 | --------------------------------------------------------------------------------