Skip to content

Commit 6daf7ea

Browse files
committed
Add FourFifths (4/5) BPM scaling control
Complement the FiveFourths (5/4) scaling from mxmilkiib's commit with its inverse FourFifths (4/5 = 0.8x) scaling. Added across all layers: enum, beats math, engine control, controller picker menu, right-click track menu, track properties dialog, and unit tests. Closes #14686
1 parent 2653298 commit 6daf7ea

11 files changed

Lines changed: 65 additions & 3 deletions

File tree

src/controllers/controlpickermenu.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,10 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent)
292292
tr("3/4 BPM"),
293293
tr("Multiply current BPM by 0.75"),
294294
pBpmMenu);
295+
addDeckAndSamplerControl("beats_set_fourfifths",
296+
tr("4/5 BPM"),
297+
tr("Multiply current BPM by 0.8"),
298+
pBpmMenu);
295299
addDeckAndSamplerControl("beats_set_fivefourths",
296300
tr("5/4 BPM"),
297301
tr("Multiply current BPM by 1.25"),

src/engine/controls/bpmcontrol.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,16 @@ BpmControl::BpmControl(const QString& group,
154154
slotScaleBpm(mixxx::Beats::BpmScale::ThreeFourths);
155155
}
156156
});
157+
m_pBeatsFourFifths = std::make_unique<ControlPushButton>(
158+
ConfigKey(group, "beats_set_fourfifths"), false);
159+
connect(m_pBeatsFourFifths.get(),
160+
&ControlObject::valueChanged,
161+
this,
162+
[this](int value) {
163+
if (value > 0) {
164+
slotScaleBpm(mixxx::Beats::BpmScale::FourFifths);
165+
}
166+
});
157167
m_pBeatsFiveFourths = std::make_unique<ControlPushButton>(
158168
ConfigKey(group, "beats_set_fivefourths"), false);
159169
connect(m_pBeatsFiveFourths.get(),

src/engine/controls/bpmcontrol.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ class BpmControl : public EngineControl {
158158
std::unique_ptr<ControlPushButton> m_pBeatsHalve;
159159
std::unique_ptr<ControlPushButton> m_pBeatsTwoThirds;
160160
std::unique_ptr<ControlPushButton> m_pBeatsThreeFourths;
161+
std::unique_ptr<ControlPushButton> m_pBeatsFourFifths;
161162
std::unique_ptr<ControlPushButton> m_pBeatsFiveFourths;
162163
std::unique_ptr<ControlPushButton> m_pBeatsFourThirds;
163164
std::unique_ptr<ControlPushButton> m_pBeatsThreeHalves;

src/library/dlgtrackinfo.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@ void DlgTrackInfo::init() {
130130
connect(bpmThreeFourths, &QPushButton::clicked, this, [this] {
131131
slotBpmScale(mixxx::Beats::BpmScale::ThreeFourths);
132132
});
133+
connect(bpmFourFifths, &QPushButton::clicked, this, [this] { // NEW
134+
slotBpmScale(mixxx::Beats::BpmScale::FourFifths); // NEW
135+
});
133136
connect(bpmFiveFourths, &QPushButton::clicked, this, [this] {
134137
slotBpmScale(mixxx::Beats::BpmScale::FiveFourths);
135138
});

src/library/dlgtrackinfo.ui

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,22 @@ Often results in higher quality beatgrids, but will not do well on tracks that h
823823
</widget>
824824
</item>
825825
<item row="3" column="1">
826+
<widget class="QPushButton" name="bpmFourFifths">
827+
<property name="minimumSize">
828+
<size>
829+
<width>125</width>
830+
<height>0</height>
831+
</size>
832+
</property>
833+
<property name="toolTip">
834+
<string>Sets the BPM to 80% of the current value.</string>
835+
</property>
836+
<property name="text">
837+
<string>4/5 BPM</string>
838+
</property>
839+
</widget>
840+
</item>
841+
<item row="4" column="0">
826842
<widget class="QPushButton" name="bpmFiveFourths">
827843
<property name="minimumSize">
828844
<size>
@@ -838,7 +854,7 @@ Often results in higher quality beatgrids, but will not do well on tracks that h
838854
</property>
839855
</widget>
840856
</item>
841-
<item row="4" column="0">
857+
<item row="4" column="1">
842858
<widget class="QPushButton" name="bpmFourThirds">
843859
<property name="minimumSize">
844860
<size>
@@ -854,7 +870,7 @@ Often results in higher quality beatgrids, but will not do well on tracks that h
854870
</property>
855871
</widget>
856872
</item>
857-
<item row="4" column="1">
873+
<item row="5" column="0">
858874
<widget class="QPushButton" name="bpmThreeHalves">
859875
<property name="minimumSize">
860876
<size>
@@ -870,7 +886,7 @@ Often results in higher quality beatgrids, but will not do well on tracks that h
870886
</property>
871887
</widget>
872888
</item>
873-
<item row="5" column="0">
889+
<item row="5" column="1">
874890
<widget class="QPushButton" name="bpmDouble">
875891
<property name="minimumSize">
876892
<size>
@@ -1088,6 +1104,7 @@ Often results in higher quality beatgrids, but will not do well on tracks that h
10881104
<tabstop>bpmHalve</tabstop>
10891105
<tabstop>bpmTwoThirds</tabstop>
10901106
<tabstop>bpmThreeFourths</tabstop>
1107+
<tabstop>bpmFourFifths</tabstop>
10911108
<tabstop>bpmFiveFourths</tabstop>
10921109
<tabstop>bpmThreeHalves</tabstop>
10931110
<tabstop>bpmFourThirds</tabstop>

src/test/beatgridtest.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,14 @@ TEST(BeatGridTest, Scale) {
9797
pGrid->getBpmInRange(audio::kStartFramePos, trackEndPosition)
9898
.value());
9999

100+
pGrid = Beats::fromConstTempo(pTrack->getSampleRate(),
101+
mixxx::audio::kStartFramePos,
102+
mixxx::Bpm(bpm));
103+
pGrid = *pGrid->tryScale(Beats::BpmScale::FourFifths);
104+
EXPECT_DOUBLE_EQ(bpm.value() * 4 / 5,
105+
pGrid->getBpmInRange(audio::kStartFramePos, trackEndPosition)
106+
.value());
107+
100108
pGrid = Beats::fromConstTempo(pTrack->getSampleRate(),
101109
mixxx::audio::kStartFramePos,
102110
mixxx::Bpm(bpm));

src/test/beatmaptest.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ TEST_F(BeatMapTest, Scale) {
8181
pMap->getBpmInRange(audio::kStartFramePos, trackEndPosition)
8282
.value());
8383

84+
pMap = Beats::fromBeatPositions(m_pTrack->getSampleRate(), beats);
85+
pMap = *pMap->tryScale(Beats::BpmScale::FourFifths);
86+
EXPECT_DOUBLE_EQ(bpm.value() * 4 / 5,
87+
pMap->getBpmInRange(audio::kStartFramePos, trackEndPosition)
88+
.value());
89+
8490
pMap = Beats::fromBeatPositions(m_pTrack->getSampleRate(), beats);
8591
pMap = *pMap->tryScale(Beats::BpmScale::FiveFourths);
8692
EXPECT_DOUBLE_EQ(bpm.value() * 5 / 4,

src/track/beats.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,9 @@ std::optional<BeatsPointer> Beats::tryScale(BpmScale scale) const {
660660
case BpmScale::ThreeFourths:
661661
scaleFactor *= 3.0 / 4;
662662
break;
663+
case BpmScale::FourFifths:
664+
scaleFactor *= 4.0 / 5;
665+
break;
663666
case BpmScale::FiveFourths:
664667
scaleFactor *= 5.0 / 4;
665668
break;

src/track/beats.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ class Beats : private std::enable_shared_from_this<Beats> {
267267
Halve,
268268
TwoThirds,
269269
ThreeFourths,
270+
FourFifths,
270271
FiveFourths,
271272
FourThirds,
272273
ThreeHalves,

src/widget/wtrackmenu.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,8 @@ void WTrackMenu::createActions() {
495495
storeActionTextAndScaleInProperties(m_pBpmTwoThirdsAction, 2.0 / 3.0);
496496
m_pBpmThreeFourthsAction = make_parented<QAction>(tr("3/4 BPM"), m_pBPMMenu);
497497
storeActionTextAndScaleInProperties(m_pBpmThreeFourthsAction, 3.0 / 4.0);
498+
m_pBpmFourFifthsAction = make_parented<QAction>(tr("4/5 BPM"), m_pBPMMenu);
499+
storeActionTextAndScaleInProperties(m_pBpmFourFifthsAction, 4.0 / 5.0);
498500
m_pBpmFiveFourthsAction = make_parented<QAction>(tr("5/4 BPM"), m_pBPMMenu);
499501
storeActionTextAndScaleInProperties(m_pBpmFiveFourthsAction, 5.0 / 4.0);
500502
m_pBpmFourThirdsAction = make_parented<QAction>(tr("4/3 BPM"), m_pBPMMenu);
@@ -513,6 +515,9 @@ void WTrackMenu::createActions() {
513515
connect(m_pBpmThreeFourthsAction, &QAction::triggered, this, [this] {
514516
slotScaleBpm(mixxx::Beats::BpmScale::ThreeFourths);
515517
});
518+
connect(m_pBpmFourFifthsAction, &QAction::triggered, this, [this] {
519+
slotScaleBpm(mixxx::Beats::BpmScale::FourFifths);
520+
});
516521
connect(m_pBpmFiveFourthsAction, &QAction::triggered, this, [this] {
517522
slotScaleBpm(mixxx::Beats::BpmScale::FiveFourths);
518523
});
@@ -646,6 +651,7 @@ void WTrackMenu::setupActions() {
646651
m_pBPMMenu->addAction(m_pBpmHalveAction);
647652
m_pBPMMenu->addAction(m_pBpmTwoThirdsAction);
648653
m_pBPMMenu->addAction(m_pBpmThreeFourthsAction);
654+
m_pBPMMenu->addAction(m_pBpmFourFifthsAction);
649655
m_pBPMMenu->addAction(m_pBpmFiveFourthsAction);
650656
m_pBPMMenu->addAction(m_pBpmFourThirdsAction);
651657
m_pBPMMenu->addAction(m_pBpmThreeHalvesAction);
@@ -1137,6 +1143,7 @@ void WTrackMenu::updateMenus() {
11371143
m_pBpmHalveAction->setEnabled(!anyBpmLocked);
11381144
m_pBpmTwoThirdsAction->setEnabled(!anyBpmLocked);
11391145
m_pBpmThreeFourthsAction->setEnabled(!anyBpmLocked);
1146+
m_pBpmFourFifthsAction->setEnabled(!anyBpmLocked);
11401147
m_pBpmFiveFourthsAction->setEnabled(!anyBpmLocked);
11411148
m_pBpmFourThirdsAction->setEnabled(!anyBpmLocked);
11421149
m_pBpmThreeHalvesAction->setEnabled(!anyBpmLocked);
@@ -1157,6 +1164,7 @@ void WTrackMenu::updateMenus() {
11571164
appendBpmPreviewtoBpmAction(m_pBpmHalveAction, bpm);
11581165
appendBpmPreviewtoBpmAction(m_pBpmTwoThirdsAction, bpm);
11591166
appendBpmPreviewtoBpmAction(m_pBpmThreeFourthsAction, bpm);
1167+
appendBpmPreviewtoBpmAction(m_pBpmFourFifthsAction, bpm);
11601168
appendBpmPreviewtoBpmAction(m_pBpmFiveFourthsAction, bpm);
11611169
appendBpmPreviewtoBpmAction(m_pBpmFourThirdsAction, bpm);
11621170
appendBpmPreviewtoBpmAction(m_pBpmThreeHalvesAction, bpm);

0 commit comments

Comments
 (0)