32 return std::accumulate(
33 powSpec.begin(), powSpec.end(), 0.f, [&](
float a,
float mag) {
35 return a + std::max(0.f, mag - prevPowSpec[k++]);
41 constexpr auto smoothingWindowDuration = 0.2;
43 const int M =
std::round(smoothingWindowDuration * hopRate / 4) * 2 + 1;
46 std::vector<float> movingAverage(x.size());
47 std::transform(x.begin(), x.end(), movingAverage.begin(), [&](
float) {
48 const auto m = IotaRange(-M, M + 1);
50 std::accumulate(m.begin(), m.end(), 0.f, [&](float y, int i) {
56 return y + x[k] * window[i + M];
65 constexpr auto thresholdRaiser = 1.5f;
66 return y * thresholdRaiser;
75 if (std::all_of(ux.begin(), ux.end(), [](
float x) { return x == 0.f; }))
77 const auto N = ux.size();
82 pffft_transform_ordered(
83 setup.get(), x.data(), x.data(), work.data(), PFFFT_FORWARD);
89 for (
auto n = 2; n < N; n += 2)
91 x[n] = x[n] * x[n] + x[n + 1] * x[n + 1];
95 pffft_transform_ordered(
96 setup.get(), x.data(), x.data(), work.data(), PFFFT_BACKWARD);
100 x.erase(x.begin() + N / 2 + 1, x.end());
102 const auto normalizer = 1 / x[0];
103 std::transform(x.begin(), x.end(), x.begin(), [normalizer](
float x) {
104 return x * normalizer;
106 return { x.begin(), x.end() };
111 const std::function<
void(
double)>& progressCallback,
115 const auto sampleRate = frameProvider.GetSampleRate();
116 const auto numFrames = frameProvider.GetNumFrames();
117 const auto frameSize = frameProvider.GetFftSize();
119 std::vector<float> odf;
120 odf.reserve(numFrames);
121 const auto powSpecSize = frameSize / 2 + 1;
125 std::fill(prevPowSpec.begin(), prevPowSpec.end(), 0.f);
129 auto frameCounter = 0;
130 while (frameProvider.GetNextFrame(buffer))
137 constexpr auto gamma = 100.f;
139 powSpec.begin(), powSpec.end(), powSpec.begin(),
140 [gamma](
float x) { return FastLog2(1 + gamma * std::sqrt(x)); });
142 if (firstPowSpec.empty())
143 firstPowSpec = powSpec;
152 if (progressCallback)
153 progressCallback(1. * ++frameCounter / numFrames);
160 const auto movingAverage =
165 debugOutput->
rawOdf = odf;
171 odf.begin(), odf.end(), movingAverage.begin(), odf.begin(),
172 [](
float a,
float b) { return std::max<float>(a - b, 0.f); });
std::unique_ptr< PFFFT_Setup, PffftSetupDeleter > PffftSetupHolder
Much faster that FFT.h's PowerSpectrum, at least in Short-Time Fourier Transform-like situations,...
float GetNoveltyMeasure(const PffftFloatVector &prevPowSpec, const PffftFloatVector &powSpec)
std::vector< float > GetMovingAverage(const std::vector< float > &x, double hopRate)
std::vector< float > GetOnsetDetectionFunction(const MirAudioReader &audio, const std::function< void(double)> &progressCallback, QuantizationFitDebugOutput *debugOutput)
std::vector< float > GetNormalizedCircularAutocorr(const std::vector< float > &ux)
Get the normalized, circular auto-correlation for a signal x whose length already is a power of two....
std::vector< float > GetNormalizedHann(int size)
constexpr auto IsPowOfTwo(int x)
constexpr auto sampleRate
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
fastfloat_really_inline void round(adjusted_mantissa &am, callback cb) noexcept
std::vector< float > rawOdf
std::vector< float > movingAverage
std::vector< PffftFloatVector > postProcessedStft
A vector of floats guaranteeing alignment as demanded by pffft.
PffftFloats aligned(PffftAlignedCount c={})