Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed bpm.tapButton in common-controller-script.js #2594

Merged
merged 12 commits into from
Apr 17, 2020
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* AutoDJ: Skip next track when both deck are playing lp:1399974 #2531
* Tweak scratch parameters for Mixtrack Platinum #2028
* Fix auto tempo going to infinity on Pioneer DDJ-SB2 #2559
* Fix bpm.tapButton logic and reject missed & double taps #2594
* Add controller mapping for Native Instruments Traktor Kontrol S2 MK3 #2348
* Add controller mapping for Soundless joyMIDI #2425
* Add controller mapping for Hercules DJControl Inpulse 300 #2465
Expand Down
71 changes: 47 additions & 24 deletions res/controllers/common-controller-scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,13 +268,13 @@ script.absoluteNonLinInverse = function(value, low, mid, high, min, max) {
if (!max) {
max = 127
}
var center = (max - min) / 2
var result
var center = (max - min) / 2;
var result;

if (value == mid) {
return center
if (value === mid) {
return center;
} else if (value < mid) {
result = (center / (mid - low)) * (value - low)
result = (center / (mid - low)) * (value - low);
} else {
result = center + (center / (high - mid)) * (value - mid)
}
Expand Down Expand Up @@ -405,8 +405,9 @@ script.softStart = function(channel, control, value, status, group, factor) {
bpm = function() {
}

bpm.tapTime = 0.0
bpm.tap = [] // Tap sample values
bpm.tapTime = 0.0;
bpm.previousTapDelta = 0.0;
bpm.tap = []; // Tap sample values

/* -------- ------------------------------------------------------
bpm.tapButton
Expand All @@ -418,29 +419,51 @@ bpm.tap = [] // Tap sample values
Output: -
-------- ------------------------------------------------------ */
bpm.tapButton = function(deck) {
var now = new Date() / 1000 // Current time in seconds
var tapDelta = now - bpm.tapTime
bpm.tapTime = now
if (tapDelta > 2.0) { // reset if longer than two seconds between taps
bpm.tap = []
return
}
bpm.tap.push(60 / tapDelta)
if (bpm.tap.length > 8) bpm.tap.shift() // Keep the last 8 samples for averaging
var sum = 0
for (i = 0; i < bpm.tap.length; i++) {
sum += bpm.tap[i]
var now = new Date() / 1000; // Current time in seconds
var tapDelta = now - bpm.tapTime;
bpm.tapTime = now;

// assign tapDelta in cases where the button has not been pressed previously
if (bpm.tap.length < 1) {
bpm.previousTapDelta = tapDelta;
}
// reset if longer than two seconds between taps
if (tapDelta > 2.0) {
bpm.tap = [];
return;
}
// reject occurences of accidental double or missed taps
// a tap is considered missed when the delta of this press is 80% longer than the previous one
// and a tap is considered double when the delta is shorter than 40% of the previous one.
// these numbers are just guesses that produced good results in practice
if ((tapDelta > bpm.previousTapDelta * 1.8)||(tapDelta < bpm.previousTapDelta * 0.6)) {
return;
}
bpm.previousTapDelta = tapDelta;
bpm.tap.push(60 / tapDelta);
// Keep the last 8 samples for averaging
if (bpm.tap.length > 8) bpm.tap.shift();
var sum = 0;
for (i=0; i<bpm.tap.length; i++) {
sum += bpm.tap[i];
}
var average = sum / bpm.tap.length

var fRateScale = average / engine.getValue("[Channel" + deck + "]", "bpm")
var group = "[Channel" + deck + "]";

// "bpm" was changed in 1.10 to reflect the *adjusted* bpm, but I presume it
// was supposed to return the tracks bpm (which it did before the change).
// "file_bpm" is supposed to return the set BPM of the loaded track of the
// channel.
var fRateScale = average/engine.getValue(group, "file_bpm");

// Adjust the rate:
fRateScale = (fRateScale - 1.) / engine.getValue("[Channel" + deck + "]", "rateRange")
fRateScale = (fRateScale - 1.) / engine.getValue(group, "rateRange")

engine.setValue("[Channel" + deck + "]", "rate", fRateScale * engine.getValue("[Channel" + deck + "]", "rate_dir"))
// print("Script: BPM="+average+" setting to "+fRateScale);
}
engine.setValue(
group, "rate",
fRateScale * engine.getValue(group, "rate_dir"));
};

// ----------------- Common regular expressions --------------------------
script.samplerRegEx = /^\[Sampler(\d+)\]$/
Expand Down