From 5cf61ebc01e4beeb50bfc1f27fe649e6fa9ecca8 Mon Sep 17 00:00:00 2001 From: toszlanyi Date: Fri, 26 Mar 2021 17:41:26 +0100 Subject: [PATCH 1/5] deleted condition for experimental beatcount --- res/controllers/Denon-MC7000-scripts.js | 248 ++++++++++++++++-------- 1 file changed, 170 insertions(+), 78 deletions(-) diff --git a/res/controllers/Denon-MC7000-scripts.js b/res/controllers/Denon-MC7000-scripts.js index fea38f8b2e4..01341ac7bf9 100644 --- a/res/controllers/Denon-MC7000-scripts.js +++ b/res/controllers/Denon-MC7000-scripts.js @@ -32,6 +32,13 @@ var MC7000 = {}; // USER VARIABLES BEGIN // ///////////////////////////////////*/ +// switch on experimental features +// experimental features are: +// 1) Beat LED in Slicer mode (counts every 8 beats AFTER the CUE point) +// only works for CONSTANT TEMPO tracks +// needs beat grid and CUE point set +MC7000.experimental = false; + // Wanna have Needle Search active while playing a track ? // In any case Needle Search is available holding "SHIFT" down. // can be true or false (recommended: false) @@ -61,18 +68,18 @@ MC7000.VinylModeOn = true; // default: true // Scratch algorithm parameters MC7000.scratchParams = { - recordSpeed: 33.3, // default: 33.3 + recordSpeed: 33 + 1/3, // default: 33 + 1/3 alpha: (1.0/10), // default: (1.0/10) beta: (1.0/10)/32 // default: (1.0/10)/32 }; -// Sensitivity of the jog wheel (also depends on audio latency) -MC7000.jogParams = { - // Sensitivity factor (0.5 for half, 2 for double sensitivity) - jogSensitivity: 1, // default: 1 - // this will limit the parameter of "jog" (keep between 0.5 and 3) - maxJogValue: 3 // default: 3 -}; +// Sensitivity factor of the jog wheel (also depends on audio latency) +// 0.5 for half, 2 for double sensitivity - Recommendation: +// set to 0.5 with audio buffer set to 50ms +// set to 1 with audio buffer set to 25ms +// set to 3 with audio buffer set to 5ms + +MC7000.jogSensitivity = 1; // default: 1.0 with audio buffer set to 23ms /*///////////////////////////////// // USER VARIABLES END // @@ -99,7 +106,7 @@ MC7000.currentRateRangeIndex = [0, 0, 0, 0]; // initialize the "factor" function for Spinback MC7000.factor = []; -//Set Shift button state to false for default +//Set Shift button state to false as default MC7000.shift = [false, false, false, false]; // initialize the PAD Mode to Hot Cue and all others off when starting @@ -114,32 +121,46 @@ MC7000.PADModeSampler = [false, false, false, false]; MC7000.PADModeVelSamp = [false, false, false, false]; MC7000.PADModePitch = [false, false, false, false]; -// Beatloop Roll sizes +// PAD Mode 'Beatloop Roll' sizes MC7000.beatLoopRoll = [1 / 16, 1 / 8, 1 / 4, 1 / 2, 1, 2, 4, 8]; +// PAD Mode - 'Fixed Loop' sizes +MC7000.fixedLoop = [1, 2, 4, 8, 16, 32, 64, 128]; + +// PAD Mode - 'Beatjump' sizes +MC7000.beatJump = [1, 2, 4, 8, 16, 32, 64, 128]; + // Define the MIDI signal for red LED at VU Meters MC7000.VuMeterLEDPeakValue = 0x76; +// initialize variables to compare LED status for VU, Jog and PAD LEDs +MC7000.prevVuLevel = [0, 0, 0, 0]; +MC7000.prevJogLED = [0, 0, 0, 0]; +MC7000.prevPadLED = [0, 0, 0, 0]; + // PAD Mode Colors MC7000.padColor = { "alloff": 0x01, // switch off completely // Hot Cue - "hotcueon": 0x04, // darkblue Hot Cue active - "hotcueoff": 0x02, // lightblue Hot Cue inactive + "hotcueon": 0x04, // blue Hot Cue active + "hotcueoff": 0x02, // dark blue Hot Cue inactive // Cue Loop - "cueloopon": 0x0D, // Cueloop colour for activated cue point - "cueloopoff": 0x1A, // Cueloop colour inactive + "cueloopon": 0x0D, // green Cueloop colour for activated cue point + "cueloopoff": 0x1A, // dark green Cueloop colour inactive // Roll - "rollon": 0x20, // BeatloopRoll active colour - "rolloff": 0x06, // BeatloopRoll off colour + "rollon": 0x20, // cyan BeatloopRoll active colour + "rolloff": 0x06, // dark cyan BeatloopRoll off colour + // Saved Loop + "fixedloopon": 0x3D, // yellow Saved Loop active + "fixedloopoff": 0x15, // dark yellow Saved Loop active // Slicer - "sliceron": 0x11, // activated Slicer - "slicerJumpFwd": 0x31, // Sliver forward jump - "slicerJumpBack": 0x31, // Sliver backward jump + "sliceron": 0x11, // dark red activated Slicer + "slicerJumpFwd": 0x31, // red Sliver forward jump + "slicerJumpBack": 0x31, // red Sliver backward jump // Sampler - "samplerloaded": 0x38, // dark pink Sampler loaded colour + "samplerloaded": 0x38, // pink Sampler loaded colour "samplerplay": 0x09, // green Sampler playing - "sampleroff": 0x12 // light pink Sampler standard colour + "sampleroff": 0x12 // dark pink Sampler standard colour }; /* DECK INITIALIZATION */ @@ -158,15 +179,17 @@ MC7000.init = function() { engine.makeConnection("[Channel3]", "VuMeter", MC7000.VuMeter); engine.makeConnection("[Channel4]", "VuMeter", MC7000.VuMeter); - // Platter Ring LED + // Platter Ring LED mode midi.sendShortMsg(0x90, 0x64, MC7000.modeSingleLED); midi.sendShortMsg(0x91, 0x64, MC7000.modeSingleLED); midi.sendShortMsg(0x92, 0x64, MC7000.modeSingleLED); midi.sendShortMsg(0x93, 0x64, MC7000.modeSingleLED); - engine.makeConnection("[Channel1]", "playposition", MC7000.JogLed); - engine.makeConnection("[Channel2]", "playposition", MC7000.JogLed); - engine.makeConnection("[Channel3]", "playposition", MC7000.JogLed); - engine.makeConnection("[Channel4]", "playposition", MC7000.JogLed); + + // Track Position LEDs for Jog Wheel and Slicer + engine.makeConnection("[Channel1]", "playposition", MC7000.TrackPositionLEDs); + engine.makeConnection("[Channel2]", "playposition", MC7000.TrackPositionLEDs); + engine.makeConnection("[Channel3]", "playposition", MC7000.TrackPositionLEDs); + engine.makeConnection("[Channel4]", "playposition", MC7000.TrackPositionLEDs); // Vinyl mode LEDs midi.sendShortMsg(0x90, 0x07, MC7000.isVinylMode ? 0x7F: 0x01); @@ -188,8 +211,8 @@ MC7000.init = function() { engine.makeConnection("[Sampler"+i+"]", "play", MC7000.SamplerLED); } - // Activate Timer for Controller Status SysEx to avoid conflicts with Softtakeover - engine.beginTimer(3000, MC7000.delayedSysEx, true); + // send Controller Status SysEx message delayed to avoid conflicts with Softtakeover + engine.beginTimer(2000, MC7000.delayedSysEx, true); }; // SysEx message to receive all knob and fader positions @@ -257,8 +280,8 @@ MC7000.padModeCueLoop = function(channel, control, value, status, group) { MC7000.PADModePitch[deckNumber] = false; // switch off PAD illumination - for (var i = 1; i <= 8; i++) { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i - 1, MC7000.padColor.alloff); + for (var i = 0; i < 8; i++) { + midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i, MC7000.padColor.alloff); } }; @@ -280,8 +303,8 @@ MC7000.padModeFlip = function(channel, control, value, status, group) { MC7000.PADModePitch[deckNumber] = false; // switch off PAD illumination - for (var i = 1; i <= 8; i++) { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x1C + i - 1, MC7000.padColor.alloff); + for (var i = 0; i < 8; i++) { + midi.sendShortMsg(0x94 + deckNumber - 1, 0x1C + i, MC7000.padColor.alloff); } }; @@ -303,8 +326,8 @@ MC7000.padModeRoll = function(channel, control, value, status, group) { MC7000.PADModePitch[deckNumber] = false; // change PAD color when switching to Roll Mode - for (var i = 1; i <= 8; i++) { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i - 1, MC7000.padColor.rolloff); + for (var i = 0; i < 8; i++) { + midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i, MC7000.padColor.rolloff); } }; @@ -325,9 +348,10 @@ MC7000.padModeSavedLoop = function(channel, control, value, status, group) { MC7000.PADModeVelSamp[deckNumber] = false; MC7000.PADModePitch[deckNumber] = false; - // switch off PAD illumination - for (var i = 1; i <= 8; i++) { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i - 1, MC7000.padColor.alloff); + // change PAD color when switching to Saved Loop Mode + for (var i = 0; i < 8; i++) { + var activeLED = engine.getValue(group, "beatloop_" + MC7000.fixedLoop[i] + "_enabled") ? MC7000.padColor.fixedloopon : MC7000.padColor.fixedloopoff; + midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i, activeLED); } }; @@ -349,8 +373,8 @@ MC7000.padModeSlicer = function(channel, control, value, status, group) { MC7000.PADModePitch[deckNumber] = false; // change PAD color when switching to Slicer Mode - for (var i = 1; i <= 8; i++) { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i - 1, MC7000.padColor.sliceron); + for (var i = 0; i < 8; i++) { + midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i, MC7000.padColor.sliceron); } }; @@ -372,8 +396,8 @@ MC7000.padModeSlicerLoop = function(channel, control, value, status, group) { MC7000.PADModePitch[deckNumber] = false; // switch off PAD illumination - for (var i = 1; i <= 8; i++) { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i - 1, MC7000.padColor.alloff); + for (var i = 0; i < 8; i++) { + midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i, MC7000.padColor.alloff); } }; @@ -424,8 +448,8 @@ MC7000.padModeVelSamp = function(channel, control, value, status, group) { MC7000.PADModePitch[deckNumber] = false; // switch off PAD illumination - for (var i = 1; i <= 8; i++) { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i - 1, MC7000.padColor.alloff); + for (var i = 0; i < 8; i++) { + midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i, MC7000.padColor.alloff); } }; @@ -447,19 +471,20 @@ MC7000.padModePitch = function(channel, control, value, status, group) { MC7000.PADModePitch[deckNumber] = true; // switch off PAD illumination - for (var i = 1; i <= 8; i++) { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i - 1, MC7000.padColor.alloff); - midi.sendShortMsg(0x94 + deckNumber - 1, 0x1C + i - 1, MC7000.padColor.alloff); + for (var i = 0; i < 8; i++) { + midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i, MC7000.padColor.alloff); + midi.sendShortMsg(0x94 + deckNumber - 1, 0x1C + i, MC7000.padColor.alloff); } }; // PAD buttons MC7000.PadButtons = function(channel, control, value, status, group) { var deckNumber = script.deckFromGroup(group); + var i, j; // activate and clear Hot Cues if (MC7000.PADModeCue[deckNumber] && engine.getValue(group, "track_loaded") === 1) { - for (var i = 1; i <= 8; i++) { + for (i = 1; i <= 8; i++) { if (control === 0x14 + i - 1 && value >= 0x01) { engine.setValue(group, "hotcue_" + i + "_activate", true); } else { @@ -475,8 +500,7 @@ MC7000.PadButtons = function(channel, control, value, status, group) { } else if (MC7000.PADModeFlip[deckNumber]) { return; } else if (MC7000.PADModeRoll[deckNumber]) { - // todo: - // check for actual beatloop_size and apply back after a PAD Roll + // TODO(all): check for actual beatloop_size and apply back after a PAD Roll i = control - 0x14; if (control === 0x14 + i && value > 0x00) { engine.setValue(group, "beatlooproll_" + MC7000.beatLoopRoll[i] + "_activate", true); @@ -486,16 +510,31 @@ MC7000.PadButtons = function(channel, control, value, status, group) { midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i, MC7000.padColor.rolloff); } } else if (MC7000.PADModeSavedLoop[deckNumber]) { - return; + if (value === 0x00) { + return; // don't respond to note off messages + } + i = control - 0x14; + engine.setValue(group, "beatloop_" + MC7000.fixedLoop[i] + "_toggle", true); + for (j =0; j < 8; j++) { + var activeLED = engine.getValue(group, "beatloop_" + MC7000.fixedLoop[j] + "_enabled") ? MC7000.padColor.fixedloopon : MC7000.padColor.fixedloopoff; + midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + j, activeLED); + } } else if (MC7000.PADModeSlicer[deckNumber]) { if (value > 0) { - var beats = 1 << (control % 4); - if (control > 0x17) { - engine.setValue(group, "beatjump_" + beats + "_backward", value); + i = control - 0x14; // unshifted button + j = control - 0x1C; // shifted button + if (control < 0x18) { + engine.setValue(group, "beatjump_" + MC7000.fixedLoop[i] + "_forward", true); + midi.sendShortMsg(0x94 + deckNumber - 1, control, MC7000.padColor.slicerJumpFwd); + } else if (control > 0x17 && control < 0x1C) { + engine.setValue(group, "beatjump_" + MC7000.fixedLoop[i - 4] + "_backward", true); midi.sendShortMsg(0x94 + deckNumber - 1, control, MC7000.padColor.slicerJumpBack); - } else { - engine.setValue(group, "beatjump_" + beats + "_forward", value); + } else if (control > 0x1B && control < 0x20) { + engine.setValue(group, "beatjump_" + MC7000.fixedLoop[j + 4] + "_forward", true); midi.sendShortMsg(0x94 + deckNumber - 1, control, MC7000.padColor.slicerJumpFwd); + } else if (control > 0x1F) { + engine.setValue(group, "beatjump_" + MC7000.fixedLoop[j] + "_backward", true); + midi.sendShortMsg(0x94 + deckNumber - 1, control, MC7000.padColor.slicerJumpBack); } } else { midi.sendShortMsg(0x94 + deckNumber - 1, control, MC7000.padColor.sliceron); @@ -528,7 +567,7 @@ MC7000.PadButtons = function(channel, control, value, status, group) { } }; -// Toggle Shift Button +// Shift Button MC7000.shiftButton = function(channel, control, value, status, group) { var deckNumber = script.deckFromGroup(group); MC7000.shift[deckNumber - 1] = ! MC7000.shift[deckNumber - 1]; @@ -599,22 +638,26 @@ MC7000.wheelTouch = function(channel, control, value, status, group) { // The wheel that actually controls the scratching MC7000.wheelTurn = function(channel, control, value, status, group) { + // TODO(all): check for latency and use it to normalize the jog factor so jog wont be + // depending on audio latency anymore. + // A: For a control that centers on 0: - var numTicks = (value < 0x64) ? value : (value - 128); - var deckNumber = script.deckFromGroup(group); + var numTicks = (value < 0x64) ? value : (value - 128), + adjustedSpeed = numTicks * MC7000.jogSensitivity * 25, + deckNumber = script.deckFromGroup(group); if (engine.isScratching(deckNumber)) { // Scratch! - engine.scratchTick(deckNumber, numTicks); + engine.scratchTick(deckNumber, numTicks * MC7000.jogSensitivity); } else { if (MC7000.shift[deckNumber - 1]) { // While Shift Button pressed -> Search through track - var jogSearch = 5000 * numTicks / MC7000.jogWheelTicksPerRevolution * MC7000.jogParams.jogSensitivity; + var jogSearch = 300 * adjustedSpeed / MC7000.jogWheelTicksPerRevolution; engine.setValue(group, "jog", jogSearch); } else { // While Shift Button released -> Pitch Bend - var jogDelta = numTicks / MC7000.jogWheelTicksPerRevolution * MC7000.jogParams.jogSensitivity * 30; + var jogDelta = adjustedSpeed / MC7000.jogWheelTicksPerRevolution; var jogAbsolute = jogDelta + engine.getValue(group, "jog"); - engine.setValue(group, "jog", Math.max(-MC7000.jogParams.maxJogValue, Math.min(MC7000.jogParams.maxJogValue, jogAbsolute))); + engine.setValue(group, "jog", jogAbsolute); } } }; @@ -646,7 +689,7 @@ MC7000.needleSearchStripPosition = function(channel, control, value, status, group) { var deckNumber = script.deckFromGroup(group); if (MC7000.needleSearchTouched[deckNumber]) { - var fullValue = (MC7000.needleDropMSB << 7) + value; // move MSB 7 binary gigits to the left and add LSB + var fullValue = (MC7000.needleDropMSB << 7) + value; // move MSB 7 binary digits to the left and add LSB var position = (fullValue / 0x3FFF); // divide by all possible positions to get relative between 0 - 1 engine.setParameter(group, "playposition", position); } @@ -746,7 +789,7 @@ MC7000.stopTime = function(channel, control, value, status, group) { MC7000.factor[deckNumber] = (1.1 - (value / 127)) * 30 - 2; }; -// Use the CENSOR button as Spinback with STOP TIME adjusted length +// Use SHIFT + CENSOR button as Spinback with STOP TIME adjusted length MC7000.reverse = function(channel, control, value, status, group) { var deckNumber = script.deckFromGroup(group); if (value > 0) { @@ -784,7 +827,7 @@ MC7000.crossFaderCurve = function(control, value) { // Set FX wet/dry value MC7000.fxWetDry = function(channel, control, value, status, group) { - var numTicks = (value < 0x64) ? value: (value - 128); + var numTicks = (value < 0x64) ? value : (value - 128); var newVal = engine.getValue(group, "mix") + numTicks/64*2; engine.setValue(group, "mix", Math.max(0, Math.min(1, newVal))); }; @@ -815,26 +858,75 @@ MC7000.sortLibrary = function(channel, control, value) { /* LEDs for VuMeter */ // VuMeters only for Channel 1-4 / Master is on Hardware MC7000.VuMeter = function(value, group) { - var deckNumber = script.deckFromGroup(group), - vuLevelOutValue = engine.getValue(group, "PeakIndicator") ? MC7000.VuMeterLEDPeakValue : Math.pow(value, 4) * (MC7000.VuMeterLEDPeakValue - 1); - - midi.sendShortMsg(0xB0 + deckNumber - 1, 0x1F, vuLevelOutValue); + var deckNumber = script.deckFromGroup(group); + var currentLED = Math.pow(value, 3) * (MC7000.VuMeterLEDPeakValue - 1); + var vuLevelOutValue = engine.getValue(group, "PeakIndicator") ? MC7000.VuMeterLEDPeakValue : currentLED; + var vuThreshold = Math.floor(currentLED / 4) * 4; + // only send Midi signal when threshold is reached + if (currentLED < 4) { + midi.sendShortMsg(0xB0 + deckNumber - 1, 0x1F, 0x00); + } else { // switch off LEDs when currentLED < threashold + if (MC7000.prevVuLevel[deckNumber - 1] !== vuThreshold) { + midi.sendShortMsg(0xB0 + deckNumber - 1, 0x1F, vuLevelOutValue); + MC7000.prevVuLevel[deckNumber - 1] = vuThreshold; + } + } }; -/* LEDs around Jog wheel */ -MC7000.JogLed = function(value, group) { +// Spinning Platter LEDs & Slicer Loop PAD LEDs as beat counter +// pulled together for the calculation to be done only once and then +// send LED signals to Jog or PAD LEDs when needed. +MC7000.TrackPositionLEDs = function(value, group) { // do nothing before track starts if (value === 0) { return; } - var deckNumber = script.deckFromGroup(group), - trackDuration = engine.getValue(group, "duration"), - position = value * trackDuration / 60 * MC7000.scratchParams.recordSpeed, - // LED ring contains 48 segments with each LED activated by the next even number - jogLedOutValue = 48 * 2, - activeLED = MC7000.isVinylMode[deckNumber - 1] ? Math.round(position * jogLedOutValue) % jogLedOutValue : value * jogLedOutValue; + // lets define some variables first + var deckNumber = script.deckFromGroup(group); + var trackDuration = engine.getValue(group, "duration"); // in seconds + var beatLength = engine.getValue(group, "file_bpm") / 60; // in Beats Per Seconds + var cuePosition = engine.getValue(group, "cue_point") / engine.getValue(group, "track_samplerate") / 2; // in seconds + var playPosition = value * trackDuration; // in seconds + var jogLEDPosition = playPosition / 60 * MC7000.scratchParams.recordSpeed; + var jogLEDNumber = 48; // LED ring contains 48 segments each triggered by the next even Midi value + // check for Vinyl Mode and decide to spin the Jog LED or show play position + var activeJogLED = MC7000.isVinylMode[deckNumber - 1] ? Math.round(jogLEDPosition * jogLEDNumber) % jogLEDNumber : Math.round(value * jogLEDNumber); + // count the beats (1 to 8) after the CUE point + var beatCountLED = (Math.floor((playPosition - cuePosition) * beatLength) % 8); //calculate PAD LED position + + // TODO(all): check for playposition < (trackduration - warning length) for sending position signals + // check if a Jog LED has changed and if so then send the signal to the next Jog LED + if (MC7000.prevJogLED[deckNumber - 1] !== activeJogLED) { + midi.sendShortMsg(0x90 + deckNumber - 1, 0x06, activeJogLED * 2); // only each 2nd midi signal triggers the next LED + MC7000.prevJogLED[deckNumber - 1] = activeJogLED; + } + // TODO(all): else blink the platter LEDs - midi.sendShortMsg(0x90 + deckNumber - 1, 0x06, activeLED); + // check if Slicer mode is active and illuminate PAD LEDs counting with the beat while playing + if (!MC7000.experimental) { + return; + } + if (MC7000.PADModeSlicer[deckNumber]) { + // only send new LED status when beatCountLED really changes + if (MC7000.prevPadLED[deckNumber - 1] !== beatCountLED) { + // first set all LEDs to default color incl shifted + for (var i = 0; i < 16; i++) { + midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i, MC7000.padColor.sliceron); + } + // now chose which PAD LED to turn on (+8 means shifted PAD LEDs) + if (beatCountLED === 0) { + midi.sendShortMsg(0x94 + deckNumber - 1, 0x14, MC7000.padColor.hotcueon); + midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + 8, MC7000.padColor.hotcueon); + } else if (beatCountLED === 7) { + midi.sendShortMsg(0x94 + deckNumber - 1, 0x1B, MC7000.padColor.hotcueon); + midi.sendShortMsg(0x94 + deckNumber - 1, 0x1B + 8, MC7000.padColor.hotcueon); + } else if (beatCountLED > 0 && beatCountLED < 7) { + midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + beatCountLED, MC7000.padColor.hotcueon); + midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + 8 + beatCountLED, MC7000.padColor.hotcueon); + } + } + MC7000.prevPadLED[deckNumber - 1] = beatCountLED; + } }; // initial HotCue LED when loading a track with already existing hotcues From 6a9e975b5624103c0f9d4604f2b92a45535192d2 Mon Sep 17 00:00:00 2001 From: toszlanyi Date: Tue, 6 Apr 2021 18:32:30 +0200 Subject: [PATCH 2/5] closing all remarks mentioned by swiftb0y --- res/controllers/Denon-MC7000-scripts.js | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/res/controllers/Denon-MC7000-scripts.js b/res/controllers/Denon-MC7000-scripts.js index 01341ac7bf9..1f39db4316b 100644 --- a/res/controllers/Denon-MC7000-scripts.js +++ b/res/controllers/Denon-MC7000-scripts.js @@ -37,7 +37,7 @@ var MC7000 = {}; // 1) Beat LED in Slicer mode (counts every 8 beats AFTER the CUE point) // only works for CONSTANT TEMPO tracks // needs beat grid and CUE point set -MC7000.experimental = false; +MC7000.experimental = true; // Wanna have Needle Search active while playing a track ? // In any case Needle Search is available holding "SHIFT" down. @@ -79,7 +79,7 @@ MC7000.scratchParams = { // set to 1 with audio buffer set to 25ms // set to 3 with audio buffer set to 5ms -MC7000.jogSensitivity = 1; // default: 1.0 with audio buffer set to 23ms +MC7000.jogSensitivity = 1.3; // default: 1.0 with audio buffer set to 23ms /*///////////////////////////////// // USER VARIABLES END // @@ -523,15 +523,19 @@ MC7000.PadButtons = function(channel, control, value, status, group) { if (value > 0) { i = control - 0x14; // unshifted button j = control - 0x1C; // shifted button + // forward buttons if (control < 0x18) { engine.setValue(group, "beatjump_" + MC7000.fixedLoop[i] + "_forward", true); midi.sendShortMsg(0x94 + deckNumber - 1, control, MC7000.padColor.slicerJumpFwd); + // backward buttons } else if (control > 0x17 && control < 0x1C) { engine.setValue(group, "beatjump_" + MC7000.fixedLoop[i - 4] + "_backward", true); midi.sendShortMsg(0x94 + deckNumber - 1, control, MC7000.padColor.slicerJumpBack); + // forward buttons (shifted controls) } else if (control > 0x1B && control < 0x20) { engine.setValue(group, "beatjump_" + MC7000.fixedLoop[j + 4] + "_forward", true); midi.sendShortMsg(0x94 + deckNumber - 1, control, MC7000.padColor.slicerJumpFwd); + // backward buttons (shifted controls) } else if (control > 0x1F) { engine.setValue(group, "beatjump_" + MC7000.fixedLoop[j] + "_backward", true); midi.sendShortMsg(0x94 + deckNumber - 1, control, MC7000.padColor.slicerJumpBack); @@ -859,17 +863,12 @@ MC7000.sortLibrary = function(channel, control, value) { // VuMeters only for Channel 1-4 / Master is on Hardware MC7000.VuMeter = function(value, group) { var deckNumber = script.deckFromGroup(group); - var currentLED = Math.pow(value, 3) * (MC7000.VuMeterLEDPeakValue - 1); - var vuLevelOutValue = engine.getValue(group, "PeakIndicator") ? MC7000.VuMeterLEDPeakValue : currentLED; - var vuThreshold = Math.floor(currentLED / 4) * 4; - // only send Midi signal when threshold is reached - if (currentLED < 4) { - midi.sendShortMsg(0xB0 + deckNumber - 1, 0x1F, 0x00); - } else { // switch off LEDs when currentLED < threashold - if (MC7000.prevVuLevel[deckNumber - 1] !== vuThreshold) { - midi.sendShortMsg(0xB0 + deckNumber - 1, 0x1F, vuLevelOutValue); - MC7000.prevVuLevel[deckNumber - 1] = vuThreshold; - } + // sends either PeakIndicator or scales value (0..1) to (0..117) while truncating to each LED + var vuLevelOutValue = engine.getValue(group, "PeakIndicator") ? MC7000.VuMeterLEDPeakValue : Math.floor(Math.pow(value, 2.5) * 9) * 13; + // only send Midi signal when LED value has changed + if (MC7000.prevVuLevel[deckNumber - 1] !== vuLevelOutValue) { + midi.sendShortMsg(0xB0 + deckNumber - 1, 0x1F, vuLevelOutValue); + MC7000.prevVuLevel[deckNumber - 1] = vuLevelOutValue; } }; From 5cda43ca18f581cf7e9ef91d7d63caddf8aa3461 Mon Sep 17 00:00:00 2001 From: toszlanyi Date: Tue, 6 Apr 2021 18:38:06 +0200 Subject: [PATCH 3/5] set my own settings back to standard --- res/controllers/Denon-MC7000-scripts.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/res/controllers/Denon-MC7000-scripts.js b/res/controllers/Denon-MC7000-scripts.js index 1f39db4316b..5c58b622607 100644 --- a/res/controllers/Denon-MC7000-scripts.js +++ b/res/controllers/Denon-MC7000-scripts.js @@ -37,7 +37,7 @@ var MC7000 = {}; // 1) Beat LED in Slicer mode (counts every 8 beats AFTER the CUE point) // only works for CONSTANT TEMPO tracks // needs beat grid and CUE point set -MC7000.experimental = true; +MC7000.experimental = false; // Wanna have Needle Search active while playing a track ? // In any case Needle Search is available holding "SHIFT" down. @@ -79,7 +79,7 @@ MC7000.scratchParams = { // set to 1 with audio buffer set to 25ms // set to 3 with audio buffer set to 5ms -MC7000.jogSensitivity = 1.3; // default: 1.0 with audio buffer set to 23ms +MC7000.jogSensitivity = 1; // default: 1.0 with audio buffer set to 23ms /*///////////////////////////////// // USER VARIABLES END // From 0e12d1cfda0f50492fbe2d804cf34a567e14c43e Mon Sep 17 00:00:00 2001 From: toszlanyi Date: Wed, 7 Apr 2021 18:52:15 +0200 Subject: [PATCH 4/5] revised PAD mode beatjump equations --- res/controllers/Denon-MC7000-scripts.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/res/controllers/Denon-MC7000-scripts.js b/res/controllers/Denon-MC7000-scripts.js index 5c58b622607..1d592434944 100644 --- a/res/controllers/Denon-MC7000-scripts.js +++ b/res/controllers/Denon-MC7000-scripts.js @@ -523,21 +523,21 @@ MC7000.PadButtons = function(channel, control, value, status, group) { if (value > 0) { i = control - 0x14; // unshifted button j = control - 0x1C; // shifted button - // forward buttons - if (control < 0x18) { - engine.setValue(group, "beatjump_" + MC7000.fixedLoop[i] + "_forward", true); + // forward buttons (PAD buttons upper row) + if (control >= 0x14 && control <= 0x17) { + engine.setValue(group, "beatjump_" + MC7000.beatJump[i] + "_forward", true); midi.sendShortMsg(0x94 + deckNumber - 1, control, MC7000.padColor.slicerJumpFwd); - // backward buttons - } else if (control > 0x17 && control < 0x1C) { - engine.setValue(group, "beatjump_" + MC7000.fixedLoop[i - 4] + "_backward", true); + // backward buttons (PAD buttons lower row) + } else if (control >= 0x18 && control <= 0x1B) { + engine.setValue(group, "beatjump_" + MC7000.beatJump[i - 4] + "_backward", true); midi.sendShortMsg(0x94 + deckNumber - 1, control, MC7000.padColor.slicerJumpBack); - // forward buttons (shifted controls) - } else if (control > 0x1B && control < 0x20) { - engine.setValue(group, "beatjump_" + MC7000.fixedLoop[j + 4] + "_forward", true); + // forward buttons (PAD buttons upper row - shifted controls) + } else if (control >= 0x1C && control <= 0x1F) { + engine.setValue(group, "beatjump_" + MC7000.beatJump[j + 4] + "_forward", true); midi.sendShortMsg(0x94 + deckNumber - 1, control, MC7000.padColor.slicerJumpFwd); - // backward buttons (shifted controls) - } else if (control > 0x1F) { - engine.setValue(group, "beatjump_" + MC7000.fixedLoop[j] + "_backward", true); + // backward buttons (PAD buttons lower row - shifted controls) + } else if (control >= 0x20 && control <= 0x23) { + engine.setValue(group, "beatjump_" + MC7000.beatJump[j] + "_backward", true); midi.sendShortMsg(0x94 + deckNumber - 1, control, MC7000.padColor.slicerJumpBack); } } else { From fb647d3e6295cc45404cb17ef37d09dfed928573 Mon Sep 17 00:00:00 2001 From: toszlanyi Date: Thu, 8 Apr 2021 09:28:57 +0200 Subject: [PATCH 5/5] changed beatjump equations and introduced var deckOffset --- res/controllers/Denon-MC7000-scripts.js | 155 +++++++++++++----------- 1 file changed, 85 insertions(+), 70 deletions(-) diff --git a/res/controllers/Denon-MC7000-scripts.js b/res/controllers/Denon-MC7000-scripts.js index 1d592434944..9381cb9365e 100644 --- a/res/controllers/Denon-MC7000-scripts.js +++ b/res/controllers/Denon-MC7000-scripts.js @@ -238,6 +238,7 @@ MC7000.samplerLevel = function(channel, control, value) { // PAD Mode Hot Cue MC7000.padModeCue = function(channel, control, value, status, group) { var deckNumber = script.deckFromGroup(group); + var deckOffset = deckNumber - 1; if (value === 0x00) { return; // don't respond to note off messages } @@ -255,9 +256,9 @@ MC7000.padModeCue = function(channel, control, value, status, group) { // change PAD color when switching to Hot Cue Mode for (var i = 1; i <= 8; i++) { if (engine.getValue(group, "hotcue_" + i + "_enabled", true)) { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i - 1, MC7000.padColor.hotcueon); + midi.sendShortMsg(0x94 + deckOffset, 0x14 + i - 1, MC7000.padColor.hotcueon); } else { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i - 1, MC7000.padColor.hotcueoff); + midi.sendShortMsg(0x94 + deckOffset, 0x14 + i - 1, MC7000.padColor.hotcueoff); } } }; @@ -265,6 +266,7 @@ MC7000.padModeCue = function(channel, control, value, status, group) { // PAD Mode Cue Loop MC7000.padModeCueLoop = function(channel, control, value, status, group) { var deckNumber = script.deckFromGroup(group); + var deckOffset = deckNumber - 1; if (value === 0x00) { return; // don't respond to note off messages } @@ -281,13 +283,14 @@ MC7000.padModeCueLoop = function(channel, control, value, status, group) { // switch off PAD illumination for (var i = 0; i < 8; i++) { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i, MC7000.padColor.alloff); + midi.sendShortMsg(0x94 + deckOffset, 0x14 + i, MC7000.padColor.alloff); } }; // PAD Mode Flip MC7000.padModeFlip = function(channel, control, value, status, group) { var deckNumber = script.deckFromGroup(group); + var deckOffset = deckNumber - 1; if (value === 0x00) { return; // don't respond to note off messages } @@ -304,13 +307,14 @@ MC7000.padModeFlip = function(channel, control, value, status, group) { // switch off PAD illumination for (var i = 0; i < 8; i++) { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x1C + i, MC7000.padColor.alloff); + midi.sendShortMsg(0x94 + deckOffset, 0x1C + i, MC7000.padColor.alloff); } }; // PAD Mode Roll MC7000.padModeRoll = function(channel, control, value, status, group) { var deckNumber = script.deckFromGroup(group); + var deckOffset = deckNumber - 1; if (value === 0x00) { return; // don't respond to note off messages } @@ -327,13 +331,14 @@ MC7000.padModeRoll = function(channel, control, value, status, group) { // change PAD color when switching to Roll Mode for (var i = 0; i < 8; i++) { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i, MC7000.padColor.rolloff); + midi.sendShortMsg(0x94 + deckOffset, 0x14 + i, MC7000.padColor.rolloff); } }; // PAD Mode Saved Loop MC7000.padModeSavedLoop = function(channel, control, value, status, group) { var deckNumber = script.deckFromGroup(group); + var deckOffset = deckNumber - 1; if (value === 0x00) { return; // don't respond to note off messages } @@ -351,13 +356,14 @@ MC7000.padModeSavedLoop = function(channel, control, value, status, group) { // change PAD color when switching to Saved Loop Mode for (var i = 0; i < 8; i++) { var activeLED = engine.getValue(group, "beatloop_" + MC7000.fixedLoop[i] + "_enabled") ? MC7000.padColor.fixedloopon : MC7000.padColor.fixedloopoff; - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i, activeLED); + midi.sendShortMsg(0x94 + deckOffset, 0x14 + i, activeLED); } }; // PAD Mode Slicer MC7000.padModeSlicer = function(channel, control, value, status, group) { var deckNumber = script.deckFromGroup(group); + var deckOffset = deckNumber - 1; if (value === 0x00) { return; // don't respond to note off messages } @@ -374,13 +380,14 @@ MC7000.padModeSlicer = function(channel, control, value, status, group) { // change PAD color when switching to Slicer Mode for (var i = 0; i < 8; i++) { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i, MC7000.padColor.sliceron); + midi.sendShortMsg(0x94 + deckOffset, 0x14 + i, MC7000.padColor.sliceron); } }; // PAD Mode Slicer Loop MC7000.padModeSlicerLoop = function(channel, control, value, status, group) { var deckNumber = script.deckFromGroup(group); + var deckOffset = deckNumber - 1; if (value === 0x00) { return; // don't respond to note off messages } @@ -397,13 +404,14 @@ MC7000.padModeSlicerLoop = function(channel, control, value, status, group) { // switch off PAD illumination for (var i = 0; i < 8; i++) { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i, MC7000.padColor.alloff); + midi.sendShortMsg(0x94 + deckOffset, 0x14 + i, MC7000.padColor.alloff); } }; // PAD Mode Sampler MC7000.padModeSampler = function(channel, control, value, status, group) { var deckNumber = script.deckFromGroup(group); + var deckOffset = deckNumber - 1; if (value === 0x00) { return; // don't respond to note off messages } @@ -421,11 +429,11 @@ MC7000.padModeSampler = function(channel, control, value, status, group) { // change PAD color when switching to Sampler Mode for (var i = 1; i <= 8; i++) { if (engine.getValue("[Sampler" + i + "]", "play")) { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i - 1, MC7000.padColor.samplerplay); + midi.sendShortMsg(0x94 + deckOffset, 0x14 + i - 1, MC7000.padColor.samplerplay); } else if (engine.getValue("[Sampler" + i + "]", "track_loaded") === 0) { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i - 1, MC7000.padColor.sampleroff); + midi.sendShortMsg(0x94 + deckOffset, 0x14 + i - 1, MC7000.padColor.sampleroff); } else if (engine.getValue("[Sampler" + i + "]", "track_loaded") === 1 && engine.getValue("[Sampler" + i + "]", "play") === 0) { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i - 1, MC7000.padColor.samplerloaded); + midi.sendShortMsg(0x94 + deckOffset, 0x14 + i - 1, MC7000.padColor.samplerloaded); } } }; @@ -433,6 +441,7 @@ MC7000.padModeSampler = function(channel, control, value, status, group) { // PAD Mode Velocity Sampler MC7000.padModeVelSamp = function(channel, control, value, status, group) { var deckNumber = script.deckFromGroup(group); + var deckOffset = deckNumber - 1; if (value === 0x00) { return; // don't respond to note off messages } @@ -449,13 +458,14 @@ MC7000.padModeVelSamp = function(channel, control, value, status, group) { // switch off PAD illumination for (var i = 0; i < 8; i++) { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i, MC7000.padColor.alloff); + midi.sendShortMsg(0x94 + deckOffset, 0x14 + i, MC7000.padColor.alloff); } }; // PAD Mode Pitch MC7000.padModePitch = function(channel, control, value, status, group) { var deckNumber = script.deckFromGroup(group); + var deckOffset = deckNumber - 1; if (value === 0x00) { return; // don't respond to note off messages } @@ -472,14 +482,15 @@ MC7000.padModePitch = function(channel, control, value, status, group) { // switch off PAD illumination for (var i = 0; i < 8; i++) { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i, MC7000.padColor.alloff); - midi.sendShortMsg(0x94 + deckNumber - 1, 0x1C + i, MC7000.padColor.alloff); + midi.sendShortMsg(0x94 + deckOffset, 0x14 + i, MC7000.padColor.alloff); + midi.sendShortMsg(0x94 + deckOffset, 0x1C + i, MC7000.padColor.alloff); } }; // PAD buttons MC7000.PadButtons = function(channel, control, value, status, group) { var deckNumber = script.deckFromGroup(group); + var deckOffset = deckNumber - 1; var i, j; // activate and clear Hot Cues @@ -492,7 +503,7 @@ MC7000.PadButtons = function(channel, control, value, status, group) { } if (control === 0x1C + i - 1 && value >= 0x01) { engine.setValue(group, "hotcue_" + i + "_clear", true); - midi.sendShortMsg(0x94 + deckNumber - 1, 0x1C + i - 1, MC7000.padColor.hotcueoff); + midi.sendShortMsg(0x94 + deckOffset, 0x1C + i - 1, MC7000.padColor.hotcueoff); } } } else if (MC7000.PADModeCueLoop[deckNumber]) { @@ -504,10 +515,10 @@ MC7000.PadButtons = function(channel, control, value, status, group) { i = control - 0x14; if (control === 0x14 + i && value > 0x00) { engine.setValue(group, "beatlooproll_" + MC7000.beatLoopRoll[i] + "_activate", true); - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i, MC7000.padColor.rollon); + midi.sendShortMsg(0x94 + deckOffset, 0x14 + i, MC7000.padColor.rollon); } else if (control === 0x14 + i && value === 0x00) { engine.setValue(group, "beatlooproll_activate", false); - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i, MC7000.padColor.rolloff); + midi.sendShortMsg(0x94 + deckOffset, 0x14 + i, MC7000.padColor.rolloff); } } else if (MC7000.PADModeSavedLoop[deckNumber]) { if (value === 0x00) { @@ -517,7 +528,7 @@ MC7000.PadButtons = function(channel, control, value, status, group) { engine.setValue(group, "beatloop_" + MC7000.fixedLoop[i] + "_toggle", true); for (j =0; j < 8; j++) { var activeLED = engine.getValue(group, "beatloop_" + MC7000.fixedLoop[j] + "_enabled") ? MC7000.padColor.fixedloopon : MC7000.padColor.fixedloopoff; - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + j, activeLED); + midi.sendShortMsg(0x94 + deckOffset, 0x14 + j, activeLED); } } else if (MC7000.PADModeSlicer[deckNumber]) { if (value > 0) { @@ -526,22 +537,22 @@ MC7000.PadButtons = function(channel, control, value, status, group) { // forward buttons (PAD buttons upper row) if (control >= 0x14 && control <= 0x17) { engine.setValue(group, "beatjump_" + MC7000.beatJump[i] + "_forward", true); - midi.sendShortMsg(0x94 + deckNumber - 1, control, MC7000.padColor.slicerJumpFwd); + midi.sendShortMsg(0x94 + deckOffset, control, MC7000.padColor.slicerJumpFwd); // backward buttons (PAD buttons lower row) } else if (control >= 0x18 && control <= 0x1B) { engine.setValue(group, "beatjump_" + MC7000.beatJump[i - 4] + "_backward", true); - midi.sendShortMsg(0x94 + deckNumber - 1, control, MC7000.padColor.slicerJumpBack); + midi.sendShortMsg(0x94 + deckOffset, control, MC7000.padColor.slicerJumpBack); // forward buttons (PAD buttons upper row - shifted controls) } else if (control >= 0x1C && control <= 0x1F) { engine.setValue(group, "beatjump_" + MC7000.beatJump[j + 4] + "_forward", true); - midi.sendShortMsg(0x94 + deckNumber - 1, control, MC7000.padColor.slicerJumpFwd); + midi.sendShortMsg(0x94 + deckOffset, control, MC7000.padColor.slicerJumpFwd); // backward buttons (PAD buttons lower row - shifted controls) } else if (control >= 0x20 && control <= 0x23) { engine.setValue(group, "beatjump_" + MC7000.beatJump[j] + "_backward", true); - midi.sendShortMsg(0x94 + deckNumber - 1, control, MC7000.padColor.slicerJumpBack); + midi.sendShortMsg(0x94 + deckOffset, control, MC7000.padColor.slicerJumpBack); } } else { - midi.sendShortMsg(0x94 + deckNumber - 1, control, MC7000.padColor.sliceron); + midi.sendShortMsg(0x94 + deckOffset, control, MC7000.padColor.sliceron); } } else if (MC7000.PADModeSlicerLoop[deckNumber]) { return; @@ -556,10 +567,10 @@ MC7000.PadButtons = function(channel, control, value, status, group) { } else if (control === 0x1C + i - 1 && value >= 0x01) { if (engine.getValue("[Sampler" + i + "]", "play") === 1) { engine.setValue("[Sampler" + i + "]", "cue_gotoandstop", 1); - midi.sendShortMsg(0x94 + deckNumber - 1, 0x1C + i - 1, MC7000.padColor.samplerloaded); + midi.sendShortMsg(0x94 + deckOffset, 0x1C + i - 1, MC7000.padColor.samplerloaded); } else { engine.setValue("[Sampler" + i + "]", "eject", 1); - midi.sendShortMsg(0x94 + deckNumber - 1, 0x1C + i - 1, MC7000.padColor.sampleroff); + midi.sendShortMsg(0x94 + deckOffset, 0x1C + i - 1, MC7000.padColor.sampleroff); engine.setValue("[Sampler" + i + "]", "eject", 0); } } @@ -573,10 +584,10 @@ MC7000.PadButtons = function(channel, control, value, status, group) { // Shift Button MC7000.shiftButton = function(channel, control, value, status, group) { - var deckNumber = script.deckFromGroup(group); - MC7000.shift[deckNumber - 1] = ! MC7000.shift[deckNumber - 1]; - midi.sendShortMsg(0x90 + deckNumber - 1, 0x32, - MC7000.shift[deckNumber - 1] ? 0x7F : 0x01); + var deckOffset = script.deckFromGroup(group) - 1; + MC7000.shift[deckOffset] = ! MC7000.shift[deckOffset]; + midi.sendShortMsg(0x90 + deckOffset, 0x32, + MC7000.shift[deckOffset] ? 0x7F : 0x01); }; // Toggle Vinyl Mode @@ -584,10 +595,10 @@ MC7000.vinylModeToggle = function(channel, control, value, status, group) { if (value === 0x00) { return; // don't respond to note off messages } - var deckNumber = script.deckFromGroup(group); - MC7000.isVinylMode[deckNumber - 1] = !MC7000.isVinylMode[deckNumber - 1]; - midi.sendShortMsg(0x90 + deckNumber - 1, 0x07, - MC7000.isVinylMode[deckNumber - 1] ? 0x7F : 0x01); + var deckOffset = script.deckFromGroup(group) - 1; + MC7000.isVinylMode[deckOffset] = !MC7000.isVinylMode[deckOffset]; + midi.sendShortMsg(0x90 + deckOffset, 0x07, + MC7000.isVinylMode[deckOffset] ? 0x7F : 0x01); }; // Use select button to load and eject track from deck @@ -628,7 +639,8 @@ MC7000.loadButton = function(channel, control, value, status, group) { // The button that enables/disables scratching MC7000.wheelTouch = function(channel, control, value, status, group) { var deckNumber = script.deckFromGroup(group); - if (MC7000.isVinylMode[deckNumber - 1]) { + var deckOffset = deckNumber - 1; + if (MC7000.isVinylMode[deckOffset]) { if (value === 0x7F) { engine.scratchEnable(deckNumber, MC7000.jogWheelTicksPerRevolution, MC7000.scratchParams.recordSpeed, @@ -646,14 +658,15 @@ MC7000.wheelTurn = function(channel, control, value, status, group) { // depending on audio latency anymore. // A: For a control that centers on 0: - var numTicks = (value < 0x64) ? value : (value - 128), - adjustedSpeed = numTicks * MC7000.jogSensitivity * 25, - deckNumber = script.deckFromGroup(group); + var numTicks = (value < 0x64) ? value : (value - 128); + var adjustedSpeed = numTicks * MC7000.jogSensitivity * 25; + var deckNumber = script.deckFromGroup(group); + var deckOffset = deckNumber - 1; if (engine.isScratching(deckNumber)) { // Scratch! engine.scratchTick(deckNumber, numTicks * MC7000.jogSensitivity); } else { - if (MC7000.shift[deckNumber - 1]) { + if (MC7000.shift[deckOffset]) { // While Shift Button pressed -> Search through track var jogSearch = 300 * adjustedSpeed / MC7000.jogWheelTicksPerRevolution; engine.setValue(group, "jog", jogSearch); @@ -716,13 +729,13 @@ MC7000.nextRateRange = function(midichan, control, value, status, group) { if (value === 0) { return; // don't respond to note off messages } - var deckNumber = script.deckFromGroup(group); + var deckOffset = script.deckFromGroup(group) - 1; // increment currentRateRangeIndex and check for overflow - if (++MC7000.currentRateRangeIndex[deckNumber - 1] === + if (++MC7000.currentRateRangeIndex[deckOffset] === MC7000.rateRanges.length) { - MC7000.currentRateRangeIndex[deckNumber - 1] = 0; + MC7000.currentRateRangeIndex[deckOffset] = 0; } - engine.setValue(group, "rateRange", MC7000.rateRanges[MC7000.currentRateRangeIndex[deckNumber - 1]]); + engine.setValue(group, "rateRange", MC7000.rateRanges[MC7000.currentRateRangeIndex[deckOffset]]); }; // Previous Rate range toggle @@ -730,19 +743,19 @@ MC7000.prevRateRange = function(midichan, control, value, status, group) { if (value === 0) { return; // don't respond to note off messages } - var deckNumber = script.deckFromGroup(group); + var deckOffset = script.deckFromGroup(group) - 1; // decrement currentRateRangeIndex and check for underflow - if (--MC7000.currentRateRangeIndex[deckNumber - 1] < 0) { - MC7000.currentRateRangeIndex[deckNumber - 1] = MC7000.rateRanges.length - 1; + if (--MC7000.currentRateRangeIndex[deckOffset] < 0) { + MC7000.currentRateRangeIndex[deckOffset] = MC7000.rateRanges.length - 1; } - engine.setValue(group, "rateRange", MC7000.rateRanges[MC7000.currentRateRangeIndex[deckNumber - 1]]); + engine.setValue(group, "rateRange", MC7000.rateRanges[MC7000.currentRateRangeIndex[deckOffset]]); }; // Key & Waveform zoom Select MC7000.keySelect = function(midichan, control, value, status, group) { - var deckNumber = script.deckFromGroup(group); + var deckOffset = script.deckFromGroup(group) - 1; // While Shift Button is pressed: Waveform Zoom - if (MC7000.shift[deckNumber - 1]) { + if (MC7000.shift[deckOffset]) { if (value === 0x7F) { script.triggerControl(group, "waveform_zoom_up", 100); } else { @@ -760,12 +773,12 @@ MC7000.keySelect = function(midichan, control, value, status, group) { // Key & Waveform zoom Reset MC7000.keyReset = function(channel, control, value, status, group) { - var deckNumber = script.deckFromGroup(group); + var deckOffset = script.deckFromGroup(group) - 1; if (value === 0x00) { return; } // While Shift Button is pressed: Waveform Zoom Reset - if (MC7000.shift[deckNumber - 1]) { + if (MC7000.shift[deckOffset]) { script.triggerControl(group, "waveform_zoom_set_default", 100); // While Shift Button is released: Key Reset } else { @@ -798,7 +811,7 @@ MC7000.reverse = function(channel, control, value, status, group) { var deckNumber = script.deckFromGroup(group); if (value > 0) { // while the button is pressed spin back - engine.brake(deckNumber, true, MC7000.factor[deckNumber], -15); // start at a rate of -15 and decrease by "factor" + engine.brake(deckNumber, true, MC7000.factor[deckNumber], - 15); // start at a rate of -15 and decrease by "factor" } else { // when releasing the button the track starts softly again engine.softStart(deckNumber, true, MC7000.factor[deckNumber]); @@ -862,13 +875,13 @@ MC7000.sortLibrary = function(channel, control, value) { /* LEDs for VuMeter */ // VuMeters only for Channel 1-4 / Master is on Hardware MC7000.VuMeter = function(value, group) { - var deckNumber = script.deckFromGroup(group); + var deckOffset = script.deckFromGroup(group) - 1; // sends either PeakIndicator or scales value (0..1) to (0..117) while truncating to each LED var vuLevelOutValue = engine.getValue(group, "PeakIndicator") ? MC7000.VuMeterLEDPeakValue : Math.floor(Math.pow(value, 2.5) * 9) * 13; // only send Midi signal when LED value has changed - if (MC7000.prevVuLevel[deckNumber - 1] !== vuLevelOutValue) { - midi.sendShortMsg(0xB0 + deckNumber - 1, 0x1F, vuLevelOutValue); - MC7000.prevVuLevel[deckNumber - 1] = vuLevelOutValue; + if (MC7000.prevVuLevel[deckOffset] !== vuLevelOutValue) { + midi.sendShortMsg(0xB0 + deckOffset, 0x1F, vuLevelOutValue); + MC7000.prevVuLevel[deckOffset] = vuLevelOutValue; } }; @@ -882,6 +895,7 @@ MC7000.TrackPositionLEDs = function(value, group) { } // lets define some variables first var deckNumber = script.deckFromGroup(group); + var deckOffset = deckNumber - 1; var trackDuration = engine.getValue(group, "duration"); // in seconds var beatLength = engine.getValue(group, "file_bpm") / 60; // in Beats Per Seconds var cuePosition = engine.getValue(group, "cue_point") / engine.getValue(group, "track_samplerate") / 2; // in seconds @@ -889,15 +903,15 @@ MC7000.TrackPositionLEDs = function(value, group) { var jogLEDPosition = playPosition / 60 * MC7000.scratchParams.recordSpeed; var jogLEDNumber = 48; // LED ring contains 48 segments each triggered by the next even Midi value // check for Vinyl Mode and decide to spin the Jog LED or show play position - var activeJogLED = MC7000.isVinylMode[deckNumber - 1] ? Math.round(jogLEDPosition * jogLEDNumber) % jogLEDNumber : Math.round(value * jogLEDNumber); + var activeJogLED = MC7000.isVinylMode[deckOffset] ? Math.round(jogLEDPosition * jogLEDNumber) % jogLEDNumber : Math.round(value * jogLEDNumber); // count the beats (1 to 8) after the CUE point var beatCountLED = (Math.floor((playPosition - cuePosition) * beatLength) % 8); //calculate PAD LED position // TODO(all): check for playposition < (trackduration - warning length) for sending position signals // check if a Jog LED has changed and if so then send the signal to the next Jog LED - if (MC7000.prevJogLED[deckNumber - 1] !== activeJogLED) { - midi.sendShortMsg(0x90 + deckNumber - 1, 0x06, activeJogLED * 2); // only each 2nd midi signal triggers the next LED - MC7000.prevJogLED[deckNumber - 1] = activeJogLED; + if (MC7000.prevJogLED[deckOffset] !== activeJogLED) { + midi.sendShortMsg(0x90 + deckOffset, 0x06, activeJogLED * 2); // only each 2nd midi signal triggers the next LED + MC7000.prevJogLED[deckOffset] = activeJogLED; } // TODO(all): else blink the platter LEDs @@ -907,39 +921,40 @@ MC7000.TrackPositionLEDs = function(value, group) { } if (MC7000.PADModeSlicer[deckNumber]) { // only send new LED status when beatCountLED really changes - if (MC7000.prevPadLED[deckNumber - 1] !== beatCountLED) { + if (MC7000.prevPadLED[deckOffset] !== beatCountLED) { // first set all LEDs to default color incl shifted for (var i = 0; i < 16; i++) { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i, MC7000.padColor.sliceron); + midi.sendShortMsg(0x94 + deckOffset, 0x14 + i, MC7000.padColor.sliceron); } // now chose which PAD LED to turn on (+8 means shifted PAD LEDs) if (beatCountLED === 0) { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14, MC7000.padColor.hotcueon); - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + 8, MC7000.padColor.hotcueon); + midi.sendShortMsg(0x94 + deckOffset, 0x14, MC7000.padColor.hotcueon); + midi.sendShortMsg(0x94 + deckOffset, 0x14 + 8, MC7000.padColor.hotcueon); } else if (beatCountLED === 7) { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x1B, MC7000.padColor.hotcueon); - midi.sendShortMsg(0x94 + deckNumber - 1, 0x1B + 8, MC7000.padColor.hotcueon); + midi.sendShortMsg(0x94 + deckOffset, 0x1B, MC7000.padColor.hotcueon); + midi.sendShortMsg(0x94 + deckOffset, 0x1B + 8, MC7000.padColor.hotcueon); } else if (beatCountLED > 0 && beatCountLED < 7) { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + beatCountLED, MC7000.padColor.hotcueon); - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + 8 + beatCountLED, MC7000.padColor.hotcueon); + midi.sendShortMsg(0x94 + deckOffset, 0x14 + beatCountLED, MC7000.padColor.hotcueon); + midi.sendShortMsg(0x94 + deckOffset, 0x14 + 8 + beatCountLED, MC7000.padColor.hotcueon); } } - MC7000.prevPadLED[deckNumber - 1] = beatCountLED; + MC7000.prevPadLED[deckOffset] = beatCountLED; } }; // initial HotCue LED when loading a track with already existing hotcues MC7000.HotCueLED = function(value, group) { var deckNumber = script.deckFromGroup(group); + var deckOffset = deckNumber - 1; if (MC7000.PADModeCue[deckNumber]) { for (var i = 1; i <= 8; i++) { if (value === 1) { if (engine.getValue(group, "hotcue_"+i+"_enabled") === 1) { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i - 1, MC7000.padColor.hotcueon); + midi.sendShortMsg(0x94 + deckOffset, 0x14 + i - 1, MC7000.padColor.hotcueon); } } else { if (engine.getValue(group, "hotcue_"+i+"_enabled") === 0) { - midi.sendShortMsg(0x94 + deckNumber - 1, 0x14 + i - 1, MC7000.padColor.hotcueoff); + midi.sendShortMsg(0x94 + deckOffset, 0x14 + i - 1, MC7000.padColor.hotcueoff); } } }