Skip to content

Commit

Permalink
feat: add support for scaling BPM by different ratios
Browse files Browse the repository at this point in the history
  • Loading branch information
Milkii Brewster committed Mar 12, 2024
1 parent a928d1c commit 5ffcb02
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 25 deletions.
55 changes: 49 additions & 6 deletions src/controllers/controlpickermenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,12 +237,55 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent)

// BPM / Beatgrid
QMenu* pBpmMenu = addSubmenu(tr("BPM / Beatgrid"));
addDeckAndSamplerControl("bpm", tr("BPM"), tr("BPM"), pBpmMenu, true);
addDeckAndSamplerControl("bpm_up", tr("BPM +1"), tr("Increase BPM by 1"), pBpmMenu);
addDeckAndSamplerControl("bpm_down", tr("BPM -1"), tr("Decrease BPM by 1"), pBpmMenu);
addDeckAndSamplerControl("bpm_up_small", tr("BPM +0.1"), tr("Increase BPM by 0.1"), pBpmMenu);
addDeckAndSamplerControl("bpm_down_small", tr("BPM -0.1"), tr("Decrease BPM by 0.1"), pBpmMenu);
addDeckAndSamplerControl("bpm_tap", tr("BPM Tap"), tr("BPM tap button"), pBpmMenu);
addDeckAndSamplerControl("bpm",
tr("BPM"),
tr("BPM"),
pBpmMenu,
true);
addDeckAndSamplerControl("bpm_up",
tr("BPM +1"),
tr("Increase BPM by 1"),
pBpmMenu);
addDeckAndSamplerControl("bpm_down",
tr("BPM -1"),
tr("Decrease BPM by 1"),
pBpmMenu);
addDeckAndSamplerControl("bpm_up_small",
tr("BPM +0.1"),
tr("Increase BPM by 0.1"),
pBpmMenu);
addDeckAndSamplerControl("bpm_down_small",
tr("BPM -0.1"),
tr("Decrease BPM by 0.1"),
pBpmMenu);
addDeckAndSamplerControl("bpm_tap",
tr("BPM Tap"),
tr("BPM tap button"),
pBpmMenu);
addDeckAndSamplerControl("beats_set_halve",
tr("BPM Halve"),
tr("Multiply current BPM by 0.5"),
pBpmMenu);
addDeckAndSamplerControl("beats_set_twothirds",
tr("BPM Two Thirds"),
tr("Multiply current BPM by 0.666"),
pBpmMenu);
addDeckAndSamplerControl("beats_set_threefourths",
tr("BPM Three Fourths"),
tr("Multiply current BPM by 0.75"),
pBpmMenu);
addDeckAndSamplerControl("beats_set_fourthirds",
tr("BPM Four Thirds"),
tr("Multiply current BPM by 1.333"),
pBpmMenu);
addDeckAndSamplerControl("beats_set_threehalves",
tr("BPM Three Halves"),
tr("Multiply current BPM by 1.5"),
pBpmMenu);
addDeckAndSamplerControl("beats_set_double",
tr("BPM Double"),
tr("Multiply current BPM by 2"),
pBpmMenu);
pBpmMenu->addSeparator();
addDeckAndSamplerControl("beats_adjust_faster",
tr("Adjust Beatgrid Faster +.01"),
Expand Down
103 changes: 88 additions & 15 deletions src/engine/controls/bpmcontrol.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "engine/controls/bpmcontrol.h"
#include "engine/controls/bbpmcontrol.h"

Check failure on line 1 in src/engine/controls/bpmcontrol.cpp

View workflow job for this annotation

GitHub Actions / clazy

'engine/controls/bbpmcontrol.h' file not found

Check failure on line 1 in src/engine/controls/bpmcontrol.cpp

View workflow job for this annotation

GitHub Actions / Ubuntu 22.04

engine/controls/bbpmcontrol.h: No such file or directory

Check failure on line 1 in src/engine/controls/bpmcontrol.cpp

View workflow job for this annotation

GitHub Actions / macOS 11 x64

'engine/controls/bbpmcontrol.h' file not found

Check failure on line 1 in src/engine/controls/bpmcontrol.cpp

View workflow job for this annotation

GitHub Actions / clang-tidy

'engine/controls/bbpmcontrol.h' file not found [clang-diagnostic-error]

Check failure on line 1 in src/engine/controls/bpmcontrol.cpp

View workflow job for this annotation

GitHub Actions / coverage

engine/controls/bbpmcontrol.h: No such file or directory

Check failure on line 1 in src/engine/controls/bpmcontrol.cpp

View workflow job for this annotation

GitHub Actions / macOS 11 arm64

'engine/controls/bbpmcontrol.h' file not found

Check failure on line 1 in src/engine/controls/bpmcontrol.cpp

View workflow job for this annotation

GitHub Actions / clazy

'engine/controls/bbpmcontrol.h' file not found

Check failure on line 1 in src/engine/controls/bpmcontrol.cpp

View workflow job for this annotation

GitHub Actions / Ubuntu 22.04

engine/controls/bbpmcontrol.h: No such file or directory

Check failure on line 1 in src/engine/controls/bpmcontrol.cpp

View workflow job for this annotation

GitHub Actions / clang-tidy

'engine/controls/bbpmcontrol.h' file not found [clang-diagnostic-error]

Check failure on line 1 in src/engine/controls/bpmcontrol.cpp

View workflow job for this annotation

GitHub Actions / macOS 11 x64

'engine/controls/bbpmcontrol.h' file not found

Check failure on line 1 in src/engine/controls/bpmcontrol.cpp

View workflow job for this annotation

GitHub Actions / coverage

engine/controls/bbpmcontrol.h: No such file or directory

Check failure on line 1 in src/engine/controls/bpmcontrol.cpp

View workflow job for this annotation

GitHub Actions / macOS 11 arm64

'engine/controls/bbpmcontrol.h' file not found

#include "control/controlencoder.h"
#include "control/controllinpotmeter.h"
Expand Down Expand Up @@ -67,24 +67,30 @@ BpmControl::BpmControl(const QString& group,
m_pLoopEndPosition = new ControlProxy(group, "loop_end_position", this);

m_pLocalBpm = new ControlObject(ConfigKey(group, "local_bpm"));
m_pAdjustBeatsFaster = new ControlPushButton(ConfigKey(group, "beats_adjust_faster"), false);

m_pAdjustBeatsFaster = std::make_unique<ControlPushButton>(
ConfigKey(group, "beats_adjust_faster"), false);
m_pAdjustBeatsFaster->setKbdRepeatable(true);
connect(m_pAdjustBeatsFaster, &ControlObject::valueChanged,
this, &BpmControl::slotAdjustBeatsFaster,
connect(m_pAdjustBeatsFaster.get(), &ControlObject::valueChanged,
this,
&BpmControl::slotAdjustBeatsFaster,
Qt::DirectConnection);
m_pAdjustBeatsSlower = new ControlPushButton(ConfigKey(group, "beats_adjust_slower"), false);
m_pAdjustBeatsSlower = std::make_unique<ControlPushButton>(ConfigKey(group, "beats_adjust_slower"), false);
m_pAdjustBeatsSlower->setKbdRepeatable(true);
connect(m_pAdjustBeatsSlower, &ControlObject::valueChanged,
this, &BpmControl::slotAdjustBeatsSlower,
connect(m_pAdjustBeatsSlower.get(),
&ControlObject::valueChanged,
this,
&BpmControl::slotAdjustBeatsSlower,
Qt::DirectConnection);
m_pTranslateBeatsEarlier = new ControlPushButton(ConfigKey(group, "beats_translate_earlier"), false);

m_pTranslateBeatsEarlier = std::make_unique<ControlPushButton>(ConfigKey(group, "beats_translate_earlier"), false);
m_pTranslateBeatsEarlier->setKbdRepeatable(true);
connect(m_pTranslateBeatsEarlier, &ControlObject::valueChanged,
connect(m_pTranslateBeatsEarlier.get(), &ControlObject::valueChanged,
this, &BpmControl::slotTranslateBeatsEarlier,
Qt::DirectConnection);
m_pTranslateBeatsLater = new ControlPushButton(ConfigKey(group, "beats_translate_later"), false);
m_pTranslateBeatsLater = std::make_unique<ControlPushButton>(ConfigKey(group, "beats_translate_later"), false);
m_pTranslateBeatsLater->setKbdRepeatable(true);
connect(m_pTranslateBeatsLater, &ControlObject::valueChanged,
connect(m_pTranslateBeatsLater.get(), &ControlObject::valueChanged,
this, &BpmControl::slotTranslateBeatsLater,
Qt::DirectConnection);
m_pTranslateBeatsMove = new ControlEncoder(ConfigKey(group, "beats_translate_move"), false);
Expand All @@ -94,6 +100,61 @@ BpmControl::BpmControl(const QString& group,
&BpmControl::slotTranslateBeatsMove,
Qt::DirectConnection);

m_pBeatsHalve = std::make_unique<ControlPushButton>(ConfigKey(group, "beats_set_halve"), false);
connect(m_pBeatsHalve.get(),
&ControlObject::valueChanged,
this,
[this](int value) {
if (value > 0) {
slotScaleBpm(mixxx::Beats::BpmScale::Halve);
}
});
m_pBeatsTwoThirds = std::make_unique<ControlPushButton>(ConfigKey(group, "beats_set_twothirds"), false);
connect(m_pBeatsTwoThirds.get(),
&ControlObject::valueChanged,
this,
[this](int value) {
if (value > 0) {
slotScaleBpm(mixxx::Beats::BpmScale::TwoThirds);
}
});
m_pBeatsThreeFourths = std::make_unique<ControlPushButton>(ConfigKey(group, "beats_set_threefourths"), false);
connect(m_pBeatsThreeFourths.get(),
&ControlObject::valueChanged,
this,
[this](int value) {
if (value > 0) {
slotScaleBpm(mixxx::Beats::BpmScale::ThreeFourths);
}
});
m_pBeatsFourThirds = std::make_unique<ControlPushButton>(ConfigKey(group, "beats_set_fourthirds"), false);
connect(m_pBeatsFourThirds.get(),
&ControlObject::valueChanged,
this,
[this](int value) {
if (value > 0) {
slotScaleBpm(mixxx::Beats::BpmScale::FourThirds);
}
});
m_pBeatsThreeHalves = std::make_unique<ControlPushButton>(ConfigKey(group, "beats_set_threehalves"), false);
connect(m_pBeatsThreeHalves.get(),
&ControlObject::valueChanged,
this,
[this](int value) {
if (value > 0) {
slotScaleBpm(mixxx::Beats::BpmScale::ThreeHalves);
}
});
m_pBeatsDouble = std::make_unique<ControlPushButton>(ConfigKey(group, "beats_set_double"), false);
connect(m_pBeatsDouble.get(),
&ControlObject::valueChanged,
this,
[this](int value) {
if (value > 0) {
slotScaleBpm(mixxx::Beats::BpmScale::Double);
}
});

// Pick a wide range (kBpmRangeMin to kBpmRangeMax) and allow out of bounds sets. This lets you
// map a soft-takeover MIDI knob to the BPM. This also creates bpm_up and
// bpm_down controls.
Expand Down Expand Up @@ -141,11 +202,7 @@ BpmControl::~BpmControl() {
delete m_pButtonTap;
delete m_pTranslateBeats;
delete m_pBeatsTranslateMatchAlignment;
delete m_pTranslateBeatsEarlier;
delete m_pTranslateBeatsLater;
delete m_pTranslateBeatsMove;
delete m_pAdjustBeatsFaster;
delete m_pAdjustBeatsSlower;
}

mixxx::Bpm BpmControl::getBpm() const {
Expand Down Expand Up @@ -264,6 +321,22 @@ void BpmControl::slotTapFilter(double averageLength, int numSamples) {
pTrack->trySetBeats(*newBeats);
}

void BpmControl::slotScaleBpm(mixxx::Beats::BpmScale bpmScale) {
const TrackPointer pTrack = getEngineBuffer()->getLoadedTrack();
if (!pTrack) {
return;
}
const mixxx::BeatsPointer pBeats = pTrack->getBeats();
if (!pBeats) {
return;
}
const auto newBeats = pBeats->tryScale(bpmScale);
if (!newBeats) {
return;
}
pTrack->trySetBeats(*newBeats);
}

// static
double BpmControl::shortestPercentageChange(const double& current_percentage,
const double& target_percentage) {
Expand Down
16 changes: 12 additions & 4 deletions src/engine/controls/bpmcontrol.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ class BpmControl : public EngineControl {
}
double calcSyncAdjustment(bool userTweakingSync);
void adjustBeatsBpm(double deltaBpm);
void slotScaleBpm(mixxx::Beats::BpmScale bpmScale);

friend class SyncControl;

Expand All @@ -139,12 +140,19 @@ class BpmControl : public EngineControl {

// The average bpm around the current playposition;
ControlObject* m_pLocalBpm;
ControlPushButton* m_pAdjustBeatsFaster;
ControlPushButton* m_pAdjustBeatsSlower;
ControlPushButton* m_pTranslateBeatsEarlier;
ControlPushButton* m_pTranslateBeatsLater;
std::unique_ptr<ControlPushButton> m_pAdjustBeatsFaster;
std::unique_ptr<ControlPushButton> m_pAdjustBeatsSlower;
std::unique_ptr<ControlPushButton> m_pTranslateBeatsEarlier;
std::unique_ptr<ControlPushButton> m_pTranslateBeatsLater;
ControlEncoder* m_pTranslateBeatsMove;

std::unique_ptr<ControlPushButton> m_pBeatsHalve;
std::unique_ptr<ControlPushButton> m_pBeatsTwoThirds;
std::unique_ptr<ControlPushButton> m_pBeatsThreeFourths;
std::unique_ptr<ControlPushButton> m_pBeatsFourThirds;
std::unique_ptr<ControlPushButton> m_pBeatsThreeHalves;
std::unique_ptr<ControlPushButton> m_pBeatsDouble;

// The current effective BPM of the engine
ControlLinPotmeter* m_pEngineBpm;

Expand Down

0 comments on commit 5ffcb02

Please sign in to comment.