SHOW:
|
|
- or go back to the newest paste.
| 1 | - | /** |
| 1 | + | |
| 2 | - | * Created by Suloo on 29.10.2014. |
| 2 | + | |
| 3 | - | */ |
| 3 | + | |
| 4 | host.defineController("Cakewalk", "A-300 PRO", "1.1", "e504e660-2b27-11e4-8c21-0800200c9a66");
| |
| 5 | host.defineMidiPorts(1, 1); | |
| 6 | host.addDeviceNameBasedDiscoveryPair(["A-PRO 1"], ["A-PRO"]); | |
| 7 | ||
| 8 | ||
| 9 | // CC 0 and CCs 120+ are reserved | |
| 10 | var LOWEST_CC = 1; | |
| 11 | var HIGHEST_CC = 119; | |
| 12 | ||
| 13 | // Two array-variables to hold the values of all the CCs and to check if they have changed | |
| 14 | var ccValue = initArray(0, ((HIGHEST_CC - LOWEST_CC + 1)*16)); | |
| 15 | var ccValueOld = initArray(0, ((HIGHEST_CC - LOWEST_CC + 1)*16)); | |
| 16 | ||
| 17 | ||
| 18 | /*Load the A-300 Bitwig.mid file in your A-300 Editor and transmit it to the Hardware device. Then select | |
| 19 | the controller Map.*/ | |
| 20 | ||
| 21 | var _down = 22; | |
| 22 | var _up = 23; | |
| 23 | var _ff = 24; | |
| 24 | var _stop = 25; | |
| 25 | var _play = 26; | |
| 26 | var _loop = 27; | |
| 27 | var _record = 28; | |
| 28 | var _b1 = 29; | |
| 29 | var _b2 = 30; | |
| 30 | var _b3 = 3; | |
| 31 | var _b4 = 4; | |
| 32 | ||
| 33 | var _knob1 = 102; | |
| 34 | var _knob2 = 103; | |
| 35 | var _knob3 = 104; | |
| 36 | var _knob4 = 105; | |
| 37 | var _knob5 = 106; | |
| 38 | var _knob6 = 107; | |
| 39 | var _knob7 = 108; | |
| 40 | var _knob8 = 109; | |
| 41 | var _mastervolume = 118; | |
| 42 | ||
| 43 | // Macros: | |
| 44 | deviceMacro = []; | |
| 45 | deviceMacroHasChanged = []; | |
| 46 | ||
| 47 | //var lockOnMacro[0] = false; | |
| 48 | ||
| 49 | // A function to create an indexed function for the Observers | |
| 50 | function getValueObserverFunc(index, varToStore) | |
| 51 | {
| |
| 52 | return function(value) | |
| 53 | {
| |
| 54 | varToStore[index] = value; | |
| 55 | } | |
| 56 | } | |
| 57 | ||
| 58 | // A function to create an indexed function for the Observers with an added state variable: | |
| 59 | function getTrackValueFunc(index, varToStore, varToSet) | |
| 60 | {
| |
| 61 | return function(value) | |
| 62 | {
| |
| 63 | varToStore[index] = value; | |
| 64 | varToSet[index] = true; | |
| 65 | } | |
| 66 | } | |
| 67 | ||
| 68 | function init() | |
| 69 | {
| |
| 70 | transport = host.createTransport(); | |
| 71 | cursorTrack = host.createCursorTrack(0,0); | |
| 72 | primaryDevice = cursorTrack.getPrimaryDevice(); | |
| 73 | masterTrack = host.createMasterTrack(0); | |
| 74 | application = host.createApplication(); | |
| 75 | ||
| 76 | for (var i = 0; i < 8; i++) {
| |
| 77 | primaryDevice.getMacro(i).getAmount().setIndication(true); | |
| 78 | } | |
| 79 | ||
| 80 | for (var i=0; i<8; i++) {
| |
| 81 | // macros | |
| 82 | primaryDevice.getMacro(i).getAmount().addValueObserver(127, getTrackValueFunc(i, deviceMacro, deviceMacroHasChanged)); | |
| 83 | } | |
| 84 | ||
| 85 | ||
| 86 | ||
| 87 | ||
| 88 | ||
| 89 | // Create 16 NoteInputs + Omni. | |
| 90 | // Verbose to allow commenting out unneeded channels | |
| 91 | // To do so, put "//" in front of the lines containing channels you don't want to use | |
| 92 | // Be sure to do it for the "createNoteInput" lines as well as the corresponding | |
| 93 | // "setShouldConsumeEvents" and "assignPolyphonicAftertouchToExpression" lines below | |
| 94 | MultiBi = host.getMidiInPort(0).createNoteInput("MultiBi - Omni", "??????");
| |
| 95 | MultiBi1 = host.getMidiInPort(0).createNoteInput("MultiBi - Ch 1", "?0????");
| |
| 96 | MultiBi2 = host.getMidiInPort(0).createNoteInput("MultiBi - Ch 2", "?1????");
| |
| 97 | ||
| 98 | ||
| 99 | // Disable the consuming of events by the NoteInputs, so they are also available for mapping | |
| 100 | MultiBi.setShouldConsumeEvents(false); | |
| 101 | MultiBi1.setShouldConsumeEvents(false); | |
| 102 | ||
| 103 | ||
| 104 | // Enable Poly AT translation into Timbre for the internal BWS instruments | |
| 105 | MultiBi.assignPolyphonicAftertouchToExpression(0, NoteExpression.TIMBRE_UP, 5); | |
| 106 | MultiBi1.assignPolyphonicAftertouchToExpression(0, NoteExpression.TIMBRE_UP, 5); | |
| 107 | MultiBi2.assignPolyphonicAftertouchToExpression(1, NoteExpression.TIMBRE_UP, 5); | |
| 108 | ||
| 109 | ||
| 110 | ||
| 111 | ||
| 112 | ||
| 113 | // Enable Midi Beat Clock. Comment out if you don't want that | |
| 114 | host.getMidiOutPort(0).setShouldSendMidiBeatClock; | |
| 115 | ||
| 116 | // Setting Callbacks for Midi and Sysex | |
| 117 | host.getMidiInPort(0).setMidiCallback(onMidi); | |
| 118 | host.getMidiInPort(0).setSysexCallback(onSysex); | |
| 119 | ||
| 120 | // Make CCs 1-119 freely mappable for all 16 Channels | |
| 121 | userControls = host.createUserControls((HIGHEST_CC - LOWEST_CC + 1)*16); | |
| 122 | ||
| 123 | for(var i=LOWEST_CC; i<=HIGHEST_CC; i++) | |
| 124 | {
| |
| 125 | for (var j=1; j<=16; j++) {
| |
| 126 | // Create the index variable c | |
| 127 | var c = i - LOWEST_CC + (j-1) * (HIGHEST_CC-LOWEST_CC+1); | |
| 128 | // Set a label/name for each userControl | |
| 129 | userControls.getControl(c).setLabel("CC " + i + " - Channel " + j);
| |
| 130 | // Add a ValueObserver for each userControl | |
| 131 | userControls.getControl(c).addValueObserver(127, getValueObserverFunc(c, ccValue)); | |
| 132 | } | |
| 133 | } | |
| 134 | } | |
| 135 | ||
| 136 | ||
| 137 | ||
| 138 | ||
| 139 | function exit() | |
| 140 | {
| |
| 141 | // nothing to do here ;-) | |
| 142 | } | |
| 143 | ||
| 144 | ||
| 145 | // Update the UserControls when Midi Data is received | |
| 146 | function onMidi(status, data1, data2) | |
| 147 | {
| |
| 148 | ||
| 149 | printMidi(status, data1, data2); | |
| 150 | ||
| 151 | if (isChannelController(status)) | |
| 152 | {
| |
| 153 | switch (data1) | |
| 154 | {
| |
| 155 | ||
| 156 | case _stop: | |
| 157 | transport.stop(); | |
| 158 | break; | |
| 159 | ||
| 160 | case _play: | |
| 161 | transport.play(); | |
| 162 | break; | |
| 163 | ||
| 164 | case _record: | |
| 165 | transport.record(); | |
| 166 | break; | |
| 167 | case _loop: | |
| 168 | transport.toggleLoop(); | |
| 169 | break; | |
| 170 | case _up: | |
| 171 | cursorTrack.selectNext(); | |
| 172 | break; | |
| 173 | case _down: | |
| 174 | cursorTrack.selectPrevious(); | |
| 175 | break; | |
| 176 | case _mastervolume: | |
| 177 | masterTrack.getVolume().set(data2, 128); | |
| 178 | masterTrack.getVolume().setIndication(true); | |
| 179 | break; | |
| 180 | case _b1: | |
| 181 | application.toggleNoteEditor(); | |
| 182 | break; | |
| 183 | case _b2: | |
| 184 | application.toggleAutomationEditor(); | |
| 185 | break; | |
| 186 | case _b3: | |
| 187 | application.toggleMixer(); | |
| 188 | break; | |
| 189 | case _b4: | |
| 190 | application.toggleDevices(); | |
| 191 | break; | |
| 192 | case _ff: | |
| 193 | cursorTrack.returnToArrangement(); | |
| 194 | break; | |
| 195 | ||
| 196 | case _knob1: | |
| 197 | primaryDevice.getMacro(0).getAmount().set(data2, 128); | |
| 198 | break; | |
| 199 | case _knob2: | |
| 200 | primaryDevice.getMacro(1).getAmount().set(data2, 128); | |
| 201 | break; | |
| 202 | case _knob3: | |
| 203 | primaryDevice.getMacro(2).getAmount().set(data2, 128); | |
| 204 | break; | |
| 205 | case _knob4: | |
| 206 | primaryDevice.getMacro(3).getAmount().set(data2, 128); | |
| 207 | break; | |
| 208 | case _knob5: | |
| 209 | primaryDevice.getMacro(4).getAmount().set(data2, 128); | |
| 210 | break; | |
| 211 | case _knob6: | |
| 212 | primaryDevice.getMacro(5).getAmount().set(data2, 128); | |
| 213 | break; | |
| 214 | case _knob7: | |
| 215 | primaryDevice.getMacro(6).getAmount().set(data2, 128); | |
| 216 | break; | |
| 217 | case _knob8: | |
| 218 | primaryDevice.getMacro(7).getAmount().set(data2, 128); | |
| 219 | break; | |
| 220 | } | |
| 221 | if (data1 >= LOWEST_CC && data1 <= HIGHEST_CC) | |
| 222 | {
| |
| 223 | var index = data1 - LOWEST_CC + ((HIGHEST_CC-LOWEST_CC+1) * MIDIChannel(status)); | |
| 224 | userControls.getControl(index).set(data2, 128); | |
| 225 | } | |
| 226 | ||
| 227 | } | |
| 228 | var threshold = 5; // you need to experiment what works here. | |
| 229 | if (data1 === _knob1[0]) {
| |
| 230 | if (lockOnMacro[0] === true) {
| |
| 231 | primaryDevice.getMacro(0).getAmount().set(data2, 128); | |
| 232 | } | |
| 233 | else if (data2 >= (deviceMacro[0] - threshold) && data2 <= (deviceMacro[0] + threshold) ) {
| |
| 234 | lockOnMacro[0] = true; | |
| 235 | primaryDevice.getMacro(0).getAmount().set(data2, 128); | |
| 236 | } | |
| 237 | ||
| 238 | } | |
| 239 | } | |
| 240 | ||
| 241 | ||
| 242 | function onSysex(data) | |
| 243 | {
| |
| 244 | //printSysex(data); | |
| 245 | } |