mirror of
https://gitlab.com/square-game-liberation-front/F.E.I.S.git
synced 2025-02-28 15:30:32 +01:00
Compute more downsampled versions of the audio
This commit is contained in:
parent
5e07b15c98
commit
1befa02cd8
@ -9,7 +9,9 @@
|
||||
#include <imgui.h>
|
||||
#include <imgui_extras.hpp>
|
||||
#include <imgui_internal.h>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
#include "toolbox.hpp"
|
||||
#include "utf8_file_input_stream.hpp"
|
||||
#include "utf8_sfml.hpp"
|
||||
@ -70,25 +72,28 @@ void WaveformView::draw(const sf::Time current_time) {
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void WaveformView::prepare_data() {
|
||||
|
||||
const std::size_t chunk_size = 64 * sound_file.getChannelCount();
|
||||
const std::size_t point_count = (sound_file.getSampleCount() / sound_file.getChannelCount() / 64) + 1;
|
||||
Channels load_initial_summary(
|
||||
feis::HoldFileStreamMixin<sf::InputSoundFile>& sound_file,
|
||||
const unsigned int window_size
|
||||
) {
|
||||
const std::size_t chunk_size = window_size * sound_file.getChannelCount();
|
||||
const std::size_t point_count = (sound_file.getSampleCount() / sound_file.getChannelCount() / window_size) + 1;
|
||||
Channels summary{sound_file.getChannelCount(), DataFrame{point_count}};
|
||||
|
||||
std::vector<sf::Int16> samples;
|
||||
samples.resize(chunk_size);
|
||||
for (std::size_t point_index = 0; point_index < point_count; point_index++) {
|
||||
const auto samples_read = sound_file.read(samples.data(), chunk_size);
|
||||
if (samples_read < chunk_size) {
|
||||
// looks like we are done reading the file ?
|
||||
if (samples_read == 0) {
|
||||
// we are done reading the file
|
||||
break;
|
||||
}
|
||||
const auto sample_indicies = samples_read / sound_file.getChannelCount();
|
||||
for (std::size_t channel_index = 0; channel_index < summary.size(); channel_index++) {
|
||||
auto& point = summary[channel_index][point_index];
|
||||
point.max = std::numeric_limits<DataPoint::value_type>::min();
|
||||
point.min = std::numeric_limits<DataPoint::value_type>::max();
|
||||
for (std::size_t sample_index = 0; sample_index < 64; sample_index++) {
|
||||
for (std::size_t sample_index = 0; sample_index < sample_indicies; sample_index++) {
|
||||
auto& sample = samples[sample_index * sound_file.getChannelCount() + channel_index];
|
||||
if (sample > point.max) {
|
||||
point.max = sample;
|
||||
@ -100,6 +105,37 @@ void WaveformView::prepare_data() {
|
||||
}
|
||||
std::ranges::fill(samples, 0);
|
||||
}
|
||||
channels_per_chunk_size[64] = summary;
|
||||
return summary;
|
||||
}
|
||||
|
||||
Channels downsample_to_half(const Channels& summary) {
|
||||
Channels downsample;
|
||||
for (const auto& channel : summary) {
|
||||
std::vector<DataPoint> downsampled{(channel.size() / 2) + 1};
|
||||
auto out = downsampled.begin();
|
||||
auto in = channel.begin();
|
||||
while (in != channel.end() and out != downsampled.end()) {
|
||||
const auto next_in = std::next(in);
|
||||
if (next_in != channel.end()) {
|
||||
out->max = std::max(in->max, next_in->max);
|
||||
out->min = std::max(in->min, next_in->min);
|
||||
} else {
|
||||
*out = *in;
|
||||
break;
|
||||
}
|
||||
out = std::next(out);
|
||||
std::advance(in, 2);
|
||||
}
|
||||
}
|
||||
return downsample;
|
||||
};
|
||||
|
||||
void WaveformView::prepare_data() {
|
||||
unsigned int size = 8;
|
||||
channels_per_chunk_size[size] = load_initial_summary(sound_file, size);
|
||||
while (channels_per_chunk_size.size() < 10) {
|
||||
channels_per_chunk_size[size * 2] = downsample_to_half(channels_per_chunk_size[size]);
|
||||
size *= 2;
|
||||
}
|
||||
data_is_ready = true;
|
||||
}
|
||||
|
@ -28,10 +28,13 @@ class WaveformView {
|
||||
public:
|
||||
explicit WaveformView(const std::filesystem::path& file);
|
||||
void draw(const sf::Time current_time);
|
||||
void draw_settings();
|
||||
bool display = false;
|
||||
private:
|
||||
feis::HoldFileStreamMixin<sf::InputSoundFile> sound_file;
|
||||
std::atomic<bool> data_is_ready = false;
|
||||
std::map<unsigned int, Channels> channels_per_chunk_size;
|
||||
std::optional<std::map<unsigned int, Channels>::iterator> selected_size;
|
||||
std::jthread worker;
|
||||
|
||||
void prepare_data();
|
||||
|
Loading…
x
Reference in New Issue
Block a user