Compute more downsampled versions of the audio

This commit is contained in:
Stepland 2023-01-15 02:06:05 +01:00
parent 5e07b15c98
commit 1befa02cd8
2 changed files with 47 additions and 8 deletions

View File

@ -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;
}

View File

@ -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();