Skip to content

Add BPM conversions 4/3 and 3/2#1106

Merged
rryan merged 9 commits intomixxxdj:masterfrom
ronso0:additional-BPM-conversions
Jan 5, 2017
Merged

Add BPM conversions 4/3 and 3/2#1106
rryan merged 9 commits intomixxxdj:masterfrom
ronso0:additional-BPM-conversions

Conversation

@ronso0
Copy link
Copy Markdown
Member

@ronso0 ronso0 commented Jan 3, 2017

Fixing my wishlist bug https://bugs.launchpad.net/mixxx/+bug/1462350
Adding two conversions that one might guess when detected BPM is far from the user estimated BPM. Basically these are the two I came across when beat analysis was wrong on some Drumfunk/Breakbeat tracks. There could be numerous more, but as @daschuer points out: it's hard to know that one needs a 7/8 conversion. So these are sufficient, I suppose.

Comment thread src/track/beatmap.cpp Outdated
break;
case FOURTHIRDS:
// introduce two beats into every gap
scaleDouble();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Maybe you can implement scaleQuadruple() and use it here instead of two calls to scaleDouble().

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.

of course, didn't look it up

Copy link
Copy Markdown
Member

@rryan rryan Jan 4, 2017

Choose a reason for hiding this comment

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

Personally I think two scaleDoubles are fine here (less code is usually better and this isn't performance critical so two passes are ok).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah -- then two scaleDoubles it is. Sorry for misguidance.

@rryan
Copy link
Copy Markdown
Member

rryan commented Jan 3, 2017

Looks like the BeatMap tests aren't passing:

[ RUN ] BeatMapTest.Scale
src/test/beatmaptest.cpp:67: Failure
Value of: pMap->getBpm()
  Actual: 40
Expected: bpm * 4 / 3
Which is: 80
src/test/beatmaptest.cpp:70: Failure
Value of: pMap->getBpm()
  Actual: 60
Expected: bpm * 3 / 2
Which is: 90

@ronso0
Copy link
Copy Markdown
Member Author

ronso0 commented Jan 4, 2017

Thank you for testing. I didn't because in mixxx both numerical and visual results are as expected.
Must admit I don't understand all of the test code:

pMap->scale(Beats::DOUBLE);
EXPECT_DOUBLE_EQ(2 * bpm, pMap->getBpm());

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

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

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

DOUBLE and TWOTHIRDS make sense, but I don't see how HALVE can succeed. And why FOURTHIRDS expects 80 from original 40...
Please give me a hint.

@ninomp
Copy link
Copy Markdown
Contributor

ninomp commented Jan 4, 2017

It seems that you forgot to write (implement) method scaleQuadruple(). It can be placed here: https://github.com/ronso0/mixxx/blob/a9284a80a4dfbde8ebaf723da5ce68aa365e247b/src/track/beatmap.cpp#L634

@ninomp
Copy link
Copy Markdown
Contributor

ninomp commented Jan 4, 2017

Furthermore, concerning unit tests and limiting of BPM, I'm really not sure why is it like that. Sorry, you will have to wait for a more experienced Mixxx developer/contributor.

@rryan
Copy link
Copy Markdown
Member

rryan commented Jan 4, 2017

DOUBLE and TWOTHIRDS make sense, but I don't see how HALVE can succeed. And why FOURTHIRDS expects 80 from original 40...
Please give me a hint.

Wow, what the heck? I'll fix this.

@rryan
Copy link
Copy Markdown
Member

rryan commented Jan 4, 2017

DOUBLE and TWOTHIRDS make sense, but I don't see how HALVE can succeed. And why FOURTHIRDS expects 80 from original 40...
Please give me a hint.
Wow, what the heck? I'll fix this.

Oh, nevermind -- these are all continuous changes to the beatgrid. So the halve succeeds since the double scaled the original BPM x2 then halving takes it back to the original bpm.

Comment thread src/test/beatmaptest.cpp
pMap->scale(Beats::THREEFOURTHS);
EXPECT_DOUBLE_EQ(bpm / 2, 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.

Comment thread src/track/beatmap.cpp Outdated
scaleFourth();
break;
case FOURTHIRDS:
if (getBpm() * 4 / 3 > getMaxBpm()) {
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.

I think you can drop these checks (and the check on double)... I'm not sure why we have a max BPM setting for anything other than determining when the BPM detector has gone awry.

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.

Done.

Comment thread src/test/beatgridtest.cpp Outdated
EXPECT_DOUBLE_EQ(bpm * 2 / 3, pGrid->getBpm());

pGrid->scale(Beats::THREEHALVES);
EXPECT_DOUBLE_EQ(bpm * 3 / 2, pGrid->getBpm());
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.

This should be
EXPECT_DOUBLE_EQ(bpm, pGrid->getBpm());
since scaling 3/2 after a 2/3 scale should cancel out

Comment thread src/test/beatgridtest.cpp Outdated
EXPECT_DOUBLE_EQ(bpm * 3 / 2, pGrid->getBpm());

pGrid->scale(Beats::THREEFOURTHS);
EXPECT_DOUBLE_EQ(bpm / 2, pGrid->getBpm());
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.

This should be
EXPECT_DOUBLE_EQ(bpm * 3 / 4, pGrid->getBpm());

Comment thread src/test/beatmaptest.cpp Outdated
EXPECT_DOUBLE_EQ(bpm * 2 / 3, pMap->getBpm());

pMap->scale(Beats::THREEHALVES);
EXPECT_DOUBLE_EQ(bpm * 3 / 2, pMap->getBpm());
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.

this should be just "bpm"

Comment thread src/test/beatmaptest.cpp Outdated
EXPECT_DOUBLE_EQ(bpm * 3 / 2, pMap->getBpm());

pMap->scale(Beats::THREEFOURTHS);
EXPECT_DOUBLE_EQ(bpm / 2, pMap->getBpm());
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.

this should be bpm * 3 / 4

Comment thread src/test/beatmaptest.cpp Outdated
EXPECT_DOUBLE_EQ(bpm / 2, pMap->getBpm());

pMap->scale(Beats::FOURTHIRDS);
EXPECT_DOUBLE_EQ(bpm * 4 / 3, pMap->getBpm());
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.

this should be "bpm" now

Copy link
Copy Markdown
Member

@rryan rryan left a comment

Choose a reason for hiding this comment

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

Nice, looks good. Now we can wait on Travis to make sure the tests pass there.

@rryan
Copy link
Copy Markdown
Member

rryan commented Jan 5, 2017

Hm, doh - looks like you need to define scaleQuadruple in src/track/beatmap.h around line 103.

[CXX] src\track\beatmap.cpp
beatmap.cpp
src\track\beatmap.cpp(576) : error C3861: 'scaleQuadruple': identifier not found
src\track\beatmap.cpp(626) : error C2039: 'scaleQuadruple' : is not a member of 'BeatMap'
        C:\projects\mixxx\src\track/beatmap.h(22) : see declaration of 'BeatMap'
src\track\beatmap.cpp(627) : error C2065: 'm_beats' : undeclared identifier
src\track\beatmap.cpp(627) : error C2228: left of '.first' must have class/struct/union
        type is 'unknown-type'
src\track\beatmap.cpp(629) : error C2065: 'm_beats' : undeclared identifier
src\track\beatmap.cpp(629) : error C2228: left of '.begin' must have class/struct/union
        type is 'unknown-type'
src\track\beatmap.cpp(630) : error C2065: 'm_beats' : undeclared identifier
src\track\beatmap.cpp(630) : error C2228: left of '.end' must have class/struct/union
        type is 'unknown-type'
src\track\beatmap.cpp(634) : error C2065: 'i' : undeclared identifier
src\track\beatmap.cpp(634) : error C2143: syntax error : missing ';' before ')'
src\track\beatmap.cpp(635) : error C2065: 'i' : undeclared identifier
src\track\beatmap.cpp(636) : error C2065: 'm_beats' : undeclared identifier
src\track\beatmap.cpp(636) : error C2228: left of '.insert' must have class/struct/union
        type is 'unknown-type'
scons: *** [win32_build\track\beatmap.obj] Error 2
scons: building terminated because of errors.

@timrae
Copy link
Copy Markdown
Contributor

timrae commented Jan 5, 2017

I didn't even know this feature existed... Why not expose some or all of the buttons in the main GUI?

@ronso0
Copy link
Copy Markdown
Member Author

ronso0 commented Jan 5, 2017

@rryan Oh it was late, should have noticed myself. Fixed in a minute.
Did anyone ever mention this conversation & comment interface on github is ...well...not intuitive? Some comments I only came across by mail notification..
@timrae All BPM conversions are available in Track Properties and as mouse context menu in Library, what do you mean? Should they apppear with the beatgrid buttons close to the waveforms?

@timrae
Copy link
Copy Markdown
Contributor

timrae commented Jan 5, 2017

what do you mean?

Oh right, I didn't realize they were available from the mouse context menu as well. I meant in the currently playing deck... For example in Deere, when you click the current bpm number, it expands to give you a bunch of bpm related options. It makes sense to put them there... I'm pretty sure Traktor had this when I used it years ago.

@ronso0
Copy link
Copy Markdown
Member Author

ronso0 commented Jan 5, 2017

Would be useful. But I don't know how to create a CO from the above code.
Either they appear there or deck has a button that would focus deck's track in library. (like discussed over there: https://bugs.launchpad.net/mixxx/+bug/1403715)

Comment thread src/track/beatmap.cpp Outdated
int distance = it->frame_position() - prevBeat.frame_position();
Beat beat;
for (i=1; i<=3, i++;) {
for (int i=1; i<=3, i++;) {
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.

oops, should be:

for (int i = 1; i <= 3; i++) {

Copy link
Copy Markdown
Member Author

@ronso0 ronso0 Jan 5, 2017

Choose a reason for hiding this comment

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

yes, already fixed it after travis failed for the 3rd time ;)
The semicolon should be there at the end, shouldn't it? Ok, not in C++
fixing once more

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.

Previous conversions appear in the manual (p43). Necessary to update this after merge?

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.

Good point -- it would be great if you submit a PR to update the manual too!
https://github.com/mixxxdj/manual

@ronso0
Copy link
Copy Markdown
Member Author

ronso0 commented Jan 5, 2017

Hope it's ready now

Comment thread src/track/beatmap.cpp Outdated
// Need to not accrue fractional frames.
int distance = it->frame_position() - prevBeat.frame_position();
Beat beat;
for (int i=1; i<=3, i++) {
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.

Not quite :). If you replace this line with exactly what I write it will work:

for (int i = 1; i <= 3; i++) {

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.

Damn..spaces!
Okay, once more. Appreciate your patience!

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.

The spaces are optional, but the initialization, the comparison, and the increment need to be separated with semicolons (not commas). Looks good now!

@rryan
Copy link
Copy Markdown
Member

rryan commented Jan 5, 2017

Looks like the tests are hanging -- I'll go ahead and merge then fix in master. Thanks @ronso0 !

@rryan rryan merged commit 65b82cf into mixxxdj:master Jan 5, 2017
@ronso0 ronso0 deleted the additional-BPM-conversions branch January 5, 2017 23:31
@ronso0
Copy link
Copy Markdown
Member Author

ronso0 commented Jan 6, 2017

Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants