Merge lp:~zestoi/mixxx/controller_scripts into lp:~mixxxdevelopers/mixxx/trunk
- controller_scripts
- Merge into trunk
Proposed by
Zestoi
Status: | Merged |
---|---|
Merged at revision: | 3213 |
Proposed branch: | lp:~zestoi/mixxx/controller_scripts |
Merge into: | lp:~mixxxdevelopers/mixxx/trunk |
Diff against target: |
3109 lines (+3045/-2) 9 files modified
mixxx/res/controllers/DJ-Tech CDJ-101.midi.xml (+196/-0) mixxx/res/controllers/DJ-Tech DJM-101.midi.xml (+204/-0) mixxx/res/controllers/DJ-Tech-CDJ-101-scripts.js (+245/-0) mixxx/res/controllers/DJ-Tech-DJM-101-scripts.js (+110/-0) mixxx/res/controllers/Hercules DJ Console Mk2.cntrlr.xml (+13/-0) mixxx/res/controllers/Hercules-DJ-Console-Mk2-hid-scripts.js (+611/-0) mixxx/res/controllers/Novation Launchpad.midi.xml (+736/-0) mixxx/res/controllers/Novation-Launchpad-scripts.js (+819/-0) mixxx/res/controllers/common-controller-scripts.js (+111/-2) |
To merge this branch: | bzr merge lp:~zestoi/mixxx/controller_scripts |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Mixxx Development Team | Pending | ||
Review via email: mp+107519@code.launchpad.net |
Commit message
Description of the change
new controller mappings:
* hercules dj console mk2 (hid)
* djtech cdj101
* djtech djm101
* novation launchpad (full led feedback and a "virtual mixer" page)
updates to common-
* new effects functions: script.spinback(), script.brake(), script.
* fix to script.pitch() as it wasn't returning the value from script.midiPitch() only calling it
To post a comment you must log in.
- 3210. By Owen Williams
-
Fix rate range setting not getting saved properly (float equality testing fail)
- 3211. By RJ Skerry-Ryan
-
Use track-ids instead of TrackPointers to keep the recent tracks window.
- 3212. By RJ Skerry-Ryan
-
Merging from lp:~zestoi/mixxx/spinback_brake
- 3213. By RJ Skerry-Ryan
-
Merging from lp:~zestoi/mixxx/controller_scripts
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added file 'mixxx/res/controllers/DJ-Tech CDJ-101.midi.xml' | |||
2 | --- mixxx/res/controllers/DJ-Tech CDJ-101.midi.xml 1970-01-01 00:00:00 +0000 | |||
3 | +++ mixxx/res/controllers/DJ-Tech CDJ-101.midi.xml 2012-05-26 14:59:19 +0000 | |||
4 | @@ -0,0 +1,196 @@ | |||
5 | 1 | <?xml version='1.0' encoding='utf-8'?> | ||
6 | 2 | <MixxxControllerPreset schemaVersion="1"> | ||
7 | 3 | <info> | ||
8 | 4 | <name>DJTech CDJ 101</name> | ||
9 | 5 | <author>zestoi</author> | ||
10 | 6 | <description>Select midi channel 1 or 2 on the CDJ101 to select which deck to control in Mixxx. Hold down the push encoder for additional controls.</description> | ||
11 | 7 | </info> | ||
12 | 8 | <controller id="DJ-Tech CDJ-101"> | ||
13 | 9 | <scriptfiles> | ||
14 | 10 | <file filename="DJ-Tech-CDJ-101-scripts.js" functionprefix="DJTechCDJ101"/> | ||
15 | 11 | </scriptfiles> | ||
16 | 12 | |||
17 | 13 | <controls> | ||
18 | 14 | |||
19 | 15 | <!-- midi channel 1 for deck 1 --> | ||
20 | 16 | |||
21 | 17 | <!-- play/cue --> | ||
22 | 18 | |||
23 | 19 | <control> | ||
24 | 20 | <group>[Channel1]</group> | ||
25 | 21 | <key>DJTechCDJ101.play</key> | ||
26 | 22 | <status>0x90</status> | ||
27 | 23 | <midino>0x2a</midino> | ||
28 | 24 | <options> | ||
29 | 25 | <Script-Binding/> | ||
30 | 26 | </options> | ||
31 | 27 | </control> | ||
32 | 28 | |||
33 | 29 | <control> | ||
34 | 30 | <group>[Channel1]</group> | ||
35 | 31 | <key>DJTechCDJ101.cue</key> | ||
36 | 32 | <status>0x90</status> | ||
37 | 33 | <midino>0x2b</midino> | ||
38 | 34 | <options> | ||
39 | 35 | <Script-Binding/> | ||
40 | 36 | </options> | ||
41 | 37 | </control> | ||
42 | 38 | |||
43 | 39 | <!-- jog --> | ||
44 | 40 | |||
45 | 41 | <control> | ||
46 | 42 | <group>[Channel1]</group> | ||
47 | 43 | <status>0x90</status> | ||
48 | 44 | <midino>0x20</midino> | ||
49 | 45 | <key>DJTechCDJ101.jogtouch</key> | ||
50 | 46 | <options> | ||
51 | 47 | <Script-Binding/> | ||
52 | 48 | </options> | ||
53 | 49 | </control> | ||
54 | 50 | |||
55 | 51 | <control> | ||
56 | 52 | <group>[Channel1]</group> | ||
57 | 53 | <status>0xb0</status> | ||
58 | 54 | <midino>0x35</midino> | ||
59 | 55 | <key>DJTechCDJ101.jogouter</key> | ||
60 | 56 | <options> | ||
61 | 57 | <Script-Binding/> | ||
62 | 58 | </options> | ||
63 | 59 | </control> | ||
64 | 60 | |||
65 | 61 | <control> | ||
66 | 62 | <group>[Channel1]</group> | ||
67 | 63 | <status>0xb0</status> | ||
68 | 64 | <midino>0x36</midino> | ||
69 | 65 | <key>DJTechCDJ101.jogtop</key> | ||
70 | 66 | <options> | ||
71 | 67 | <Script-Binding/> | ||
72 | 68 | </options> | ||
73 | 69 | </control> | ||
74 | 70 | |||
75 | 71 | <!-- pitch --> | ||
76 | 72 | |||
77 | 73 | <control> | ||
78 | 74 | <status>0xe0</status> | ||
79 | 75 | <group>[Channel1]</group> | ||
80 | 76 | <key>DJTechCDJ101.pitch</key> | ||
81 | 77 | <options> | ||
82 | 78 | <Script-Binding/> | ||
83 | 79 | </options> | ||
84 | 80 | </control> | ||
85 | 81 | |||
86 | 82 | <!-- track browse/load --> | ||
87 | 83 | |||
88 | 84 | <control> | ||
89 | 85 | <group>[Channel1]</group> | ||
90 | 86 | <key>DJTechCDJ101.push</key> | ||
91 | 87 | <status>0x90</status> | ||
92 | 88 | <midino>0x1F</midino> | ||
93 | 89 | <options> | ||
94 | 90 | <Script-Binding/> | ||
95 | 91 | </options> | ||
96 | 92 | </control> | ||
97 | 93 | |||
98 | 94 | <control> | ||
99 | 95 | <group>[Channel1]</group> | ||
100 | 96 | <key>DJTechCDJ101.browse</key> | ||
101 | 97 | <status>0xB0</status> | ||
102 | 98 | <midino>0x38</midino> | ||
103 | 99 | <options> | ||
104 | 100 | <Script-Binding/> | ||
105 | 101 | </options> | ||
106 | 102 | </control> | ||
107 | 103 | |||
108 | 104 | <!-- midi channel 2 for deck 2 --> | ||
109 | 105 | |||
110 | 106 | <!-- play/cue --> | ||
111 | 107 | |||
112 | 108 | <control> | ||
113 | 109 | <group>[Channel2]</group> | ||
114 | 110 | <key>DJTechCDJ101.play</key> | ||
115 | 111 | <status>0x91</status> | ||
116 | 112 | <midino>0x2a</midino> | ||
117 | 113 | <options> | ||
118 | 114 | <Script-Binding/> | ||
119 | 115 | </options> | ||
120 | 116 | </control> | ||
121 | 117 | |||
122 | 118 | <control> | ||
123 | 119 | <group>[Channel2]</group> | ||
124 | 120 | <key>DJTechCDJ101.cue</key> | ||
125 | 121 | <status>0x91</status> | ||
126 | 122 | <midino>0x2b</midino> | ||
127 | 123 | <options> | ||
128 | 124 | <Script-Binding/> | ||
129 | 125 | </options> | ||
130 | 126 | </control> | ||
131 | 127 | |||
132 | 128 | <!-- jog --> | ||
133 | 129 | |||
134 | 130 | <control> | ||
135 | 131 | <group>[Channel2]</group> | ||
136 | 132 | <status>0x91</status> | ||
137 | 133 | <midino>0x20</midino> | ||
138 | 134 | <key>DJTechCDJ101.jogtouch</key> | ||
139 | 135 | <options> | ||
140 | 136 | <Script-Binding/> | ||
141 | 137 | </options> | ||
142 | 138 | </control> | ||
143 | 139 | |||
144 | 140 | <control> | ||
145 | 141 | <group>[Channel2]</group> | ||
146 | 142 | <status>0xb1</status> | ||
147 | 143 | <midino>0x35</midino> | ||
148 | 144 | <key>DJTechCDJ101.jogouter</key> | ||
149 | 145 | <options> | ||
150 | 146 | <Script-Binding/> | ||
151 | 147 | </options> | ||
152 | 148 | </control> | ||
153 | 149 | |||
154 | 150 | <control> | ||
155 | 151 | <group>[Channel2]</group> | ||
156 | 152 | <status>0xb1</status> | ||
157 | 153 | <midino>0x36</midino> | ||
158 | 154 | <key>DJTechCDJ101.jogtop</key> | ||
159 | 155 | <options> | ||
160 | 156 | <Script-Binding/> | ||
161 | 157 | </options> | ||
162 | 158 | </control> | ||
163 | 159 | |||
164 | 160 | <!-- pitch --> | ||
165 | 161 | |||
166 | 162 | <control> | ||
167 | 163 | <status>0xe1</status> | ||
168 | 164 | <group>[Channel2]</group> | ||
169 | 165 | <key>DJTechCDJ101.pitch</key> | ||
170 | 166 | <options> | ||
171 | 167 | <Script-Binding/> | ||
172 | 168 | </options> | ||
173 | 169 | </control> | ||
174 | 170 | |||
175 | 171 | <!-- track browse/load --> | ||
176 | 172 | |||
177 | 173 | <control> | ||
178 | 174 | <group>[Channel2]</group> | ||
179 | 175 | <key>DJTechCDJ101.push</key> | ||
180 | 176 | <status>0x91</status> | ||
181 | 177 | <midino>0x1F</midino> | ||
182 | 178 | <options> | ||
183 | 179 | <Script-Binding/> | ||
184 | 180 | </options> | ||
185 | 181 | </control> | ||
186 | 182 | |||
187 | 183 | <control> | ||
188 | 184 | <group>[Channel1]</group> | ||
189 | 185 | <key>DJTechCDJ101.browse</key> | ||
190 | 186 | <status>0xB1</status> | ||
191 | 187 | <midino>0x38</midino> | ||
192 | 188 | <options> | ||
193 | 189 | <Script-Binding/> | ||
194 | 190 | </options> | ||
195 | 191 | </control> | ||
196 | 192 | |||
197 | 193 | </controls> | ||
198 | 194 | |||
199 | 195 | </controller> | ||
200 | 196 | </MixxxControllerPreset> | ||
201 | 0 | 197 | ||
202 | === added file 'mixxx/res/controllers/DJ-Tech DJM-101.midi.xml' | |||
203 | --- mixxx/res/controllers/DJ-Tech DJM-101.midi.xml 1970-01-01 00:00:00 +0000 | |||
204 | +++ mixxx/res/controllers/DJ-Tech DJM-101.midi.xml 2012-05-26 14:59:19 +0000 | |||
205 | @@ -0,0 +1,204 @@ | |||
206 | 1 | <?xml version='1.0' encoding='utf-8'?> | ||
207 | 2 | <MixxxControllerPreset schemaVersion="1"> | ||
208 | 3 | <info> | ||
209 | 4 | <name>DJTech DJM 101</name> | ||
210 | 5 | <author>zestoi</author> | ||
211 | 6 | <description>Mapping with full led feedback for the DJTech DJM 101</description> | ||
212 | 7 | </info> | ||
213 | 8 | <controller id="DJM-101"> | ||
214 | 9 | <scriptfiles> | ||
215 | 10 | <file filename="DJ-Tech-DJM-101-scripts.js" functionprefix="DJTechDJM101"/> | ||
216 | 11 | </scriptfiles> | ||
217 | 12 | <controls> | ||
218 | 13 | |||
219 | 14 | <!-- global controls --> | ||
220 | 15 | |||
221 | 16 | <control> | ||
222 | 17 | <group>[Master]</group> | ||
223 | 18 | <key>headVolume</key> | ||
224 | 19 | <status>0xB0</status> | ||
225 | 20 | <midino>0x45</midino> | ||
226 | 21 | <options> | ||
227 | 22 | <normal/> | ||
228 | 23 | </options> | ||
229 | 24 | </control> | ||
230 | 25 | <control> | ||
231 | 26 | <group>[Master]</group> | ||
232 | 27 | <key>headMix</key> | ||
233 | 28 | <status>0xB0</status> | ||
234 | 29 | <midino>0x44</midino> | ||
235 | 30 | <options> | ||
236 | 31 | <normal/> | ||
237 | 32 | </options> | ||
238 | 33 | </control> | ||
239 | 34 | |||
240 | 35 | <!-- master/pfl vumeter select --> | ||
241 | 36 | |||
242 | 37 | <control> | ||
243 | 38 | <group>[Master]</group> | ||
244 | 39 | <status>0x90</status> | ||
245 | 40 | <midino>0x24</midino> | ||
246 | 41 | <key>DJTechDJM101.vumeter_select_master</key> | ||
247 | 42 | <options> | ||
248 | 43 | <Script-Binding/> | ||
249 | 44 | </options> | ||
250 | 45 | </control> | ||
251 | 46 | |||
252 | 47 | <control> | ||
253 | 48 | <group>[Master]</group> | ||
254 | 49 | <status>0x90</status> | ||
255 | 50 | <midino>0x23</midino> | ||
256 | 51 | <key>DJTechDJM101.vumeter_select_pfl</key> | ||
257 | 52 | <options> | ||
258 | 53 | <Script-Binding/> | ||
259 | 54 | </options> | ||
260 | 55 | </control> | ||
261 | 56 | |||
262 | 57 | <control> | ||
263 | 58 | <group>[Master]</group> | ||
264 | 59 | <key>volume</key> | ||
265 | 60 | <status>0xB0</status> | ||
266 | 61 | <midino>0x43</midino> | ||
267 | 62 | <options> | ||
268 | 63 | <normal/> | ||
269 | 64 | </options> | ||
270 | 65 | </control> | ||
271 | 66 | |||
272 | 67 | <control> | ||
273 | 68 | <group>[Master]</group> | ||
274 | 69 | <key>crossfader</key> | ||
275 | 70 | <status>0xB0</status> | ||
276 | 71 | <midino>0x40</midino> | ||
277 | 72 | <options> | ||
278 | 73 | <normal/> | ||
279 | 74 | </options> | ||
280 | 75 | </control> | ||
281 | 76 | |||
282 | 77 | <!-- channel 1 --> | ||
283 | 78 | |||
284 | 79 | <control> | ||
285 | 80 | <group>[Channel1]</group> | ||
286 | 81 | <key>pregain</key> | ||
287 | 82 | <status>0xB0</status> | ||
288 | 83 | <midino>0x48</midino> | ||
289 | 84 | <options> | ||
290 | 85 | <normal/> | ||
291 | 86 | </options> | ||
292 | 87 | </control> | ||
293 | 88 | |||
294 | 89 | <control> | ||
295 | 90 | <group>[Channel1]</group> | ||
296 | 91 | <key>volume</key> | ||
297 | 92 | <status>0xB0</status> | ||
298 | 93 | <midino>0x41</midino> | ||
299 | 94 | <options> | ||
300 | 95 | <normal/> | ||
301 | 96 | </options> | ||
302 | 97 | </control> | ||
303 | 98 | |||
304 | 99 | <control> | ||
305 | 100 | <group>[Channel1]</group> | ||
306 | 101 | <key>pfl</key> | ||
307 | 102 | <status>0x90</status> | ||
308 | 103 | <midino>0x21</midino> | ||
309 | 104 | <options> | ||
310 | 105 | <normal/> | ||
311 | 106 | </options> | ||
312 | 107 | </control> | ||
313 | 108 | |||
314 | 109 | <!-- channel 1 eq --> | ||
315 | 110 | |||
316 | 111 | <control> | ||
317 | 112 | <group>[Channel1]</group> | ||
318 | 113 | <key>filterHigh</key> | ||
319 | 114 | <status>0xB0</status> | ||
320 | 115 | <midino>0x4A</midino> | ||
321 | 116 | <options> | ||
322 | 117 | <normal/> | ||
323 | 118 | </options> | ||
324 | 119 | </control> | ||
325 | 120 | <control> | ||
326 | 121 | <group>[Channel1]</group> | ||
327 | 122 | <key>filterMid</key> | ||
328 | 123 | <status>0xB0</status> | ||
329 | 124 | <midino>0x4E</midino> | ||
330 | 125 | <options> | ||
331 | 126 | <normal/> | ||
332 | 127 | </options> | ||
333 | 128 | </control> | ||
334 | 129 | <control> | ||
335 | 130 | <group>[Channel1]</group> | ||
336 | 131 | <key>filterLow</key> | ||
337 | 132 | <status>0xB0</status> | ||
338 | 133 | <midino>0x4C</midino> | ||
339 | 134 | <options> | ||
340 | 135 | <normal/> | ||
341 | 136 | </options> | ||
342 | 137 | </control> | ||
343 | 138 | |||
344 | 139 | <!-- channel 2 --> | ||
345 | 140 | |||
346 | 141 | <control> | ||
347 | 142 | <group>[Channel2]</group> | ||
348 | 143 | <key>pregain</key> | ||
349 | 144 | <status>0xB0</status> | ||
350 | 145 | <midino>0x4F</midino> | ||
351 | 146 | <options> | ||
352 | 147 | <normal/> | ||
353 | 148 | </options> | ||
354 | 149 | </control> | ||
355 | 150 | |||
356 | 151 | <control> | ||
357 | 152 | <group>[Channel2]</group> | ||
358 | 153 | <key>volume</key> | ||
359 | 154 | <status>0xB0</status> | ||
360 | 155 | <midino>0x42</midino> | ||
361 | 156 | <options> | ||
362 | 157 | <normal/> | ||
363 | 158 | </options> | ||
364 | 159 | </control> | ||
365 | 160 | |||
366 | 161 | <control> | ||
367 | 162 | <group>[Channel2]</group> | ||
368 | 163 | <key>pfl</key> | ||
369 | 164 | <status>0x90</status> | ||
370 | 165 | <midino>0x22</midino> | ||
371 | 166 | <options> | ||
372 | 167 | <normal/> | ||
373 | 168 | </options> | ||
374 | 169 | </control> | ||
375 | 170 | |||
376 | 171 | <!-- channel 2 eq --> | ||
377 | 172 | |||
378 | 173 | <control> | ||
379 | 174 | <group>[Channel2]</group> | ||
380 | 175 | <key>filterHigh</key> | ||
381 | 176 | <status>0xB0</status> | ||
382 | 177 | <midino>0x4D</midino> | ||
383 | 178 | <options> | ||
384 | 179 | <normal/> | ||
385 | 180 | </options> | ||
386 | 181 | </control> | ||
387 | 182 | <control> | ||
388 | 183 | <group>[Channel2]</group> | ||
389 | 184 | <key>filterMid</key> | ||
390 | 185 | <status>0xB0</status> | ||
391 | 186 | <midino>0x4B</midino> | ||
392 | 187 | <options> | ||
393 | 188 | <normal/> | ||
394 | 189 | </options> | ||
395 | 190 | </control> | ||
396 | 191 | <control> | ||
397 | 192 | <group>[Channel2]</group> | ||
398 | 193 | <key>filterLow</key> | ||
399 | 194 | <status>0xB0</status> | ||
400 | 195 | <midino>0x49</midino> | ||
401 | 196 | <options> | ||
402 | 197 | <normal/> | ||
403 | 198 | </options> | ||
404 | 199 | </control> | ||
405 | 200 | |||
406 | 201 | </controls> | ||
407 | 202 | <outputs/> | ||
408 | 203 | </controller> | ||
409 | 204 | </MixxxControllerPreset> | ||
410 | 0 | 205 | ||
411 | === added file 'mixxx/res/controllers/DJ-Tech-CDJ-101-scripts.js' | |||
412 | --- mixxx/res/controllers/DJ-Tech-CDJ-101-scripts.js 1970-01-01 00:00:00 +0000 | |||
413 | +++ mixxx/res/controllers/DJ-Tech-CDJ-101-scripts.js 2012-05-26 14:59:19 +0000 | |||
414 | @@ -0,0 +1,245 @@ | |||
415 | 1 | /****************************************************************/ | ||
416 | 2 | /* DJ-Tech CDJ101 controller script */ | ||
417 | 3 | /* For Mixxx version 1.11 */ | ||
418 | 4 | /* Author: zestoi */ | ||
419 | 5 | /****************************************************************/ | ||
420 | 6 | // | ||
421 | 7 | // pitch slider works as you'd expect | ||
422 | 8 | // holding down the push button works as a "shift" to activate secondary functions | ||
423 | 9 | // needs the cdj101 to be on midi channel 1 for deck1 and 2 for deck2 | ||
424 | 10 | // | ||
425 | 11 | // track playing: | ||
426 | 12 | // | ||
427 | 13 | // * surface of jog wheel: scratch | ||
428 | 14 | // * edge of jog wheel: tempo bend | ||
429 | 15 | // * shift + edge of jog wheel: fine tempo bend | ||
430 | 16 | // | ||
431 | 17 | // track not playing: | ||
432 | 18 | // | ||
433 | 19 | // * click push button: load a track | ||
434 | 20 | // * surface of jog wheel: scratch thru track | ||
435 | 21 | // * shift + surface of jog wheel: scan through track quickly | ||
436 | 22 | // * edge of jog wheel: jog though track slowly | ||
437 | 23 | // * shift + cue: move beatgrid | ||
438 | 24 | // | ||
439 | 25 | // track playing or not: | ||
440 | 26 | // | ||
441 | 27 | // * rotate push button: navigate tracks | ||
442 | 28 | // * shift + rotate push button: switch between playlists | ||
443 | 29 | // * cue button: default cue behaviour | ||
444 | 30 | // * play: toggle play | ||
445 | 31 | // * shift + play: sync | ||
446 | 32 | // | ||
447 | 33 | |||
448 | 34 | DJTechCDJ101 = {}; | ||
449 | 35 | DJTechCDJ101.pushmaxtime = 200; | ||
450 | 36 | DJTechCDJ101.pushed = false; | ||
451 | 37 | DJTechCDJ101.pushedon = 0; | ||
452 | 38 | DJTechCDJ101.outer2inner = false; | ||
453 | 39 | DJTechCDJ101.scratch_timeout = 100; | ||
454 | 40 | |||
455 | 41 | DJTechCDJ101.init = function(id) { | ||
456 | 42 | engine.connectControl("[Channel1]", "play", "DJTechCDJ101.play_feedback_deck1"); | ||
457 | 43 | engine.connectControl("[Channel2]", "play", "DJTechCDJ101.play_feedback_deck2"); | ||
458 | 44 | engine.connectControl("[Channel1]", "cue_default", "DJTechCDJ101.cue_feedback_deck1"); | ||
459 | 45 | engine.connectControl("[Channel2]", "cue_default", "DJTechCDJ101.cue_feedback_deck2"); | ||
460 | 46 | } | ||
461 | 47 | |||
462 | 48 | DJTechCDJ101.shutdown = function() {} | ||
463 | 49 | |||
464 | 50 | // | ||
465 | 51 | // utility function | ||
466 | 52 | // | ||
467 | 53 | |||
468 | 54 | DJTechCDJ101.mtime = function() | ||
469 | 55 | { | ||
470 | 56 | var t = new Date(); | ||
471 | 57 | return t.getTime(); | ||
472 | 58 | } | ||
473 | 59 | |||
474 | 60 | // | ||
475 | 61 | // cue+play led feedback | ||
476 | 62 | // | ||
477 | 63 | |||
478 | 64 | DJTechCDJ101.play_feedback_deck1 = function(value) | ||
479 | 65 | { | ||
480 | 66 | midi.sendShortMsg(0x90, 0x2a, value > 0 ? 0x7f : 0); | ||
481 | 67 | } | ||
482 | 68 | |||
483 | 69 | DJTechCDJ101.play_feedback_deck2 = function(value) | ||
484 | 70 | { | ||
485 | 71 | midi.sendShortMsg(0x91, 0x2a, value > 0 ? 0x7f : 0); | ||
486 | 72 | } | ||
487 | 73 | |||
488 | 74 | DJTechCDJ101.cue_feedback_deck1 = function(value) | ||
489 | 75 | { | ||
490 | 76 | midi.sendShortMsg(0x90, 0x2b, value > 0 ? 0x7f : 0); | ||
491 | 77 | } | ||
492 | 78 | |||
493 | 79 | DJTechCDJ101.cue_feedback_deck2 = function(value) | ||
494 | 80 | { | ||
495 | 81 | midi.sendShortMsg(0x91, 0x2b, value > 0 ? 0x7f : 0); | ||
496 | 82 | } | ||
497 | 83 | |||
498 | 84 | // | ||
499 | 85 | // translate 14bit pitchbend message into pitch control | ||
500 | 86 | // | ||
501 | 87 | |||
502 | 88 | DJTechCDJ101.pitch = function(channel, lsb, msb, status, group) | ||
503 | 89 | { | ||
504 | 90 | engine.setValue(group, "rate", script.pitch(lsb, msb, status)); // not working for some reason | ||
505 | 91 | //engine.setValue(group, "rate", (8192 - (msb << 7 | lsb)) / 8192); | ||
506 | 92 | } | ||
507 | 93 | |||
508 | 94 | DJTechCDJ101.beatjump = function(group, jump) | ||
509 | 95 | { | ||
510 | 96 | jump = jump * 120 / engine.getValue(group, "bpm") / engine.getValue(group, "track_samples") * engine.getValue(group, "track_samplerate"); | ||
511 | 97 | engine.setValue(group, "playposition", engine.getValue(group, "playposition") + jump); | ||
512 | 98 | } | ||
513 | 99 | |||
514 | 100 | // | ||
515 | 101 | // hold down encoder and turn to change playlists | ||
516 | 102 | // turn while not pushed in to scroll through tracks | ||
517 | 103 | // click to load track | ||
518 | 104 | // | ||
519 | 105 | |||
520 | 106 | DJTechCDJ101.browse = function(channel, control, value, status, group) | ||
521 | 107 | { | ||
522 | 108 | if (DJTechCDJ101.pushed) { | ||
523 | 109 | engine.setValue("[Playlist]", value == 0x41 ? "SelectNextPlaylist" : "SelectPrevPlaylist", 1); | ||
524 | 110 | } | ||
525 | 111 | else { | ||
526 | 112 | engine.setValue("[Playlist]", value == 0x41 ? "SelectNextTrack" : "SelectPrevTrack", 1); | ||
527 | 113 | } | ||
528 | 114 | } | ||
529 | 115 | |||
530 | 116 | DJTechCDJ101.push = function(channel, control, value, status, group) | ||
531 | 117 | { | ||
532 | 118 | if (value > 0) { | ||
533 | 119 | DJTechCDJ101.pushed = true; | ||
534 | 120 | DJTechCDJ101.pushedon = DJTechCDJ101.mtime(); | ||
535 | 121 | } | ||
536 | 122 | else { | ||
537 | 123 | |||
538 | 124 | // | ||
539 | 125 | // load selected track if released quickly enough | ||
540 | 126 | // | ||
541 | 127 | |||
542 | 128 | if (DJTechCDJ101.mtime() - DJTechCDJ101.pushedon < DJTechCDJ101.pushmaxtime) { | ||
543 | 129 | engine.setValue(group, "LoadSelectedTrack", 1); | ||
544 | 130 | } | ||
545 | 131 | |||
546 | 132 | DJTechCDJ101.pushed = false; | ||
547 | 133 | DJTechCDJ101.pushedon = 0; | ||
548 | 134 | } | ||
549 | 135 | } | ||
550 | 136 | |||
551 | 137 | // | ||
552 | 138 | // when deck is not playing and the push button is held, pressing cue will move the beatgrid | ||
553 | 139 | // | ||
554 | 140 | |||
555 | 141 | DJTechCDJ101.cue = function(channel, control, value, status, group) | ||
556 | 142 | { | ||
557 | 143 | if (DJTechCDJ101.pushed && !engine.getValue(group, "play")) { | ||
558 | 144 | engine.setValue(group, "beats_translate_curpos", value > 0 ? 1 : 0); | ||
559 | 145 | } | ||
560 | 146 | else { | ||
561 | 147 | engine.setValue(group, "cue_default", value > 0 ? 1 : 0); | ||
562 | 148 | } | ||
563 | 149 | } | ||
564 | 150 | |||
565 | 151 | // | ||
566 | 152 | // when the push button is held, pressing play will sync | ||
567 | 153 | // | ||
568 | 154 | |||
569 | 155 | DJTechCDJ101.play = function(channel, control, value, status, group) | ||
570 | 156 | { | ||
571 | 157 | if (DJTechCDJ101.pushed) { | ||
572 | 158 | engine.setValue(group, "beatsync", value > 0 ? 1 : 0); | ||
573 | 159 | } | ||
574 | 160 | else if (value > 0) { | ||
575 | 161 | // | ||
576 | 162 | // we want play to toggle | ||
577 | 163 | // | ||
578 | 164 | |||
579 | 165 | engine.setValue(group, "play", !engine.getValue(group, "play")); | ||
580 | 166 | } | ||
581 | 167 | } | ||
582 | 168 | |||
583 | 169 | // | ||
584 | 170 | // when deck is playing either enable or disable scratch mode, no action otherwise | ||
585 | 171 | // | ||
586 | 172 | |||
587 | 173 | DJTechCDJ101.jogtouch = function(channel, control, value, status, group) | ||
588 | 174 | { | ||
589 | 175 | var deck = parseInt(group.substring(8,9)); | ||
590 | 176 | |||
591 | 177 | if (value > 0) { | ||
592 | 178 | engine.scratchEnable(deck, 143, 45, 0.125, 0.125/32); | ||
593 | 179 | } | ||
594 | 180 | else { | ||
595 | 181 | // | ||
596 | 182 | // don't disable right away in case of spin backs if playing and also morph | ||
597 | 183 | // outer jog movements into top jog movements during this time | ||
598 | 184 | // | ||
599 | 185 | |||
600 | 186 | if (!engine.getValue(group, "play")) { | ||
601 | 187 | DJTechCDJ101.finishScratch(deck, false); | ||
602 | 188 | } | ||
603 | 189 | else { | ||
604 | 190 | DJTechCDJ101.outer2inner = true; | ||
605 | 191 | DJTechCDJ101.scratch_timer = engine.beginTimer(DJTechCDJ101.scratch_timeout, 'DJTechCDJ101.finishScratch(' + deck + ', true)'); | ||
606 | 192 | } | ||
607 | 193 | } | ||
608 | 194 | } | ||
609 | 195 | |||
610 | 196 | DJTechCDJ101.finishScratch = function(deck, stop_timer) | ||
611 | 197 | { | ||
612 | 198 | if (stop_timer) { | ||
613 | 199 | engine.stopTimer(DJTechCDJ101.scratch_timer); | ||
614 | 200 | } | ||
615 | 201 | engine.scratchDisable(deck); | ||
616 | 202 | DJTechCDJ101.outer2inner = false; | ||
617 | 203 | } | ||
618 | 204 | |||
619 | 205 | // | ||
620 | 206 | // use outer part of jog to pitchbend when in play mode and fine track seek when not | ||
621 | 207 | // | ||
622 | 208 | |||
623 | 209 | DJTechCDJ101.jogouter = function(channel, control, value, status, group) | ||
624 | 210 | { | ||
625 | 211 | // | ||
626 | 212 | // when touch surface has been release for a short time convert | ||
627 | 213 | // outer jog movements into surface jog ones for spinbacks etc | ||
628 | 214 | // | ||
629 | 215 | |||
630 | 216 | if (DJTechCDJ101.outer2inner) { | ||
631 | 217 | return DJTechCDJ101.jogtop(channel, control, value, status, group); | ||
632 | 218 | } | ||
633 | 219 | |||
634 | 220 | // | ||
635 | 221 | // scale down based on whether we are playing and the shift is held down | ||
636 | 222 | // | ||
637 | 223 | |||
638 | 224 | value = (value - 0x40) / 2; | ||
639 | 225 | if (DJTechCDJ101.pushed) value /= 2.5; | ||
640 | 226 | if (!engine.getValue(group, "play")) value /= 2.5; | ||
641 | 227 | engine.setValue(group, "jog", value); | ||
642 | 228 | } | ||
643 | 229 | |||
644 | 230 | // | ||
645 | 231 | // track playing: top of jog scratches | ||
646 | 232 | // track not playing: seek thru track (using same scratch ticks and gives more postive response) or seek faster through track when push button held down | ||
647 | 233 | // | ||
648 | 234 | |||
649 | 235 | DJTechCDJ101.jogtop = function(channel, control, value, status, group) | ||
650 | 236 | { | ||
651 | 237 | value -= 0x40; | ||
652 | 238 | if (!engine.getValue(group, "play") && DJTechCDJ101.pushed) { | ||
653 | 239 | DJTechCDJ101.beatjump(group, value); | ||
654 | 240 | } | ||
655 | 241 | else { | ||
656 | 242 | engine.scratchTick(parseInt(group.substring(8,9)), value); | ||
657 | 243 | } | ||
658 | 244 | } | ||
659 | 245 | |||
660 | 0 | 246 | ||
661 | === added file 'mixxx/res/controllers/DJ-Tech-DJM-101-scripts.js' | |||
662 | --- mixxx/res/controllers/DJ-Tech-DJM-101-scripts.js 1970-01-01 00:00:00 +0000 | |||
663 | +++ mixxx/res/controllers/DJ-Tech-DJM-101-scripts.js 2012-05-26 14:59:19 +0000 | |||
664 | @@ -0,0 +1,110 @@ | |||
665 | 1 | /****************************************************************/ | ||
666 | 2 | /* DJ-Tech DJM101 controller script */ | ||
667 | 3 | /* For Mixxx version 1.11 */ | ||
668 | 4 | /* Author: zestoi */ | ||
669 | 5 | /****************************************************************/ | ||
670 | 6 | |||
671 | 7 | DJTechDJM101 = {}; | ||
672 | 8 | DJTechDJM101.vumeter = {}; | ||
673 | 9 | DJTechDJM101.vumeter[1] = 0; | ||
674 | 10 | DJTechDJM101.vumeter[2] = 0; | ||
675 | 11 | |||
676 | 12 | DJTechDJM101.init = function(id) { | ||
677 | 13 | DJTechDJM101.vumeter_select(true); | ||
678 | 14 | engine.connectControl("[Master]", "VuMeterL", "DJTechDJM101.VuMeterMasterL"); | ||
679 | 15 | engine.connectControl("[Master]", "VuMeterR", "DJTechDJM101.VuMeterMasterR"); | ||
680 | 16 | engine.connectControl("[Channel1]", "VuMeter", "DJTechDJM101.VuMeterDeck1"); | ||
681 | 17 | engine.connectControl("[Channel2]", "VuMeter", "DJTechDJM101.VuMeterDeck2"); | ||
682 | 18 | engine.connectControl("[Channel1]", "pfl", "DJTechDJM101.pfl"); | ||
683 | 19 | engine.connectControl("[Channel2]", "pfl", "DJTechDJM101.pfl"); | ||
684 | 20 | } | ||
685 | 21 | |||
686 | 22 | DJTechDJM101.shutdown = function() {} | ||
687 | 23 | |||
688 | 24 | // | ||
689 | 25 | // change output to vumeter and reset | ||
690 | 26 | // | ||
691 | 27 | |||
692 | 28 | DJTechDJM101.vumeter_select = function(master) | ||
693 | 29 | { | ||
694 | 30 | DJTechDJM101.vumeter_master_mode = master; | ||
695 | 31 | DJTechDJM101.update_vumeter(1, 0); | ||
696 | 32 | DJTechDJM101.update_vumeter(2, 0); | ||
697 | 33 | } | ||
698 | 34 | |||
699 | 35 | // | ||
700 | 36 | // select what data is sent to the vumeter | ||
701 | 37 | // | ||
702 | 38 | |||
703 | 39 | DJTechDJM101.vumeter_select_master = function(channel, control, value, status, group) | ||
704 | 40 | { | ||
705 | 41 | if (value > 0) { | ||
706 | 42 | DJTechDJM101.vumeter_select(true); | ||
707 | 43 | } | ||
708 | 44 | } | ||
709 | 45 | |||
710 | 46 | DJTechDJM101.vumeter_select_pfl = function(channel, control, value, status, group) | ||
711 | 47 | { | ||
712 | 48 | if (value > 0) { | ||
713 | 49 | DJTechDJM101.vumeter_select(false); | ||
714 | 50 | } | ||
715 | 51 | } | ||
716 | 52 | |||
717 | 53 | // | ||
718 | 54 | // update a vumeter channel | ||
719 | 55 | // | ||
720 | 56 | |||
721 | 57 | DJTechDJM101.update_vumeter = function(channel, value) | ||
722 | 58 | { | ||
723 | 59 | var newval = parseInt(value * 0xf7); | ||
724 | 60 | if (DJTechDJM101.vumeter[channel] != newval) { | ||
725 | 61 | DJTechDJM101.vumeter[channel] = newval; | ||
726 | 62 | |||
727 | 63 | // | ||
728 | 64 | // a bit nasty - four different cc's depending on master/pfl mode and which channel | ||
729 | 65 | // | ||
730 | 66 | |||
731 | 67 | midi.sendShortMsg(0xb0, DJTechDJM101.vumeter_master_mode ? 0x4f + channel : 0x51 + channel, newval); | ||
732 | 68 | } | ||
733 | 69 | } | ||
734 | 70 | |||
735 | 71 | // | ||
736 | 72 | // only feed the correct levels to each channel of the vumeter | ||
737 | 73 | // | ||
738 | 74 | |||
739 | 75 | DJTechDJM101.VuMeterMasterL = function(value) | ||
740 | 76 | { | ||
741 | 77 | if (DJTechDJM101.vumeter_master_mode == false) return; | ||
742 | 78 | DJTechDJM101.update_vumeter(1, value); | ||
743 | 79 | } | ||
744 | 80 | |||
745 | 81 | DJTechDJM101.VuMeterMasterR = function(value) | ||
746 | 82 | { | ||
747 | 83 | if (DJTechDJM101.vumeter_master_mode == false) return; | ||
748 | 84 | DJTechDJM101.update_vumeter(2, value); | ||
749 | 85 | } | ||
750 | 86 | |||
751 | 87 | DJTechDJM101.VuMeterDeck1 = function(value) | ||
752 | 88 | { | ||
753 | 89 | if (DJTechDJM101.vumeter_master_mode == true) return; | ||
754 | 90 | DJTechDJM101.update_vumeter(1, value); | ||
755 | 91 | } | ||
756 | 92 | |||
757 | 93 | DJTechDJM101.VuMeterDeck2 = function(value) | ||
758 | 94 | { | ||
759 | 95 | if (DJTechDJM101.vumeter_master_mode == true) return; | ||
760 | 96 | DJTechDJM101.update_vumeter(2, value); | ||
761 | 97 | } | ||
762 | 98 | |||
763 | 99 | // | ||
764 | 100 | // led feedback for headphone cue buttons | ||
765 | 101 | // | ||
766 | 102 | |||
767 | 103 | DJTechDJM101.pfl = function(value, group) | ||
768 | 104 | { | ||
769 | 105 | // has to be a noteon msg in both case and seems more reliable issuing 0x7f for 'on' amd 0x0 for 'off' | ||
770 | 106 | midi.sendShortMsg(0x90, group == "[Channel1]" ? 0x21 : 0x22, value > 0 ? 0x7f : 0); | ||
771 | 107 | } | ||
772 | 108 | |||
773 | 109 | |||
774 | 110 | |||
775 | 0 | 111 | ||
776 | === added file 'mixxx/res/controllers/Hercules DJ Console Mk2.cntrlr.xml' | |||
777 | --- mixxx/res/controllers/Hercules DJ Console Mk2.cntrlr.xml 1970-01-01 00:00:00 +0000 | |||
778 | +++ mixxx/res/controllers/Hercules DJ Console Mk2.cntrlr.xml 2012-05-26 14:59:19 +0000 | |||
779 | @@ -0,0 +1,13 @@ | |||
780 | 1 | <?xml version="1.0" encoding="utf-8"?> | ||
781 | 2 | <MixxxControllerPreset schemaVersion="1"> | ||
782 | 3 | <info> | ||
783 | 4 | <name>Hercules DJ Console MK2 HID</name> | ||
784 | 5 | <author>zestoi</author> | ||
785 | 6 | <description>Native high-resolution HID script for the Hercules DJ Console MK2 controller.</description> | ||
786 | 7 | </info> | ||
787 | 8 | <controller id="Hercules DJ Console MK2 HID"> | ||
788 | 9 | <scriptfiles> | ||
789 | 10 | <file filename="Hercules-DJ-Console-Mk2-hid-scripts.js" functionprefix="HerculesMk2Hid"/> | ||
790 | 11 | </scriptfiles> | ||
791 | 12 | </controller> | ||
792 | 13 | </MixxxControllerPreset> | ||
793 | 0 | 14 | ||
794 | === added file 'mixxx/res/controllers/Hercules-DJ-Console-Mk2-hid-scripts.js' | |||
795 | --- mixxx/res/controllers/Hercules-DJ-Console-Mk2-hid-scripts.js 1970-01-01 00:00:00 +0000 | |||
796 | +++ mixxx/res/controllers/Hercules-DJ-Console-Mk2-hid-scripts.js 2012-05-26 14:59:19 +0000 | |||
797 | @@ -0,0 +1,611 @@ | |||
798 | 1 | /****************************************************************/ | ||
799 | 2 | /* Hercules DJ Console Mk2 HID controller script */ | ||
800 | 3 | /* For Mixxx version 1.11 */ | ||
801 | 4 | /* Author: zestoi */ | ||
802 | 5 | /****************************************************************/ | ||
803 | 6 | |||
804 | 7 | HerculesMk2Hid = new Controller(); | ||
805 | 8 | HerculesMk2Hid.controls = []; | ||
806 | 9 | HerculesMk2Hid.leds = []; | ||
807 | 10 | HerculesMk2Hid.cache_in = []; | ||
808 | 11 | HerculesMk2Hid.cache_out = []; | ||
809 | 12 | HerculesMk2Hid.callbacks = []; | ||
810 | 13 | HerculesMk2Hid.feedbacks = []; | ||
811 | 14 | HerculesMk2Hid.layer = [ "fx", "fx" ]; // fx, hotcue, loop, kill | ||
812 | 15 | HerculesMk2Hid.tempo_scaling = 400; | ||
813 | 16 | HerculesMk2Hid.beatjump_size = 8; | ||
814 | 17 | HerculesMk2Hid.kills = [ { filterHighKill: 0, filterMidKill: 0, filterLowKill: 0 }, { filterHighKill: 0, filterMidKill: 0, filterLowKill: 0 } ]; | ||
815 | 18 | HerculesMk2Hid.loop_lengths = [ 0.25, 0.5, 1 ]; // edit to loop size needed | ||
816 | 19 | HerculesMk2Hid.kill_order = [ "filterHighKill", "filterMidKill", "filterLowKill" ]; // edit if needed | ||
817 | 20 | HerculesMk2Hid.scratch_enabled = { "[Channel1]": false, "[Channel2]": false }; | ||
818 | 21 | HerculesMk2Hid.jog_skip = { "[Channel1]": true, "[Channel2]": true }; | ||
819 | 22 | HerculesMk2Hid.shift = false; // either autobeat button | ||
820 | 23 | |||
821 | 24 | // | ||
822 | 25 | // the actual mapping is defined in this function | ||
823 | 26 | // | ||
824 | 27 | |||
825 | 28 | HerculesMk2Hid.init = function() { | ||
826 | 29 | |||
827 | 30 | var c = HerculesMk2Hid; | ||
828 | 31 | |||
829 | 32 | // | ||
830 | 33 | // define the hid packet | ||
831 | 34 | // | ||
832 | 35 | |||
833 | 36 | c.define_hid_format(); | ||
834 | 37 | |||
835 | 38 | // | ||
836 | 39 | // create the actual mapping | ||
837 | 40 | // deck controls (will work for any decks as the group is passed in) | ||
838 | 41 | // | ||
839 | 42 | |||
840 | 43 | c.capture("crossfader", "all", function(g, e, v) { engine.setValue(g, e, (v - 128) / 128); }); | ||
841 | 44 | |||
842 | 45 | c.capture("play", "press", function(g, e, v) { engine.setValue(g, e, !engine.getValue(g, e)); }); | ||
843 | 46 | c.capture("cue_default", "all", function(g, e, v) { engine.setValue(g, e, v); }); | ||
844 | 47 | c.capture("beatsync", "all", function(g, e, v) { HerculesMk2Hid.shift = v > 0; engine.setValue(g, e, v); }); | ||
845 | 48 | |||
846 | 49 | c.capture("volume", "all", function(g, e, v) { engine.setValue(g, e, v / 256); }); | ||
847 | 50 | c.capture("filterHigh", "all", function(g, e, v) { engine.setValue(g, e, v / 128); }); | ||
848 | 51 | c.capture("filterMid", "all", function(g, e, v) { engine.setValue(g, e, v / 128); }); | ||
849 | 52 | c.capture("filterLow", "all", function(g, e, v) { engine.setValue(g, e, v / 128); }); | ||
850 | 53 | |||
851 | 54 | c.capture("jog", "all", function(g, e, v, ctrl) { | ||
852 | 55 | // skip initial jog values | ||
853 | 56 | if (HerculesMk2Hid.jog_skip[g]) { | ||
854 | 57 | HerculesMk2Hid.jog_skip[g] = false; | ||
855 | 58 | return; | ||
856 | 59 | } | ||
857 | 60 | |||
858 | 61 | // scratch mode | ||
859 | 62 | if (HerculesMk2Hid.scratch_enabled[g]) { | ||
860 | 63 | engine.scratchTick(parseInt(g.substring(8,9)), ctrl.relative); | ||
861 | 64 | } | ||
862 | 65 | |||
863 | 66 | // fine jog mode when playing | ||
864 | 67 | else if (engine.getValue(g, "play")) { | ||
865 | 68 | engine.setValue(g, e, ctrl.relative/2); | ||
866 | 69 | } | ||
867 | 70 | |||
868 | 71 | // track browsing when shift held (sync) and not playing | ||
869 | 72 | else if (HerculesMk2Hid.shift) { | ||
870 | 73 | engine.setValue("[Playlist]", "SelectTrackKnob", ctrl.relative); | ||
871 | 74 | } | ||
872 | 75 | |||
873 | 76 | // normal jog mode when not playing | ||
874 | 77 | else { | ||
875 | 78 | engine.setValue(g, e, ctrl.relative); | ||
876 | 79 | } | ||
877 | 80 | }); | ||
878 | 81 | |||
879 | 82 | // | ||
880 | 83 | // double up pitch bend buttons as beatjumps when the track is stopped | ||
881 | 84 | // | ||
882 | 85 | |||
883 | 86 | c.capture("pitchbend_down", "all", function(g, e, v) { | ||
884 | 87 | if (engine.getValue(g, "play") == 0) { | ||
885 | 88 | engine.setValue(g, "back", v > 0 ? 1 : 0); | ||
886 | 89 | } | ||
887 | 90 | else if (v > 0) { | ||
888 | 91 | engine.setValue(g, "jog", -3); | ||
889 | 92 | } | ||
890 | 93 | }); | ||
891 | 94 | |||
892 | 95 | c.capture("pitchbend_up", "all", function(g, e, v) { | ||
893 | 96 | if (engine.getValue(g, "play") == 0) { | ||
894 | 97 | engine.setValue(g, "fwd", v > 0 ? 1 : 0); | ||
895 | 98 | } | ||
896 | 99 | else if (v > 0) { | ||
897 | 100 | engine.setValue(g, "jog", 3); | ||
898 | 101 | } | ||
899 | 102 | }); | ||
900 | 103 | |||
901 | 104 | // | ||
902 | 105 | // track browsing - don't use the joystick or track load buttons as they function as a normal mouse too | ||
903 | 106 | // (map joystick_y/joystick_x/load if you want to use the joystick) | ||
904 | 107 | // | ||
905 | 108 | |||
906 | 109 | c.capture("track_previous_a", "all", c.scroll_tracks); | ||
907 | 110 | c.capture("track_next_a", "all", c.scroll_tracks); | ||
908 | 111 | c.capture("track_previous_b", "press", function(g, e, v) { engine.setValue("[Channel1]", "LoadSelectedTrack", 1); }); | ||
909 | 112 | c.capture("track_next_b", "press", function(g, e, v) { engine.setValue("[Channel2]", "LoadSelectedTrack", 1); }); | ||
910 | 113 | |||
911 | 114 | // | ||
912 | 115 | // uncomment this code and the function HerculesMk2Hid.scroll_tracks_joystick() below if you really want the joystick | ||
913 | 116 | // to be used for track browsing and the left/right joystick buttons for track loading | ||
914 | 117 | // | ||
915 | 118 | |||
916 | 119 | /* | ||
917 | 120 | c.capture("load", "press", function(g, e, v) { engine.setValue(g, "LoadSelectedTrack", 1); }); | ||
918 | 121 | |||
919 | 122 | c.capture("joystick_y", "all", function(g, e, v) { | ||
920 | 123 | if (v == 128) { | ||
921 | 124 | HerculesMk2Hid.direction = 0; | ||
922 | 125 | if (HerculesMk2Hid.track_timer) { | ||
923 | 126 | engine.stopTimer(HerculesMk2Hid.track_timer); | ||
924 | 127 | HerculesMk2Hid.track_timer = null; | ||
925 | 128 | } | ||
926 | 129 | } | ||
927 | 130 | else { | ||
928 | 131 | if (v > 128) { | ||
929 | 132 | HerculesMk2Hid.direction = 1; | ||
930 | 133 | v -= 128; | ||
931 | 134 | } | ||
932 | 135 | else { | ||
933 | 136 | HerculesMk2Hid.direction = -1; | ||
934 | 137 | v = 128 - v; | ||
935 | 138 | } | ||
936 | 139 | |||
937 | 140 | if (v < 30) v = 30; | ||
938 | 141 | if (HerculesMk2Hid.track_timer) engine.stopTimer(HerculesMk2Hid.track_timer); | ||
939 | 142 | HerculesMk2Hid.track_timer = engine.beginTimer(parseInt(5120 / v), 'HerculesMk2Hid.scroll_tracks_joystick'); | ||
940 | 143 | } | ||
941 | 144 | }); | ||
942 | 145 | */ | ||
943 | 146 | |||
944 | 147 | // | ||
945 | 148 | // tempo encoder | ||
946 | 149 | // | ||
947 | 150 | |||
948 | 151 | c.capture("rate", "all", function(g, e, v, ctrl) { | ||
949 | 152 | var rate = engine.getValue(g, "rate") + ctrl.relative / c.tempo_scaling; | ||
950 | 153 | if (rate > 1) rate = 1; else if (rate < -1) rate = -1; | ||
951 | 154 | engine.setValue(g, e, rate); | ||
952 | 155 | }); | ||
953 | 156 | |||
954 | 157 | // | ||
955 | 158 | // enable/disable scratching with the beatlock buttons (as jogs are non touch sensitive) | ||
956 | 159 | // | ||
957 | 160 | |||
958 | 161 | c.capture("beatlock", "press", function(g, e, v) { | ||
959 | 162 | |||
960 | 163 | HerculesMk2Hid.scratch_enabled[g] = !HerculesMk2Hid.scratch_enabled[g]; | ||
961 | 164 | |||
962 | 165 | if (HerculesMk2Hid.scratch_enabled[g]) { | ||
963 | 166 | engine.scratchEnable(parseInt(g.substring(8,9)), 64, 45, 0.125, 0.125/32); | ||
964 | 167 | } | ||
965 | 168 | else { | ||
966 | 169 | engine.scratchDisable(parseInt(g.substring(8,9))); | ||
967 | 170 | } | ||
968 | 171 | |||
969 | 172 | c.send(g, e, HerculesMk2Hid.scratch_enabled[g] ? 1 : 0); | ||
970 | 173 | }); | ||
971 | 174 | |||
972 | 175 | // | ||
973 | 176 | // toggle between fx, hotcue and loop modes and update leds | ||
974 | 177 | // | ||
975 | 178 | |||
976 | 179 | c.capture("layer_select", "press", function(g, e, v) { | ||
977 | 180 | var deck = parseInt(g.substring(8,9)); | ||
978 | 181 | c.send(g, "fx", 0); | ||
979 | 182 | c.send(g, "hotcue", 0); | ||
980 | 183 | c.send(g, "loop", 0); | ||
981 | 184 | switch (c.layer[deck-1]) { | ||
982 | 185 | case "fx": c.layer[deck-1] = "hotcue"; break; | ||
983 | 186 | case "hotcue": c.layer[deck-1] = "loop"; break; | ||
984 | 187 | case "loop": | ||
985 | 188 | c.layer[deck-1] = "kill"; | ||
986 | 189 | c.send(g, "fx", !c.kills[deck-1]['filterHighKill']); | ||
987 | 190 | c.send(g, "hotcue", !c.kills[deck-1]['filterMidKill']); | ||
988 | 191 | c.send(g, "loop", !c.kills[deck-1]['filterLowKill']); | ||
989 | 192 | break; | ||
990 | 193 | case "kill": | ||
991 | 194 | c.layer[deck-1] = "fx"; | ||
992 | 195 | } | ||
993 | 196 | if (c.layer[deck-1] != "kill") { | ||
994 | 197 | c.send(g, c.layer[deck-1], 1); | ||
995 | 198 | } | ||
996 | 199 | }); | ||
997 | 200 | |||
998 | 201 | c.capture("layer_btn1", "all", function(g, e, v) { c.layer_btn(g, e, v); }); | ||
999 | 202 | c.capture("layer_btn2", "all", function(g, e, v) { c.layer_btn(g, e, v); }); | ||
1000 | 203 | c.capture("layer_btn3", "all", function(g, e, v) { c.layer_btn(g, e, v); }); | ||
1001 | 204 | |||
1002 | 205 | // | ||
1003 | 206 | // headphone cue | ||
1004 | 207 | // | ||
1005 | 208 | |||
1006 | 209 | c.capture("monitor_a", "all", function(g, e, v) { engine.setValue("[Channel1]", "pfl", v); }); | ||
1007 | 210 | c.capture("monitor_b", "all", function(g, e, v) { engine.setValue("[Channel2]", "pfl", v); }); | ||
1008 | 211 | c.capture("monitor_both", "all", function(g, e, v) { | ||
1009 | 212 | engine.setValue("[Channel1]", "pfl", v); | ||
1010 | 213 | engine.setValue("[Channel2]", "pfl", v); | ||
1011 | 214 | }); | ||
1012 | 215 | |||
1013 | 216 | // | ||
1014 | 217 | // led feedback | ||
1015 | 218 | // | ||
1016 | 219 | |||
1017 | 220 | c.feedback("[Channel1]", "play", function(g, e, v) { c.send(g, e, v); }); | ||
1018 | 221 | c.feedback("[Channel2]", "play", function(g, e, v) { c.send(g, e, v); }); | ||
1019 | 222 | c.feedback("[Channel1]", "cue_default", function(g, e, v) { c.send(g, e, v); }); | ||
1020 | 223 | c.feedback("[Channel2]", "cue_default", function(g, e, v) { c.send(g, e, v); }); | ||
1021 | 224 | c.feedback("[Channel1]", "beatsync", function(g, e, v) { c.send(g, e, v); }); | ||
1022 | 225 | c.feedback("[Channel2]", "beatsync", function(g, e, v) { c.send(g, e, v); }); | ||
1023 | 226 | |||
1024 | 227 | // | ||
1025 | 228 | // kill status | ||
1026 | 229 | // | ||
1027 | 230 | |||
1028 | 231 | c.feedback("[Channel1]", "filterHighKill", c.kill_status); | ||
1029 | 232 | c.feedback("[Channel1]", "filterMidKill", c.kill_status); | ||
1030 | 233 | c.feedback("[Channel1]", "filterLowKill", c.kill_status); | ||
1031 | 234 | |||
1032 | 235 | // | ||
1033 | 236 | // clear/setup any initial leds | ||
1034 | 237 | // | ||
1035 | 238 | |||
1036 | 239 | for (id in c.leds) { | ||
1037 | 240 | c.send(c.leds[id].group, c.leds[id].name, 0); | ||
1038 | 241 | } | ||
1039 | 242 | |||
1040 | 243 | c.send("[Channel1]", "fx", 1); | ||
1041 | 244 | c.send("[Channel2]", "fx", 1); | ||
1042 | 245 | } | ||
1043 | 246 | |||
1044 | 247 | // | ||
1045 | 248 | // map the 6 buttons that control either effects, hotcues, loops or kills | ||
1046 | 249 | // | ||
1047 | 250 | |||
1048 | 251 | HerculesMk2Hid.layer_btn = function(g, e, v) { | ||
1049 | 252 | var deck = parseInt(g.substring(8,9)); | ||
1050 | 253 | var btn = parseInt(e.substring(9,10)); | ||
1051 | 254 | switch (HerculesMk2Hid.layer[deck-1]) { | ||
1052 | 255 | case "fx": | ||
1053 | 256 | switch (btn) { | ||
1054 | 257 | case 1: | ||
1055 | 258 | engine.setValue("[Flanger]", "lfoDepth", 1); | ||
1056 | 259 | engine.setValue("[Flanger]", "lfoPeriod", 500000); | ||
1057 | 260 | engine.setValue("[Flanger]", "lfoDelay", 666); | ||
1058 | 261 | engine.setValue(g, "flanger", v > 0); | ||
1059 | 262 | break; | ||
1060 | 263 | case 2: | ||
1061 | 264 | script.spinback(g, v > 0); | ||
1062 | 265 | break; | ||
1063 | 266 | case 3: | ||
1064 | 267 | script.brake(g, v > 0); | ||
1065 | 268 | } | ||
1066 | 269 | break; | ||
1067 | 270 | case "hotcue": | ||
1068 | 271 | engine.setValue(g, "hotcue_" + btn + "_activate", v > 0 ? 1 : 0); | ||
1069 | 272 | break; | ||
1070 | 273 | case "loop": | ||
1071 | 274 | var len = HerculesMk2Hid.loop_lengths[btn-1]; | ||
1072 | 275 | engine.setValue(g, "beatloop_" + len + "_toggle", 1); | ||
1073 | 276 | break; | ||
1074 | 277 | case 'kill': | ||
1075 | 278 | if (v > 0) { | ||
1076 | 279 | engine.setValue(g, HerculesMk2Hid.kill_order[btn-1], !engine.getValue(g, HerculesMk2Hid.kill_order[btn-1])); | ||
1077 | 280 | } | ||
1078 | 281 | } | ||
1079 | 282 | } | ||
1080 | 283 | |||
1081 | 284 | // | ||
1082 | 285 | // beatjump - will get out of sync if called while deck is playing | ||
1083 | 286 | // | ||
1084 | 287 | |||
1085 | 288 | HerculesMk2Hid.beatjump = function(group, jump) { | ||
1086 | 289 | jump = jump * 120 / engine.getValue(group, "bpm") / engine.getValue(group, "track_samples") * engine.getValue(group, "track_samplerate"); | ||
1087 | 290 | engine.setValue(group, "playposition", engine.getValue(group, "playposition") + jump); | ||
1088 | 291 | } | ||
1089 | 292 | |||
1090 | 293 | // | ||
1091 | 294 | // playlist scroll nex/previous with auto-repeat when held | ||
1092 | 295 | // | ||
1093 | 296 | |||
1094 | 297 | HerculesMk2Hid.scroll_tracks = function(g, e, v) { | ||
1095 | 298 | if (v > 0) { | ||
1096 | 299 | engine.setValue("[Playlist]", e == "track_next_a" ? "SelectNextTrack" : "SelectPrevTrack", 1); | ||
1097 | 300 | if (!HerculesMk2Hid.scroll_timer) { | ||
1098 | 301 | HerculesMk2Hid.scroll_timer = engine.beginTimer(150, 'HerculesMk2Hid.scroll_tracks("[Playlist]","' + e + '",' + v + ')'); | ||
1099 | 302 | } | ||
1100 | 303 | } | ||
1101 | 304 | else { | ||
1102 | 305 | if (HerculesMk2Hid.scroll_timer) { | ||
1103 | 306 | engine.stopTimer(HerculesMk2Hid.scroll_timer); | ||
1104 | 307 | HerculesMk2Hid.scroll_timer = null; | ||
1105 | 308 | } | ||
1106 | 309 | } | ||
1107 | 310 | } | ||
1108 | 311 | |||
1109 | 312 | // | ||
1110 | 313 | // eq kill status | ||
1111 | 314 | // | ||
1112 | 315 | |||
1113 | 316 | HerculesMk2Hid.kill_status = function(g, e, v) { | ||
1114 | 317 | var deck = parseInt(g.substring(8,9)); | ||
1115 | 318 | HerculesMk2Hid.kills[deck-1][e] = v; | ||
1116 | 319 | |||
1117 | 320 | // | ||
1118 | 321 | // update leds with kill status if we're on that layer | ||
1119 | 322 | // | ||
1120 | 323 | |||
1121 | 324 | if (HerculesMk2Hid.layer[deck-1] == "kill") { | ||
1122 | 325 | switch (e) { | ||
1123 | 326 | case 'filterHighKill': HerculesMk2Hid.send(g, "fx", !v); break; | ||
1124 | 327 | case 'filterMidKill': HerculesMk2Hid.send(g, "hotcue", !v); break; | ||
1125 | 328 | case 'filterLowKill': HerculesMk2Hid.send(g, "loop", !v); | ||
1126 | 329 | } | ||
1127 | 330 | } | ||
1128 | 331 | } | ||
1129 | 332 | |||
1130 | 333 | /* | ||
1131 | 334 | HerculesMk2Hid.scroll_tracks_joystick = function() { | ||
1132 | 335 | engine.setValue("[Playlist]", HerculesMk2Hid.direction > 0 ? "SelectNextTrack" : "SelectPrevTrack", 1); | ||
1133 | 336 | } | ||
1134 | 337 | */ | ||
1135 | 338 | |||
1136 | 339 | |||
1137 | 340 | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||
1138 | 341 | // define the hid packet to event mapping, could be defined via xml so can be used in multiple mappings | ||
1139 | 342 | // naming the controls as much as possible inline with the mixxx engine names makes most mappings trivial | ||
1140 | 343 | // | ||
1141 | 344 | |||
1142 | 345 | HerculesMk2Hid.define_hid_format = function() { | ||
1143 | 346 | |||
1144 | 347 | var c = HerculesMk2Hid; | ||
1145 | 348 | var pid = 0x1; | ||
1146 | 349 | |||
1147 | 350 | // deck 1 | ||
1148 | 351 | |||
1149 | 352 | c.add_control(pid, "play", "[Channel1]", "button", 1, 0x80) | ||
1150 | 353 | c.add_control(pid, "cue_default", "[Channel1]", "button", 2, 0x01) | ||
1151 | 354 | c.add_control(pid, "track_previous_a", "[Channel1]", "button", 2, 0x04) | ||
1152 | 355 | c.add_control(pid, "track_next_a", "[Channel1]", "button", 2, 0x08) | ||
1153 | 356 | c.add_control(pid, "beatsync", "[Channel1]", "button", 2, 0x02) | ||
1154 | 357 | c.add_control(pid, "pitchbend_down", "[Channel1]", "button", 3, 0x08) | ||
1155 | 358 | c.add_control(pid, "pitchbend_up", "[Channel1]", "button", 3, 0x04) | ||
1156 | 359 | c.add_control(pid, "load", "[Channel1]", "button", 4, 0x04) | ||
1157 | 360 | c.add_control(pid, "beatlock", "[Channel1]", "button", 3, 0x20) | ||
1158 | 361 | c.add_control(pid, "source", "[Channel1]", "button", 4, 0x10) | ||
1159 | 362 | c.add_control(pid, "filterLow", "[Channel1]", "fader", 9, 0xff) | ||
1160 | 363 | c.add_control(pid, "filterMid", "[Channel1]", "fader", 10, 0xff) | ||
1161 | 364 | c.add_control(pid, "filterHigh", "[Channel1]", "fader", 11, 0xff) | ||
1162 | 365 | c.add_control(pid, "volume", "[Channel1]", "fader", 13, 0xff) | ||
1163 | 366 | c.add_control(pid, "rate", "[Channel1]", "encoder", 15, 0xff) | ||
1164 | 367 | c.add_control(pid, "jog", "[Channel1]", "encoder", 17, 0xff) | ||
1165 | 368 | c.add_control(pid, "layer_select", "[Channel1]", "button", 1, 0x40) | ||
1166 | 369 | c.add_control(pid, "layer_btn1", "[Channel1]", "button", 2, 0x40) | ||
1167 | 370 | c.add_control(pid, "layer_btn2", "[Channel1]", "button", 2, 0x20) | ||
1168 | 371 | c.add_control(pid, "layer_btn3", "[Channel1]", "button", 2, 0x10) | ||
1169 | 372 | |||
1170 | 373 | // deck 2 | ||
1171 | 374 | |||
1172 | 375 | c.add_control(pid, "play", "[Channel2]", "button", 1, 0x02) | ||
1173 | 376 | c.add_control(pid, "cue_default", "[Channel2]", "button", 1, 0x04) | ||
1174 | 377 | c.add_control(pid, "track_previous_b", "[Channel2]", "button", 1, 0x10) | ||
1175 | 378 | c.add_control(pid, "track_next_b", "[Channel2]", "button", 1, 0x20) | ||
1176 | 379 | c.add_control(pid, "beatsync", "[Channel2]", "button", 1, 0x08) | ||
1177 | 380 | c.add_control(pid, "pitchbend_down", "[Channel2]", "button", 3, 0x80) | ||
1178 | 381 | c.add_control(pid, "pitchbend_up", "[Channel2]", "button", 3, 0x40) | ||
1179 | 382 | c.add_control(pid, "load", "[Channel2]", "button", 4, 0x08) | ||
1180 | 383 | c.add_control(pid, "beatlock", "[Channel2]", "button", 4, 0x02) | ||
1181 | 384 | c.add_control(pid, "source", "[Channel2]", "button", 4, 0x20) | ||
1182 | 385 | c.add_control(pid, "filterLow", "[Channel2]", "fader", 6, 0xff) | ||
1183 | 386 | c.add_control(pid, "filterMid", "[Channel2]", "fader", 7, 0xff) | ||
1184 | 387 | c.add_control(pid, "filterHigh", "[Channel2]", "fader", 8, 0xff) | ||
1185 | 388 | c.add_control(pid, "volume", "[Channel2]", "fader", 14, 0xff) | ||
1186 | 389 | c.add_control(pid, "rate", "[Channel2]", "encoder", 16, 0xff) | ||
1187 | 390 | c.add_control(pid, "jog", "[Channel2]", "encoder", 18, 0xff) | ||
1188 | 391 | c.add_control(pid, "layer_select", "[Channel2]", "button", 1, 0x01) | ||
1189 | 392 | c.add_control(pid, "layer_btn1", "[Channel2]", "button", 2, 0x80) | ||
1190 | 393 | c.add_control(pid, "layer_btn2", "[Channel2]", "button", 3, 0x01) | ||
1191 | 394 | c.add_control(pid, "layer_btn3", "[Channel2]", "button", 3, 0x02) | ||
1192 | 395 | |||
1193 | 396 | // master | ||
1194 | 397 | |||
1195 | 398 | c.add_control(pid, "crossfader", "[Master]", "fader", 12, 0xff) | ||
1196 | 399 | c.add_control(pid, "joystick_x", "[Master]", "fader", 19, 0xff) | ||
1197 | 400 | c.add_control(pid, "joystick_y", "[Master]", "fader", 20, 0xff) | ||
1198 | 401 | |||
1199 | 402 | // headphone cue | ||
1200 | 403 | |||
1201 | 404 | c.add_control(pid, "monitor_a", "[Master]", "button", 5, 0x1); | ||
1202 | 405 | c.add_control(pid, "monitor_b", "[Master]", "button", 5, 0x2); | ||
1203 | 406 | //c.add_control(pid, "monitor_both", "[Master]", "button", 5, 0x4); | ||
1204 | 407 | c.add_control(pid, "monitor_both", "[Master]", "button", 5, 0x8); | ||
1205 | 408 | |||
1206 | 409 | // define led feedback | ||
1207 | 410 | |||
1208 | 411 | pid = 0; | ||
1209 | 412 | c.cache_out[pid] = [ pid, 0x0, 0x0, 0x0 ]; | ||
1210 | 413 | |||
1211 | 414 | c.add_control(pid, "play", "[Channel1]", "led", 2, 0x01); // blinking: 3, 0x2 | ||
1212 | 415 | c.add_control(pid, "cue_default", "[Channel1]", "led", 2, 0x08); | ||
1213 | 416 | c.add_control(pid, "beatsync", "[Channel1]", "led", 2, 0x10); | ||
1214 | 417 | c.add_control(pid, "beatlock", "[Channel1]", "led", 1, 0x01); | ||
1215 | 418 | |||
1216 | 419 | c.add_control(pid, "play", "[Channel2]", "led", 1, 0x40); // blinking: 3, 0x1 | ||
1217 | 420 | c.add_control(pid, "cue_default", "[Channel2]", "led", 1, 0x20); | ||
1218 | 421 | c.add_control(pid, "beatsync", "[Channel2]", "led", 2, 0x20); | ||
1219 | 422 | c.add_control(pid, "beatlock", "[Channel2]", "led", 1, 0x02); | ||
1220 | 423 | |||
1221 | 424 | c.add_control(pid, "fx", "[Channel1]", "led", 1, 0x04); | ||
1222 | 425 | c.add_control(pid, "fx", "[Channel2]", "led", 1, 0x08); | ||
1223 | 426 | c.add_control(pid, "hotcue", "[Channel2]", "led", 1, 0x10); | ||
1224 | 427 | c.add_control(pid, "hotcue", "[Channel1]", "led", 1, 0x80); | ||
1225 | 428 | c.add_control(pid, "loop", "[Channel1]", "led", 2, 0x40); | ||
1226 | 429 | c.add_control(pid, "loop", "[Channel2]", "led", 2, 0x80); | ||
1227 | 430 | } | ||
1228 | 431 | |||
1229 | 432 | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||
1230 | 433 | // non-specific controller framework to allow hid packets to be defined and processed via | ||
1231 | 434 | // callback functions - could/should be in a shared file | ||
1232 | 435 | // | ||
1233 | 436 | |||
1234 | 437 | HerculesMk2Hid.add_control = function(packetid, name, group, type, offset, mask) { | ||
1235 | 438 | if (type == "led") { | ||
1236 | 439 | HerculesMk2Hid.leds[group + name] = new HerculesMk2Hid.control(packetid, name, group, type, offset, mask); | ||
1237 | 440 | } | ||
1238 | 441 | else { | ||
1239 | 442 | if (HerculesMk2Hid.controls[offset] == undefined) { | ||
1240 | 443 | HerculesMk2Hid.controls[offset] = []; | ||
1241 | 444 | } | ||
1242 | 445 | HerculesMk2Hid.controls[offset].push(new HerculesMk2Hid.control(packetid, name, group, type, offset, mask)); | ||
1243 | 446 | } | ||
1244 | 447 | } | ||
1245 | 448 | |||
1246 | 449 | // | ||
1247 | 450 | // bind a function to a modified controller value | ||
1248 | 451 | // | ||
1249 | 452 | |||
1250 | 453 | HerculesMk2Hid.capture = function(name, values, func) { | ||
1251 | 454 | if (HerculesMk2Hid.callbacks[name] == undefined) { | ||
1252 | 455 | HerculesMk2Hid.callbacks[name] = [ [ values, func ] ]; | ||
1253 | 456 | } | ||
1254 | 457 | else { | ||
1255 | 458 | HerculesMk2Hid.callbacks[name].push([ values, func ]); | ||
1256 | 459 | } | ||
1257 | 460 | } | ||
1258 | 461 | |||
1259 | 462 | // | ||
1260 | 463 | // bind a function to feedback from mixxx, callbacks accept args in same order as from capture() | ||
1261 | 464 | // | ||
1262 | 465 | |||
1263 | 466 | HerculesMk2Hid.feedback = function(g, e, f) { | ||
1264 | 467 | engine.connectControl(g, e, "HerculesMk2Hid.feedbackData"); | ||
1265 | 468 | if (HerculesMk2Hid.feedbacks[g + e] == undefined) { | ||
1266 | 469 | HerculesMk2Hid.feedbacks[g + e] = []; | ||
1267 | 470 | } | ||
1268 | 471 | HerculesMk2Hid.feedbacks[g + e].push(f); | ||
1269 | 472 | } | ||
1270 | 473 | |||
1271 | 474 | // | ||
1272 | 475 | // controller feedback: send data to the controller by name and automatically send out the full hid packet needed | ||
1273 | 476 | // | ||
1274 | 477 | |||
1275 | 478 | HerculesMk2Hid.send = function(g, e, v) { | ||
1276 | 479 | if ((ctrl = this.leds[g + e]) != undefined) { | ||
1277 | 480 | |||
1278 | 481 | // | ||
1279 | 482 | // for the byte in the hid packet that this led control affects, mask out it's old value | ||
1280 | 483 | // and then add in it's new one | ||
1281 | 484 | // | ||
1282 | 485 | |||
1283 | 486 | this.cache_out[ctrl.packetid][ctrl.offset] = this.cache_out[ctrl.packetid][ctrl.offset] & ctrl.maskinv | (v << ctrl.bitshift); | ||
1284 | 487 | |||
1285 | 488 | // | ||
1286 | 489 | // send complete hid packet and update our cache | ||
1287 | 490 | // | ||
1288 | 491 | |||
1289 | 492 | controller.send(this.cache_out[ctrl.packetid], this.cache_out[ctrl.packetid].length, 0); | ||
1290 | 493 | this.cache_out[ctrl.packetid] = this.cache_out[ctrl.packetid]; | ||
1291 | 494 | } | ||
1292 | 495 | } | ||
1293 | 496 | |||
1294 | 497 | // | ||
1295 | 498 | // process incoming data from mixxx and call any callbacks | ||
1296 | 499 | // | ||
1297 | 500 | |||
1298 | 501 | HerculesMk2Hid.feedbackData = function(v, g, e) { | ||
1299 | 502 | if (HerculesMk2Hid.feedbacks[g + e] != undefined) { | ||
1300 | 503 | for (func in HerculesMk2Hid.feedbacks[g + e]) { | ||
1301 | 504 | if (typeof(HerculesMk2Hid.feedbacks[g + e][func]) == "function") { | ||
1302 | 505 | HerculesMk2Hid.feedbacks[g + e][func](g, e, v); | ||
1303 | 506 | } | ||
1304 | 507 | } | ||
1305 | 508 | } | ||
1306 | 509 | } | ||
1307 | 510 | |||
1308 | 511 | // | ||
1309 | 512 | // a single hid control, store last known value and offset/mask to work out the new value from incoming data | ||
1310 | 513 | // | ||
1311 | 514 | |||
1312 | 515 | HerculesMk2Hid.control = function(packetid, name, group, type, offset, mask) { | ||
1313 | 516 | this.packetid = packetid; | ||
1314 | 517 | this.name = name; | ||
1315 | 518 | this.group = group; | ||
1316 | 519 | this.type = type; | ||
1317 | 520 | this.value = 0; | ||
1318 | 521 | this.relative = 0; | ||
1319 | 522 | this.offset = offset; | ||
1320 | 523 | this.mask = mask; | ||
1321 | 524 | this.maskinv = ~mask; | ||
1322 | 525 | this.bitshift = 0; | ||
1323 | 526 | this.maxval = 255; // needed for encoder, could guess from the mask | ||
1324 | 527 | this.changed = function(value) { | ||
1325 | 528 | value = (value & this.mask) >> this.bitshift; | ||
1326 | 529 | if (this.value == value) { | ||
1327 | 530 | return false; | ||
1328 | 531 | } | ||
1329 | 532 | else { | ||
1330 | 533 | // map to a relative value if it's an encoder, usually +1 or -1 | ||
1331 | 534 | if (this.type == 'encoder') { | ||
1332 | 535 | this.relative = value - this.value; | ||
1333 | 536 | if (this.relative > 100) { | ||
1334 | 537 | this.relative -= this.maxval; | ||
1335 | 538 | } | ||
1336 | 539 | else if (this.relative < -100) { | ||
1337 | 540 | this.relative += this.maxval; | ||
1338 | 541 | } | ||
1339 | 542 | } | ||
1340 | 543 | this.value = value; | ||
1341 | 544 | return true; | ||
1342 | 545 | } | ||
1343 | 546 | }; | ||
1344 | 547 | while (mask != 0 && (mask & 0x1) == 0) { | ||
1345 | 548 | mask = mask >> 1; | ||
1346 | 549 | this.bitshift++; | ||
1347 | 550 | } | ||
1348 | 551 | } | ||
1349 | 552 | |||
1350 | 553 | // | ||
1351 | 554 | // process incoming data and call any callbacks if their bound controls have changed | ||
1352 | 555 | // | ||
1353 | 556 | |||
1354 | 557 | HerculesMk2Hid.incomingData = function (data, length) { | ||
1355 | 558 | |||
1356 | 559 | var c = HerculesMk2Hid; | ||
1357 | 560 | var packetid = data[0]; | ||
1358 | 561 | |||
1359 | 562 | // | ||
1360 | 563 | // iterate thru each byte and only check controls for that byte if the byte has changed | ||
1361 | 564 | // | ||
1362 | 565 | |||
1363 | 566 | for (i=1; i<length; i++) { | ||
1364 | 567 | if ((c.cache_in[packetid] == undefined || data[i] != c.cache_in[packetid][i]) && c.controls[i] != undefined) { | ||
1365 | 568 | |||
1366 | 569 | // | ||
1367 | 570 | // a byte has changed, check any controls defined in that byte, more efficient | ||
1368 | 571 | // than checking old+new values for all controls | ||
1369 | 572 | // | ||
1370 | 573 | |||
1371 | 574 | for (key in c.controls[i]) { | ||
1372 | 575 | var control = c.controls[i][key]; | ||
1373 | 576 | if (typeof(control) == 'object' && control.packetid == data[0] && control.changed(data[i])) { | ||
1374 | 577 | |||
1375 | 578 | // | ||
1376 | 579 | // we found a hid control that has changed value within that byte, check for callbacks | ||
1377 | 580 | // | ||
1378 | 581 | |||
1379 | 582 | var callbacks = c.callbacks[control.name]; | ||
1380 | 583 | if (callbacks != undefined) { | ||
1381 | 584 | for (var i=0; i<callbacks.length; i++) { | ||
1382 | 585 | if (typeof(callbacks[i][1]) == 'function') { | ||
1383 | 586 | |||
1384 | 587 | // | ||
1385 | 588 | // check we need to call for this value change: all, press, release | ||
1386 | 589 | // | ||
1387 | 590 | |||
1388 | 591 | if (callbacks[i][0] == "all" || | ||
1389 | 592 | (callbacks[i][0] == "press" && control.value > 0) || | ||
1390 | 593 | (callbacks[i][0] == "release" && control.value == 0)) { | ||
1391 | 594 | |||
1392 | 595 | // | ||
1393 | 596 | // call a callback function for this control | ||
1394 | 597 | // | ||
1395 | 598 | |||
1396 | 599 | callbacks[i][1](control.group, control.name, control.value, control); | ||
1397 | 600 | } | ||
1398 | 601 | } | ||
1399 | 602 | } | ||
1400 | 603 | } | ||
1401 | 604 | } | ||
1402 | 605 | } | ||
1403 | 606 | } | ||
1404 | 607 | } | ||
1405 | 608 | |||
1406 | 609 | // store the new raw data | ||
1407 | 610 | c.cache_in[data[0]] = data; | ||
1408 | 611 | } | ||
1409 | 0 | 612 | ||
1410 | === added file 'mixxx/res/controllers/Novation Launchpad.midi.xml' | |||
1411 | --- mixxx/res/controllers/Novation Launchpad.midi.xml 1970-01-01 00:00:00 +0000 | |||
1412 | +++ mixxx/res/controllers/Novation Launchpad.midi.xml 2012-05-26 14:59:19 +0000 | |||
1413 | @@ -0,0 +1,736 @@ | |||
1414 | 1 | <?xml version='1.0' encoding='utf-8'?> | ||
1415 | 2 | <MixxxControllerPreset schemaVersion="1"> | ||
1416 | 3 | <controller id="Novation Launchpad"> | ||
1417 | 4 | <info> | ||
1418 | 5 | <name>Novation Launchpad</name> | ||
1419 | 6 | <author>zestoi</author> | ||
1420 | 7 | <description>Multi page mapping for the Novation Launchpad</description> | ||
1421 | 8 | </info> | ||
1422 | 9 | <scriptfiles> | ||
1423 | 10 | <file filename="Novation-Launchpad-scripts.js" functionprefix="NovationLaunchpad"/> | ||
1424 | 11 | </scriptfiles> | ||
1425 | 12 | <controls> | ||
1426 | 13 | <control> | ||
1427 | 14 | <group>[Master]</group> | ||
1428 | 15 | <key>NovationLaunchpad.incomingData</key> | ||
1429 | 16 | <status>0xb0</status> | ||
1430 | 17 | <midino>0x68</midino> | ||
1431 | 18 | <options> | ||
1432 | 19 | <Script-Binding/> | ||
1433 | 20 | </options> | ||
1434 | 21 | </control> | ||
1435 | 22 | <control> | ||
1436 | 23 | <group>[Master]</group> | ||
1437 | 24 | <key>NovationLaunchpad.incomingData</key> | ||
1438 | 25 | <status>0xb0</status> | ||
1439 | 26 | <midino>0x69</midino> | ||
1440 | 27 | <options> | ||
1441 | 28 | <Script-Binding/> | ||
1442 | 29 | </options> | ||
1443 | 30 | </control> | ||
1444 | 31 | <control> | ||
1445 | 32 | <group>[Master]</group> | ||
1446 | 33 | <key>NovationLaunchpad.incomingData</key> | ||
1447 | 34 | <status>0xb0</status> | ||
1448 | 35 | <midino>0x6A</midino> | ||
1449 | 36 | <options> | ||
1450 | 37 | <Script-Binding/> | ||
1451 | 38 | </options> | ||
1452 | 39 | </control> | ||
1453 | 40 | <control> | ||
1454 | 41 | <group>[Master]</group> | ||
1455 | 42 | <key>NovationLaunchpad.incomingData</key> | ||
1456 | 43 | <status>0xb0</status> | ||
1457 | 44 | <midino>0x6B</midino> | ||
1458 | 45 | <options> | ||
1459 | 46 | <Script-Binding/> | ||
1460 | 47 | </options> | ||
1461 | 48 | </control> | ||
1462 | 49 | <control> | ||
1463 | 50 | <group>[Master]</group> | ||
1464 | 51 | <key>NovationLaunchpad.incomingData</key> | ||
1465 | 52 | <status>0xb0</status> | ||
1466 | 53 | <midino>0x6C</midino> | ||
1467 | 54 | <options> | ||
1468 | 55 | <Script-Binding/> | ||
1469 | 56 | </options> | ||
1470 | 57 | </control> | ||
1471 | 58 | <control> | ||
1472 | 59 | <group>[Master]</group> | ||
1473 | 60 | <key>NovationLaunchpad.incomingData</key> | ||
1474 | 61 | <status>0xb0</status> | ||
1475 | 62 | <midino>0x6D</midino> | ||
1476 | 63 | <options> | ||
1477 | 64 | <Script-Binding/> | ||
1478 | 65 | </options> | ||
1479 | 66 | </control> | ||
1480 | 67 | <control> | ||
1481 | 68 | <group>[Master]</group> | ||
1482 | 69 | <key>NovationLaunchpad.incomingData</key> | ||
1483 | 70 | <status>0xb0</status> | ||
1484 | 71 | <midino>0x6E</midino> | ||
1485 | 72 | <options> | ||
1486 | 73 | <Script-Binding/> | ||
1487 | 74 | </options> | ||
1488 | 75 | </control> | ||
1489 | 76 | <control> | ||
1490 | 77 | <group>[Master]</group> | ||
1491 | 78 | <key>NovationLaunchpad.incomingData</key> | ||
1492 | 79 | <status>0xb0</status> | ||
1493 | 80 | <midino>0x6F</midino> | ||
1494 | 81 | <options> | ||
1495 | 82 | <Script-Binding/> | ||
1496 | 83 | </options> | ||
1497 | 84 | </control> | ||
1498 | 85 | <control> | ||
1499 | 86 | <group>[Master]</group> | ||
1500 | 87 | <key>NovationLaunchpad.incomingData</key> | ||
1501 | 88 | <status>0x90</status> | ||
1502 | 89 | <midino>0x8</midino> | ||
1503 | 90 | <options> | ||
1504 | 91 | <Script-Binding/> | ||
1505 | 92 | </options> | ||
1506 | 93 | </control> | ||
1507 | 94 | <control> | ||
1508 | 95 | <group>[Master]</group> | ||
1509 | 96 | <key>NovationLaunchpad.incomingData</key> | ||
1510 | 97 | <status>0x90</status> | ||
1511 | 98 | <midino>0x18</midino> | ||
1512 | 99 | <options> | ||
1513 | 100 | <Script-Binding/> | ||
1514 | 101 | </options> | ||
1515 | 102 | </control> | ||
1516 | 103 | <control> | ||
1517 | 104 | <group>[Master]</group> | ||
1518 | 105 | <key>NovationLaunchpad.incomingData</key> | ||
1519 | 106 | <status>0x90</status> | ||
1520 | 107 | <midino>0x28</midino> | ||
1521 | 108 | <options> | ||
1522 | 109 | <Script-Binding/> | ||
1523 | 110 | </options> | ||
1524 | 111 | </control> | ||
1525 | 112 | <control> | ||
1526 | 113 | <group>[Master]</group> | ||
1527 | 114 | <key>NovationLaunchpad.incomingData</key> | ||
1528 | 115 | <status>0x90</status> | ||
1529 | 116 | <midino>0x38</midino> | ||
1530 | 117 | <options> | ||
1531 | 118 | <Script-Binding/> | ||
1532 | 119 | </options> | ||
1533 | 120 | </control> | ||
1534 | 121 | <control> | ||
1535 | 122 | <group>[Master]</group> | ||
1536 | 123 | <key>NovationLaunchpad.incomingData</key> | ||
1537 | 124 | <status>0x90</status> | ||
1538 | 125 | <midino>0x48</midino> | ||
1539 | 126 | <options> | ||
1540 | 127 | <Script-Binding/> | ||
1541 | 128 | </options> | ||
1542 | 129 | </control> | ||
1543 | 130 | <control> | ||
1544 | 131 | <group>[Master]</group> | ||
1545 | 132 | <key>NovationLaunchpad.incomingData</key> | ||
1546 | 133 | <status>0x90</status> | ||
1547 | 134 | <midino>0x58</midino> | ||
1548 | 135 | <options> | ||
1549 | 136 | <Script-Binding/> | ||
1550 | 137 | </options> | ||
1551 | 138 | </control> | ||
1552 | 139 | <control> | ||
1553 | 140 | <group>[Master]</group> | ||
1554 | 141 | <key>NovationLaunchpad.incomingData</key> | ||
1555 | 142 | <status>0x90</status> | ||
1556 | 143 | <midino>0x68</midino> | ||
1557 | 144 | <options> | ||
1558 | 145 | <Script-Binding/> | ||
1559 | 146 | </options> | ||
1560 | 147 | </control> | ||
1561 | 148 | <control> | ||
1562 | 149 | <group>[Master]</group> | ||
1563 | 150 | <key>NovationLaunchpad.incomingData</key> | ||
1564 | 151 | <status>0x90</status> | ||
1565 | 152 | <midino>0x78</midino> | ||
1566 | 153 | <options> | ||
1567 | 154 | <Script-Binding/> | ||
1568 | 155 | </options> | ||
1569 | 156 | </control> | ||
1570 | 157 | <control> | ||
1571 | 158 | <group>[Master]</group> | ||
1572 | 159 | <key>NovationLaunchpad.incomingData</key> | ||
1573 | 160 | <status>0x90</status> | ||
1574 | 161 | <midino>0x0</midino> | ||
1575 | 162 | <options> | ||
1576 | 163 | <Script-Binding/> | ||
1577 | 164 | </options> | ||
1578 | 165 | </control> | ||
1579 | 166 | <control> | ||
1580 | 167 | <group>[Master]</group> | ||
1581 | 168 | <key>NovationLaunchpad.incomingData</key> | ||
1582 | 169 | <status>0x90</status> | ||
1583 | 170 | <midino>0x1</midino> | ||
1584 | 171 | <options> | ||
1585 | 172 | <Script-Binding/> | ||
1586 | 173 | </options> | ||
1587 | 174 | </control> | ||
1588 | 175 | <control> | ||
1589 | 176 | <group>[Master]</group> | ||
1590 | 177 | <key>NovationLaunchpad.incomingData</key> | ||
1591 | 178 | <status>0x90</status> | ||
1592 | 179 | <midino>0x2</midino> | ||
1593 | 180 | <options> | ||
1594 | 181 | <Script-Binding/> | ||
1595 | 182 | </options> | ||
1596 | 183 | </control> | ||
1597 | 184 | <control> | ||
1598 | 185 | <group>[Master]</group> | ||
1599 | 186 | <key>NovationLaunchpad.incomingData</key> | ||
1600 | 187 | <status>0x90</status> | ||
1601 | 188 | <midino>0x3</midino> | ||
1602 | 189 | <options> | ||
1603 | 190 | <Script-Binding/> | ||
1604 | 191 | </options> | ||
1605 | 192 | </control> | ||
1606 | 193 | <control> | ||
1607 | 194 | <group>[Master]</group> | ||
1608 | 195 | <key>NovationLaunchpad.incomingData</key> | ||
1609 | 196 | <status>0x90</status> | ||
1610 | 197 | <midino>0x4</midino> | ||
1611 | 198 | <options> | ||
1612 | 199 | <Script-Binding/> | ||
1613 | 200 | </options> | ||
1614 | 201 | </control> | ||
1615 | 202 | <control> | ||
1616 | 203 | <group>[Master]</group> | ||
1617 | 204 | <key>NovationLaunchpad.incomingData</key> | ||
1618 | 205 | <status>0x90</status> | ||
1619 | 206 | <midino>0x5</midino> | ||
1620 | 207 | <options> | ||
1621 | 208 | <Script-Binding/> | ||
1622 | 209 | </options> | ||
1623 | 210 | </control> | ||
1624 | 211 | <control> | ||
1625 | 212 | <group>[Master]</group> | ||
1626 | 213 | <key>NovationLaunchpad.incomingData</key> | ||
1627 | 214 | <status>0x90</status> | ||
1628 | 215 | <midino>0x6</midino> | ||
1629 | 216 | <options> | ||
1630 | 217 | <Script-Binding/> | ||
1631 | 218 | </options> | ||
1632 | 219 | </control> | ||
1633 | 220 | <control> | ||
1634 | 221 | <group>[Master]</group> | ||
1635 | 222 | <key>NovationLaunchpad.incomingData</key> | ||
1636 | 223 | <status>0x90</status> | ||
1637 | 224 | <midino>0x7</midino> | ||
1638 | 225 | <options> | ||
1639 | 226 | <Script-Binding/> | ||
1640 | 227 | </options> | ||
1641 | 228 | </control> | ||
1642 | 229 | <control> | ||
1643 | 230 | <group>[Master]</group> | ||
1644 | 231 | <key>NovationLaunchpad.incomingData</key> | ||
1645 | 232 | <status>0x90</status> | ||
1646 | 233 | <midino>0x10</midino> | ||
1647 | 234 | <options> | ||
1648 | 235 | <Script-Binding/> | ||
1649 | 236 | </options> | ||
1650 | 237 | </control> | ||
1651 | 238 | <control> | ||
1652 | 239 | <group>[Master]</group> | ||
1653 | 240 | <key>NovationLaunchpad.incomingData</key> | ||
1654 | 241 | <status>0x90</status> | ||
1655 | 242 | <midino>0x11</midino> | ||
1656 | 243 | <options> | ||
1657 | 244 | <Script-Binding/> | ||
1658 | 245 | </options> | ||
1659 | 246 | </control> | ||
1660 | 247 | <control> | ||
1661 | 248 | <group>[Master]</group> | ||
1662 | 249 | <key>NovationLaunchpad.incomingData</key> | ||
1663 | 250 | <status>0x90</status> | ||
1664 | 251 | <midino>0x12</midino> | ||
1665 | 252 | <options> | ||
1666 | 253 | <Script-Binding/> | ||
1667 | 254 | </options> | ||
1668 | 255 | </control> | ||
1669 | 256 | <control> | ||
1670 | 257 | <group>[Master]</group> | ||
1671 | 258 | <key>NovationLaunchpad.incomingData</key> | ||
1672 | 259 | <status>0x90</status> | ||
1673 | 260 | <midino>0x13</midino> | ||
1674 | 261 | <options> | ||
1675 | 262 | <Script-Binding/> | ||
1676 | 263 | </options> | ||
1677 | 264 | </control> | ||
1678 | 265 | <control> | ||
1679 | 266 | <group>[Master]</group> | ||
1680 | 267 | <key>NovationLaunchpad.incomingData</key> | ||
1681 | 268 | <status>0x90</status> | ||
1682 | 269 | <midino>0x14</midino> | ||
1683 | 270 | <options> | ||
1684 | 271 | <Script-Binding/> | ||
1685 | 272 | </options> | ||
1686 | 273 | </control> | ||
1687 | 274 | <control> | ||
1688 | 275 | <group>[Master]</group> | ||
1689 | 276 | <key>NovationLaunchpad.incomingData</key> | ||
1690 | 277 | <status>0x90</status> | ||
1691 | 278 | <midino>0x15</midino> | ||
1692 | 279 | <options> | ||
1693 | 280 | <Script-Binding/> | ||
1694 | 281 | </options> | ||
1695 | 282 | </control> | ||
1696 | 283 | <control> | ||
1697 | 284 | <group>[Master]</group> | ||
1698 | 285 | <key>NovationLaunchpad.incomingData</key> | ||
1699 | 286 | <status>0x90</status> | ||
1700 | 287 | <midino>0x16</midino> | ||
1701 | 288 | <options> | ||
1702 | 289 | <Script-Binding/> | ||
1703 | 290 | </options> | ||
1704 | 291 | </control> | ||
1705 | 292 | <control> | ||
1706 | 293 | <group>[Master]</group> | ||
1707 | 294 | <key>NovationLaunchpad.incomingData</key> | ||
1708 | 295 | <status>0x90</status> | ||
1709 | 296 | <midino>0x17</midino> | ||
1710 | 297 | <options> | ||
1711 | 298 | <Script-Binding/> | ||
1712 | 299 | </options> | ||
1713 | 300 | </control> | ||
1714 | 301 | <control> | ||
1715 | 302 | <group>[Master]</group> | ||
1716 | 303 | <key>NovationLaunchpad.incomingData</key> | ||
1717 | 304 | <status>0x90</status> | ||
1718 | 305 | <midino>0x20</midino> | ||
1719 | 306 | <options> | ||
1720 | 307 | <Script-Binding/> | ||
1721 | 308 | </options> | ||
1722 | 309 | </control> | ||
1723 | 310 | <control> | ||
1724 | 311 | <group>[Master]</group> | ||
1725 | 312 | <key>NovationLaunchpad.incomingData</key> | ||
1726 | 313 | <status>0x90</status> | ||
1727 | 314 | <midino>0x21</midino> | ||
1728 | 315 | <options> | ||
1729 | 316 | <Script-Binding/> | ||
1730 | 317 | </options> | ||
1731 | 318 | </control> | ||
1732 | 319 | <control> | ||
1733 | 320 | <group>[Master]</group> | ||
1734 | 321 | <key>NovationLaunchpad.incomingData</key> | ||
1735 | 322 | <status>0x90</status> | ||
1736 | 323 | <midino>0x22</midino> | ||
1737 | 324 | <options> | ||
1738 | 325 | <Script-Binding/> | ||
1739 | 326 | </options> | ||
1740 | 327 | </control> | ||
1741 | 328 | <control> | ||
1742 | 329 | <group>[Master]</group> | ||
1743 | 330 | <key>NovationLaunchpad.incomingData</key> | ||
1744 | 331 | <status>0x90</status> | ||
1745 | 332 | <midino>0x23</midino> | ||
1746 | 333 | <options> | ||
1747 | 334 | <Script-Binding/> | ||
1748 | 335 | </options> | ||
1749 | 336 | </control> | ||
1750 | 337 | <control> | ||
1751 | 338 | <group>[Master]</group> | ||
1752 | 339 | <key>NovationLaunchpad.incomingData</key> | ||
1753 | 340 | <status>0x90</status> | ||
1754 | 341 | <midino>0x24</midino> | ||
1755 | 342 | <options> | ||
1756 | 343 | <Script-Binding/> | ||
1757 | 344 | </options> | ||
1758 | 345 | </control> | ||
1759 | 346 | <control> | ||
1760 | 347 | <group>[Master]</group> | ||
1761 | 348 | <key>NovationLaunchpad.incomingData</key> | ||
1762 | 349 | <status>0x90</status> | ||
1763 | 350 | <midino>0x25</midino> | ||
1764 | 351 | <options> | ||
1765 | 352 | <Script-Binding/> | ||
1766 | 353 | </options> | ||
1767 | 354 | </control> | ||
1768 | 355 | <control> | ||
1769 | 356 | <group>[Master]</group> | ||
1770 | 357 | <key>NovationLaunchpad.incomingData</key> | ||
1771 | 358 | <status>0x90</status> | ||
1772 | 359 | <midino>0x26</midino> | ||
1773 | 360 | <options> | ||
1774 | 361 | <Script-Binding/> | ||
1775 | 362 | </options> | ||
1776 | 363 | </control> | ||
1777 | 364 | <control> | ||
1778 | 365 | <group>[Master]</group> | ||
1779 | 366 | <key>NovationLaunchpad.incomingData</key> | ||
1780 | 367 | <status>0x90</status> | ||
1781 | 368 | <midino>0x27</midino> | ||
1782 | 369 | <options> | ||
1783 | 370 | <Script-Binding/> | ||
1784 | 371 | </options> | ||
1785 | 372 | </control> | ||
1786 | 373 | <control> | ||
1787 | 374 | <group>[Master]</group> | ||
1788 | 375 | <key>NovationLaunchpad.incomingData</key> | ||
1789 | 376 | <status>0x90</status> | ||
1790 | 377 | <midino>0x30</midino> | ||
1791 | 378 | <options> | ||
1792 | 379 | <Script-Binding/> | ||
1793 | 380 | </options> | ||
1794 | 381 | </control> | ||
1795 | 382 | <control> | ||
1796 | 383 | <group>[Master]</group> | ||
1797 | 384 | <key>NovationLaunchpad.incomingData</key> | ||
1798 | 385 | <status>0x90</status> | ||
1799 | 386 | <midino>0x31</midino> | ||
1800 | 387 | <options> | ||
1801 | 388 | <Script-Binding/> | ||
1802 | 389 | </options> | ||
1803 | 390 | </control> | ||
1804 | 391 | <control> | ||
1805 | 392 | <group>[Master]</group> | ||
1806 | 393 | <key>NovationLaunchpad.incomingData</key> | ||
1807 | 394 | <status>0x90</status> | ||
1808 | 395 | <midino>0x32</midino> | ||
1809 | 396 | <options> | ||
1810 | 397 | <Script-Binding/> | ||
1811 | 398 | </options> | ||
1812 | 399 | </control> | ||
1813 | 400 | <control> | ||
1814 | 401 | <group>[Master]</group> | ||
1815 | 402 | <key>NovationLaunchpad.incomingData</key> | ||
1816 | 403 | <status>0x90</status> | ||
1817 | 404 | <midino>0x33</midino> | ||
1818 | 405 | <options> | ||
1819 | 406 | <Script-Binding/> | ||
1820 | 407 | </options> | ||
1821 | 408 | </control> | ||
1822 | 409 | <control> | ||
1823 | 410 | <group>[Master]</group> | ||
1824 | 411 | <key>NovationLaunchpad.incomingData</key> | ||
1825 | 412 | <status>0x90</status> | ||
1826 | 413 | <midino>0x34</midino> | ||
1827 | 414 | <options> | ||
1828 | 415 | <Script-Binding/> | ||
1829 | 416 | </options> | ||
1830 | 417 | </control> | ||
1831 | 418 | <control> | ||
1832 | 419 | <group>[Master]</group> | ||
1833 | 420 | <key>NovationLaunchpad.incomingData</key> | ||
1834 | 421 | <status>0x90</status> | ||
1835 | 422 | <midino>0x35</midino> | ||
1836 | 423 | <options> | ||
1837 | 424 | <Script-Binding/> | ||
1838 | 425 | </options> | ||
1839 | 426 | </control> | ||
1840 | 427 | <control> | ||
1841 | 428 | <group>[Master]</group> | ||
1842 | 429 | <key>NovationLaunchpad.incomingData</key> | ||
1843 | 430 | <status>0x90</status> | ||
1844 | 431 | <midino>0x36</midino> | ||
1845 | 432 | <options> | ||
1846 | 433 | <Script-Binding/> | ||
1847 | 434 | </options> | ||
1848 | 435 | </control> | ||
1849 | 436 | <control> | ||
1850 | 437 | <group>[Master]</group> | ||
1851 | 438 | <key>NovationLaunchpad.incomingData</key> | ||
1852 | 439 | <status>0x90</status> | ||
1853 | 440 | <midino>0x37</midino> | ||
1854 | 441 | <options> | ||
1855 | 442 | <Script-Binding/> | ||
1856 | 443 | </options> | ||
1857 | 444 | </control> | ||
1858 | 445 | <control> | ||
1859 | 446 | <group>[Master]</group> | ||
1860 | 447 | <key>NovationLaunchpad.incomingData</key> | ||
1861 | 448 | <status>0x90</status> | ||
1862 | 449 | <midino>0x40</midino> | ||
1863 | 450 | <options> | ||
1864 | 451 | <Script-Binding/> | ||
1865 | 452 | </options> | ||
1866 | 453 | </control> | ||
1867 | 454 | <control> | ||
1868 | 455 | <group>[Master]</group> | ||
1869 | 456 | <key>NovationLaunchpad.incomingData</key> | ||
1870 | 457 | <status>0x90</status> | ||
1871 | 458 | <midino>0x41</midino> | ||
1872 | 459 | <options> | ||
1873 | 460 | <Script-Binding/> | ||
1874 | 461 | </options> | ||
1875 | 462 | </control> | ||
1876 | 463 | <control> | ||
1877 | 464 | <group>[Master]</group> | ||
1878 | 465 | <key>NovationLaunchpad.incomingData</key> | ||
1879 | 466 | <status>0x90</status> | ||
1880 | 467 | <midino>0x42</midino> | ||
1881 | 468 | <options> | ||
1882 | 469 | <Script-Binding/> | ||
1883 | 470 | </options> | ||
1884 | 471 | </control> | ||
1885 | 472 | <control> | ||
1886 | 473 | <group>[Master]</group> | ||
1887 | 474 | <key>NovationLaunchpad.incomingData</key> | ||
1888 | 475 | <status>0x90</status> | ||
1889 | 476 | <midino>0x43</midino> | ||
1890 | 477 | <options> | ||
1891 | 478 | <Script-Binding/> | ||
1892 | 479 | </options> | ||
1893 | 480 | </control> | ||
1894 | 481 | <control> | ||
1895 | 482 | <group>[Master]</group> | ||
1896 | 483 | <key>NovationLaunchpad.incomingData</key> | ||
1897 | 484 | <status>0x90</status> | ||
1898 | 485 | <midino>0x44</midino> | ||
1899 | 486 | <options> | ||
1900 | 487 | <Script-Binding/> | ||
1901 | 488 | </options> | ||
1902 | 489 | </control> | ||
1903 | 490 | <control> | ||
1904 | 491 | <group>[Master]</group> | ||
1905 | 492 | <key>NovationLaunchpad.incomingData</key> | ||
1906 | 493 | <status>0x90</status> | ||
1907 | 494 | <midino>0x45</midino> | ||
1908 | 495 | <options> | ||
1909 | 496 | <Script-Binding/> | ||
1910 | 497 | </options> | ||
1911 | 498 | </control> | ||
1912 | 499 | <control> | ||
1913 | 500 | <group>[Master]</group> | ||
1914 | 501 | <key>NovationLaunchpad.incomingData</key> | ||
1915 | 502 | <status>0x90</status> | ||
1916 | 503 | <midino>0x46</midino> | ||
1917 | 504 | <options> | ||
1918 | 505 | <Script-Binding/> | ||
1919 | 506 | </options> | ||
1920 | 507 | </control> | ||
1921 | 508 | <control> | ||
1922 | 509 | <group>[Master]</group> | ||
1923 | 510 | <key>NovationLaunchpad.incomingData</key> | ||
1924 | 511 | <status>0x90</status> | ||
1925 | 512 | <midino>0x47</midino> | ||
1926 | 513 | <options> | ||
1927 | 514 | <Script-Binding/> | ||
1928 | 515 | </options> | ||
1929 | 516 | </control> | ||
1930 | 517 | <control> | ||
1931 | 518 | <group>[Master]</group> | ||
1932 | 519 | <key>NovationLaunchpad.incomingData</key> | ||
1933 | 520 | <status>0x90</status> | ||
1934 | 521 | <midino>0x50</midino> | ||
1935 | 522 | <options> | ||
1936 | 523 | <Script-Binding/> | ||
1937 | 524 | </options> | ||
1938 | 525 | </control> | ||
1939 | 526 | <control> | ||
1940 | 527 | <group>[Master]</group> | ||
1941 | 528 | <key>NovationLaunchpad.incomingData</key> | ||
1942 | 529 | <status>0x90</status> | ||
1943 | 530 | <midino>0x51</midino> | ||
1944 | 531 | <options> | ||
1945 | 532 | <Script-Binding/> | ||
1946 | 533 | </options> | ||
1947 | 534 | </control> | ||
1948 | 535 | <control> | ||
1949 | 536 | <group>[Master]</group> | ||
1950 | 537 | <key>NovationLaunchpad.incomingData</key> | ||
1951 | 538 | <status>0x90</status> | ||
1952 | 539 | <midino>0x52</midino> | ||
1953 | 540 | <options> | ||
1954 | 541 | <Script-Binding/> | ||
1955 | 542 | </options> | ||
1956 | 543 | </control> | ||
1957 | 544 | <control> | ||
1958 | 545 | <group>[Master]</group> | ||
1959 | 546 | <key>NovationLaunchpad.incomingData</key> | ||
1960 | 547 | <status>0x90</status> | ||
1961 | 548 | <midino>0x53</midino> | ||
1962 | 549 | <options> | ||
1963 | 550 | <Script-Binding/> | ||
1964 | 551 | </options> | ||
1965 | 552 | </control> | ||
1966 | 553 | <control> | ||
1967 | 554 | <group>[Master]</group> | ||
1968 | 555 | <key>NovationLaunchpad.incomingData</key> | ||
1969 | 556 | <status>0x90</status> | ||
1970 | 557 | <midino>0x54</midino> | ||
1971 | 558 | <options> | ||
1972 | 559 | <Script-Binding/> | ||
1973 | 560 | </options> | ||
1974 | 561 | </control> | ||
1975 | 562 | <control> | ||
1976 | 563 | <group>[Master]</group> | ||
1977 | 564 | <key>NovationLaunchpad.incomingData</key> | ||
1978 | 565 | <status>0x90</status> | ||
1979 | 566 | <midino>0x55</midino> | ||
1980 | 567 | <options> | ||
1981 | 568 | <Script-Binding/> | ||
1982 | 569 | </options> | ||
1983 | 570 | </control> | ||
1984 | 571 | <control> | ||
1985 | 572 | <group>[Master]</group> | ||
1986 | 573 | <key>NovationLaunchpad.incomingData</key> | ||
1987 | 574 | <status>0x90</status> | ||
1988 | 575 | <midino>0x56</midino> | ||
1989 | 576 | <options> | ||
1990 | 577 | <Script-Binding/> | ||
1991 | 578 | </options> | ||
1992 | 579 | </control> | ||
1993 | 580 | <control> | ||
1994 | 581 | <group>[Master]</group> | ||
1995 | 582 | <key>NovationLaunchpad.incomingData</key> | ||
1996 | 583 | <status>0x90</status> | ||
1997 | 584 | <midino>0x57</midino> | ||
1998 | 585 | <options> | ||
1999 | 586 | <Script-Binding/> | ||
2000 | 587 | </options> | ||
2001 | 588 | </control> | ||
2002 | 589 | <control> | ||
2003 | 590 | <group>[Master]</group> | ||
2004 | 591 | <key>NovationLaunchpad.incomingData</key> | ||
2005 | 592 | <status>0x90</status> | ||
2006 | 593 | <midino>0x60</midino> | ||
2007 | 594 | <options> | ||
2008 | 595 | <Script-Binding/> | ||
2009 | 596 | </options> | ||
2010 | 597 | </control> | ||
2011 | 598 | <control> | ||
2012 | 599 | <group>[Master]</group> | ||
2013 | 600 | <key>NovationLaunchpad.incomingData</key> | ||
2014 | 601 | <status>0x90</status> | ||
2015 | 602 | <midino>0x61</midino> | ||
2016 | 603 | <options> | ||
2017 | 604 | <Script-Binding/> | ||
2018 | 605 | </options> | ||
2019 | 606 | </control> | ||
2020 | 607 | <control> | ||
2021 | 608 | <group>[Master]</group> | ||
2022 | 609 | <key>NovationLaunchpad.incomingData</key> | ||
2023 | 610 | <status>0x90</status> | ||
2024 | 611 | <midino>0x62</midino> | ||
2025 | 612 | <options> | ||
2026 | 613 | <Script-Binding/> | ||
2027 | 614 | </options> | ||
2028 | 615 | </control> | ||
2029 | 616 | <control> | ||
2030 | 617 | <group>[Master]</group> | ||
2031 | 618 | <key>NovationLaunchpad.incomingData</key> | ||
2032 | 619 | <status>0x90</status> | ||
2033 | 620 | <midino>0x63</midino> | ||
2034 | 621 | <options> | ||
2035 | 622 | <Script-Binding/> | ||
2036 | 623 | </options> | ||
2037 | 624 | </control> | ||
2038 | 625 | <control> | ||
2039 | 626 | <group>[Master]</group> | ||
2040 | 627 | <key>NovationLaunchpad.incomingData</key> | ||
2041 | 628 | <status>0x90</status> | ||
2042 | 629 | <midino>0x64</midino> | ||
2043 | 630 | <options> | ||
2044 | 631 | <Script-Binding/> | ||
2045 | 632 | </options> | ||
2046 | 633 | </control> | ||
2047 | 634 | <control> | ||
2048 | 635 | <group>[Master]</group> | ||
2049 | 636 | <key>NovationLaunchpad.incomingData</key> | ||
2050 | 637 | <status>0x90</status> | ||
2051 | 638 | <midino>0x65</midino> | ||
2052 | 639 | <options> | ||
2053 | 640 | <Script-Binding/> | ||
2054 | 641 | </options> | ||
2055 | 642 | </control> | ||
2056 | 643 | <control> | ||
2057 | 644 | <group>[Master]</group> | ||
2058 | 645 | <key>NovationLaunchpad.incomingData</key> | ||
2059 | 646 | <status>0x90</status> | ||
2060 | 647 | <midino>0x66</midino> | ||
2061 | 648 | <options> | ||
2062 | 649 | <Script-Binding/> | ||
2063 | 650 | </options> | ||
2064 | 651 | </control> | ||
2065 | 652 | <control> | ||
2066 | 653 | <group>[Master]</group> | ||
2067 | 654 | <key>NovationLaunchpad.incomingData</key> | ||
2068 | 655 | <status>0x90</status> | ||
2069 | 656 | <midino>0x67</midino> | ||
2070 | 657 | <options> | ||
2071 | 658 | <Script-Binding/> | ||
2072 | 659 | </options> | ||
2073 | 660 | </control> | ||
2074 | 661 | <control> | ||
2075 | 662 | <group>[Master]</group> | ||
2076 | 663 | <key>NovationLaunchpad.incomingData</key> | ||
2077 | 664 | <status>0x90</status> | ||
2078 | 665 | <midino>0x70</midino> | ||
2079 | 666 | <options> | ||
2080 | 667 | <Script-Binding/> | ||
2081 | 668 | </options> | ||
2082 | 669 | </control> | ||
2083 | 670 | <control> | ||
2084 | 671 | <group>[Master]</group> | ||
2085 | 672 | <key>NovationLaunchpad.incomingData</key> | ||
2086 | 673 | <status>0x90</status> | ||
2087 | 674 | <midino>0x71</midino> | ||
2088 | 675 | <options> | ||
2089 | 676 | <Script-Binding/> | ||
2090 | 677 | </options> | ||
2091 | 678 | </control> | ||
2092 | 679 | <control> | ||
2093 | 680 | <group>[Master]</group> | ||
2094 | 681 | <key>NovationLaunchpad.incomingData</key> | ||
2095 | 682 | <status>0x90</status> | ||
2096 | 683 | <midino>0x72</midino> | ||
2097 | 684 | <options> | ||
2098 | 685 | <Script-Binding/> | ||
2099 | 686 | </options> | ||
2100 | 687 | </control> | ||
2101 | 688 | <control> | ||
2102 | 689 | <group>[Master]</group> | ||
2103 | 690 | <key>NovationLaunchpad.incomingData</key> | ||
2104 | 691 | <status>0x90</status> | ||
2105 | 692 | <midino>0x73</midino> | ||
2106 | 693 | <options> | ||
2107 | 694 | <Script-Binding/> | ||
2108 | 695 | </options> | ||
2109 | 696 | </control> | ||
2110 | 697 | <control> | ||
2111 | 698 | <group>[Master]</group> | ||
2112 | 699 | <key>NovationLaunchpad.incomingData</key> | ||
2113 | 700 | <status>0x90</status> | ||
2114 | 701 | <midino>0x74</midino> | ||
2115 | 702 | <options> | ||
2116 | 703 | <Script-Binding/> | ||
2117 | 704 | </options> | ||
2118 | 705 | </control> | ||
2119 | 706 | <control> | ||
2120 | 707 | <group>[Master]</group> | ||
2121 | 708 | <key>NovationLaunchpad.incomingData</key> | ||
2122 | 709 | <status>0x90</status> | ||
2123 | 710 | <midino>0x75</midino> | ||
2124 | 711 | <options> | ||
2125 | 712 | <Script-Binding/> | ||
2126 | 713 | </options> | ||
2127 | 714 | </control> | ||
2128 | 715 | <control> | ||
2129 | 716 | <group>[Master]</group> | ||
2130 | 717 | <key>NovationLaunchpad.incomingData</key> | ||
2131 | 718 | <status>0x90</status> | ||
2132 | 719 | <midino>0x76</midino> | ||
2133 | 720 | <options> | ||
2134 | 721 | <Script-Binding/> | ||
2135 | 722 | </options> | ||
2136 | 723 | </control> | ||
2137 | 724 | <control> | ||
2138 | 725 | <group>[Master]</group> | ||
2139 | 726 | <key>NovationLaunchpad.incomingData</key> | ||
2140 | 727 | <status>0x90</status> | ||
2141 | 728 | <midino>0x77</midino> | ||
2142 | 729 | <options> | ||
2143 | 730 | <Script-Binding/> | ||
2144 | 731 | </options> | ||
2145 | 732 | </control> | ||
2146 | 733 | </controls> | ||
2147 | 734 | <outputs/> | ||
2148 | 735 | </controller> | ||
2149 | 736 | </MixxxControllerPreset> | ||
2150 | 0 | 737 | ||
2151 | === added file 'mixxx/res/controllers/Novation-Launchpad-scripts.js' | |||
2152 | --- mixxx/res/controllers/Novation-Launchpad-scripts.js 1970-01-01 00:00:00 +0000 | |||
2153 | +++ mixxx/res/controllers/Novation-Launchpad-scripts.js 2012-05-26 14:59:19 +0000 | |||
2154 | @@ -0,0 +1,819 @@ | |||
2155 | 1 | /****************************************************************/ | ||
2156 | 2 | /* Novation Launchpad Mapping */ | ||
2157 | 3 | /* For Mixxx version 1.11 */ | ||
2158 | 4 | /* Author: zestoi */ | ||
2159 | 5 | /****************************************************************/ | ||
2160 | 6 | |||
2161 | 7 | NovationLaunchpad = { | ||
2162 | 8 | |||
2163 | 9 | init: function() { | ||
2164 | 10 | |||
2165 | 11 | // | ||
2166 | 12 | // setup variables and methods | ||
2167 | 13 | // | ||
2168 | 14 | |||
2169 | 15 | this.page = 1; | ||
2170 | 16 | this.shift = 0; | ||
2171 | 17 | this.shift2 = 0; | ||
2172 | 18 | this.callbacks = {}; | ||
2173 | 19 | this.feedbacks = {}; | ||
2174 | 20 | this.cache = [{}, {}, {}, {}]; | ||
2175 | 21 | this.feedback_cache = {}; | ||
2176 | 22 | this.toggle_cache = [{}, {}, {}, {}]; | ||
2177 | 23 | this.name2control = {}; | ||
2178 | 24 | this.control2name = {}; | ||
2179 | 25 | this.vumeters = []; | ||
2180 | 26 | |||
2181 | 27 | var self = NovationLaunchpad; | ||
2182 | 28 | this.colors = self.colors(); | ||
2183 | 29 | this.capture = self.capture; | ||
2184 | 30 | this.feedback = self.feedback; | ||
2185 | 31 | this.send = self.send; | ||
2186 | 32 | this.button = self.button; | ||
2187 | 33 | this.toggle = self.toggle; | ||
2188 | 34 | this.hotcue = self.hotcue; | ||
2189 | 35 | this.flanger = self.flanger; | ||
2190 | 36 | this.jog = self.jog; | ||
2191 | 37 | this.get = self.get; | ||
2192 | 38 | this.loop = self.loop; | ||
2193 | 39 | this.gator = self.gator; | ||
2194 | 40 | this.set_page = self.set_page; | ||
2195 | 41 | this.vfader = self.vfader; | ||
2196 | 42 | this.vumeter = self.vumeter; | ||
2197 | 43 | this.vumeter_toggle = self.vumeter_toggle; | ||
2198 | 44 | this.playlist = self.playlist; | ||
2199 | 45 | |||
2200 | 46 | // | ||
2201 | 47 | // map the midi config into something more useful | ||
2202 | 48 | // | ||
2203 | 49 | |||
2204 | 50 | var buttons = self.buttons(); | ||
2205 | 51 | for (name in buttons) { | ||
2206 | 52 | var type = buttons[name][0]; | ||
2207 | 53 | var chan = buttons[name][1]; | ||
2208 | 54 | var value = buttons[name][2]; | ||
2209 | 55 | var status = (type == 'cc') ? 0xb0 + chan - 1 : 0x90 + chan - 1; | ||
2210 | 56 | this.name2control[name]= [ status, value ]; | ||
2211 | 57 | this.control2name["" + status + value] = name; // stringify it | ||
2212 | 58 | } | ||
2213 | 59 | |||
2214 | 60 | // | ||
2215 | 61 | // reset device, enable flashing colors | ||
2216 | 62 | // | ||
2217 | 63 | |||
2218 | 64 | midi.sendShortMsg(0xb0, 0x0, 0x0); | ||
2219 | 65 | midi.sendShortMsg(0xb0, 0x0, 0x28); | ||
2220 | 66 | |||
2221 | 67 | ///////////////////////////////////////////////////////////////////////// | ||
2222 | 68 | // button layout mapping starts here | ||
2223 | 69 | ///////////////////////////////////////////////////////////////////////// | ||
2224 | 70 | |||
2225 | 71 | // shift buttons | ||
2226 | 72 | |||
2227 | 73 | this.button("arm", "all", 1, 'hi_yellow', 'lo_yellow', '', '', function(g, n, v) { this.shift = v > 0 ? 1 : 0; }); | ||
2228 | 74 | this.button("solo", "all", 1, 'hi_yellow', 'lo_yellow', '', '', function(g, n, v) { this.shift2 = v > 0 ? 1 : 0; }); | ||
2229 | 75 | this.toggle("mixer", "all", 0, 'hi_red', 'lo_red', '', '', function(g, n, v) { this.set_page(v > 0 ? 2 : 1); }); | ||
2230 | 76 | this.toggle("vol", "all", 2, 'hi_red', 'lo_red', '', '', function(g, n, v) { this.vumeter_toggle(v); }); | ||
2231 | 77 | |||
2232 | 78 | //// MAIN PAGE //// | ||
2233 | 79 | |||
2234 | 80 | // track navigation | ||
2235 | 81 | |||
2236 | 82 | this.playlist("up", 0, "SelectPrevTrack"); | ||
2237 | 83 | this.playlist("down", 0, "SelectNextTrack"); | ||
2238 | 84 | this.button("left", "press", 0, 'hi_yellow', 'lo_yellow', "[Playlist]", "SelectPrevPlaylist"); | ||
2239 | 85 | this.button("right", "press", 0, 'hi_yellow', 'lo_yellow', "[Playlist]", "SelectNextPlaylist"); | ||
2240 | 86 | |||
2241 | 87 | // deck mappings | ||
2242 | 88 | |||
2243 | 89 | for (deck=1; deck<=2; deck++) { | ||
2244 | 90 | var offset = deck == 1 ? 0 : 4; | ||
2245 | 91 | var group = "[Channel" + deck + "]"; | ||
2246 | 92 | |||
2247 | 93 | // tracks | ||
2248 | 94 | |||
2249 | 95 | this.toggle("0," + (offset + 0), "all", 1, 'hi_red', 'lo_red', group, "quantize"); | ||
2250 | 96 | this.toggle("0," + (offset + 1), "all", 1, 'hi_red', 'lo_red', group, "keylock"); | ||
2251 | 97 | this.toggle("0," + (offset + 2), "all", 1, 'hi_red', 'lo_red', group, "pfl"); | ||
2252 | 98 | this.button("0," + (offset + 3), "all", 1, 'hi_yellow', 'lo_amber', group, "LoadSelectedTrack"); | ||
2253 | 99 | |||
2254 | 100 | // flanger | ||
2255 | 101 | |||
2256 | 102 | this.flanger("1," + (offset + 0), 1, group, 0.5, 1500000, 333); | ||
2257 | 103 | this.flanger("1," + (offset + 1), 1, group, 1, 500000, 666); | ||
2258 | 104 | |||
2259 | 105 | // spinback effect | ||
2260 | 106 | |||
2261 | 107 | this.button("1," + (offset + 2), "all", 1, 'hi_red', 'lo_red', group, "", function(g, n, v) { | ||
2262 | 108 | script.spinback(g, v > 0); | ||
2263 | 109 | }); | ||
2264 | 110 | |||
2265 | 111 | // brake effect | ||
2266 | 112 | |||
2267 | 113 | this.button("1," + (offset + 3), "all", 1, 'hi_red', 'lo_red', group, "", function(g, n, v) { | ||
2268 | 114 | script.brake(g, v > 0); | ||
2269 | 115 | }); | ||
2270 | 116 | |||
2271 | 117 | // instant loops | ||
2272 | 118 | |||
2273 | 119 | this.loop("2," + (offset + 0), 1, group, 1); | ||
2274 | 120 | this.loop("2," + (offset + 1), 1, group, 0.5); | ||
2275 | 121 | this.loop("2," + (offset + 2), 1, group, 0.25); | ||
2276 | 122 | this.loop("2," + (offset + 3), 1, group, 0.125); | ||
2277 | 123 | |||
2278 | 124 | // loop in or loop half when active | ||
2279 | 125 | |||
2280 | 126 | this.button("3," + (offset + 0), "press", 1, 'hi_green', 'lo_green', group, "", function(g, n, v) { | ||
2281 | 127 | if (engine.getValue(g, "loop_enabled")) { | ||
2282 | 128 | engine.setValue(g, "loop_halve", 1); | ||
2283 | 129 | } | ||
2284 | 130 | else { | ||
2285 | 131 | engine.setValue(g, "loop_in", 1); | ||
2286 | 132 | } | ||
2287 | 133 | }); | ||
2288 | 134 | |||
2289 | 135 | // loop out or loop double when active | ||
2290 | 136 | |||
2291 | 137 | this.button("3," + (offset + 1), "press", 1, 'hi_green', 'lo_green', group, "", function(g, n, v) { | ||
2292 | 138 | if (engine.getValue(g, "loop_enabled")) { | ||
2293 | 139 | engine.setValue(g, "loop_double", 1); | ||
2294 | 140 | } | ||
2295 | 141 | else { | ||
2296 | 142 | engine.setValue(g, "loop_out", 1); | ||
2297 | 143 | } | ||
2298 | 144 | }); | ||
2299 | 145 | |||
2300 | 146 | // reloop or exit loop | ||
2301 | 147 | |||
2302 | 148 | this.button("3," + (offset + 2), "all", 1, 'hi_green', 'lo_green', group, "reloop_exit"); | ||
2303 | 149 | |||
2304 | 150 | // gator effect | ||
2305 | 151 | |||
2306 | 152 | this.gator("3," + (offset + 3), 1, group, 8, 0.7); | ||
2307 | 153 | |||
2308 | 154 | // led feedback for loop in/out buttons to show loop status | ||
2309 | 155 | |||
2310 | 156 | this.feedback(group, "loop_enabled", function(self, g, e, value) { | ||
2311 | 157 | var offset = g == "[Channel1]" ? 0 : 4; // ???? | ||
2312 | 158 | self.send("3," + (offset + 0), self.colors[value > 0 ? 'hi_green' : 'lo_green'], page); | ||
2313 | 159 | self.send("3," + (offset + 1), self.colors[value > 0 ? 'hi_green' : 'lo_green'], page); | ||
2314 | 160 | }); | ||
2315 | 161 | |||
2316 | 162 | // hotcues or needle drop with shift2 pressed | ||
2317 | 163 | |||
2318 | 164 | this.hotcue("4," + (offset + 0), 1, group, 1); | ||
2319 | 165 | this.hotcue("4," + (offset + 1), 1, group, 2); | ||
2320 | 166 | this.hotcue("4," + (offset + 2), 1, group, 3); | ||
2321 | 167 | this.hotcue("4," + (offset + 3), 1, group, 4); | ||
2322 | 168 | this.hotcue("5," + (offset + 0), 1, group, 5); | ||
2323 | 169 | this.hotcue("5," + (offset + 1), 1, group, 6); | ||
2324 | 170 | this.hotcue("5," + (offset + 2), 1, group, 7); | ||
2325 | 171 | this.hotcue("5," + (offset + 3), 1, group, 8); | ||
2326 | 172 | |||
2327 | 173 | // transport | ||
2328 | 174 | |||
2329 | 175 | this.button("6," + (offset + 0), "all", 1, 'hi_yellow', 'lo_red', group, "cue_default"); | ||
2330 | 176 | |||
2331 | 177 | this.button("6," + (offset + 1), "press", 1, 'hi_yellow', 'lo_yellow', group, "rate", function(g, n, v) { | ||
2332 | 178 | engine.setValue(g, n, 0); | ||
2333 | 179 | }); | ||
2334 | 180 | |||
2335 | 181 | this.button("6," + (offset + 2), "press", 1, 'hi_yellow', 'lo_yellow', group, "rate_perm_down_small"); | ||
2336 | 182 | this.button("6," + (offset + 3), "press", 1, 'hi_yellow', 'lo_yellow', group, "rate_perm_up_small"); | ||
2337 | 183 | |||
2338 | 184 | // play button | ||
2339 | 185 | this.toggle("7," + (offset + 0), "press", 1, 'hi_yellow', 'lo_red', group, "play"); | ||
2340 | 186 | |||
2341 | 187 | // flash play button when near end of track | ||
2342 | 188 | this.feedback(group, "playposition", function(self, g, e, value) { | ||
2343 | 189 | if (value > 0.9 && engine.getValue(g, "play") > 0) { | ||
2344 | 190 | self.send(g == "[Channel1]" ? "7,0" : "7,4", self.colors['flash_hi_red'], 1); | ||
2345 | 191 | } | ||
2346 | 192 | }); | ||
2347 | 193 | |||
2348 | 194 | // sync or move beatgrid when shift is pressed | ||
2349 | 195 | |||
2350 | 196 | this.button("7," + (offset + 1), "all", 1, 'hi_yellow', 'lo_amber', group, "beatsync", function(g, n, v) { | ||
2351 | 197 | if (this.shift > 0) | ||
2352 | 198 | engine.setValue(g, "beats_translate_curpos", v > 0 ? 1 : 0); | ||
2353 | 199 | else | ||
2354 | 200 | engine.setValue(g, n, v > 0 ? 1 : 0); | ||
2355 | 201 | }); | ||
2356 | 202 | |||
2357 | 203 | // fwd/rev when not playing unless shift and then fine jog movements for beat gridding, jog when playing, jog more when shift+playing | ||
2358 | 204 | |||
2359 | 205 | this.jog("7," + (offset + 2), 1, group, "back"); | ||
2360 | 206 | this.jog("7," + (offset + 3), 1, group, "fwd"); | ||
2361 | 207 | } | ||
2362 | 208 | |||
2363 | 209 | //// MIXER PAGE //// | ||
2364 | 210 | |||
2365 | 211 | this.toggle("0,0", "all", 2, 'flash_hi_red', 'lo_red', "[Channel1]", "filterHighKill"); | ||
2366 | 212 | this.toggle("0,1", "all", 2, 'flash_hi_red', 'lo_red', "[Channel1]", "filterMidKill"); | ||
2367 | 213 | this.toggle("0,2", "all", 2, 'flash_hi_red', 'lo_red', "[Channel1]", "filterLowKill"); | ||
2368 | 214 | this.toggle("0,5", "all", 2, 'flash_hi_red', 'lo_red', "[Channel2]", "filterHighKill"); | ||
2369 | 215 | this.toggle("0,6", "all", 2, 'flash_hi_red', 'lo_red', "[Channel2]", "filterMidKill"); | ||
2370 | 216 | this.toggle("0,7", "all", 2, 'flash_hi_red', 'lo_red', "[Channel2]", "filterLowKill"); | ||
2371 | 217 | |||
2372 | 218 | this.vfader(7, 0, 2, 7, 'hi_orange', 'lo_green', "[Channel1]", "filterLow"); | ||
2373 | 219 | this.vfader(7, 1, 2, 7, 'hi_orange', 'lo_green', "[Channel1]", "filterMid"); | ||
2374 | 220 | this.vfader(7, 2, 2, 7, 'hi_orange', 'lo_green', "[Channel1]", "filterHigh"); | ||
2375 | 221 | this.vfader(7, 5, 2, 7, 'hi_orange', 'lo_green', "[Channel2]", "filterLow"); | ||
2376 | 222 | this.vfader(7, 6, 2, 7, 'hi_orange', 'lo_green', "[Channel2]", "filterMid"); | ||
2377 | 223 | this.vfader(7, 7, 2, 7, 'hi_orange', 'lo_green', "[Channel2]", "filterHigh"); | ||
2378 | 224 | |||
2379 | 225 | this.vfader(7, 3, 2, 8, 'hi_yellow', 'lo_red', "[Channel1]", "volume"); | ||
2380 | 226 | this.vfader(7, 4, 2, 8, 'hi_yellow', 'lo_red', "[Channel2]", "volume"); | ||
2381 | 227 | this.vumeter(7, 3, 2, 8, 'hi_yellow', 'lo_red', "[Channel1]", "VuMeter"); | ||
2382 | 228 | this.vumeter(7, 4, 2, 8, 'hi_yellow', 'lo_red', "[Channel2]", "VuMeter"); | ||
2383 | 229 | |||
2384 | 230 | ///////////////////////////////////////////////////////////////////////// | ||
2385 | 231 | // button layout mapping ends here | ||
2386 | 232 | ///////////////////////////////////////////////////////////////////////// | ||
2387 | 233 | }, | ||
2388 | 234 | |||
2389 | 235 | // | ||
2390 | 236 | // convert incoming midi to a 'name' and call callbacks (if any) | ||
2391 | 237 | // | ||
2392 | 238 | |||
2393 | 239 | incomingData: function(channel, control, value, status, group) { | ||
2394 | 240 | if ((name = this.control2name["" + status + control]) != undefined) { | ||
2395 | 241 | if (this.callbacks[name] != undefined) { | ||
2396 | 242 | var callbacks = this.callbacks[name]; | ||
2397 | 243 | for (var i=0; i<callbacks.length; i++) { | ||
2398 | 244 | if ((callbacks[i][1] == 0 || callbacks[i][1] == this.page) && typeof(callbacks[i][2]) == 'function') { | ||
2399 | 245 | |||
2400 | 246 | // | ||
2401 | 247 | // check we need to call for this value change: all, press, release | ||
2402 | 248 | // | ||
2403 | 249 | |||
2404 | 250 | if (callbacks[i][0] == "all" || | ||
2405 | 251 | (callbacks[i][0] == "press" && value > 0) || | ||
2406 | 252 | (callbacks[i][0] == "release" && value == 0)) { | ||
2407 | 253 | |||
2408 | 254 | // | ||
2409 | 255 | // call a callback function for this control | ||
2410 | 256 | // | ||
2411 | 257 | |||
2412 | 258 | callbacks[i][2](this, group, name, value); | ||
2413 | 259 | } | ||
2414 | 260 | } | ||
2415 | 261 | } | ||
2416 | 262 | } | ||
2417 | 263 | } | ||
2418 | 264 | }, | ||
2419 | 265 | |||
2420 | 266 | // | ||
2421 | 267 | // gator effect using high eq kill | ||
2422 | 268 | // | ||
2423 | 269 | |||
2424 | 270 | gator: function(name, page, group, rate, depth) { | ||
2425 | 271 | this.button(name, "all", page, 'hi_red', 'lo_red', group, "", function(g, n, v) { | ||
2426 | 272 | var self = NovationLaunchpad; | ||
2427 | 273 | if (typeof(self.gator_timer) != undefined && self.gator_timer != null) { | ||
2428 | 274 | engine.stopTimer(self.gator_timer); | ||
2429 | 275 | self.gator_timer = null; | ||
2430 | 276 | } | ||
2431 | 277 | |||
2432 | 278 | if (v > 0) { | ||
2433 | 279 | if ((bpm = engine.getValue(g, 'bpm')) > 0) { | ||
2434 | 280 | var interval = parseInt(1000 / bpm * 60 / rate); | ||
2435 | 281 | self.gator_direction = false; | ||
2436 | 282 | self.gator_depth = depth; | ||
2437 | 283 | self.gator_timer = engine.beginTimer(interval, 'NovationLaunchpad.process_gator("' + g + '")'); | ||
2438 | 284 | } | ||
2439 | 285 | } | ||
2440 | 286 | else { | ||
2441 | 287 | engine.setValue(group, 'filterHighKill', 0); | ||
2442 | 288 | } | ||
2443 | 289 | }); | ||
2444 | 290 | }, | ||
2445 | 291 | |||
2446 | 292 | // | ||
2447 | 293 | // gator | ||
2448 | 294 | // | ||
2449 | 295 | |||
2450 | 296 | process_gator: function(group) { | ||
2451 | 297 | var self = NovationLaunchpad; | ||
2452 | 298 | self.gator_direction = !self.gator_direction; | ||
2453 | 299 | engine.setValue(group, 'filterHighKill', self.gator_direction ? 1 : 0); | ||
2454 | 300 | }, | ||
2455 | 301 | |||
2456 | 302 | // | ||
2457 | 303 | // flanger button | ||
2458 | 304 | // | ||
2459 | 305 | |||
2460 | 306 | flanger: function(name, page, group, depth, period, delay) { | ||
2461 | 307 | this.button(name, "all", page, 'hi_amber', 'lo_amber', group, "flanger", function(g, name, v) { | ||
2462 | 308 | if (v > 0) { | ||
2463 | 309 | engine.setValue("[Flanger]", "lfoDepth", depth); | ||
2464 | 310 | engine.setValue("[Flanger]", "lfoPeriod", period); | ||
2465 | 311 | engine.setValue("[Flanger]", "lfoDelay", delay); | ||
2466 | 312 | } | ||
2467 | 313 | engine.setValue(group, "flanger", v > 0 ? 1 : 0); | ||
2468 | 314 | }); | ||
2469 | 315 | }, | ||
2470 | 316 | |||
2471 | 317 | loop: function(name, page, group, size) { | ||
2472 | 318 | this.button(name, "all", page, 'hi_yellow', 'lo_yellow', group, "", function(g, name, v) { | ||
2473 | 319 | if (v > 0) { | ||
2474 | 320 | engine.setValue(g, "beatloop_" + size + "_activate", 1); | ||
2475 | 321 | } | ||
2476 | 322 | else { | ||
2477 | 323 | if (engine.getValue(g, "beatloop_" + size + "_enabled")) { | ||
2478 | 324 | engine.setValue(g, "beatloop_" + size + "_toggle", 1); | ||
2479 | 325 | } | ||
2480 | 326 | } | ||
2481 | 327 | }); | ||
2482 | 328 | }, | ||
2483 | 329 | |||
2484 | 330 | // | ||
2485 | 331 | // track scrolling | ||
2486 | 332 | // | ||
2487 | 333 | |||
2488 | 334 | playlist: function(name, page, action) { | ||
2489 | 335 | this.button(name, "all", page, 'hi_yellow', 'lo_yellow', "[Playlist]", action, function(g, n, v) { | ||
2490 | 336 | var self = NovationLaunchpad; | ||
2491 | 337 | if (typeof(self.playlist_timer) != undefined && self.playlist_timer != null) { | ||
2492 | 338 | engine.stopTimer(self.playlist_timer); | ||
2493 | 339 | self.playlist_timer = null; | ||
2494 | 340 | } | ||
2495 | 341 | |||
2496 | 342 | if (v > 0) { | ||
2497 | 343 | engine.setValue("[Playlist]", action, 1); | ||
2498 | 344 | self.playlist_timer = engine.beginTimer(this.shift > 0 ? 30 : 150, 'NovationLaunchpad.process_playlist("' + action + '")'); | ||
2499 | 345 | } | ||
2500 | 346 | }); | ||
2501 | 347 | }, | ||
2502 | 348 | |||
2503 | 349 | process_playlist: function(name) { | ||
2504 | 350 | engine.setValue("[Playlist]", name, 1); | ||
2505 | 351 | }, | ||
2506 | 352 | |||
2507 | 353 | // | ||
2508 | 354 | // map a callback to an event from mixxx | ||
2509 | 355 | // | ||
2510 | 356 | |||
2511 | 357 | feedback: function(g, e, f) { | ||
2512 | 358 | if (g != "" && e != "") { | ||
2513 | 359 | engine.connectControl(g, e, "NovationLaunchpad.feedbackData"); | ||
2514 | 360 | if (this.feedbacks[g + e] == undefined) { | ||
2515 | 361 | this.feedbacks[g + e] = []; | ||
2516 | 362 | } | ||
2517 | 363 | this.feedbacks[g + e].push(f); | ||
2518 | 364 | } | ||
2519 | 365 | }, | ||
2520 | 366 | |||
2521 | 367 | // | ||
2522 | 368 | // call callbacks from mixxx events | ||
2523 | 369 | // | ||
2524 | 370 | |||
2525 | 371 | feedbackData: function(v, g, e) { | ||
2526 | 372 | this.feedback_cache[g + e] = v; | ||
2527 | 373 | if (this.feedbacks[g + e] != undefined) { | ||
2528 | 374 | for (func in this.feedbacks[g + e]) { | ||
2529 | 375 | if (typeof(this.feedbacks[g + e][func]) == "function") { | ||
2530 | 376 | this.feedbacks[g + e][func](this, g, e, v); | ||
2531 | 377 | } | ||
2532 | 378 | } | ||
2533 | 379 | } | ||
2534 | 380 | }, | ||
2535 | 381 | |||
2536 | 382 | // | ||
2537 | 383 | // map a callback to a launchpad button name | ||
2538 | 384 | // | ||
2539 | 385 | |||
2540 | 386 | capture: function(name, values, page, func) { | ||
2541 | 387 | if (this.callbacks[name] == undefined) { | ||
2542 | 388 | this.callbacks[name] = [ [ values, page, func ] ]; | ||
2543 | 389 | } | ||
2544 | 390 | else { | ||
2545 | 391 | this.callbacks[name].push([ values, page, func ]); | ||
2546 | 392 | } | ||
2547 | 393 | }, | ||
2548 | 394 | |||
2549 | 395 | // | ||
2550 | 396 | // send back to the launchpad for leds by name | ||
2551 | 397 | // | ||
2552 | 398 | |||
2553 | 399 | send: function(name, value, page) { | ||
2554 | 400 | if (page == 0 || this.page == page) { | ||
2555 | 401 | if ((control = this.name2control[name]) != undefined) { | ||
2556 | 402 | if (this.cache[page][name] == value) return; | ||
2557 | 403 | midi.sendShortMsg(control[0], control[1], value); | ||
2558 | 404 | } | ||
2559 | 405 | } | ||
2560 | 406 | this.cache[page][name] = value; | ||
2561 | 407 | }, | ||
2562 | 408 | |||
2563 | 409 | // | ||
2564 | 410 | // hold button | ||
2565 | 411 | // | ||
2566 | 412 | |||
2567 | 413 | button: function(name, values, page, on_color, off_color, group, event, callback) { | ||
2568 | 414 | |||
2569 | 415 | // launchpad => mixxx | ||
2570 | 416 | |||
2571 | 417 | this.capture(name, "all", page, function(self, g, name, value) { | ||
2572 | 418 | if (callback == undefined) { | ||
2573 | 419 | engine.setValue(group, event, value); | ||
2574 | 420 | } | ||
2575 | 421 | else if (typeof(callback) == "function") { | ||
2576 | 422 | if (values == "all" || (values == "press" && value > 0) || (values == "release" && value == 0)) { | ||
2577 | 423 | callback(group, event, value); | ||
2578 | 424 | } | ||
2579 | 425 | } | ||
2580 | 426 | |||
2581 | 427 | if (values == "all" || (values == "press" && value > 0) || (values == "release" && value == 0)) { | ||
2582 | 428 | self.send(name, self.colors[value > 0 ? on_color : off_color], page); | ||
2583 | 429 | } | ||
2584 | 430 | }); | ||
2585 | 431 | |||
2586 | 432 | // mixxx => launchpad | ||
2587 | 433 | |||
2588 | 434 | this.feedback(group, event, function(self, g, e, value) { | ||
2589 | 435 | self.send(name, self.colors[value > 0 ? on_color : off_color], page); | ||
2590 | 436 | }); | ||
2591 | 437 | |||
2592 | 438 | // init led | ||
2593 | 439 | |||
2594 | 440 | this.send(name, this.colors[off_color], page); | ||
2595 | 441 | }, | ||
2596 | 442 | |||
2597 | 443 | // | ||
2598 | 444 | // toggle | ||
2599 | 445 | // | ||
2600 | 446 | |||
2601 | 447 | toggle: function(name, values, page, on_color, off_color, group, event, callback) { | ||
2602 | 448 | this.capture(name, "press", page, function(self, g, name, value) { | ||
2603 | 449 | if (typeof(self.toggle_cache[page][name]) == "undefined") { | ||
2604 | 450 | self.toggle_cache[page][name] = 0; | ||
2605 | 451 | } | ||
2606 | 452 | self.toggle_cache[page][name] = self.toggle_cache[page][name] == 0 ? 1 : 0; | ||
2607 | 453 | |||
2608 | 454 | if (callback == undefined) { | ||
2609 | 455 | engine.setValue(group, event, self.toggle_cache[page][name]); | ||
2610 | 456 | } | ||
2611 | 457 | else if (typeof(callback) == "function") { | ||
2612 | 458 | callback(group, event, self.toggle_cache[page][name]); | ||
2613 | 459 | } | ||
2614 | 460 | |||
2615 | 461 | self.send(name, self.colors[self.toggle_cache[page][name] > 0 ? on_color : off_color], page); | ||
2616 | 462 | }); | ||
2617 | 463 | |||
2618 | 464 | // mixxx => launchpad | ||
2619 | 465 | |||
2620 | 466 | this.feedback(group, event, function(self, g, e, value) { | ||
2621 | 467 | self.send(name, self.colors[value > 0 ? on_color : off_color], page); | ||
2622 | 468 | self.toggle_cache[page][name] = value > 0 ? 1 : 0; | ||
2623 | 469 | }); | ||
2624 | 470 | |||
2625 | 471 | // init led | ||
2626 | 472 | |||
2627 | 473 | this.send(name, this.colors[off_color], page); | ||
2628 | 474 | }, | ||
2629 | 475 | |||
2630 | 476 | // | ||
2631 | 477 | // hotcues | ||
2632 | 478 | // | ||
2633 | 479 | |||
2634 | 480 | hotcue: function(name, page, group, num) { | ||
2635 | 481 | this.capture(name, "press", page, function(self, g, name, value) { | ||
2636 | 482 | if (self.shift2) { | ||
2637 | 483 | engine.setValue(group, "playposition", (num-1)/8); | ||
2638 | 484 | } | ||
2639 | 485 | else if (self.shift) { | ||
2640 | 486 | engine.setValue(group, "hotcue_" + num + "_clear", 1); | ||
2641 | 487 | } | ||
2642 | 488 | else { | ||
2643 | 489 | engine.setValue(group, "hotcue_" + num + "_activate", 1); | ||
2644 | 490 | } | ||
2645 | 491 | }); | ||
2646 | 492 | |||
2647 | 493 | this.feedback(group, "hotcue_" + num + "_enabled", function(self, g, e, value) { | ||
2648 | 494 | self.send(name, self.colors[value > 0 ? 'hi_red' : 'black'], page); | ||
2649 | 495 | }); | ||
2650 | 496 | }, | ||
2651 | 497 | |||
2652 | 498 | // | ||
2653 | 499 | // jog | ||
2654 | 500 | // | ||
2655 | 501 | |||
2656 | 502 | jog: function(name, page, group, dir) { | ||
2657 | 503 | this.button(name, "all", page, 'hi_yellow', 'lo_amber', group, "", function(g, n, v) { | ||
2658 | 504 | |||
2659 | 505 | if (dir == "fwd") { | ||
2660 | 506 | mult = 1; | ||
2661 | 507 | rate = "rate_temp_up"; | ||
2662 | 508 | } | ||
2663 | 509 | else { | ||
2664 | 510 | mult = -1; | ||
2665 | 511 | rate = "rate_temp_down"; | ||
2666 | 512 | } | ||
2667 | 513 | |||
2668 | 514 | if (engine.getValue(g, "play") > 0) { | ||
2669 | 515 | if (this.shift > 0) { | ||
2670 | 516 | engine.setValue(g, rate, v > 0 ? 1 : 0); | ||
2671 | 517 | } | ||
2672 | 518 | else { | ||
2673 | 519 | engine.setValue(g, rate + "_small", v > 0 ? 1 : 0); | ||
2674 | 520 | } | ||
2675 | 521 | } | ||
2676 | 522 | else if (this.shift > 0) { | ||
2677 | 523 | if (v > 0) { | ||
2678 | 524 | engine.setValue(g, 'jog', 0.2 * mult); | ||
2679 | 525 | } | ||
2680 | 526 | } | ||
2681 | 527 | else engine.setValue(g, dir, v); | ||
2682 | 528 | }); | ||
2683 | 529 | }, | ||
2684 | 530 | |||
2685 | 531 | // | ||
2686 | 532 | // turn a column of pads into a virtual fader | ||
2687 | 533 | // | ||
2688 | 534 | |||
2689 | 535 | vfader: function(y, x, page, nbtns, on_color, off_color, group, action) { | ||
2690 | 536 | var incr = 1 / nbtns; | ||
2691 | 537 | |||
2692 | 538 | // launchpad => mixxx | ||
2693 | 539 | |||
2694 | 540 | for (var btn=0; btn<nbtns; btn++) { | ||
2695 | 541 | this.capture((y-btn)+","+x, "press", page, function(self, g, name, value) { | ||
2696 | 542 | var cap = name.match(/^(\d+),\d+/); | ||
2697 | 543 | var num = y - cap[1] + 1; | ||
2698 | 544 | engine.setValue(group, action, incr * num); | ||
2699 | 545 | }); | ||
2700 | 546 | this.send((y-btn)+","+x, this.colors[on_color], page); | ||
2701 | 547 | } | ||
2702 | 548 | |||
2703 | 549 | // mixxx => launchpad | ||
2704 | 550 | |||
2705 | 551 | this.feedback(group, action, function(self, g, e, value) { | ||
2706 | 552 | for (btn=0; btn<nbtns; btn++) { | ||
2707 | 553 | if (value > btn*incr) { | ||
2708 | 554 | self.send((y-btn)+","+x, self.colors[on_color], page); | ||
2709 | 555 | } | ||
2710 | 556 | else { | ||
2711 | 557 | self.send((y-btn)+","+x, self.colors[off_color], page); | ||
2712 | 558 | } | ||
2713 | 559 | } | ||
2714 | 560 | }); | ||
2715 | 561 | }, | ||
2716 | 562 | |||
2717 | 563 | // | ||
2718 | 564 | // turn a column of pads into a vumeter | ||
2719 | 565 | // | ||
2720 | 566 | |||
2721 | 567 | vumeter: function(y, x, page, nbtns, on_color, off_color, group, action) { | ||
2722 | 568 | var incr = 1 / nbtns; | ||
2723 | 569 | this.vumeters.push([ y, x, page, nbtns, on_color, off_color, group, action ]); | ||
2724 | 570 | this.feedback(group, action, function(self, g, e, value) { | ||
2725 | 571 | if (self.vumeter_shift > 0) { | ||
2726 | 572 | for (btn=0; btn<nbtns; btn++) { | ||
2727 | 573 | if (value > btn*incr) { | ||
2728 | 574 | self.send((y-btn)+","+x, self.colors[on_color], page); | ||
2729 | 575 | } | ||
2730 | 576 | else { | ||
2731 | 577 | self.send((y-btn)+","+x, self.colors[off_color], page); | ||
2732 | 578 | } | ||
2733 | 579 | } | ||
2734 | 580 | } | ||
2735 | 581 | }); | ||
2736 | 582 | }, | ||
2737 | 583 | |||
2738 | 584 | vumeter_toggle: function(v) { | ||
2739 | 585 | this.vumeter_shift = v > 0 ? 1 : 0; | ||
2740 | 586 | |||
2741 | 587 | // | ||
2742 | 588 | // clear fader leds when enabling vumeter and set back the leds for the volume if disabling | ||
2743 | 589 | // | ||
2744 | 590 | |||
2745 | 591 | for (i in this.vumeters) { | ||
2746 | 592 | |||
2747 | 593 | var value = this.vumeter_shift > 0 ? 0 : this.feedback_cache[ this.vumeters[i][6] + 'volume' ]; | ||
2748 | 594 | |||
2749 | 595 | if (value != undefined) { | ||
2750 | 596 | var y = this.vumeters[i][0]; | ||
2751 | 597 | var x = this.vumeters[i][1]; | ||
2752 | 598 | var page = this.vumeters[i][2]; | ||
2753 | 599 | var nbtns = this.vumeters[i][3]; | ||
2754 | 600 | var on_color = this.vumeters[i][4]; | ||
2755 | 601 | var off_color = this.vumeters[i][5]; | ||
2756 | 602 | var incr = 1 / nbtns; | ||
2757 | 603 | |||
2758 | 604 | for (btn=0; btn<nbtns; btn++) { | ||
2759 | 605 | if (value > btn*incr) { | ||
2760 | 606 | this.send((y-btn)+","+x, this.colors[on_color], page); | ||
2761 | 607 | } | ||
2762 | 608 | else { | ||
2763 | 609 | this.send((y-btn)+","+x, this.colors[off_color], page); | ||
2764 | 610 | } | ||
2765 | 611 | } | ||
2766 | 612 | } | ||
2767 | 613 | } | ||
2768 | 614 | }, | ||
2769 | 615 | |||
2770 | 616 | // | ||
2771 | 617 | // get the last value sent to a launchpad led | ||
2772 | 618 | // | ||
2773 | 619 | |||
2774 | 620 | get: function(name, page) { | ||
2775 | 621 | if (typeof(this.cache[page][name]) == undefined) { | ||
2776 | 622 | return 0; | ||
2777 | 623 | } | ||
2778 | 624 | else { | ||
2779 | 625 | return this.cache[page][name]; | ||
2780 | 626 | } | ||
2781 | 627 | }, | ||
2782 | 628 | |||
2783 | 629 | // | ||
2784 | 630 | // set page | ||
2785 | 631 | // | ||
2786 | 632 | |||
2787 | 633 | set_page: function(page) { | ||
2788 | 634 | if (page == this.page) return; | ||
2789 | 635 | |||
2790 | 636 | var updates = {}; | ||
2791 | 637 | var flashing = []; | ||
2792 | 638 | |||
2793 | 639 | for (i in this.cache[page]) { | ||
2794 | 640 | if (this.cache[this.page][i] == undefined || this.cache[this.page][i] != this.cache[page][i]) { | ||
2795 | 641 | updates[i] = this.cache[page][i]; | ||
2796 | 642 | } | ||
2797 | 643 | } | ||
2798 | 644 | |||
2799 | 645 | for (i in this.cache[this.page]) { | ||
2800 | 646 | if (this.cache[page][i] == undefined) { | ||
2801 | 647 | updates[i] = 0x4; // black with copy bit set | ||
2802 | 648 | } | ||
2803 | 649 | else if (this.cache[this.page][i] != this.cache[page][i] && updates[i] == undefined) { | ||
2804 | 650 | updates[i] = this.cache[page][i]; | ||
2805 | 651 | } | ||
2806 | 652 | } | ||
2807 | 653 | |||
2808 | 654 | // select buffer 1 | ||
2809 | 655 | midi.sendShortMsg(0xb0, 0x0, 0x31); | ||
2810 | 656 | |||
2811 | 657 | for (i in updates) { | ||
2812 | 658 | if ((control = this.name2control[i]) != undefined) { | ||
2813 | 659 | |||
2814 | 660 | // 0 makes no sense - need 0x4 for black/off | ||
2815 | 661 | if (updates[i] == 0) { | ||
2816 | 662 | updates[i] = 0x4; | ||
2817 | 663 | } | ||
2818 | 664 | |||
2819 | 665 | // send out non-flashing colors with copy bit removed | ||
2820 | 666 | if (updates[i] & 0x4) { | ||
2821 | 667 | midi.sendShortMsg(control[0], control[1], updates[i] & 0xfb); | ||
2822 | 668 | } | ||
2823 | 669 | else { | ||
2824 | 670 | // send out off for this buffer for a flashing color | ||
2825 | 671 | midi.sendShortMsg(control[0], control[1], 0x4); | ||
2826 | 672 | flashing.push([ control[0], control[1], updates[i] ]); | ||
2827 | 673 | } | ||
2828 | 674 | } | ||
2829 | 675 | } | ||
2830 | 676 | |||
2831 | 677 | // select buffer 0 | ||
2832 | 678 | midi.sendShortMsg(0xb0, 0x0, 0x34); | ||
2833 | 679 | |||
2834 | 680 | // send out any flashing updates | ||
2835 | 681 | for (i in flashing) { | ||
2836 | 682 | midi.sendShortMsg(flashing[i][0], flashing[i][1], flashing[i][2]); | ||
2837 | 683 | } | ||
2838 | 684 | |||
2839 | 685 | // re-enable internal buffer cycling for flashing colors | ||
2840 | 686 | midi.sendShortMsg(0xb0, 0x0, 0x28); | ||
2841 | 687 | |||
2842 | 688 | this.page = page; | ||
2843 | 689 | }, | ||
2844 | 690 | |||
2845 | 691 | // | ||
2846 | 692 | // define colors | ||
2847 | 693 | // | ||
2848 | 694 | |||
2849 | 695 | colors: function() { | ||
2850 | 696 | return { | ||
2851 | 697 | black: 4, | ||
2852 | 698 | |||
2853 | 699 | lo_red: 1 + 4, | ||
2854 | 700 | mi_red: 2 + 4, | ||
2855 | 701 | hi_red: 3 + 4, | ||
2856 | 702 | lo_green: 16 + 4, | ||
2857 | 703 | mi_green: 32 + 4, | ||
2858 | 704 | hi_green: 48 + 4, | ||
2859 | 705 | lo_amber: 17 + 4, | ||
2860 | 706 | mi_amber: 34 + 4, | ||
2861 | 707 | hi_amber: 51 + 4, | ||
2862 | 708 | hi_orange: 35 + 4, | ||
2863 | 709 | lo_orange: 18 + 4, | ||
2864 | 710 | hi_yellow: 50 + 4, | ||
2865 | 711 | lo_yellow: 33 + 4, | ||
2866 | 712 | |||
2867 | 713 | flash_lo_red: 1, | ||
2868 | 714 | flash_mi_red: 2, | ||
2869 | 715 | flash_hi_red: 3, | ||
2870 | 716 | flash_lo_green: 16, | ||
2871 | 717 | flash_mi_green: 32, | ||
2872 | 718 | flash_hi_green: 48, | ||
2873 | 719 | flash_lo_amber: 17, | ||
2874 | 720 | flash_mi_amber: 34, | ||
2875 | 721 | flash_hi_amber: 51, | ||
2876 | 722 | flash_hi_orange: 35, | ||
2877 | 723 | flash_lo_orange: 18, | ||
2878 | 724 | flash_hi_yellow: 50, | ||
2879 | 725 | flash_lo_yellow: 33 | ||
2880 | 726 | } | ||
2881 | 727 | }, | ||
2882 | 728 | |||
2883 | 729 | // | ||
2884 | 730 | // define midi for all the buttons (as we can't define names in the xml or access that data here) | ||
2885 | 731 | // to create a 90 degree rotated mapping just redefine this list so "0,0" is still top left etc | ||
2886 | 732 | // | ||
2887 | 733 | |||
2888 | 734 | buttons: function() { | ||
2889 | 735 | return { | ||
2890 | 736 | 'up': [ 'cc', 1, 0x68 ], | ||
2891 | 737 | 'down': [ 'cc', 1, 0x69 ], | ||
2892 | 738 | 'left': [ 'cc', 1, 0x6A ], | ||
2893 | 739 | 'right': [ 'cc', 1, 0x6B ], | ||
2894 | 740 | 'session': [ 'cc', 1, 0x6C ], | ||
2895 | 741 | 'user1': [ 'cc', 1, 0x6D ], | ||
2896 | 742 | 'user2': [ 'cc', 1, 0x6E ], | ||
2897 | 743 | 'mixer': [ 'cc', 1, 0x6F ], | ||
2898 | 744 | 'vol': [ 'note', 1, 0x8 ], | ||
2899 | 745 | 'pan': [ 'note', 1, 0x18 ], | ||
2900 | 746 | 'snda': [ 'note', 1, 0x28 ], | ||
2901 | 747 | 'sndb': [ 'note', 1, 0x38 ], | ||
2902 | 748 | 'stop': [ 'note', 1, 0x48 ], | ||
2903 | 749 | 'trkon': [ 'note', 1, 0x58 ], | ||
2904 | 750 | 'solo': [ 'note', 1, 0x68 ], | ||
2905 | 751 | 'arm': [ 'note', 1, 0x78 ], | ||
2906 | 752 | '0,0': [ 'note', 1, 0x00 ], | ||
2907 | 753 | '0,1': [ 'note', 1, 0x01 ], | ||
2908 | 754 | '0,2': [ 'note', 1, 0x02 ], | ||
2909 | 755 | '0,3': [ 'note', 1, 0x03 ], | ||
2910 | 756 | '0,4': [ 'note', 1, 0x04 ], | ||
2911 | 757 | '0,5': [ 'note', 1, 0x05 ], | ||
2912 | 758 | '0,6': [ 'note', 1, 0x06 ], | ||
2913 | 759 | '0,7': [ 'note', 1, 0x07 ], | ||
2914 | 760 | '1,0': [ 'note', 1, 0x10 ], | ||
2915 | 761 | '1,1': [ 'note', 1, 0x11 ], | ||
2916 | 762 | '1,2': [ 'note', 1, 0x12 ], | ||
2917 | 763 | '1,3': [ 'note', 1, 0x13 ], | ||
2918 | 764 | '1,4': [ 'note', 1, 0x14 ], | ||
2919 | 765 | '1,5': [ 'note', 1, 0x15 ], | ||
2920 | 766 | '1,6': [ 'note', 1, 0x16 ], | ||
2921 | 767 | '1,7': [ 'note', 1, 0x17 ], | ||
2922 | 768 | '2,0': [ 'note', 1, 0x20 ], | ||
2923 | 769 | '2,1': [ 'note', 1, 0x21 ], | ||
2924 | 770 | '2,2': [ 'note', 1, 0x22 ], | ||
2925 | 771 | '2,3': [ 'note', 1, 0x23 ], | ||
2926 | 772 | '2,4': [ 'note', 1, 0x24 ], | ||
2927 | 773 | '2,5': [ 'note', 1, 0x25 ], | ||
2928 | 774 | '2,6': [ 'note', 1, 0x26 ], | ||
2929 | 775 | '2,7': [ 'note', 1, 0x27 ], | ||
2930 | 776 | '3,0': [ 'note', 1, 0x30 ], | ||
2931 | 777 | '3,1': [ 'note', 1, 0x31 ], | ||
2932 | 778 | '3,2': [ 'note', 1, 0x32 ], | ||
2933 | 779 | '3,3': [ 'note', 1, 0x33 ], | ||
2934 | 780 | '3,4': [ 'note', 1, 0x34 ], | ||
2935 | 781 | '3,5': [ 'note', 1, 0x35 ], | ||
2936 | 782 | '3,6': [ 'note', 1, 0x36 ], | ||
2937 | 783 | '3,7': [ 'note', 1, 0x37 ], | ||
2938 | 784 | '4,0': [ 'note', 1, 0x40 ], | ||
2939 | 785 | '4,1': [ 'note', 1, 0x41 ], | ||
2940 | 786 | '4,2': [ 'note', 1, 0x42 ], | ||
2941 | 787 | '4,3': [ 'note', 1, 0x43 ], | ||
2942 | 788 | '4,4': [ 'note', 1, 0x44 ], | ||
2943 | 789 | '4,5': [ 'note', 1, 0x45 ], | ||
2944 | 790 | '4,6': [ 'note', 1, 0x46 ], | ||
2945 | 791 | '4,7': [ 'note', 1, 0x47 ], | ||
2946 | 792 | '5,0': [ 'note', 1, 0x50 ], | ||
2947 | 793 | '5,1': [ 'note', 1, 0x51 ], | ||
2948 | 794 | '5,2': [ 'note', 1, 0x52 ], | ||
2949 | 795 | '5,3': [ 'note', 1, 0x53 ], | ||
2950 | 796 | '5,4': [ 'note', 1, 0x54 ], | ||
2951 | 797 | '5,5': [ 'note', 1, 0x55 ], | ||
2952 | 798 | '5,6': [ 'note', 1, 0x56 ], | ||
2953 | 799 | '5,7': [ 'note', 1, 0x57 ], | ||
2954 | 800 | '6,0': [ 'note', 1, 0x60 ], | ||
2955 | 801 | '6,1': [ 'note', 1, 0x61 ], | ||
2956 | 802 | '6,2': [ 'note', 1, 0x62 ], | ||
2957 | 803 | '6,3': [ 'note', 1, 0x63 ], | ||
2958 | 804 | '6,4': [ 'note', 1, 0x64 ], | ||
2959 | 805 | '6,5': [ 'note', 1, 0x65 ], | ||
2960 | 806 | '6,6': [ 'note', 1, 0x66 ], | ||
2961 | 807 | '6,7': [ 'note', 1, 0x67 ], | ||
2962 | 808 | '7,0': [ 'note', 1, 0x70 ], | ||
2963 | 809 | '7,1': [ 'note', 1, 0x71 ], | ||
2964 | 810 | '7,2': [ 'note', 1, 0x72 ], | ||
2965 | 811 | '7,3': [ 'note', 1, 0x73 ], | ||
2966 | 812 | '7,4': [ 'note', 1, 0x74 ], | ||
2967 | 813 | '7,5': [ 'note', 1, 0x75 ], | ||
2968 | 814 | '7,6': [ 'note', 1, 0x76 ], | ||
2969 | 815 | '7,7': [ 'note', 1, 0x77 ] | ||
2970 | 816 | }; | ||
2971 | 817 | } | ||
2972 | 818 | }; | ||
2973 | 819 | |||
2974 | 0 | 820 | ||
2975 | === modified file 'mixxx/res/controllers/common-controller-scripts.js' | |||
2976 | --- mixxx/res/controllers/common-controller-scripts.js 2012-04-03 11:49:10 +0000 | |||
2977 | +++ mixxx/res/controllers/common-controller-scripts.js 2012-05-26 14:59:19 +0000 | |||
2978 | @@ -82,7 +82,7 @@ | |||
2979 | 82 | 82 | ||
2980 | 83 | 83 | ||
2981 | 84 | script.pitch = function (LSB, MSB, status) { | 84 | script.pitch = function (LSB, MSB, status) { |
2983 | 85 | script.midiPitch(LSB, MSB, status); | 85 | return script.midiPitch(LSB, MSB, status); |
2984 | 86 | } | 86 | } |
2985 | 87 | 87 | ||
2986 | 88 | /* -------- ------------------------------------------------------ | 88 | /* -------- ------------------------------------------------------ |
2987 | @@ -106,6 +106,115 @@ | |||
2988 | 106 | return rate; | 106 | return rate; |
2989 | 107 | } | 107 | } |
2990 | 108 | 108 | ||
2991 | 109 | /* -------- ------------------------------------------------------ | ||
2992 | 110 | script.spinbackDefault | ||
2993 | 111 | Purpose: wrapper around spinback() that can be directly mapped | ||
2994 | 112 | from xml for a spinback effect | ||
2995 | 113 | Input: channel, control, value, status, group | ||
2996 | 114 | Output: none | ||
2997 | 115 | -------- ------------------------------------------------------ */ | ||
2998 | 116 | script.spinbackDefault = function(channel, control, value, status, group) { | ||
2999 | 117 | // disable on note-off or zero value note/cc | ||
3000 | 118 | script.spinback(group, ((status & 0xF0) != 0x80 && value > 0)); | ||
3001 | 119 | } | ||
3002 | 120 | |||
3003 | 121 | /* -------- ------------------------------------------------------ | ||
3004 | 122 | script.brakeDefault | ||
3005 | 123 | Purpose: wrapper around brake() that can be directly mapped | ||
3006 | 124 | from xml for a brake effect | ||
3007 | 125 | Input: channel, control, value, status, group | ||
3008 | 126 | Output: none | ||
3009 | 127 | -------- ------------------------------------------------------ */ | ||
3010 | 128 | script.brakeDefault = function(channel, control, value, status, group) { | ||
3011 | 129 | // disable on note-off or zero value note/cc | ||
3012 | 130 | script.brake(group, ((status & 0xF0) != 0x80 && value > 0)); | ||
3013 | 131 | } | ||
3014 | 132 | |||
3015 | 133 | /* -------- ------------------------------------------------------ | ||
3016 | 134 | script.spinback | ||
3017 | 135 | Purpose: Activate or disable a spinback effect on the chosen deck | ||
3018 | 136 | Input: group, enable/disable, [delay], [factor], [inital rate] | ||
3019 | 137 | Output: None | ||
3020 | 138 | -------- ------------------------------------------------------ */ | ||
3021 | 139 | script.spinback = function(group, activate, factor, rate, delay) { | ||
3022 | 140 | if (factor == undefined) factor = 0.8; | ||
3023 | 141 | if (rate == undefined) rate = -10; | ||
3024 | 142 | if (delay == undefined) delay = 5; | ||
3025 | 143 | script.deckSpinbackBrake(group, activate, factor, rate, delay); | ||
3026 | 144 | } | ||
3027 | 145 | |||
3028 | 146 | /* -------- ------------------------------------------------------ | ||
3029 | 147 | script.brake | ||
3030 | 148 | Purpose: Activate or disable a brake effect on the chosen deck | ||
3031 | 149 | Input: group, enable/disable, [delay], [factor], [inital rate] | ||
3032 | 150 | Output: None | ||
3033 | 151 | -------- ------------------------------------------------------ */ | ||
3034 | 152 | script.brake = function(group, activate, factor, rate, delay) { | ||
3035 | 153 | if (factor == undefined) factor = 0.95; | ||
3036 | 154 | if (rate == undefined) rate = 1; | ||
3037 | 155 | if (delay == undefined) delay = 0; | ||
3038 | 156 | script.deckSpinbackBrake(group, activate, factor, rate, delay); | ||
3039 | 157 | } | ||
3040 | 158 | |||
3041 | 159 | script.deckSpinbackBrakeData = {}; | ||
3042 | 160 | |||
3043 | 161 | script.deckSpinbackBrake = function(group, activate, factor, rate, delay) { | ||
3044 | 162 | |||
3045 | 163 | if (activate != undefined) { | ||
3046 | 164 | |||
3047 | 165 | // store the current settings | ||
3048 | 166 | |||
3049 | 167 | if (script.deckSpinbackBrakeData[group] == undefined) { | ||
3050 | 168 | script.deckSpinbackBrakeData[group] = { timer: null, delay: delay, factor: factor, rate: rate }; | ||
3051 | 169 | } | ||
3052 | 170 | else { | ||
3053 | 171 | script.deckSpinbackBrakeData[group].delay = delay; | ||
3054 | 172 | script.deckSpinbackBrakeData[group].factor = factor; | ||
3055 | 173 | script.deckSpinbackBrakeData[group].rate = rate; | ||
3056 | 174 | } | ||
3057 | 175 | |||
3058 | 176 | // kill timer when both enabling or disabling | ||
3059 | 177 | |||
3060 | 178 | if (script.deckSpinbackBrakeData[group].timer != null) { | ||
3061 | 179 | engine.stopTimer(script.deckSpinbackBrakeData[group].timer); | ||
3062 | 180 | script.deckSpinbackBrakeData[group].timer = null; | ||
3063 | 181 | } | ||
3064 | 182 | |||
3065 | 183 | // enable/disable scratch2 mode | ||
3066 | 184 | |||
3067 | 185 | engine.setValue(group, 'scratch2_enable', activate ? 1 : 0); | ||
3068 | 186 | |||
3069 | 187 | if (activate) { | ||
3070 | 188 | // save keylock status and disable it | ||
3071 | 189 | if ((script.deckSpinbackBrakeData[group].keylock = engine.getValue(group, "keylock")) > 0) { | ||
3072 | 190 | engine.setValue(group, "keylock", 0); | ||
3073 | 191 | } | ||
3074 | 192 | |||
3075 | 193 | // setup timer and send first scratch2 'tick' if activating | ||
3076 | 194 | script.deckSpinbackBrakeData[group].timer = engine.beginTimer(50, 'script.deckSpinbackBrake("' + group + '")'); | ||
3077 | 195 | engine.setValue(group, 'scratch2', script.deckSpinbackBrakeData[group].rate); | ||
3078 | 196 | } | ||
3079 | 197 | |||
3080 | 198 | // re-enable keylock if needed | ||
3081 | 199 | |||
3082 | 200 | else if (script.deckSpinbackBrakeData[group].keylock) { | ||
3083 | 201 | engine.setValue(group, "keylock", 1); | ||
3084 | 202 | } | ||
3085 | 203 | } | ||
3086 | 204 | else { | ||
3087 | 205 | // being called from a timer | ||
3088 | 206 | |||
3089 | 207 | engine.setValue(group, 'scratch2', script.deckSpinbackBrakeData[group].rate); | ||
3090 | 208 | |||
3091 | 209 | if (script.deckSpinbackBrakeData[group].delay > 0) { | ||
3092 | 210 | script.deckSpinbackBrakeData[group].delay--; | ||
3093 | 211 | } | ||
3094 | 212 | else { | ||
3095 | 213 | script.deckSpinbackBrakeData[group].rate *= script.deckSpinbackBrakeData[group].factor; | ||
3096 | 214 | } | ||
3097 | 215 | } | ||
3098 | 216 | } | ||
3099 | 217 | |||
3100 | 109 | // bpm - Used for tapping the desired BPM for a deck | 218 | // bpm - Used for tapping the desired BPM for a deck |
3101 | 110 | function bpm() {} | 219 | function bpm() {} |
3102 | 111 | 220 | ||
3103 | @@ -244,4 +353,4 @@ | |||
3104 | 244 | } | 353 | } |
3105 | 245 | } | 354 | } |
3106 | 246 | 355 | ||
3107 | 247 | // ----------------- END Object definitions ---------------------- | ||
3108 | 248 | \ No newline at end of file | 356 | \ No newline at end of file |
3109 | 357 | // ----------------- END Object definitions ---------------------- |