From 56d1afb46f18ff8ca15418c5e9814abe071df903 Mon Sep 17 00:00:00 2001 From: Stepland <10530295-Buggyroom@users.noreply.gitlab.com> Date: Wed, 10 May 2023 02:00:20 +0200 Subject: [PATCH] We are getting somewhere with aubio --- src/aubio_cpp.cpp | 27 +++++++++++++++++++++++++++ src/aubio_cpp.hpp | 25 +++++++++++++++++++++++++ src/guess_tempo.cpp | 31 +++++++++++++++++++++++++++++++ src/guess_tempo.hpp | 17 +++++++++++++++++ 4 files changed, 100 insertions(+) create mode 100644 src/aubio_cpp.cpp create mode 100644 src/aubio_cpp.hpp create mode 100644 src/guess_tempo.cpp create mode 100644 src/guess_tempo.hpp diff --git a/src/aubio_cpp.cpp b/src/aubio_cpp.cpp new file mode 100644 index 0000000..f211020 --- /dev/null +++ b/src/aubio_cpp.cpp @@ -0,0 +1,27 @@ +#include "aubio_cpp.hpp" + +#include +#include +#include + +#include + +namespace aubio { + std::optional onset_detector::detect(const std::vector& samples) { + std::unique_ptr out{new_fvec(2), del_fvec}; + std::vector input; + std::ranges::transform(samples, std::back_inserter(input), [](const sf::Int16 i) -> float { + return static_cast(i) / std::numeric_limits::max(); + }); + fvec_t _input = { + .length=static_cast(input.size()), + .data=input.data(), + }; + aubio_onset_do(this->get(), &_input, out.get()); + if (out->data[0] != 0) { + return aubio_onset_get_last(this->get()); + } else { + return {}; + } + } +} \ No newline at end of file diff --git a/src/aubio_cpp.hpp b/src/aubio_cpp.hpp new file mode 100644 index 0000000..b6cd20f --- /dev/null +++ b/src/aubio_cpp.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include +#include + +#include +#include +#include + +// Thanks stack overflow ! +// https://stackoverflow.com/a/54121092/10768117 +template +struct Functor { + template + auto operator()(Args&&... args) const { return std::invoke(F, std::forward(args)...); } +}; + +namespace aubio { + using _aubio_onset_t_unique_ptr = std::unique_ptr>; + struct onset_detector : _aubio_onset_t_unique_ptr { + template + onset_detector(Args&&... args) : _aubio_onset_t_unique_ptr(new_aubio_onset(std::forward(args)...)) {} + std::optional detect(const std::vector& samples); + }; +} \ No newline at end of file diff --git a/src/guess_tempo.cpp b/src/guess_tempo.cpp new file mode 100644 index 0000000..7887467 --- /dev/null +++ b/src/guess_tempo.cpp @@ -0,0 +1,31 @@ +#include "guess_tempo.hpp" +#include +#include +#include + +#include "aubio_cpp.hpp" +#include "custom_sfml_audio/precise_sound_stream.hpp" + +std::vector guess_tempo(feis::InputSoundFile& music) { + const auto onsets = detect_onsets(music); +} + +std::vector detect_onsets(feis::InputSoundFile& music) { + auto samplerate = music.getSampleRate(); + std::size_t win_s = 1024; // window size + std::size_t hop_size = win_s / 4; + std::size_t read = 0; + std::vector samples(hop_size); // input audio buffer + std::vector onsets; + auto detector = aubio::onset_detector("default", win_s, hop_size, samplerate); + do { + read = music.read(samples.data(), hop_size); + auto onset = detector.detect(samples); + // do something with the onsets + if (onset) { + onsets.push_back(samples_to_time(*onset, music.getSampleRate(), music.getChannelCount())); + } + } while ( read == hop_size ); + aubio_cleanup(); + return onsets; +} \ No newline at end of file diff --git a/src/guess_tempo.hpp b/src/guess_tempo.hpp new file mode 100644 index 0000000..0ff5782 --- /dev/null +++ b/src/guess_tempo.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include +#include +#include + +#include "special_numeric_types.hpp" +#include "utf8_sfml_redefinitions.hpp" + +struct TempoEstimate { + Decimal bpm; + sf::Time offset; + float fitness; +}; + +std::vector guess_tempo(feis::InputSoundFile& music); +std::vector detect_onsets(feis::InputSoundFile& music);