// Mode button does give out midi, but the selection itself is done inside the // controller -- no control over which mode is selected for instance. HercDJCompact = function() { this.group = "[Master]"; }; HercDJCompact.init = function(id) { engine.setValue("[Master]", "num_samplers", 8); scratch = false; scratch_timer = []; scratch_timer_on = []; engine.connectControl("[Recording]", "status", "HercDJCompact.OnRecordingStatusChange"); // Tell controller to send midi to update knob and slider positions. midi.sendShortMsg(0xB0, 0x7F, 0x7F); // But the rate values get messed up, so reset them engine.setValue("[Channel1]", "rate_set_default", 1.0); engine.setValue("[Channel2]", "rate_set_default", 1.0); }; HercDJCompact.shutdown = function() { // toggle all lights off. for (i = 0x01; i < 0x57; i++) { midi.sendShortMsg(0x90, i, 0x00); } }; HercDJCompact.controls = { // "name" is just for reference in the code. "inputs": { 0x30: { "name": "jog", "channel": 1, "group": "[Channel1]"}, 0x31: { "name": "jog", "channel": 2, "group": "[Channel2]"}, 0x37: { "name": "pitch", "channel": 1, "group": "[Channel1]"}, 0x38: { "name": "pitch", "channel": 2, "group": "[Channel2]"}, } }; HercDJCompact.scratch = function (group, control, value, status) { scratch = value > 0; }; HercDJCompact.jog_wheel = function (group, control, value, status) { var input = HercDJCompact.controls.inputs[control]; // If the high bit is 1, convert to a negative number if (value & 0x40) { value = value - 0x80; } if (scratch) { if (value !== 0) { if (scratch_timer_on[input.channel]) { engine.stopTimer(scratch_timer[input.channel]); scratch_timer_on[input.channel] = false; } if (!engine.getValue(input.group, "scratch2_enable")) { engine.scratchEnable(input.channel, 256, 33+1/3, 1.0/8*(0.500), (1.0/8)*(0.500)/32); } else { engine.scratchTick(input.channel, value); } } if(engine.getValue(input.group, "scratch2_enable")) { //when not moved for 200 msecs, probably we are not touching the wheel anymore scratch_timer[input.channel] = engine.beginTimer(200, () => HercDJCompact.jog_wheelhelper(input.channel), true); scratch_timer_on[input.channel] = true; } } else { if (value !== 0) { engine.setValue(input.group, "jog", value); } } }; HercDJCompact.jog_wheelhelper = function(n) { engine.scratchDisable(n); scratch_timer_on[n] = false; }; // Pitch is adjusted by holding down shift and turning the jog wheel. HercDJCompact.pitch = function (group, control, value, status) { var input = HercDJCompact.controls.inputs[control]; if (value & 0x40) { value = value - 0x80; } var delta = Math.pow(Math.abs(value), 2) / 1000.0; if (value < 0) { delta = -delta; } var pitch = engine.getValue(input.group, "rate") + delta; if (pitch > 1.0) { pitch = 1.0; } if (pitch < -1.0) { pitch = -1.0; } engine.setValue(input.group, "rate", pitch); }; HercDJCompact.OnRecordingStatusChange = function(value, group, control) { // Not sure why this doesn't work with a regular midi output in the xml. if (value == 2) { midi.sendShortMsg(0x90, 0x2B, 0x7F); midi.sendShortMsg(0x90, 0x2C, 0x7F); } else { midi.sendShortMsg(0x90, 0x2B, 0x0); midi.sendShortMsg(0x90, 0x2C, 0x0); } };