Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/library/dlgtrackinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ void DlgTrackInfo::init() {
this, SLOT(slotBpmTwoThirds()));
connect(bpmThreeFourth, SIGNAL(clicked()),
this, SLOT(slotBpmThreeFourth()));
connect(bpmFourThirds, SIGNAL(clicked()),
this, SLOT(slotBpmFourThirds()));
connect(bpmThreeHalves, SIGNAL(clicked()),
this, SLOT(slotBpmThreeHalves()));
connect(bpmClear, SIGNAL(clicked()),
this, SLOT(slotBpmClear()));

Expand Down Expand Up @@ -503,6 +507,20 @@ void DlgTrackInfo::slotBpmThreeFourth() {
spinBpm->setValue(newValue);
}

void DlgTrackInfo::slotBpmFourThirds() {
m_pBeatsClone->scale(Beats::FOURTHIRDS);
// read back the actual value
double newValue = m_pBeatsClone->getBpm();
spinBpm->setValue(newValue);
}

void DlgTrackInfo::slotBpmThreeHalves() {
m_pBeatsClone->scale(Beats::THREEHALVES);
// read back the actual value
double newValue = m_pBeatsClone->getBpm();
spinBpm->setValue(newValue);
}

void DlgTrackInfo::slotBpmClear() {
spinBpm->setValue(0);
m_pBeatsClone.clear();
Expand Down
2 changes: 2 additions & 0 deletions src/library/dlgtrackinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class DlgTrackInfo : public QDialog, public Ui::DlgTrackInfo {
void slotBpmHalve();
void slotBpmTwoThirds();
void slotBpmThreeFourth();
void slotBpmFourThirds();
void slotBpmThreeHalves();
void slotBpmClear();
void slotBpmConstChanged(int state);
void slotBpmTap(double averageLength, int numSamples);
Expand Down
34 changes: 33 additions & 1 deletion src/library/dlgtrackinfo.ui
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,38 @@
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QPushButton" name="bpmThreeHalves">
<property name="minimumSize">
<size>
<width>125</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Sets the BPM to 150% of the current value.</string>
</property>
<property name="text">
<string>3/2 BPM</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QPushButton" name="bpmFourThirds">
<property name="minimumSize">
<size>
<width>125</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Sets the BPM to 133% of the current value.</string>
</property>
<property name="text">
<string>4/3 BPM</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="bpmClear">
<property name="text">
Expand All @@ -814,7 +846,7 @@
<property name="maximumSize">
<size>
<width>123</width>
<height>91</height>
<height>128</height>
</size>
</property>
<property name="toolTip">
Expand Down
8 changes: 7 additions & 1 deletion src/test/beatgridtest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,14 @@ TEST(BeatGridTest, Scale) {
pGrid->scale(Beats::TWOTHIRDS);
EXPECT_DOUBLE_EQ(bpm * 2 / 3, pGrid->getBpm());

pGrid->scale(Beats::THREEHALVES);
EXPECT_DOUBLE_EQ(bpm, pGrid->getBpm());

pGrid->scale(Beats::THREEFOURTHS);
EXPECT_DOUBLE_EQ(bpm / 2, pGrid->getBpm());
EXPECT_DOUBLE_EQ(bpm * 3 / 4, pGrid->getBpm());

pGrid->scale(Beats::FOURTHIRDS);
EXPECT_DOUBLE_EQ(bpm, pGrid->getBpm());
}

TEST(BeatGridTest, TestNthBeatWhenOnBeat) {
Expand Down
8 changes: 7 additions & 1 deletion src/test/beatmaptest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,14 @@ TEST_F(BeatMapTest, Scale) {
pMap->scale(Beats::TWOTHIRDS);
EXPECT_DOUBLE_EQ(bpm * 2 / 3, pMap->getBpm());

pMap->scale(Beats::THREEHALVES);
EXPECT_DOUBLE_EQ(bpm, pMap->getBpm());

pMap->scale(Beats::THREEFOURTHS);
EXPECT_DOUBLE_EQ(bpm / 2, pMap->getBpm());
EXPECT_DOUBLE_EQ(bpm * 3 / 4, pMap->getBpm());

pMap->scale(Beats::FOURTHIRDS);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So these two should be bpm * 2 / 3 and bpm. Please also update src/test/beatgridtest.cpp.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh you could also re-order three-halves to come after two-thirds so that each pair cancels out.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied these changes, but I'm not sure why it'll work.
Did the same in beatgridtest.cpp, but I didn't do a testbuild to check it

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oookay, think I got it! Just to bes sure:
TEST(BeatGridTest, Scale) is (like?) and function and called, therein all pGrid->scale(Beats::XXXX) are applied one after another, return values are checked in between.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea it's kind of confusing. Do you know how to run the tests locally?

Run scons with the test=1 flag. Then you should end up with a mixxx-test binary, so you can run ./mixxx-test to see if the tests pass. If you don't want to, then the pull request checks by AppVeyor and Travis will let us know if the tests pass anyway.

EXPECT_DOUBLE_EQ(bpm, pMap->getBpm());
}

TEST_F(BeatMapTest, TestNthBeat) {
Expand Down
6 changes: 6 additions & 0 deletions src/track/beatgrid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,12 @@ void BeatGrid::scale(enum BPMScale scale) {
case THREEFOURTHS:
bpm *= 3.0 / 4;
break;
case FOURTHIRDS:
bpm *= 4.0 / 3;
break;
case THREEHALVES:
bpm *= 3.0 / 2;
break;
default:
DEBUG_ASSERT(!"scale value invalid");
return;
Expand Down
31 changes: 28 additions & 3 deletions src/track/beatmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -552,9 +552,6 @@ void BeatMap::scale(enum BPMScale scale) {

switch (scale) {
case DOUBLE:
if (getBpm() * 2 > getMaxBpm()) {
return;
}
// introduce a new beat into every gap
scaleDouble();
break;
Expand All @@ -574,6 +571,18 @@ void BeatMap::scale(enum BPMScale scale) {
// remove every second third and forth beat
scaleFourth();
break;
case FOURTHIRDS:
// introduce three beats into every gap
scaleQuadruple();
// remove every second third and forth beat
scaleThird();
break;
case THREEHALVES:
// introduce two beats into every gap
scaleTriple();
// remove every second beat
scaleHalve();
break;
default:
DEBUG_ASSERT(!"scale value invalid");
return;
Expand Down Expand Up @@ -614,6 +623,22 @@ void BeatMap::scaleTriple() {
}
}

void BeatMap::scaleQuadruple() {
Beat prevBeat = m_beats.first();
// Skip the first beat to preserve the first beat in a measure
BeatList::iterator it = m_beats.begin() + 1;
for (; it != m_beats.end(); ++it) {
// Need to not accrue fractional frames.
int distance = it->frame_position() - prevBeat.frame_position();
Beat beat;
for (int i = 1; i <= 3; i++) {
beat.set_frame_position(prevBeat.frame_position() + distance * i / 4);
it = m_beats.insert(it, beat);
}
prevBeat = (++it)[0];
}
}

void BeatMap::scaleHalve() {
// Skip the first beat to preserve the first beat in a measure
BeatList::iterator it = m_beats.begin() + 1;
Expand Down
1 change: 1 addition & 0 deletions src/track/beatmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class BeatMap : public QObject, public Beats {

void scaleDouble();
void scaleTriple();
void scaleQuadruple();
void scaleHalve();
void scaleThird();
void scaleFourth();
Expand Down
2 changes: 2 additions & 0 deletions src/track/beats.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ class Beats {
HALVE,
TWOTHIRDS,
THREEFOURTHS,
FOURTHIRDS,
THREEHALVES,
};

virtual Beats::CapabilitiesFlags getCapabilities() const = 0;
Expand Down
22 changes: 22 additions & 0 deletions src/widget/wtracktableview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ WTrackTableView::~WTrackTableView() {
delete m_pBpmHalveAction;
delete m_pBpmTwoThirdsAction;
delete m_pBpmThreeFourthsAction;
delete m_pBpmFourThirdsAction;
delete m_pBpmThreeHalvesAction;
delete m_pBPMMenu;
delete m_pReplayGainResetAction;
delete m_pPurgeAct;
Expand Down Expand Up @@ -419,11 +421,15 @@ void WTrackTableView::createActions() {
m_pBpmHalveAction = new QAction(tr("Halve BPM"), this);
m_pBpmTwoThirdsAction = new QAction(tr("2/3 BPM"), this);
m_pBpmThreeFourthsAction = new QAction(tr("3/4 BPM"), this);
m_pBpmFourThirdsAction = new QAction(tr("4/3 BPM"), this);
m_pBpmThreeHalvesAction = new QAction(tr("3/2 BPM"), this);

m_BpmMapper.setMapping(m_pBpmDoubleAction, Beats::DOUBLE);
m_BpmMapper.setMapping(m_pBpmHalveAction, Beats::HALVE);
m_BpmMapper.setMapping(m_pBpmTwoThirdsAction, Beats::TWOTHIRDS);
m_BpmMapper.setMapping(m_pBpmThreeFourthsAction, Beats::THREEFOURTHS);
m_BpmMapper.setMapping(m_pBpmFourThirdsAction, Beats::FOURTHIRDS);
m_BpmMapper.setMapping(m_pBpmThreeHalvesAction, Beats::THREEHALVES);

connect(m_pBpmDoubleAction, SIGNAL(triggered()),
&m_BpmMapper, SLOT(map()));
Expand All @@ -433,6 +439,10 @@ void WTrackTableView::createActions() {
&m_BpmMapper, SLOT(map()));
connect(m_pBpmThreeFourthsAction, SIGNAL(triggered()),
&m_BpmMapper, SLOT(map()));
connect(m_pBpmFourThirdsAction, SIGNAL(triggered()),
&m_BpmMapper, SLOT(map()));
connect(m_pBpmThreeHalvesAction, SIGNAL(triggered()),
&m_BpmMapper, SLOT(map()));

m_pClearBeatsAction = new QAction(tr("Clear BPM and Beatgrid"), this);
connect(m_pClearBeatsAction, SIGNAL(triggered()),
Expand Down Expand Up @@ -837,6 +847,8 @@ void WTrackTableView::contextMenuEvent(QContextMenuEvent* event) {
m_pBPMMenu->addAction(m_pBpmHalveAction);
m_pBPMMenu->addAction(m_pBpmTwoThirdsAction);
m_pBPMMenu->addAction(m_pBpmThreeFourthsAction);
m_pBPMMenu->addAction(m_pBpmFourThirdsAction);
m_pBPMMenu->addAction(m_pBpmThreeHalvesAction);
m_pBPMMenu->addSeparator();
m_pBPMMenu->addAction(m_pBpmLockAction);
m_pBPMMenu->addAction(m_pBpmUnlockAction);
Expand All @@ -854,13 +866,17 @@ void WTrackTableView::contextMenuEvent(QContextMenuEvent* event) {
m_pBpmHalveAction->setEnabled(false);
m_pBpmTwoThirdsAction->setEnabled(false);
m_pBpmThreeFourthsAction->setEnabled(false);
m_pBpmFourThirdsAction->setEnabled(false);
m_pBpmThreeHalvesAction->setEnabled(false);
} else { //BPM is not locked
m_pBpmUnlockAction->setEnabled(false);
m_pBpmLockAction->setEnabled(true);
m_pBpmDoubleAction->setEnabled(true);
m_pBpmHalveAction->setEnabled(true);
m_pBpmTwoThirdsAction->setEnabled(true);
m_pBpmThreeFourthsAction->setEnabled(true);
m_pBpmFourThirdsAction->setEnabled(true);
m_pBpmThreeHalvesAction->setEnabled(true);
}
} else {
bool anyLocked = false; //true if any of the selected items are locked
Expand All @@ -878,12 +894,18 @@ void WTrackTableView::contextMenuEvent(QContextMenuEvent* event) {
m_pBpmDoubleAction->setEnabled(false);
m_pBpmHalveAction->setEnabled(false);
m_pBpmTwoThirdsAction->setEnabled(false);
m_pBpmThreeFourthsAction->setEnabled(false);
m_pBpmFourThirdsAction->setEnabled(false);
m_pBpmThreeHalvesAction->setEnabled(false);
} else {
m_pBpmLockAction->setEnabled(true);
m_pBpmUnlockAction->setEnabled(false);
m_pBpmDoubleAction->setEnabled(true);
m_pBpmHalveAction->setEnabled(true);
m_pBpmTwoThirdsAction->setEnabled(true);
m_pBpmThreeFourthsAction->setEnabled(true);
m_pBpmFourThirdsAction->setEnabled(true);
m_pBpmThreeHalvesAction->setEnabled(true);
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/widget/wtracktableview.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ class WTrackTableView : public WLibraryTableView {
QAction *m_pBpmHalveAction;
QAction *m_pBpmTwoThirdsAction;
QAction *m_pBpmThreeFourthsAction;
QAction *m_pBpmFourThirdsAction;
QAction *m_pBpmThreeHalvesAction;

// Clear track beats
QAction* m_pClearBeatsAction;
Expand Down