diff --git a/Userland/Applications/SoundPlayer/BarsVisualizationWidget.cpp b/Userland/Applications/SoundPlayer/BarsVisualizationWidget.cpp index 2bfe9fb4e7..810cf783a5 100644 --- a/Userland/Applications/SoundPlayer/BarsVisualizationWidget.cpp +++ b/Userland/Applications/SoundPlayer/BarsVisualizationWidget.cpp @@ -7,6 +7,7 @@ #include "BarsVisualizationWidget.h" #include +#include #include #include #include @@ -22,8 +23,14 @@ void BarsVisualizationWidget::render(GUI::PaintEvent& event, FixedArray painter.add_clip_rect(event.rect()); painter.fill_rect(frame_inner_rect(), Color::Black); - for (size_t i = 0; i < fft_size; i++) - m_fft_samples[i] = samples[i] * m_fft_window[i]; + // First half of data is from previous iteration, second half is from now. + // This gives us fully overlapping windows, which result in more accurate and visually appealing STFT. + for (size_t i = 0; i < fft_size / 2; i++) + m_fft_samples[i] = m_previous_samples[i] * m_fft_window[i]; + for (size_t i = 0; i < fft_size / 2; i++) + m_fft_samples[i + fft_size / 2] = samples[i] * m_fft_window[i + fft_size / 2]; + + AK::TypedTransfer::copy(m_previous_samples.data(), samples.data(), samples.size()); LibDSP::fft(m_fft_samples.span(), false); @@ -74,7 +81,8 @@ BarsVisualizationWidget::BarsVisualizationWidget() m_fft_window = LibDSP::Window::hann(); - MUST(set_render_sample_count(fft_size)); + // As we use full-overlapping windows, the passed-in data is only half the size of one FFT operation. + MUST(set_render_sample_count(fft_size / 2)); } void BarsVisualizationWidget::context_menu_event(GUI::ContextMenuEvent& event) diff --git a/Userland/Applications/SoundPlayer/BarsVisualizationWidget.h b/Userland/Applications/SoundPlayer/BarsVisualizationWidget.h index ae44cc3253..d2bd539422 100644 --- a/Userland/Applications/SoundPlayer/BarsVisualizationWidget.h +++ b/Userland/Applications/SoundPlayer/BarsVisualizationWidget.h @@ -26,12 +26,13 @@ private: void render(GUI::PaintEvent&, FixedArray const&) override; void context_menu_event(GUI::ContextMenuEvent& event) override; - static constexpr size_t fft_size = 256; + static constexpr size_t fft_size = 512; static constexpr size_t bar_count = 64; static constexpr size_t values_per_bar = (fft_size / 2) / bar_count; Array, fft_size> m_fft_samples {}; Array m_fft_window {}; + Array m_previous_samples {}; Array m_gfx_falling_bars {}; bool m_is_using_last; bool m_adjust_frequencies;