mirror of
https://gitlab.com/square-game-liberation-front/F.E.I.S.git
synced 2025-02-28 15:30:32 +01:00
We are getting somewhere with aubio
This commit is contained in:
parent
69a6f5437c
commit
56d1afb46f
27
src/aubio_cpp.cpp
Normal file
27
src/aubio_cpp.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include "aubio_cpp.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
|
||||
#include <aubio/fvec.h>
|
||||
|
||||
namespace aubio {
|
||||
std::optional<std::size_t> onset_detector::detect(const std::vector<sf::Int16>& samples) {
|
||||
std::unique_ptr<fvec_t, decltype(&del_fvec)> out{new_fvec(2), del_fvec};
|
||||
std::vector<float> input;
|
||||
std::ranges::transform(samples, std::back_inserter(input), [](const sf::Int16 i) -> float {
|
||||
return static_cast<float>(i) / std::numeric_limits<sf::Int16>::max();
|
||||
});
|
||||
fvec_t _input = {
|
||||
.length=static_cast<uint_t>(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 {};
|
||||
}
|
||||
}
|
||||
}
|
25
src/aubio_cpp.hpp
Normal file
25
src/aubio_cpp.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <aubio/aubio.h>
|
||||
#include <aubio/onset/onset.h>
|
||||
#include <SFML/Config.hpp>
|
||||
|
||||
// Thanks stack overflow !
|
||||
// https://stackoverflow.com/a/54121092/10768117
|
||||
template <auto F>
|
||||
struct Functor {
|
||||
template <typename... Args>
|
||||
auto operator()(Args&&... args) const { return std::invoke(F, std::forward<Args>(args)...); }
|
||||
};
|
||||
|
||||
namespace aubio {
|
||||
using _aubio_onset_t_unique_ptr = std::unique_ptr<aubio_onset_t, Functor<del_aubio_onset>>;
|
||||
struct onset_detector : _aubio_onset_t_unique_ptr {
|
||||
template <typename... Args>
|
||||
onset_detector(Args&&... args) : _aubio_onset_t_unique_ptr(new_aubio_onset(std::forward<Args>(args)...)) {}
|
||||
std::optional<std::size_t> detect(const std::vector<sf::Int16>& samples);
|
||||
};
|
||||
}
|
31
src/guess_tempo.cpp
Normal file
31
src/guess_tempo.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
#include "guess_tempo.hpp"
|
||||
#include <SFML/Config.hpp>
|
||||
#include <SFML/System/Utf.hpp>
|
||||
#include <deque>
|
||||
|
||||
#include "aubio_cpp.hpp"
|
||||
#include "custom_sfml_audio/precise_sound_stream.hpp"
|
||||
|
||||
std::vector<TempoEstimate> guess_tempo(feis::InputSoundFile& music) {
|
||||
const auto onsets = detect_onsets(music);
|
||||
}
|
||||
|
||||
std::vector<sf::Time> 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<sf::Int16> samples(hop_size); // input audio buffer
|
||||
std::vector<sf::Time> 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;
|
||||
}
|
17
src/guess_tempo.hpp
Normal file
17
src/guess_tempo.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <SFML/System/Time.hpp>
|
||||
#include <filesystem>
|
||||
#include <vector>
|
||||
|
||||
#include "special_numeric_types.hpp"
|
||||
#include "utf8_sfml_redefinitions.hpp"
|
||||
|
||||
struct TempoEstimate {
|
||||
Decimal bpm;
|
||||
sf::Time offset;
|
||||
float fitness;
|
||||
};
|
||||
|
||||
std::vector<TempoEstimate> guess_tempo(feis::InputSoundFile& music);
|
||||
std::vector<sf::Time> detect_onsets(feis::InputSoundFile& music);
|
Loading…
x
Reference in New Issue
Block a user