Merge lp:~zestoi/mixxx/controller_scripts into lp:~mixxxdevelopers/mixxx/trunk

Proposed by Zestoi
Status: Merged
Merged at revision: 3226
Proposed branch: lp:~zestoi/mixxx/controller_scripts
Merge into: lp:~mixxxdevelopers/mixxx/trunk
Diff against target: 429 lines (+80/-166)
3 files modified
mixxx/res/controllers/Hercules-DJ-Console-Mk2-hid-scripts.js (+5/-2)
mixxx/res/controllers/Novation-Launchpad-scripts.js (+63/-69)
mixxx/res/controllers/common-controller-scripts.js (+12/-95)
To merge this branch: bzr merge lp:~zestoi/mixxx/controller_scripts
Reviewer Review Type Date Requested Status
Mixxx Development Team Pending
Review via email: mp+107559@code.launchpad.net

Description of the change

* use engine.spinback() and engine.brake() in launchpad and mk2 mappings and the common-controller-scripts.js file in the thin wrappers which allow direct xml mapping (leave the js implementation in there for now)

* add in missing led feedback for channel2 eq kills in the herc mapping

* fix for the led feedback in the launchpad mapping - cause by the different runtime environment after the merge of madjester's code last night (i think) where 'this' is now in the engine as opposed to the controller instance

To post a comment you must log in.
lp:~zestoi/mixxx/controller_scripts updated
3218. By Zestoi

remove debug

3219. By Zestoi

removed javascript implementation of spinback/brake and renamed script.spinbackDefault to script.spinback and script.brakeDefault to script.brake

3220. By Zestoi

whitespace

3221. By Zestoi

fixed new context for incomingData() and used new lambda style calling of engine.connectControl()

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'mixxx/res/controllers/Hercules-DJ-Console-Mk2-hid-scripts.js'
--- mixxx/res/controllers/Hercules-DJ-Console-Mk2-hid-scripts.js 2012-05-26 14:22:39 +0000
+++ mixxx/res/controllers/Hercules-DJ-Console-Mk2-hid-scripts.js 2012-05-29 18:21:20 +0000
@@ -231,6 +231,9 @@
231 c.feedback("[Channel1]", "filterHighKill", c.kill_status);231 c.feedback("[Channel1]", "filterHighKill", c.kill_status);
232 c.feedback("[Channel1]", "filterMidKill", c.kill_status);232 c.feedback("[Channel1]", "filterMidKill", c.kill_status);
233 c.feedback("[Channel1]", "filterLowKill", c.kill_status);233 c.feedback("[Channel1]", "filterLowKill", c.kill_status);
234 c.feedback("[Channel2]", "filterHighKill", c.kill_status);
235 c.feedback("[Channel2]", "filterMidKill", c.kill_status);
236 c.feedback("[Channel2]", "filterLowKill", c.kill_status);
234237
235 //238 //
236 // clear/setup any initial leds239 // clear/setup any initial leds
@@ -261,10 +264,10 @@
261 engine.setValue(g, "flanger", v > 0);264 engine.setValue(g, "flanger", v > 0);
262 break;265 break;
263 case 2:266 case 2:
264 script.spinback(g, v > 0);267 engine.spinback(parseInt(g.substring(8,9)), v > 0);
265 break;268 break;
266 case 3:269 case 3:
267 script.brake(g, v > 0);270 engine.brake(parseInt(g.substring(8,9)), v > 0);
268 }271 }
269 break;272 break;
270 case "hotcue":273 case "hotcue":
271274
=== modified file 'mixxx/res/controllers/Novation-Launchpad-scripts.js'
--- mixxx/res/controllers/Novation-Launchpad-scripts.js 2012-05-26 14:22:39 +0000
+++ mixxx/res/controllers/Novation-Launchpad-scripts.js 2012-05-29 18:21:20 +0000
@@ -25,6 +25,8 @@
25 this.vumeters = [];25 this.vumeters = [];
2626
27 var self = NovationLaunchpad;27 var self = NovationLaunchpad;
28 self.instance = this; // needed for incoming data from the launchpad
29
28 this.colors = self.colors();30 this.colors = self.colors();
29 this.capture = self.capture;31 this.capture = self.capture;
30 this.feedback = self.feedback;32 this.feedback = self.feedback;
@@ -153,10 +155,11 @@
153155
154 // led feedback for loop in/out buttons to show loop status156 // led feedback for loop in/out buttons to show loop status
155157
156 this.feedback(group, "loop_enabled", function(self, g, e, value) {158 engine.connectControl(group, "loop_enabled", function(value, g, e) {
157 var offset = g == "[Channel1]" ? 0 : 4; // ????159 var offset = g == "[Channel1]" ? 0 : 4; // value not closed
158 self.send("3," + (offset + 0), self.colors[value > 0 ? 'hi_green' : 'lo_green'], page);160 this.send("3," + (offset + 0), this.colors[value > 0 ? 'hi_green' : 'lo_green'], 1);
159 self.send("3," + (offset + 1), self.colors[value > 0 ? 'hi_green' : 'lo_green'], page);161 this.send("3," + (offset + 1), this.colors[value > 0 ? 'hi_green' : 'lo_green'], 1);
162 this.feedback_cache[g + e] = value;
160 });163 });
161164
162 // hotcues or needle drop with shift2 pressed165 // hotcues or needle drop with shift2 pressed
@@ -185,10 +188,11 @@
185 this.toggle("7," + (offset + 0), "press", 1, 'hi_yellow', 'lo_red', group, "play");188 this.toggle("7," + (offset + 0), "press", 1, 'hi_yellow', 'lo_red', group, "play");
186189
187 // flash play button when near end of track190 // flash play button when near end of track
188 this.feedback(group, "playposition", function(self, g, e, value) {191 engine.connectControl(group, "playposition", function(value, g, e) {
189 if (value > 0.9 && engine.getValue(g, "play") > 0) {192 if (value > 0.9 && engine.getValue(g, "play") > 0) {
190 self.send(g == "[Channel1]" ? "7,0" : "7,4", self.colors['flash_hi_red'], 1);193 this.send(g == "[Channel1]" ? "7,0" : "7,4", this.colors['flash_hi_red'], 1);
191 }194 }
195 this.feedback_cache[g + e] = value;
192 });196 });
193 197
194 // sync or move beatgrid when shift is pressed198 // sync or move beatgrid when shift is pressed
@@ -233,15 +237,23 @@
233 },237 },
234238
235 //239 //
240 // empty shutdown method
241 //
242
243 shutdown: function() {
244 },
245
246 //
236 // convert incoming midi to a 'name' and call callbacks (if any)247 // convert incoming midi to a 'name' and call callbacks (if any)
237 //248 //
238249
239 incomingData: function(channel, control, value, status, group) {250 incomingData: function(channel, control, value, status, group) {
240 if ((name = this.control2name["" + status + control]) != undefined) {251 var me = NovationLaunchpad.instance;
241 if (this.callbacks[name] != undefined) {252 if ((name = me.control2name["" + status + control]) != undefined) {
242 var callbacks = this.callbacks[name];253 if (me.callbacks[name] != undefined) {
254 var callbacks = me.callbacks[name];
243 for (var i=0; i<callbacks.length; i++) {255 for (var i=0; i<callbacks.length; i++) {
244 if ((callbacks[i][1] == 0 || callbacks[i][1] == this.page) && typeof(callbacks[i][2]) == 'function') {256 if ((callbacks[i][1] == 0 || callbacks[i][1] == me.page) && typeof(callbacks[i][2]) == 'function') {
245257
246 //258 //
247 // check we need to call for this value change: all, press, release259 // check we need to call for this value change: all, press, release
@@ -255,7 +267,7 @@
255 // call a callback function for this control267 // call a callback function for this control
256 //268 //
257269
258 callbacks[i][2](this, group, name, value);270 callbacks[i][2].call(me, group, name, value);
259 }271 }
260 }272 }
261 }273 }
@@ -351,35 +363,6 @@
351 },363 },
352364
353 //365 //
354 // map a callback to an event from mixxx
355 //
356
357 feedback: function(g, e, f) {
358 if (g != "" && e != "") {
359 engine.connectControl(g, e, "NovationLaunchpad.feedbackData");
360 if (this.feedbacks[g + e] == undefined) {
361 this.feedbacks[g + e] = [];
362 }
363 this.feedbacks[g + e].push(f);
364 }
365 },
366
367 //
368 // call callbacks from mixxx events
369 //
370
371 feedbackData: function(v, g, e) {
372 this.feedback_cache[g + e] = v;
373 if (this.feedbacks[g + e] != undefined) {
374 for (func in this.feedbacks[g + e]) {
375 if (typeof(this.feedbacks[g + e][func]) == "function") {
376 this.feedbacks[g + e][func](this, g, e, v);
377 }
378 }
379 }
380 },
381
382 //
383 // map a callback to a launchpad button name366 // map a callback to a launchpad button name
384 //367 //
385368
@@ -414,25 +397,27 @@
414397
415 // launchpad => mixxx398 // launchpad => mixxx
416399
417 this.capture(name, "all", page, function(self, g, name, value) {400 this.capture(name, "all", page, function(g, name, value) {
401
418 if (callback == undefined) {402 if (callback == undefined) {
419 engine.setValue(group, event, value);403 engine.setValue(group, event, value);
420 }404 }
421 else if (typeof(callback) == "function") {405 else if (typeof(callback) == "function") {
422 if (values == "all" || (values == "press" && value > 0) || (values == "release" && value == 0)) {406 if (values == "all" || (values == "press" && value > 0) || (values == "release" && value == 0)) {
423 callback(group, event, value);407 callback.call(this, group, event, value);
424 }408 }
425 }409 }
426410
427 if (values == "all" || (values == "press" && value > 0) || (values == "release" && value == 0)) {411 if (values == "all" || (values == "press" && value > 0) || (values == "release" && value == 0)) {
428 self.send(name, self.colors[value > 0 ? on_color : off_color], page);412 this.send(name, this.colors[value > 0 ? on_color : off_color], page);
429 }413 }
430 });414 });
431415
432 // mixxx => launchpad416 // mixxx => launchpad
433417
434 this.feedback(group, event, function(self, g, e, value) {418 engine.connectControl(group, event, function(value, g, e) {
435 self.send(name, self.colors[value > 0 ? on_color : off_color], page);419 this.send(name, this.colors[value > 0 ? on_color : off_color], page);
420 this.feedback_cache[g + e] = value;
436 });421 });
437422
438 // init led423 // init led
@@ -445,27 +430,28 @@
445 //430 //
446431
447 toggle: function(name, values, page, on_color, off_color, group, event, callback) {432 toggle: function(name, values, page, on_color, off_color, group, event, callback) {
448 this.capture(name, "press", page, function(self, g, name, value) {433 this.capture(name, "press", page, function(g, name, value) {
449 if (typeof(self.toggle_cache[page][name]) == "undefined") {434 if (typeof(this.toggle_cache[page][name]) == "undefined") {
450 self.toggle_cache[page][name] = 0;435 this.toggle_cache[page][name] = 0;
451 }436 }
452 self.toggle_cache[page][name] = self.toggle_cache[page][name] == 0 ? 1 : 0;437 this.toggle_cache[page][name] = this.toggle_cache[page][name] == 0 ? 1 : 0;
453438
454 if (callback == undefined) {439 if (callback == undefined) {
455 engine.setValue(group, event, self.toggle_cache[page][name]);440 engine.setValue(group, event, this.toggle_cache[page][name]);
456 }441 }
457 else if (typeof(callback) == "function") {442 else if (typeof(callback) == "function") {
458 callback(group, event, self.toggle_cache[page][name]);443 callback.call(this, group, event, this.toggle_cache[page][name]);
459 }444 }
460445
461 self.send(name, self.colors[self.toggle_cache[page][name] > 0 ? on_color : off_color], page);446 this.send(name, this.colors[this.toggle_cache[page][name] > 0 ? on_color : off_color], page);
462 });447 });
463448
464 // mixxx => launchpad449 // mixxx => launchpad
465450
466 this.feedback(group, event, function(self, g, e, value) {451 engine.connectControl(group, event, function(value, g, e) {
467 self.send(name, self.colors[value > 0 ? on_color : off_color], page);452 this.send(name, this.colors[value > 0 ? on_color : off_color], page);
468 self.toggle_cache[page][name] = value > 0 ? 1 : 0;453 this.toggle_cache[page][name] = value > 0 ? 1 : 0;
454 this.feedback_cache[g + e] = value;
469 });455 });
470456
471 // init led457 // init led
@@ -478,11 +464,14 @@
478 //464 //
479465
480 hotcue: function(name, page, group, num) {466 hotcue: function(name, page, group, num) {
481 this.capture(name, "press", page, function(self, g, name, value) {467
482 if (self.shift2) {468 // launchpad => mixxx
469
470 this.capture(name, "press", page, function(g, name, value) {
471 if (this.shift2) {
483 engine.setValue(group, "playposition", (num-1)/8);472 engine.setValue(group, "playposition", (num-1)/8);
484 }473 }
485 else if (self.shift) {474 else if (this.shift) {
486 engine.setValue(group, "hotcue_" + num + "_clear", 1);475 engine.setValue(group, "hotcue_" + num + "_clear", 1);
487 }476 }
488 else {477 else {
@@ -490,8 +479,11 @@
490 }479 }
491 });480 });
492481
493 this.feedback(group, "hotcue_" + num + "_enabled", function(self, g, e, value) { 482 // mixxx => launchpad
494 self.send(name, self.colors[value > 0 ? 'hi_red' : 'black'], page);483
484 engine.connectControl(group, "hotcue_" + num + "_enabled", function(value, g, e) {
485 this.send(name, this.colors[value > 0 ? 'hi_red' : 'black'], page);
486 this.feedback_cache[g + e] = value;
495 });487 });
496 },488 },
497489
@@ -538,8 +530,8 @@
538 // launchpad => mixxx530 // launchpad => mixxx
539531
540 for (var btn=0; btn<nbtns; btn++) {532 for (var btn=0; btn<nbtns; btn++) {
541 this.capture((y-btn)+","+x, "press", page, function(self, g, name, value) {533 this.capture((y-btn)+","+x, "press", page, function(g, name, value) {
542 var cap = name.match(/^(\d+),\d+/);534 var cap = name.match(/^(\d+),\d+/); // value not closed
543 var num = y - cap[1] + 1;535 var num = y - cap[1] + 1;
544 engine.setValue(group, action, incr * num);536 engine.setValue(group, action, incr * num);
545 });537 });
@@ -548,15 +540,16 @@
548540
549 // mixxx => launchpad541 // mixxx => launchpad
550542
551 this.feedback(group, action, function(self, g, e, value) { 543 engine.connectControl(group, action, function(value, g, e) {
552 for (btn=0; btn<nbtns; btn++) {544 for (btn=0; btn<nbtns; btn++) {
553 if (value > btn*incr) {545 if (value > btn*incr) {
554 self.send((y-btn)+","+x, self.colors[on_color], page);546 this.send((y-btn)+","+x, this.colors[on_color], page);
555 }547 }
556 else {548 else {
557 self.send((y-btn)+","+x, self.colors[off_color], page);549 this.send((y-btn)+","+x, this.colors[off_color], page);
558 }550 }
559 }551 }
552 this.feedback_cache[g + e] = value;
560 });553 });
561 },554 },
562555
@@ -567,17 +560,18 @@
567 vumeter: function(y, x, page, nbtns, on_color, off_color, group, action) {560 vumeter: function(y, x, page, nbtns, on_color, off_color, group, action) {
568 var incr = 1 / nbtns;561 var incr = 1 / nbtns;
569 this.vumeters.push([ y, x, page, nbtns, on_color, off_color, group, action ]);562 this.vumeters.push([ y, x, page, nbtns, on_color, off_color, group, action ]);
570 this.feedback(group, action, function(self, g, e, value) { 563 engine.connectControl(group, action, function(value, g, e) {
571 if (self.vumeter_shift > 0) {564 if (this.vumeter_shift > 0) {
572 for (btn=0; btn<nbtns; btn++) {565 for (btn=0; btn<nbtns; btn++) {
573 if (value > btn*incr) {566 if (value > btn*incr) {
574 self.send((y-btn)+","+x, self.colors[on_color], page);567 this.send((y-btn)+","+x, this.colors[on_color], page);
575 }568 }
576 else {569 else {
577 self.send((y-btn)+","+x, self.colors[off_color], page);570 this.send((y-btn)+","+x, this.colors[off_color], page);
578 }571 }
579 }572 }
580 }573 }
574 this.feedback_cache[g + e] = value;
581 });575 });
582 },576 },
583577
584578
=== modified file 'mixxx/res/controllers/common-controller-scripts.js'
--- mixxx/res/controllers/common-controller-scripts.js 2012-05-27 12:48:11 +0000
+++ mixxx/res/controllers/common-controller-scripts.js 2012-05-29 18:21:20 +0000
@@ -123,112 +123,29 @@
123}123}
124124
125/* -------- ------------------------------------------------------125/* -------- ------------------------------------------------------
126 script.spinbackDefault126 script.spinback
127 Purpose: wrapper around spinback() that can be directly mapped 127 Purpose: wrapper around engine.spinback() that can be directly mapped
128 from xml for a spinback effect128 from xml for a spinback effect
129 e.g: <key>script.spinback</key>
129 Input: channel, control, value, status, group130 Input: channel, control, value, status, group
130 Output: none131 Output: none
131 -------- ------------------------------------------------------ */132 -------- ------------------------------------------------------ */
132script.spinbackDefault = function(channel, control, value, status, group) {133script.spinback = function(channel, control, value, status, group) {
133 // disable on note-off or zero value note/cc134 // disable on note-off or zero value note/cc
134 script.spinback(group, ((status & 0xF0) != 0x80 && value > 0));135 engine.spinback(parseInt(group.substring(8,9)), ((status & 0xF0) != 0x80 && value > 0));
135}136}
136137
137/* -------- ------------------------------------------------------138/* -------- ------------------------------------------------------
138 script.brakeDefault139 script.brake
139 Purpose: wrapper around brake() that can be directly mapped 140 Purpose: wrapper around engine.brake() that can be directly mapped
140 from xml for a brake effect141 from xml for a brake effect
142 e.g: <key>script.brake</key>
141 Input: channel, control, value, status, group143 Input: channel, control, value, status, group
142 Output: none144 Output: none
143 -------- ------------------------------------------------------ */145 -------- ------------------------------------------------------ */
144script.brakeDefault = function(channel, control, value, status, group) {146script.brake = function(channel, control, value, status, group) {
145 // disable on note-off or zero value note/cc147 // disable on note-off or zero value note/cc
146 script.brake(group, ((status & 0xF0) != 0x80 && value > 0));148 engine.brake(parseInt(group.substring(8,9)), ((status & 0xF0) != 0x80 && value > 0));
147}
148
149/* -------- ------------------------------------------------------
150 script.spinback
151 Purpose: Activate or disable a spinback effect on the chosen deck
152 Input: group, enable/disable, [delay], [factor], [inital rate]
153 Output: None
154 -------- ------------------------------------------------------ */
155script.spinback = function(group, activate, factor, rate, delay) {
156 if (factor == undefined) factor = 0.8;
157 if (rate == undefined) rate = -10;
158 if (delay == undefined) delay = 5;
159 script.deckSpinbackBrake(group, activate, factor, rate, delay);
160}
161
162/* -------- ------------------------------------------------------
163 script.brake
164 Purpose: Activate or disable a brake effect on the chosen deck
165 Input: group, enable/disable, [delay], [factor], [inital rate]
166 Output: None
167 -------- ------------------------------------------------------ */
168script.brake = function(group, activate, factor, rate, delay) {
169 if (factor == undefined) factor = 0.95;
170 if (rate == undefined) rate = 1;
171 if (delay == undefined) delay = 0;
172 script.deckSpinbackBrake(group, activate, factor, rate, delay);
173}
174
175script.deckSpinbackBrakeData = {};
176
177script.deckSpinbackBrake = function(group, activate, factor, rate, delay) {
178
179 if (activate != undefined) {
180
181 // store the current settings
182
183 if (script.deckSpinbackBrakeData[group] == undefined) {
184 script.deckSpinbackBrakeData[group] = { timer: null, delay: delay, factor: factor, rate: rate };
185 }
186 else {
187 script.deckSpinbackBrakeData[group].delay = delay;
188 script.deckSpinbackBrakeData[group].factor = factor;
189 script.deckSpinbackBrakeData[group].rate = rate;
190 }
191
192 // kill timer when both enabling or disabling
193
194 if (script.deckSpinbackBrakeData[group].timer != null) {
195 engine.stopTimer(script.deckSpinbackBrakeData[group].timer);
196 script.deckSpinbackBrakeData[group].timer = null;
197 }
198
199 // enable/disable scratch2 mode
200
201 engine.setValue(group, 'scratch2_enable', activate ? 1 : 0);
202
203 if (activate) {
204 // save keylock status and disable it
205 if ((script.deckSpinbackBrakeData[group].keylock = engine.getValue(group, "keylock")) > 0) {
206 engine.setValue(group, "keylock", 0);
207 }
208
209 // setup timer and send first scratch2 'tick' if activating
210 script.deckSpinbackBrakeData[group].timer = engine.beginTimer(50, 'script.deckSpinbackBrake("' + group + '")');
211 engine.setValue(group, 'scratch2', script.deckSpinbackBrakeData[group].rate);
212 }
213
214 // re-enable keylock if needed
215
216 else if (script.deckSpinbackBrakeData[group].keylock) {
217 engine.setValue(group, "keylock", 1);
218 }
219 }
220 else {
221 // being called from a timer
222
223 engine.setValue(group, 'scratch2', script.deckSpinbackBrakeData[group].rate);
224
225 if (script.deckSpinbackBrakeData[group].delay > 0) {
226 script.deckSpinbackBrakeData[group].delay--;
227 }
228 else {
229 script.deckSpinbackBrakeData[group].rate *= script.deckSpinbackBrakeData[group].factor;
230 }
231 }
232}149}
233150
234// bpm - Used for tapping the desired BPM for a deck151// bpm - Used for tapping the desired BPM for a deck

Subscribers

People subscribed via source and target branches