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

[POC] Down beat range #3036

Draft
wants to merge 56 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
36ada6f
add rhythm analyzer
crisclacerda Jun 16, 2020
5013059
rhythm detector preferences
crisclacerda Jun 17, 2020
2487e6d
rhythm detector output downbeats to beapmap
crisclacerda Jun 17, 2020
8ee1fe4
rhythm analyzer fix downbeat positions
crisclacerda Jun 17, 2020
a54340c
rhythm analyzer add cleanups
crisclacerda Jun 18, 2020
4469fb7
rhythm analyzer style fixes
crisclacerda Jun 18, 2020
485cca9
rhythm analyzer add tempo detection
crisclacerda Jun 20, 2020
1ab8f62
qm-dsp - allow for multi feature beat detection.
crisclacerda Jun 23, 2020
9ff3f9f
rhythm analyzer - dirty hack to keep mix building.
crisclacerda Jun 23, 2020
d643861
rhythm analyzer - implement multi feature beat detection
crisclacerda Jun 23, 2020
5ba7497
rhythm analyzer - use std::vector constructors rather the newer QT ra…
crisclacerda Jun 23, 2020
1fa23ab
rhythm analyzer - add new files to CMakeLists
crisclacerda Jun 23, 2020
ce94ecb
rhythm analyzer - don't re-analyze with there are beats
crisclacerda Jun 26, 2020
6b54980
rhythm analyzer - do not use even vector size for computing median tempo
crisclacerda Jun 26, 2020
07e4d79
rhythm analyzer - improved agreement calculation
crisclacerda Jun 26, 2020
1fcf369
rhythm analyzer - improved fixedBeatsPositions and bpm calculation
crisclacerda Jun 30, 2020
9cb681d
rhythm analyzer - remove old comment
crisclacerda Jun 30, 2020
13ac5f8
Merge branch 'rhythm-detector' of https://github.com/crisclacerda/mix…
daschuer Jun 30, 2020
3be8916
rhythm analyzer - removed m_stepSize and m_windowSize
crisclacerda Jul 1, 2020
abc6002
rhythm analyzer - revert changes in qm-dsp/downbeat
crisclacerda Jul 2, 2020
cc876a1
SnapGrid proof of concept
daschuer Jul 5, 2020
56d8320
print fftbins
daschuer Jul 6, 2020
e364a87
Merge branch 'master' of https://github.com/mixxxdj/mixxx into rhythm…
crisclacerda Jul 7, 2020
0b772db
Merge branch 'master' of https://github.com/mixxxdj/mixxx into rhythm…
crisclacerda Jul 13, 2020
e56fdb0
Merge branch 'master' of https://github.com/mixxxdj/mixxx into rhythm…
crisclacerda Jul 15, 2020
3763e8f
decouple downbeat from onset processing
crisclacerda Jul 15, 2020
31c7773
experimenting with constQ for onset
crisclacerda Jul 16, 2020
4924dc1
Merge branch 'rhythm-detector' of https://github.com/crisclacerda/mix…
daschuer Jul 17, 2020
eef60d0
Bars per Minute. Experiments on tracking the tempo of measures,
crisclacerda Aug 4, 2020
95d13e1
rhythm analyzer - add and start using qm-tempogram code
crisclacerda Aug 5, 2020
c41f865
rhythm analyzer - small fixes to build tempogram
crisclacerda Aug 5, 2020
ee2c071
rhythm analyzer - convert dft tempogram y axis to bpm
crisclacerda Aug 6, 2020
d631bfd
rhythm analyzer - add ACF tempogram
crisclacerda Aug 7, 2020
bc0fe48
Merge remote-tracking branch 'upstream/master' into snapgrid
daschuer Aug 7, 2020
a2d0e32
rhythm analyzer - refactor tempogram computation into isolated methods
crisclacerda Aug 7, 2020
2fba341
analyzer rhythm - add tempogram constants and fallback to default par…
crisclacerda Aug 7, 2020
a3ae5c0
Use a magice curve to be more sesitive in the Boom region
daschuer Aug 8, 2020
8bcba01
Improve Onset detection
daschuer Aug 11, 2020
e031a63
rhythm analyzer - fix novelty curve and use it as input of qm beat tr…
crisclacerda Aug 11, 2020
a88ed6f
Merge branch 'rhythm-detector' into snapgrid
crisclacerda Aug 11, 2020
c56bf12
use snapgrid to make new novelty curve
crisclacerda Aug 11, 2020
c5c53dc
add metergram
crisclacerda Aug 12, 2020
a4d6c9e
add new meter detection
crisclacerda Aug 14, 2020
5815978
Fix Novelty curve generation
daschuer Aug 14, 2020
b27f741
Merge branch 'master' of https://github.com/mixxxdj/mixxx into rhythm…
crisclacerda Aug 17, 2020
0b7dfe4
rhythm analyzer - meter detection improvements
crisclacerda Aug 18, 2020
08a60c7
Merge branch 'rhythm-detector' of https://github.com/crisclacerda/mix…
daschuer Aug 18, 2020
4ce148c
A POC commit, that uses a autocorelation of the ComplexSD and tries t…
daschuer Aug 21, 2020
3b6f947
Still not working ..
daschuer Aug 23, 2020
e97d28f
Added a diffrent approch to add a downbeats. "A DownBeat is in the mi…
daschuer Aug 24, 2020
af72c0d
adjust debug
daschuer Aug 27, 2020
07ae68f
Assuem measures form AC period
daschuer Aug 27, 2020
ea6402a
Output measure by phase probability
daschuer Aug 30, 2020
8efe13a
Fill gaps in snap gid
daschuer Sep 8, 2020
09e41d8
Moved complexSdMinDiff calculations
daschuer Sep 16, 2020
e74d862
Center ACF generation around a single sample. Improve the snapgrid by…
daschuer Sep 16, 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
10 changes: 10 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,9 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL
src/analyzer/analyzersilence.cpp
src/analyzer/analyzerthread.cpp
src/analyzer/analyzerwaveform.cpp
src/analyzer/analyzerrhythm.cpp
src/analyzer/analyzerrhythmstats.cpp
src/analyzer/analyzerrhythmbpm.cpp
src/analyzer/plugins/analyzerqueenmarybeats.cpp
src/analyzer/plugins/analyzerqueenmarykey.cpp
src/analyzer/plugins/analyzersoundtouchbeats.cpp
Expand Down Expand Up @@ -644,6 +647,8 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL
src/preferences/dialog/dlgprefautodjdlg.ui
src/preferences/dialog/dlgprefbeats.cpp
src/preferences/dialog/dlgprefbeatsdlg.ui
src/preferences/dialog/dlgprefrhythm.cpp
src/preferences/dialog/dlgprefrhythm.ui
src/preferences/dialog/dlgprefcolors.cpp
src/preferences/dialog/dlgprefcolorsdlg.ui
src/preferences/dialog/dlgprefcrossfader.cpp
Expand Down Expand Up @@ -1826,6 +1831,11 @@ add_library(QueenMaryDsp STATIC EXCLUDE_FROM_ALL
lib/qm-dsp/maths/KLDivergence.cpp lib/qm-dsp/maths/MathUtilities.cpp
# lib/qm-dsp/maths/pca/pca.c
# lib/qm-dsp/thread/Thread.cpp
lib/qm-dsp/dsp/tempogram/FIRFilter.cpp
lib/qm-dsp/dsp/tempogram/WindowFunction.cpp
lib/qm-dsp/dsp/tempogram/NoveltyCurveProcessor.cpp
lib/qm-dsp/dsp/tempogram/SpectrogramProcessor.cpp
lib/qm-dsp/dsp/tempogram/AutocorrelationProcessor.cpp
)
target_compile_definitions(QueenMaryDsp PRIVATE kiss_fft_scalar=double)
if(UNIX)
Expand Down
5 changes: 5 additions & 0 deletions build/depends.py
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,7 @@ def sources(self, build):
"src/preferences/dialog/dlgprefsounditem.cpp",
"src/preferences/dialog/dlgprefwaveform.cpp",
"src/preferences/dialog/dlgprefbeats.cpp",
"src/preferences/dialog/dlgprefrhythm.cpp",
"src/preferences/dialog/dlgprefkey.cpp",
"src/preferences/settingsmanager.cpp",
"src/preferences/replaygainsettings.cpp",
Expand Down Expand Up @@ -895,6 +896,9 @@ def sources(self, build):
"src/analyzer/analyzerkey.cpp",
"src/analyzer/analyzerebur128.cpp",
"src/analyzer/analyzersilence.cpp",
"src/analyzer/analyzerrhythm.cpp",
"src/analyzer/analyzerrhythmstats.cpp",
"src/analyzer/analyzerrhythmbpm.cpp",
"src/analyzer/plugins/analyzersoundtouchbeats.cpp",
"src/analyzer/plugins/analyzerqueenmarybeats.cpp",
"src/analyzer/plugins/analyzerqueenmarykey.cpp",
Expand Down Expand Up @@ -1394,6 +1398,7 @@ def sources(self, build):
'src/preferences/dialog/dlgprefsounditem.ui',
'src/preferences/dialog/dlgprefvinyldlg.ui',
'src/preferences/dialog/dlgprefwaveformdlg.ui',
'src/preferences/dialog/dlgprefrhythm.ui',
]

# In Python 3.x, map() returns a "map object" (instead of a list),
Expand Down
87 changes: 55 additions & 32 deletions lib/qm-dsp/dsp/onsets/DetectionFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ void DetectionFunction::deInitialise()
delete m_window;
}

double DetectionFunction::processTimeDomain(const double *samples)
DFresults DetectionFunction::processTimeDomain(const double *samples)
{
m_window->cut(samples, m_windowed);

Expand All @@ -103,7 +103,7 @@ double DetectionFunction::processTimeDomain(const double *samples)
return runDF();
}

double DetectionFunction::processFrequencyDomain(const double *reals,
DFresults DetectionFunction::processFrequencyDomain(const double *reals,
const double *imags)
{
m_phaseVoc->processFrequencyDomain(reals, imags,
Expand All @@ -116,6 +116,35 @@ double DetectionFunction::processFrequencyDomain(const double *reals,

void DetectionFunction::whiten()
{
static int count = 0;
static double oldPitch = 0;

if (count >= 109 && count <= 120) {
for (int i = 0; i < m_halfLength; ++i) {
double m = m_magnitude[i];
std::cout << m << " ";
}
std::cout << "\n";
}

for (int i = 1; i < m_halfLength; ++i) {
m_magnitude[i] *= log((i+300)/((double)i+2));
}


/*

if (count == 35 || count == 52 || count == 53 || count == 54) {
for (int i = 0; i < m_halfLength; ++i) {
double m = m_magnitude[i];
std::cout << m << " ";
}
std::cout << "\n";
}
*/


/*
for (int i = 0; i < m_halfLength; ++i) {
double m = m_magnitude[i];
if (m < m_magPeaks[i]) {
Expand All @@ -125,40 +154,34 @@ void DetectionFunction::whiten()
m_magPeaks[i] = m;
m_magnitude[i] /= m;
}
*/

count++;
}

double DetectionFunction::runDF()
DFresults DetectionFunction::runDF()
{
double retVal = 0;

switch( m_DFType )
{
case DF_HFC:
retVal = HFC( m_halfLength, m_magnitude);
break;

case DF_SPECDIFF:
retVal = specDiff( m_halfLength, m_magnitude);
break;

case DF_PHASEDEV:
// Using the instantaneous phases here actually provides the
// same results (for these calculations) as if we had used
// unwrapped phases, but without the possible accumulation of
// phase error over time
retVal = phaseDev( m_halfLength, m_thetaAngle);
break;

case DF_COMPLEXSD:
retVal = complexSD( m_halfLength, m_magnitude, m_thetaAngle);
break;

case DF_BROADBAND:
retVal = broadband( m_halfLength, m_magnitude);
break;
DFresults result = {};
if (m_DFType & dfHfc) {
result.t.hiFrequency = HFC(m_halfLength, m_magnitude);
}

return retVal;
if (m_DFType & dfSpecDiff) {
result.t.specDiff = specDiff(m_halfLength, m_magnitude);
}
// Using the instantaneous phases here actually provides the
// same results (for these calculations) as if we had used
// unwrapped phases, but without the possible accumulation of
// phase error over time
if (m_DFType & dfPhaseDev) {
result.t.phaseDev = phaseDev(m_halfLength, m_thetaAngle);
}
if (m_DFType & dfComplexSd) {
result.t.complexSpecDiff = complexSD(m_halfLength, m_magnitude, m_thetaAngle);
}
if (m_DFType & dfBroadBand) {
result.t.broadband = broadband(m_halfLength, m_magnitude);
}
return result;
}

double DetectionFunction::HFC(int length, double *src)
Expand Down
29 changes: 21 additions & 8 deletions lib/qm-dsp/dsp/onsets/DetectionFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,24 @@
#include "dsp/phasevocoder/PhaseVocoder.h"
#include "base/Window.h"

#define DF_HFC (1)
#define DF_SPECDIFF (2)
#define DF_PHASEDEV (3)
#define DF_COMPLEXSD (4)
#define DF_BROADBAND (5)
constexpr int dfHfc = 1;
constexpr int dfSpecDiff = 2;
constexpr int dfPhaseDev = 4;
constexpr int dfComplexSd = 8;
constexpr int dfBroadBand = 16;
constexpr int dfAll = 31;

struct DFTypes {
double hiFrequency;
double specDiff;
double phaseDev;
double complexSpecDiff;
double broadband;
};
union DFresults {
DFTypes t;
double results[5]; //c style so it has exact same memory locations of t items
};

struct DFConfig{
int stepSize; // DF step in samples
Expand All @@ -48,17 +61,17 @@ class DetectionFunction
* Process a single time-domain frame of audio, provided as
* frameLength samples.
*/
double processTimeDomain(const double* samples);
DFresults processTimeDomain(const double* samples);

/**
* Process a single frequency-domain frame, provided as
* frameLength/2+1 real and imaginary component values.
*/
double processFrequencyDomain(const double* reals, const double* imags);
DFresults processFrequencyDomain(const double* reals, const double* imags);

private:
void whiten();
double runDF();
DFresults runDF();

double HFC(int length, double* src);
double specDiff(int length, double* src);
Expand Down
Loading