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

Changing tempos support #2930

Draft
wants to merge 29 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
4236315
Changing tempos support
crisclacerda Jul 10, 2020
21adb5b
better styling
crisclacerda Jul 11, 2020
4b60566
better comments and names
crisclacerda Jul 17, 2020
8cd56e6
Remove Small Arrhythmic regions of tracks that have const tempo
crisclacerda Jul 29, 2020
22119d1
ironing code improvements
crisclacerda Aug 25, 2020
50e4afc
no spikes on ironing...
crisclacerda Aug 26, 2020
47a2298
fix iron code bug, better names and coments
crisclacerda Aug 27, 2020
9928587
more names and comments improvements
crisclacerda Aug 27, 2020
b7b0b31
add wraper to silince qt range constructor warning
crisclacerda Aug 27, 2020
2cc53e5
implemented Daniel's red ironing algorithm
crisclacerda Aug 28, 2020
35236ac
start investigating the dip problem near tempo changes
crisclacerda Aug 28, 2020
289ac87
add preferences and subversioning for new features
crisclacerda Aug 28, 2020
74a95a7
failed to add beatfactory.h on previous commit
crisclacerda Aug 28, 2020
fb2b6ba
Merge branch 'master' of https://github.com/mixxxdj/mixxx into transi…
crisclacerda Aug 29, 2020
f712f66
decouple statistics classes from beats, use circular buffer, other st…
crisclacerda Aug 29, 2020
4c1ed3c
change build files
crisclacerda Aug 29, 2020
43f19a0
fix CMakeList.txt
crisclacerda Aug 29, 2020
879603f
fix formating issues with git-clang-format
crisclacerda Aug 29, 2020
9031aff
add analyzer debug mode
crisclacerda Aug 29, 2020
74cfc23
move debugBeats to beatFactory, structure output, add help info and t…
crisclacerda Aug 29, 2020
e144e92
should fix fast msvc build
crisclacerda Aug 29, 2020
e838292
fix dip add extra condition for remove arrythmic
crisclacerda Aug 30, 2020
266eade
style fixes on statistics files
crisclacerda Aug 30, 2020
da6d275
Apply suggestions from code review
crisclacerda Aug 30, 2020
7f4f0df
switch to const refs when possible, added \n before eof, use Sample r…
crisclacerda Aug 31, 2020
9dfb9a0
Apply suggestions from code review
crisclacerda Sep 4, 2020
ea016e0
use the beat lenght instead of bpm for processing
crisclacerda Sep 6, 2020
583cbaa
failed to add windowedstatistics.h on previous commit
crisclacerda Sep 6, 2020
1aa3fbc
add todo to remove new preferences before 2.4
crisclacerda Sep 6, 2020
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
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,7 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL
src/track/beatmap.cpp
src/track/beats.cpp
src/track/beatutils.cpp
src/track/beatstats.cpp
src/track/bpm.cpp
src/track/cue.cpp
src/track/cueinfo.cpp
Expand Down
1 change: 1 addition & 0 deletions build/depends.py
Original file line number Diff line number Diff line change
Expand Up @@ -1221,6 +1221,7 @@ def sources(self, build):
"src/track/beatgrid.cpp",
"src/track/beatmap.cpp",
"src/track/beatutils.cpp",
"src/track/beatstats.cpp",
"src/track/beats.cpp",
"src/track/bpm.cpp",
"src/track/cue.cpp",
Expand Down
3 changes: 2 additions & 1 deletion src/track/beatfactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ mixxx::BeatsPointer BeatFactory::makePreferredBeats(const Track& track,
pGrid->setSubVersion(subVersion);
return mixxx::BeatsPointer(pGrid, &BeatFactory::deleteBeats);
} else if (version == BEAT_MAP_VERSION) {
mixxx::BeatMap* pBeatMap = new mixxx::BeatMap(track, iSampleRate, beats);
auto fixedBeats = BeatUtils::FixBeatmap(beats, iSampleRate, iMinBpm, iMaxBpm);
mixxx::BeatMap* pBeatMap = new mixxx::BeatMap(track, iSampleRate, fixedBeats);
pBeatMap->setSubVersion(subVersion);
return mixxx::BeatsPointer(pBeatMap, &BeatFactory::deleteBeats);
Copy link
Member

Choose a reason for hiding this comment

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

Legacy issue:

I think we should immediately hand over the raw pointer after construction to clarify the ownership.
subVersion can also be set during the constructor.

return mixxx::BeatsPointer(
        new mixxx::BeatMap(track, iSampleRate, fixedBeats, subVersion),
        &BeatFactory::deleteBeats);

The same above.

Copy link
Author

Choose a reason for hiding this comment

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

No constructor of beatmap receives subversion as parameter, since we are getting rid of that anyways I think it's not worth the trouble, right?

} else {
crisclacerda marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
38 changes: 38 additions & 0 deletions src/track/beatstats.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <QList>
crisclacerda marked this conversation as resolved.
Show resolved Hide resolved
#include <QMap>

#include <algorithm>
#include <cmath>

#include "track/beatstats.h"
#include "util/fpclassify.h"

void MovingMedian::update(double newValue, double oldValue) {
auto insertPosition = std::lower_bound(m_sortedValues.begin(), m_sortedValues.end(), newValue);
m_sortedValues.insert(insertPosition, newValue);
if (!util_isnan(oldValue)) {
m_sortedValues.removeAt(m_sortedValues.indexOf(oldValue));
}
}

double MovingMedian::compute() {
return BeatStatistics::median(m_sortedValues);
}

double BeatStatistics::median(QList<double> sortedItems) {
if (sortedItems.empty()) {
return 0.0;
}
// When there are an even number of elements, the sample median is the mean
// of the middle 2 elements.
if (sortedItems.size() % 2 == 0) {
int item_position = sortedItems.size() / 2;
double item_value1 = sortedItems.at(item_position - 1);
double item_value2 = sortedItems.at(item_position);
return (item_value1 + item_value2) / 2.0;
}
// When there are an odd number of elements, find the {(n+1)/2}th item in
// the sorted list.
int item_position = (sortedItems.size() + 1) / 2;
return sortedItems.at(item_position - 1);
}
61 changes: 61 additions & 0 deletions src/track/beatstats.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#pragma once

#include <QQueue>
#include "util/assert.h"

/// These classes are used to compute statistics descriptors
/// of a series of tempo values and are called from beatutils

class WindowedStatistics {

public:

WindowedStatistics(int period) {
DEBUG_ASSERT(period > 0);
m_period = period;
}
virtual ~WindowedStatistics() = default;

double operator()(double newValue) {
crisclacerda marked this conversation as resolved.
Show resolved Hide resolved
double oldValue = updateWindow(newValue);
update(newValue, oldValue);
return compute();
}
double operator()(void) {
crisclacerda marked this conversation as resolved.
Show resolved Hide resolved
return compute();
}
int lag() {
// expected latency
return (m_window.size() - 1)/2;
}

private:

double updateWindow(double newValue) {
m_window.enqueue(newValue);
crisclacerda marked this conversation as resolved.
Show resolved Hide resolved
if (m_window.count() > m_period) {
return m_window.dequeue();
} else {
return std::nan("");
}
}
virtual double compute() = 0;
virtual void update(double newValue, double oldValue) = 0;
QQueue<double> m_window;
crisclacerda marked this conversation as resolved.
Show resolved Hide resolved
int m_period;
};

class BeatStatistics {
Holzhaus marked this conversation as resolved.
Show resolved Hide resolved
public:
static double median(QList<double> sortedItems);
crisclacerda marked this conversation as resolved.
Show resolved Hide resolved
};

class MovingMedian : public WindowedStatistics {
QList<double> m_sortedValues;
void update(double, double) override;
double compute() override;
public:
MovingMedian(int period)
: WindowedStatistics(period) {};
~MovingMedian() = default;
};
Loading