From 50572ac40f09c79b1c4f0e844f8e1108d7dd7e98 Mon Sep 17 00:00:00 2001 From: Guzpido Date: Sat, 8 Jun 2024 21:54:42 -0300 Subject: [PATCH] WaveRubber: a simple waveform analyzer This kinda elastic analyzer uses no transformations and is colored by a gradient based on the user QT "Highlight" palette. WaveRubber: a kinda elastic waveform analyzer Update src/analyzer/waverubber.cpp better pointer declaration Co-authored-by: Jonas Kvinge --- src/CMakeLists.txt | 2 + src/analyzer/analyzercontainer.cpp | 2 + src/analyzer/waverubber.cpp | 93 ++++++++++++++++++++++++++++++ src/analyzer/waverubber.h | 43 ++++++++++++++ 4 files changed, 140 insertions(+) create mode 100644 src/analyzer/waverubber.cpp create mode 100644 src/analyzer/waverubber.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1bf19284b..9e49616fe 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -74,6 +74,7 @@ set(SOURCES analyzer/boomanalyzer.cpp analyzer/rainbowanalyzer.cpp analyzer/sonogram.cpp + analyzer/waverubber.cpp equalizer/equalizer.cpp equalizer/equalizerslider.cpp @@ -331,6 +332,7 @@ set(HEADERS analyzer/boomanalyzer.h analyzer/rainbowanalyzer.h analyzer/sonogram.h + analyzer/waverubber.h equalizer/equalizer.h equalizer/equalizerslider.h diff --git a/src/analyzer/analyzercontainer.cpp b/src/analyzer/analyzercontainer.cpp index 7ee091358..831af5ddd 100644 --- a/src/analyzer/analyzercontainer.cpp +++ b/src/analyzer/analyzercontainer.cpp @@ -41,6 +41,7 @@ #include "boomanalyzer.h" #include "rainbowanalyzer.h" #include "sonogram.h" +#include "waverubber.h" #include "core/logging.h" #include "core/shared_ptr.h" @@ -88,6 +89,7 @@ AnalyzerContainer::AnalyzerContainer(QWidget *parent) AddAnalyzerType(); AddAnalyzerType(); AddAnalyzerType(); + AddAnalyzerType(); disable_action_ = context_menu_->addAction(tr("No analyzer"), this, &AnalyzerContainer::DisableAnalyzer); disable_action_->setCheckable(true); diff --git a/src/analyzer/waverubber.cpp b/src/analyzer/waverubber.cpp new file mode 100644 index 000000000..eac42e6c3 --- /dev/null +++ b/src/analyzer/waverubber.cpp @@ -0,0 +1,93 @@ +/* + Strawberry Music Player + Copyright 2024, Gustavo L Conte + + Strawberry is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Strawberry is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Strawberry. If not, see . + */ + +#include +#include +#include "engine/enginebase.h" +#include "waverubber.h" + +const char *WaveRubber::kName = QT_TRANSLATE_NOOP("AnalyzerContainer", "WaveRubber"); + +WaveRubber::WaveRubber(QWidget *parent) + : AnalyzerBase(parent, 9) {} + +void WaveRubber::resizeEvent(QResizeEvent *e) { + + Q_UNUSED(e) + canvas_ = QPixmap(size()); + canvas_.fill(palette().color(QPalette::AlternateBase)); + +} + +void WaveRubber::analyze(QPainter &p, const Scope &s, bool new_frame) { + + if (!new_frame || engine_->state() == EngineBase::State::Paused) { + p.drawPixmap(0, 0, canvas_); + return; + } + + // Clear the canvas + canvas_ = QPixmap(size()); + canvas_.fill(palette().color(QPalette::Window)); + + QPainter canvas_painter(&canvas_); + + // Set the pen color to the QT palette highlight color + canvas_painter.setPen(palette().color(QPalette::Highlight)); + // Get pointer to amplitude data + const float *amplitude_data = s.data(); + + int mid_y = height() / 4; + int num_samples = s.size(); + + float x_scale = static_cast(width()) / num_samples; + float prev_y = mid_y; + + // Draw the waveform + for (int i = 0; i < num_samples; ++i) { + + // Normalize amplitude to 0-1 range + float color_factor = amplitude_data[i] / 2.0f + 0.5f; + int rgb_value = static_cast(255 - color_factor * 255); + QColor highlight_color = palette().color(QPalette::Highlight); + // Blend blue and green with highlight color from QT palette based on amplitude + QColor blended_color = QColor(rgb_value, highlight_color.green(), highlight_color.blue()); + canvas_painter.setPen(blended_color); + + int x = static_cast(i * x_scale ); + int y = static_cast(mid_y - (s[i] * mid_y)); + + canvas_painter.drawLine(x, prev_y + mid_y, x + x_scale, y + mid_y); // Draw + prev_y = y; + + } + + canvas_painter.end(); + p.drawPixmap(0, 0, canvas_); + +} + +void WaveRubber::transform(Scope &s) { + // No need transformation for waveform analyzer + Q_UNUSED(s); +} + +void WaveRubber::demo(QPainter &p) { + analyze(p, Scope(fht_->size(), 0), new_frame_); +} + diff --git a/src/analyzer/waverubber.h b/src/analyzer/waverubber.h new file mode 100644 index 000000000..ae60f8d89 --- /dev/null +++ b/src/analyzer/waverubber.h @@ -0,0 +1,43 @@ +/* + Strawberry Music Player + Copyright 2024, Gustavo L Conte + + Strawberry is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Strawberry is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Strawberry. If not, see . +*/ + + +#include +#include + +#include "analyzerbase.h" + +class WaveRubber : public AnalyzerBase { + + Q_OBJECT + public: + Q_INVOKABLE explicit WaveRubber(QWidget *parent); + + static const char *kName; + + protected: + void resizeEvent(QResizeEvent *e) override; + void analyze(QPainter &p, const Scope &s, bool new_frame) override; + void transform(Scope &scope) override; + void demo(QPainter &p) override; + + private: + QPixmap canvas_; + +}; +