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: case sf::Keyboard::Add:
if (editor_state) { if (editor_state) {
editor_state->linear_view.zoom_in(); 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")); notificationsQueue.push(std::make_shared<TextNotification>("Zoom in"));
} }
break; break;
case sf::Keyboard::Subtract: case sf::Keyboard::Subtract:
if (editor_state) { if (editor_state) {
editor_state->linear_view.zoom_out(); 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")); notificationsQueue.push(std::make_shared<TextNotification>("Zoom out"));
} }
break; break;

View File

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

View File

@ -30,12 +30,24 @@ public:
void draw(const sf::Time current_time); void draw(const sf::Time current_time);
void draw_settings(); void draw_settings();
bool display = false; bool display = false;
void set_zoom(int zoom);
void zoom_in();
void zoom_out();
private: private:
feis::HoldFileStreamMixin<sf::InputSoundFile> sound_file; feis::HoldFileStreamMixin<sf::InputSoundFile> sound_file;
std::atomic<bool> data_is_ready = false; 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::optional<std::map<unsigned int, Channels>::iterator> selected_size;
std::jthread worker; std::jthread worker;
int zoom = 0;
void prepare_data(); 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);