1
function HerculesMP3e2 () {}
3
// Control schema: http://blog.ebruni.it/blog/wp-content/uploads/2010/01/Hercules-mp3e2-schema-comandi.jpg
5
// Image: http://www.hablarcom.com.br/Imagens/arquivos/jptech/DJ_control_MP3_2_frente.jpg
9
// Number of the standard RPM value. Lower values increase de sensitivity as the really records.
12
// The alpha value for the filter (start with 1/8 (0.125) and tune from there)
15
// The beta value for the filter (start with alpha/32 and tune from there)
28
/*HerculesMP3e2.controls = {
30
0x11: { "channel": 1, "name": "loadA", "type": "button" },
31
0x25: { "channel": 2, "name": "loadB", "type": "button" },
32
0x0B: { "channel": 1, "name": "pitchbend+", "type": "button" },
33
0x0A: { "channel": 1, "name": "pitchbend-", "type": "button" },
34
0x1F: { "channel": 2, "name": "pitchbend+", "type": "button" },
35
0x1E: { "channel": 2, "name": "pitchbend-", "type": "button" },
36
0x12: { "channel": 1, "name": "sync", "type": "button" },
37
0x26: { "channel": 2, "name": "sync", "type": "button" },
38
0x13: { "channel": 1, "name": "mastertempo", "type": "button" },
39
0x27: { "channel": 2, "name": "mastertempo", "type": "button" },
40
0x0F: { "channel": 1, "name": "play", "type": "button" },
41
0x23: { "channel": 2, "name": "play", "type": "button" },
42
0x0E: { "channel": 1, "name": "cue", "type": "button" },
43
0x22: { "channel": 2, "name": "cue", "type": "button" },
44
0x2D: { "channel": 1, "name": "scratch", "type": "button" },
45
0x2E: { "channel": 1, "name": "automix", "type": "button" },
46
0x01: { "channel": 1, "name": "K1", "type": "button" },
47
0x02: { "channel": 1, "name": "K2", "type": "button" },
48
0x03: { "channel": 1, "name": "K3", "type": "button" },
49
0x04: { "channel": 1, "name": "K4", "type": "button" },
50
0x05: { "channel": 1, "name": "K5", "type": "button" },
51
0x06: { "channel": 1, "name": "K6", "type": "button" },
52
0x07: { "channel": 1, "name": "K7", "type": "button" },
53
0x08: { "channel": 1, "name": "K8", "type": "button" },
54
0x15: { "channel": 2, "name": "K1", "type": "button" },
55
0x16: { "channel": 2, "name": "K2", "type": "button" },
56
0x17: { "channel": 2, "name": "K3", "type": "button" },
57
0x18: { "channel": 2, "name": "K4", "type": "button" },
58
0x19: { "channel": 2, "name": "K5", "type": "button" },
59
0x1A: { "channel": 2, "name": "K6", "type": "button" },
60
0x1B: { "channel": 2, "name": "K7", "type": "button" },
61
0x1C: { "channel": 2, "name": "K8", "type": "button" },
62
0x30: { "channel": 1, "name": "wheel", "type": "pot" },
63
0x31: { "channel": 2, "name": "wheel", "type": "pot" },
64
0x2C: { "channel": 1, "name": "folder", "type": "button" },
65
0x2B: { "channel": 1, "name": "files", "type": "button" },
69
HerculesMP3e2.init = function (id) {
70
// Switch off all LEDs
71
for (i=1; i<95; i++) midi.sendShortMsg(0x90, i, 0x00);
72
// Switch-on the LEDs for improve the usability
73
midi.sendShortMsg(0x90, 45, 0x7F); // Scratch LED
74
midi.sendShortMsg(0x90, 46, 0x7F); // Automix LED
75
midi.sendShortMsg(0x90, 14, 0x7F); // Cue deck A LED
76
midi.sendShortMsg(0x90, 34, 0x7F); // Cue deck B LED
79
HerculesMP3e2.shutdown = function (id) {
80
// Switch off all LEDs
81
for (i=1; i<95; i++) midi.sendShortMsg(0x90, i, 0x00);
84
HerculesMP3e2.automix = function (midino, control, value, status, group) {
86
// The "Automix" button is used like a shift button. When this is hold
87
// down, many commands of the console has another functions
89
if (value) { // Button pressed
91
midi.sendShortMsg(0x90, 30, 0x7F); // Switch on some LEDs
92
midi.sendShortMsg(0x90, 31, 0x7F);
93
midi.sendShortMsg(0x90, 10, 0x7F);
94
midi.sendShortMsg(0x90, 11, 0x7F);
96
else { // Button released
98
midi.sendShortMsg(0x90, 30, 0x00);
99
midi.sendShortMsg(0x90, 31, 0x00);
100
midi.sendShortMsg(0x90, 10, 0x00);
101
midi.sendShortMsg(0x90, 11, 0x00);
105
HerculesMP3e2.loadTrack = function (midino, control, value, status, group) {
106
// Load the selected track in the corresponding deck only if the track is
109
if(value && engine.getValue(group, "play") != 1) {
110
engine.setValue(group, "LoadSelectedTrack", 1);
111
engine.setValue(group, "rate", 0);
113
else engine.setValue(group, "LoadSelectedTrack", 0);
117
HerculesMP3e2.scroll = function (midino, control, value, status, group) {
118
// Button "Files": up 10 tracks
119
// Button "Folder": down 10 tracks
120
// This function scroll up or down 10 tracks on the playlist, like the mouse
123
if(control == 0x2C && value == 0x7F) {
124
engine.setValue("[Playlist]", "SelectPrevTrack", "1");
125
engine.setValue("[Playlist]", "SelectPrevTrack", "1");
126
engine.setValue("[Playlist]", "SelectPrevTrack", "1");
127
engine.setValue("[Playlist]", "SelectPrevTrack", "1");
128
engine.setValue("[Playlist]", "SelectPrevTrack", "1");
129
engine.setValue("[Playlist]", "SelectPrevTrack", "1");
130
engine.setValue("[Playlist]", "SelectPrevTrack", "1");
131
engine.setValue("[Playlist]", "SelectPrevTrack", "1");
132
engine.setValue("[Playlist]", "SelectPrevTrack", "1");
133
engine.setValue("[Playlist]", "SelectPrevTrack", "1");
134
engine.setValue("[Playlist]", "SelectPrevTrack", "0");
136
if (control == 0x2B && value == 0x7F) {
137
engine.setValue("[Playlist]", "SelectNextTrack", "1");
138
engine.setValue("[Playlist]", "SelectNextTrack", "1");
139
engine.setValue("[Playlist]", "SelectNextTrack", "1");
140
engine.setValue("[Playlist]", "SelectNextTrack", "1");
141
engine.setValue("[Playlist]", "SelectNextTrack", "1");
142
engine.setValue("[Playlist]", "SelectNextTrack", "1");
143
engine.setValue("[Playlist]", "SelectNextTrack", "1");
144
engine.setValue("[Playlist]", "SelectNextTrack", "1");
145
engine.setValue("[Playlist]", "SelectNextTrack", "1");
146
engine.setValue("[Playlist]", "SelectNextTrack", "1");
147
engine.setValue("[Playlist]", "SelectNextTrack", "0");
155
HerculesMP3e2.holdTimer = function (group, first, second) {
158
engine.setValue(group, first, 0); // Set "Off" the first function
159
engine.setValue(group, second, 1); // Set "On" the second function
163
HerculesMP3e2.holdButton = function (group, value, first, second) {
164
// This feature allows you to perform a different function if a button is
165
// pressed for 2 seconds. When the button is pressed, the first function is
166
// performed. If the button is hold down for 2 seconds, the second function
167
// is performed and the first function is disables.
170
engine.setValue(group, first, 1); // Set "On" the first function
171
holdTimerID = engine.beginTimer(2000, "HerculesMP3e2.holdTimer(\""+group+"\", \""+first+"\", \""+second+"\")", true);
174
if (holdButtonFlag) {
175
engine.setValue(group, second, 0); // Set "Off" the second function
179
engine.stopTimer(holdTimerID);
180
engine.setValue(group, first, 0); // Set "Off" the first function
187
HerculesMP3e2.keyButton = function (midino, control, value, status, group) {
188
// Loop command for the first 4 Key, Hotcues command for the latest 4
193
case 0x01: case 0x15: // K1, Loop in
194
engine.setValue(group, "loop_in", value ? 1 : 0);
196
case 0x02: case 0x16: // K2, Loop out
197
engine.setValue(group, "loop_out", value ? 1 : 0);
199
case 0x03: case 0x17: // K3, Reloop/Exit
200
engine.setValue(group, "reloop_exit", value ? 1 : 0); break;
202
case 0x04: case 0x18: // K4, Reloop/Exit
203
engine.setValue(group, "reloop_exit", value ? 1 : 0);
207
// Simple press: go to the hotcue position
208
// Shift (hold down "Automix"): clear the hotcue
210
case 0x05: case 0x19 : // K5
211
if (superButtonHold == 1) {
212
//HerculesMP3e2.holdButton(group, value, "hotcue_1_set", "hotcue_1_clear");
213
engine.setValue(group, "hotcue_1_clear", value ? 1 : 0);
215
else engine.setValue(group, "hotcue_1_activate", value ? 1 : 0);
218
case 0x06: case 0x1A: // K6
219
if (superButtonHold == 1) {
220
//HerculesMP3e2.holdButton(group, value, "hotcue_2_set", "hotcue_2_clear");
221
engine.setValue(group, "hotcue_2_clear", value ? 1 : 0);
223
else engine.setValue(group, "hotcue_2_activate", value ? 1 : 0);
226
case 0x07: case 0x1B: // K7
227
if (superButtonHold == 1) {
228
//HerculesMP3e2.holdButton(group, value, "hotcue_3_set", "hotcue_3_clear");
229
engine.setValue(group, "hotcue_3_clear", value ? 1 : 0);
231
else engine.setValue(group, "hotcue_3_activate", value ? 1 : 0);
234
case 0x08: case 0x1C: // K8
235
if (superButtonHold == 1) {
236
//HerculesMP3e2.holdButton(group, value, "hotcue_4_set", "hotcue_4_clear");
237
engine.setValue(group, "hotcue_4_clear", value ? 1 : 0);
239
else engine.setValue(group, "hotcue_4_activate", value ? 1 : 0);
244
HerculesMP3e2.knobIncrement = function (group, action, minValue, maxValue, centralValue, step, sign) {
245
// This function allows you to increment a non-linear value like the volume's knob
246
// sign must be 1 for positive increment, -1 for negative increment
248
rangeWidthLeft = centralValue-minValue;
249
rangeWidthRight = maxValue-centralValue;
250
actual = engine.getValue(group, action);
251
if (actual < 1) increment = ((rangeWidthLeft)/semiStep)*sign;
252
if (actual > 1) increment = ((rangeWidthRight)/semiStep)*sign;
254
increment = (sign == 1) ? rangeWidthRight/semiStep : (rangeWidthLeft/semiStep)*sign;
257
if (sign == 1 && actual < maxValue) newValue = actual + increment;
258
if (sign == -1 && actual > minValue) newValue = actual + increment;
262
HerculesMP3e2.pitch = function (midino, control, value, status, group) {
263
// Simple: pitch slider
264
// Shifted: Headphone volume and pre/main
266
if (superButtonHold == 1) {
267
sign = (value == 0x01) ? 1 : -1;
268
if (group == "[Channel2]") {
269
newValue = HerculesMP3e2.knobIncrement("[Master]", "headVolume", 0, 5, 1, 30, sign);
270
engine.setValue("[Master]", "headVolume", newValue);
272
if (group == "[Channel1]") {
273
newValue = HerculesMP3e2.knobIncrement("[Master]", "headMix", -1, 1, 0, 20, sign);
274
engine.setValue("[Master]", "headMix", newValue);
278
//increment = 0.0166;
280
increment = (value == 0x01) ? increment : increment * -1;
281
engine.setValue(group, "rate", engine.getValue(group, "rate") + increment);
285
HerculesMP3e2.pitchbend = function (midino, control, value, status, group) {
286
// Simple: temporary pitch adjust
287
// Shift: pregain adjust
288
if (superButtonHold == 1 && value) {
289
if (control == 0x0B || control == 0x1F) { // Pitchbend +
290
newValue = HerculesMP3e2.knobIncrement(group, "pregain", 0, 4, 1, 20, 1);
291
engine.setValue(group, "pregain", newValue);
293
else { // Pitchbend -
294
newValue = HerculesMP3e2.knobIncrement(group, "pregain", 0, 4, 1, 20, -1);
295
engine.setValue(group, "pregain", newValue);
299
if (control == 0x0B || control == 0x1F) { // Pitchbend +
300
engine.setValue(group, "rate_temp_up", value ? 1 : 0);
302
else { // Pitchbend -
303
engine.setValue(group, "rate_temp_down", value ? 1 : 0);
309
HerculesMP3e2.cue = function (midino, control, value, status, group) {
310
// Don't set Cue accidentaly at the end of the song
312
if(engine.getValue(group, "playposition") <= 0.97) {
313
engine.setValue(group, "cue_default", value ? 1 : 0);
315
else engine.setValue(group, "cue_preview", value ? 1 : 0);
318
HerculesMP3e2.scratch = function (midino, control, value, status, group) {
319
// The "scratch" button is used like a shift button only for enable the scratch mode on the
320
// deck A and/or B with the "sync" buttons
323
//Switch-on the LEDs of Sync buttons while the "scratch" button is hold down
324
midi.sendShortMsg(0x90, 18, 0x7F);
325
midi.sendShortMsg(0x90, 38, 0x7F);
329
midi.sendShortMsg(0x90, 18, 0x00);
330
midi.sendShortMsg(0x90, 38, 0x00);
334
HerculesMP3e2.sync = function (midino, control, value, status, group) {
336
if (scratchButton && value) { // If the "scratch" button is hold down
337
deck = (group == "[Channel1]") ? 1 : 2;
339
if(scratchModeDA==0) {
340
engine.scratchEnable(1, 128, standardRpm, alpha, beta); // Enable the scratch mode on Deck A
342
midi.sendShortMsg(0x90, 66, 0x7F); // Blinks the sync led
345
engine.scratchDisable(1);
347
midi.sendShortMsg(0x90, 66, 0x00); // Switch-off the sync led
351
if(scratchModeDB==0) {
352
engine.scratchEnable(2, 128, standardRpm, alpha, beta); // Enable the scratch mode on Deck B
354
midi.sendShortMsg(0x90, 86, 0x7F); // Blinks the sync led
357
engine.scratchDisable(2);
359
midi.sendShortMsg(0x90, 86, 0x00); // Switch-off the sync led
363
else engine.setValue(group, "beatsync", value ? 1 : 0);
366
HerculesMP3e2.jogWheelDA = function (midino, control, value, status, group) {
367
// This function is called everytime the jog is moved
369
engine.scratchTick(1, 1);
370
engine.setValue(group, "jog", 1);
373
engine.scratchTick(1, -1);
374
engine.setValue(group, "jog", -1);
378
HerculesMP3e2.jogWheelDB = function (midino, control, value, status, group) {
379
// This function is called everytime the jog is moved
381
engine.scratchTick(2, 1);
382
engine.setValue(group, "jog", 1);
385
engine.scratchTick(2, -1);
386
engine.setValue(group, "jog", -1);