Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Leander Schulten
Lichtsteuerung
Commits
8f69b479
Commit
8f69b479
authored
Sep 26, 2019
by
Leander Schulten
Browse files
Aubio: Add classes to wrap aubio analyzes
parent
13b36798
Pipeline
#187505
passed with stage
in 3 minutes and 24 seconds
Changes
7
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
src/Lichtsteuerung.pro
View file @
8f69b479
...
...
@@ -18,6 +18,9 @@ QML_DESIGNER_IMPORT_PATH =
SOURCES += \
applicationdata.cpp \
audio/aubio/aubiocapi.cpp \
audio/aubio/onsetanalysis.cpp \
audio/aubio/tempoanalysis.cpp \
dmx/channel.cpp \
gui/channelprogrammeditor.cpp \
gui/colorplot.cpp \
...
...
@@ -94,6 +97,9 @@ DEFINES += _USE_MATH_DEFINES
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
HEADERS += \
audio/aubio/aubiocapi.h \
audio/aubio/onsetanalysis.h \
audio/aubio/tempoanalysis.h \
dmx/deviceprototype.h \
dmx/channel.h \
id.h \
...
...
src/audio/aubio/aubiocapi.cpp
0 → 100644
View file @
8f69b479
#include "aubiocapi.h"
#include <QString>
#include <QtGlobal>
namespace
Audio
::
Aubio
{
OnsetDetectionFunction
toOnsetDetectionFunction
(
int
i
)
{
Q_ASSERT
(
i
>=
0
&&
i
<=
static_cast
<
int
>
(
OnsetDetectionFunction
::
Last
));
return
static_cast
<
OnsetDetectionFunction
>
(
i
);
}
const
C_API
::
char_t
*
C_API
::
toName
(
OnsetDetectionFunction
f
)
{
using
E
=
OnsetDetectionFunction
;
switch
(
f
)
{
case
E
::
EnergyBased
:
return
"energy"
;
case
E
::
SpectralDifference
:
return
"specdiff"
;
case
E
::
HighFrequencyContent
:
return
"hfc"
;
case
E
::
ComplexDomain
:
return
"complex"
;
case
E
::
PhaseDeviation
:
return
"phase"
;
case
E
::
KullbackLiebler
:
return
"kl"
;
case
E
::
ModifiedKullbackLiebler
:
return
"mkl"
;
case
E
::
SpectralFlux
:
return
"specflux"
;
}
}
QString
toQString
(
OnsetDetectionFunction
f
)
{
using
E
=
OnsetDetectionFunction
;
switch
(
f
)
{
case
E
::
EnergyBased
:
return
QStringLiteral
(
"Energy Based"
);
case
E
::
SpectralDifference
:
return
QStringLiteral
(
"Spectral Difference"
);
case
E
::
HighFrequencyContent
:
return
QStringLiteral
(
"High-Frequency Content"
);
case
E
::
ComplexDomain
:
return
QStringLiteral
(
"Complex Domain"
);
case
E
::
PhaseDeviation
:
return
QStringLiteral
(
"Phase Deviation"
);
case
E
::
KullbackLiebler
:
return
QStringLiteral
(
"Kullback-Liebler"
);
case
E
::
ModifiedKullbackLiebler
:
return
QStringLiteral
(
"Modified Kullback-Liebler"
);
case
E
::
SpectralFlux
:
return
QStringLiteral
(
"Spectral Flux"
);
}
}
}
// namespace Audio::Aubio
src/audio/aubio/aubiocapi.h
0 → 100644
View file @
8f69b479
#ifndef AUBIOCAPI_H
#define AUBIOCAPI_H
#include <type_traits>
class
QString
;
namespace
Audio
::
Aubio
{
namespace
C_API
{
// hide the c api behind the C_API namespace
#include <aubio/aubio.h>
}
// namespace C_API
/**
* @brief The OnsetDetectionFunction enum holds all possible onset detection functions
*/
enum
class
OnsetDetectionFunction
{
EnergyBased
,
SpectralDifference
,
HighFrequencyContent
,
ComplexDomain
,
PhaseDeviation
,
KullbackLiebler
,
ModifiedKullbackLiebler
,
SpectralFlux
,
Last
=
SpectralFlux
,
};
/**
* @brief toOnsetDetectionFunction converts a int to an OnsetDetectionFunction. The function asserts that the int is a valid OnsetDetectionFunction
* @param i The int that should be convertet to a OnsetDetectionFunction
* @return the corresponding OnsetDetectionFunction (the function asserts if there is no corresponsing OnsetDetectionFunction)
*/
OnsetDetectionFunction
toOnsetDetectionFunction
(
int
i
);
/**
* Converts an enum to the underlying type (mostly a int)
*/
template
<
typename
E
>
constexpr
auto
to_integral
(
E
e
)
->
typename
std
::
underlying_type
<
E
>::
type
{
return
static_cast
<
typename
std
::
underlying_type
<
E
>::
type
>
(
e
);
}
namespace
C_API
{
/**
* @brief toName Converts the enum to an string that is used by the aubio c lib
* @param f the enum that should be converted
* @return the c string representation of the enum that can be used with the aubio lib
*/
const
C_API
::
char_t
*
toName
(
OnsetDetectionFunction
f
);
}
// namespace C_API
/**
* @brief toQString Converts the enum to a human readable string
* @param f the enum that should be converted
* @return a human readable string
*/
QString
toQString
(
OnsetDetectionFunction
f
);
}
// namespace Audio::Aubio
#endif // AUBIOCAPI_H
src/audio/aubio/onsetanalysis.cpp
0 → 100644
View file @
8f69b479
#include "onsetanalysis.h"
#include <QDebug>
#include <array>
namespace
Audio
::
Aubio
{
using
namespace
C_API
;
OnsetAnalysis
::
OnsetAnalysis
(
OnsetDetectionFunction
onsetDetectionFunction
,
uint_t
fftSize
,
uint_t
stepSize
,
uint_t
sampleRate
)
:
onset
(
new_aubio_onset
(
toName
(
onsetDetectionFunction
),
fftSize
,
stepSize
,
sampleRate
),
del_aubio_onset
),
inputData
{
stepSize
,
nullptr
}
{}
bool
OnsetAnalysis
::
processNewSamples
(
float
*
newSamples
)
{
// setup the data structures
smpl_t
wasOnset
;
fvec_t
out
{
1
,
&
wasOnset
};
inputData
.
data
=
newSamples
;
aubio_onset_do
(
onset
.
get
(),
&
inputData
,
&
out
);
return
wasOnset
!=
0
;
}
unsigned
OnsetAnalysis
::
getLastOnset
()
{
return
aubio_onset_get_last
(
onset
.
get
());
}
float
OnsetAnalysis
::
getOnsetValue
()
{
return
aubio_onset_get_descriptor
(
onset
.
get
());
}
float
OnsetAnalysis
::
getCurrentThreshold
()
{
return
aubio_onset_get_thresholded_descriptor
(
onset
.
get
());
}
}
// namespace Audio::Aubio
src/audio/aubio/onsetanalysis.h
0 → 100644
View file @
8f69b479
#ifndef ONSETANALYSIS_H
#define ONSETANALYSIS_H
#include "aubiocapi.h"
#include <memory>
namespace
Audio
::
Aubio
{
/**
* @brief The OnsetAnalysis class can detect onsets (music events). They are similar to the beats, but not so uniformly (rather the feeling of the music).
*/
class
OnsetAnalysis
{
std
::
unique_ptr
<
C_API
::
aubio_onset_t
,
decltype
(
&
C_API
::
del_aubio_onset
)
>
onset
;
C_API
::
fvec_t
inputData
;
public:
/**
* @brief OnsetAnalysis Creates a onset analysis, which can detect onsets (music events)
* @param onsetDetectionFunction The onset detection function that should be used. The results can vary greatly based on the onset detection function
* @param fftSize The size of the fft that should be used. Larger fft sizes are slower but result in better results (must be a power of 2)
* @param stepSize The size of a new block that gets passed to this->processNewSamples().
* @param sampleRate The sample rate of the data
*/
OnsetAnalysis
(
OnsetDetectionFunction
onsetDetectionFunction
,
C_API
::
uint_t
fftSize
,
C_API
::
uint_t
stepSize
,
C_API
::
uint_t
sampleRate
);
/**
* @brief processNewSamples process and analyse new samples
* @param newSamples A pointer to the new samples, the length of the array must be minimun the step size from the constructor
* @return true, if there was a onset in the new sample, false otherwise
*/
bool
processNewSamples
(
float
*
newSamples
);
/**
* @brief getLastOnset return the last detected onset
* @return the position of the last detected onset in samples
*/
unsigned
getLastOnset
();
/**
* @brief getOnsetValue return the last value of the onset detection function that is used
* @return the latest value of the onset detection function, the value range can vary from onset detection function to onset detection function
*/
float
getOnsetValue
();
/**
* @brief getCurrentThreshold return the current threshold used by the detection function to detect onsets
* @return the current threshold used by the detection function to detect onsets
*/
float
getCurrentThreshold
();
};
}
// namespace Audio::Aubio
#endif // ONSETANALYSIS_H
src/audio/aubio/tempoanalysis.cpp
0 → 100644
View file @
8f69b479
#include "tempoanalysis.h"
#include <QDebug>
#include <array>
namespace
Audio
::
Aubio
{
using
namespace
C_API
;
TempoAnalysis
::
TempoAnalysis
(
OnsetDetectionFunction
onsetDetectionFunction
,
uint_t
fftSize
,
uint_t
stepSize
,
uint_t
sampleRate
)
:
tempo
(
new_aubio_tempo
(
toName
(
onsetDetectionFunction
),
fftSize
,
stepSize
,
sampleRate
),
del_aubio_tempo
),
inputData
{
stepSize
,
nullptr
}
{}
bool
TempoAnalysis
::
processNewSamples
(
float
*
newSamples
)
{
// setup the data structures
smpl_t
wasBeat
;
fvec_t
out
{
1
,
&
wasBeat
};
inputData
.
data
=
newSamples
;
aubio_tempo_do
(
tempo
.
get
(),
&
inputData
,
&
out
);
return
wasBeat
!=
0
;
}
unsigned
TempoAnalysis
::
getLastBeat
()
{
return
aubio_tempo_get_last
(
tempo
.
get
());
}
float
TempoAnalysis
::
getCurrentBPM
()
{
return
aubio_tempo_get_bpm
(
tempo
.
get
());
}
unsigned
TempoAnalysis
::
getLastTatum
()
{
return
static_cast
<
unsigned
>
(
aubio_tempo_get_last_tatum
(
tempo
.
get
()));
}
}
// namespace Audio::Aubio
src/audio/aubio/tempoanalysis.h
0 → 100644
View file @
8f69b479
#ifndef TEMPOANALYSIS_H
#define TEMPOANALYSIS_H
#include "aubiocapi.h"
#include <memory>
namespace
Audio
::
Aubio
{
/**
* @brief The TempoAnalysis class can determine the tempo (beats per minute) of the input audio data. Also the class can detect beats.
* The class can use different onset detection methods (onset = "music event"), which leads to different results.
*/
class
TempoAnalysis
{
std
::
unique_ptr
<
C_API
::
aubio_tempo_t
,
decltype
(
&
C_API
::
del_aubio_tempo
)
>
tempo
;
C_API
::
fvec_t
inputData
;
public:
/**
* @brief TempoAnalysis Creates a tempo analysis, which can detect beats, tatums and the current bpm
* @param onsetDetectionFunction The onset detection function that should be used. The results can vary greatly based on the onset detection function
* @param fftSize The size of the fft that should be used. Larger fft sizes are slower but result in better results (must be a power of 2)
* @param stepSize The size of a new block that gets passed to this->processNewSamples().
* @param sampleRate The sample rate of the data
*/
TempoAnalysis
(
OnsetDetectionFunction
onsetDetectionFunction
,
C_API
::
uint_t
fftSize
,
C_API
::
uint_t
stepSize
,
C_API
::
uint_t
sampleRate
);
/**
* @brief processNewSamples process and analyse new samples
* @param newSamples A pointer to the new samples, the length of the array must be minimun the step size from the constructor
* @return true, if there was a beat in the new sample, false otherwise
*/
bool
processNewSamples
(
float
*
newSamples
);
/**
* @brief getLastBeat returns the position of the last detected beat, in samples
* @return the position of the last beat in samples
*/
unsigned
getLastBeat
();
/**
* @brief getCurrentBPM return the current determined beats per second
* @return the currently determined beats per minute
*/
float
getCurrentBPM
();
/**
* @brief getLastTatum return the position of the last detected tatum (sub beat) in samples
* @return the position of the last tatum im samples
*/
unsigned
getLastTatum
();
};
}
// namespace Audio::Aubio
#endif // TEMPOANALYSIS_H
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment