More waveform stuff

This commit is contained in:
Stepland 2023-01-16 00:51:48 +01:00
parent 1befa02cd8
commit 9e37cfd67d
3 changed files with 46 additions and 14 deletions

View File

@ -346,12 +346,18 @@ int main() {
case sf::Keyboard::Add:
if (editor_state) {
editor_state->linear_view.zoom_in();
if (editor_state->waveform_view) {
editor_state->waveform_view->zoom_in();
}
notificationsQueue.push(std::make_shared<TextNotification>("Zoom in"));
}
break;
case sf::Keyboard::Subtract:
if (editor_state) {
editor_state->linear_view.zoom_out();
if (editor_state->waveform_view) {
editor_state->waveform_view->zoom_out();
}
notificationsQueue.push(std::make_shared<TextNotification>("Zoom out"));
}
break;

View File

@ -5,6 +5,7 @@
#include <SFML/Graphics/Rect.hpp>
#include <SFML/System/Vector2.hpp>
#include <algorithm>
#include <cstddef>
#include <imgui.h>
#include <imgui_extras.hpp>
@ -27,14 +28,14 @@ void WaveformView::draw(const sf::Time current_time) {
feis::CenteredText("Loading ...");
return ImGui::End();
}
const auto channels_it = channels_per_chunk_size.begin();
if (channels_it == channels_per_chunk_size.end()) {
if (channels_per_chunk_size.empty()) {
feis::CenteredText("No data ???");
return ImGui::End();
}
const auto& [chunk_size, channels] = *channels_it;
zoom = std::clamp(zoom, 0, static_cast<int>(channels_per_chunk_size.size()) - 1);
const auto& channels_it = channels_per_chunk_size.at(channels_per_chunk_size.size() - zoom - 1);
const auto& [chunk_size, channels] = channels_it;
const auto window = ImGui::GetCurrentWindow();
const auto work_rect = window->WorkRect;
auto draw_list = window->DrawList;
@ -72,6 +73,19 @@ void WaveformView::draw(const sf::Time current_time) {
ImGui::End();
}
void WaveformView::set_zoom(int new_zoom) {
zoom = std::clamp(new_zoom, 0, 9);
}
void WaveformView::zoom_in() {
set_zoom(zoom + 1);
}
void WaveformView::zoom_out() {
set_zoom(zoom - 1);
}
Channels load_initial_summary(
feis::HoldFileStreamMixin<sf::InputSoundFile>& sound_file,
const unsigned int window_size
@ -109,16 +123,16 @@ Channels load_initial_summary(
}
Channels downsample_to_half(const Channels& summary) {
Channels downsample;
Channels downsampled_summary;
for (const auto& channel : summary) {
std::vector<DataPoint> downsampled{(channel.size() / 2) + 1};
auto out = downsampled.begin();
auto& downsampled_channel = downsampled_summary.emplace_back((channel.size() / 2) + 1);
auto out = downsampled_channel.begin();
auto in = channel.begin();
while (in != channel.end() and out != downsampled.end()) {
while (in != channel.end() and out != downsampled_channel.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);
out->min = std::min(in->min, next_in->min);
} else {
*out = *in;
break;
@ -127,14 +141,14 @@ Channels downsample_to_half(const Channels& summary) {
std::advance(in, 2);
}
}
return downsample;
return downsampled_summary;
};
void WaveformView::prepare_data() {
unsigned int size = 8;
channels_per_chunk_size[size] = load_initial_summary(sound_file, size);
channels_per_chunk_size.emplace_back(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]);
channels_per_chunk_size.emplace_back(size * 2, downsample_to_half(channels_per_chunk_size.rbegin()->second));
size *= 2;
}
data_is_ready = true;

View File

@ -30,12 +30,24 @@ public:
void draw(const sf::Time current_time);
void draw_settings();
bool display = false;
void set_zoom(int zoom);
void zoom_in();
void zoom_out();
private:
feis::HoldFileStreamMixin<sf::InputSoundFile> sound_file;
std::atomic<bool> data_is_ready = false;
std::map<unsigned int, Channels> channels_per_chunk_size;
std::vector<std::pair<unsigned int, Channels>> channels_per_chunk_size;
std::optional<std::map<unsigned int, Channels>::iterator> selected_size;
std::jthread worker;
int zoom = 0;
void prepare_data();
};
Channels load_initial_summary(
feis::HoldFileStreamMixin<sf::InputSoundFile>& sound_file,
const unsigned int window_size
);
Channels downsample_to_half(const Channels& summary);