Files
lmms/plugins/SpectrumAnalyzer
Tres Finocchiaro 51529cefb1 Add Qt6 Support (#7339)
* Rebase against master

Co-authored-by: michaelgregorius <michael.gregorius.git@arcor.de>
Co-authored-by: Rossmaxx <74815851+Rossmaxx@users.noreply.github.com>

* Fix Qt6 DMG on Apple (#7240)

- Fix linking issues with Qt Framework files
- Fix qmake detection

* Fixes after rebase

* Fix embed.cpp compilation

Fix implicit conversion from int when using QString.arg(...)

* Fix Qt6 signature change for nativeEventFilter (#7254)

* Adds win32EventFilter a wrapper for nativeEventFilter on Windows
* win32EventFilter is currently used to intercept top-level Window events (currently, to avoid VSTs setting transparency of the parent application)

* fix broken signal slot connections (#7274)

QComboBox activated() replaced with textActivated() since Qt 5.14

* Enabled VSTs on Qt 6 (#7273)

* enabled VST support for Qt 6 builds
* Note : Embedding on QT6 will be buggy on linux as a result of using qt embedding, which unfortunately is a qt bug which hasn't been resolved.

* Changed bar lines to follow snap size (#7034)

* Added lines in between bars
* Changed bar lines to follow snap size
* Changed default zoom and quantization value
* Added constants for line widths
* Added QSS configuration for new grid line colors
* Tied line widths to QSS properties
* Changed default quantization to 1/4
* Removed clear() from destructor model
* Removed destructor in ComboBoxModel.h
* Changed member set/get functions to pass by value
* Updated signal connection with newer syntax

* Fix compilation

* Fix MSVC builds

* fix nullptr deref in AudioFileProcessor (qt6 branch) (#7532)

* ensured mouse event != nullptr before deref

* separation of concerns: AFP WaveView updateCursor

extract check to pointerCloseToStartEndOrLoop()

* marked some function parameters as const

* Remove Core5Compat usage

* Fix bad merge

* Fixes after rebase

* Simplify QTX_WRAP_CPP call

* Remove comments that are obvious to a developer

* Whitespace

* Try using Qt 6 for MSVC CI

I chose Qt 6.5 because it's the last Qt LTS release with declared
support for Visual Studio 2019. Once we upgrade to Visual Studio 2022,
we could upgrade Qt as well.

* Fix MSVC build

Also fixes two memory leaks in MidiWinMM

* Fix GuiApplication on MSVC

* Fix interpolateInRgb

* Try building with patched Calf

* Fix submodule

* Fix OpulenZ build

* Try to fix zyn

* Fix comment

* Ty to fix zyn (again)

* Ty to fix RemotePluginBase

* Revert "Ty to fix RemotePluginBase"

This reverts commit 92dac44ffb11e19d1d5a21d9155369f017bd59e9.

* Update plugins/ZynAddSubFx/CMakeLists.txt

Co-authored-by: Dalton Messmer <messmer.dalton@gmail.com>

* Fix vertical & horizontal scroll wheel in SongEditor

* AppImage: Fix finding of Qt6 libs

* Fix implicit QString --> QFileInfo conversion

* Point submodule to lmms

* Fix multiple deprecation warnings

* Fix for Clang compiler

* Build with latest Qt LTS version now that we use MSVC 2022

* Update jurplel/install-qt-action to v4.3.0

* Bump minimum Qt6 version for MSVC

* Fix incorrect Qt version checks

Some comparisons were using ">" rather than ">="

* `QSize()` != `QSize(0, 0)`

* Fix more deprecation warnings

* Fix style

* Simplify Spectrum Analyzer mouse events

The Qt bug that used to be present appears to have been fixed, so the
workaround can be removed

* Minor changes

* Fix deprecated QCheckBox signal

* Fix setContent helper functions

* Remove QMultiMap usage from ControlLayout

* Remove SIGNAL and SLOT macros

* Revert TrackView.cpp changes

* Remove Q_DISABLE_MOVE usage since it does not seem to be available in Qt6

---------

Co-authored-by: michaelgregorius <michael.gregorius.git@arcor.de>
Co-authored-by: Rossmaxx <74815851+Rossmaxx@users.noreply.github.com>
Co-authored-by: BoredGuy1 <66702733+BoredGuy1@users.noreply.github.com>
Co-authored-by: Hyunjin Song <tteu.ingog@gmail.com>
Co-authored-by: Lisa Magdalena Riedler <git@riedler.wien>
Co-authored-by: Dalton Messmer <messmer.dalton@gmail.com>
2025-11-03 11:58:15 -06:00
..
2024-09-20 20:00:36 -04:00
2019-07-17 22:45:26 +02:00
2019-07-17 22:45:26 +02:00
2019-07-17 22:45:26 +02:00
2016-07-29 00:40:02 +02:00
2019-07-17 22:45:26 +02:00
2019-07-17 22:45:26 +02:00
2019-11-21 14:44:18 +01:00
2025-11-03 11:58:15 -06:00
2025-11-03 11:58:15 -06:00
2019-07-17 22:45:26 +02:00
2019-07-17 22:45:26 +02:00
2019-07-17 22:45:26 +02:00
2019-07-17 22:45:26 +02:00
2019-07-17 22:45:26 +02:00

Spectrum Analyzer plugin

Overview

This plugin consists of three widgets and back-end code to provide them with required data.

The top-level widget is SaControlDialog. It populates configuration widgets (created dynamically) and instantiates spectrum display widgets. Its main back-end class is SaControls, which holds all configuration values.

SaSpectrumView and SaWaterfallView widgets show the result of spectrum analysis. Their main back-end class is SaProcessor, which performs FFT analysis on data received from the Analyzer class, which in turn handles the interface with LMMS.

Threads

The Spectrum Analyzer is involved in three different threads:

  • Effect mixer thread: periodically calls Analyzer::processAudioBuffer() to provide the plugin with more data. This thread is real-time sensitive -- any latency spikes can potentially cause interruptions in the audio stream. For this reason, Analyzer::processAudioBuffer() must finish as fast as possible and must not call any functions that could cause it to be delayed for unpredictable amount of time. A lock-less ring buffer is used to safely feed data to the FFT analysis thread without risking any latency spikes due to a shared mutex being unavailable at the time of writing.
  • FFT analysis thread: a standalone thread formed by the SaProcessor::analyze() function. Takes in data from the ring buffer, performs FFT analysis and prepares results for display. This thread is not real-time sensitive but excessive locking is discouraged to maintain good performance.
  • GUI thread: periodically triggers paintEvent() of all Qt widgets, including SaSpectrumView and SaWaterfallView. While it is not as sensitive to latency spikes as the effect mixer thread, the paintEvent()s appear to be called sequentially and the execution time of each widget therefore adds to the total time needed to complete one full refresh cycle. This means the maximum frame rate of the Qt GUI will be limited to 1 / total_execution_time. Good performance of the paintEvent() functions should be therefore kept in mind.

Changelog

1.1.2	2019-11-18
	- waterfall is no longer cut short when width limit is reached
	- various small tweaks based on final review
1.1.1	2019-10-13
	- improved interface for accessing SaProcessor private data
	- readme file update
	- other small improvements based on reviews
1.1.0	2019-08-29
	- advanced config: expose hidden constants to user
	- advanced config: add support for FFT window overlapping
	- waterfall: display at native resolution on high-DPI screens
	- waterfall: add cursor and improve label density
	- FFT: fix normalization so that 0 dBFS matches full-scale sinewave
	- FFT: decouple data acquisition from processing and display
	- FFT: separate lock for reallocation (to avoid some needless waiting)
	- moved ranges and other constants to a separate file
	- debug: better performance measurements
	- various performance optimizations
1.0.3	2019-07-25
	- rename and tweak amplitude ranges based on feedback
1.0.2	2019-07-12
	- variety of small changes based on code review
1.0.1	2019-06-02
	- code style changes
	- added tool-tips
	- use const for unmodified arrays passed to fft_helpers
1.0.0	2019-04-07
	- initial release