* Adds a new native plugin for incoming waveform display
* Features the ability to pause, zoom in, set window size and set amplification (scale)
* Does not feature a pitch-tracking option
---------
Co-authored-by: Fawn <rubiefawn@gmail.com>
Co-authored-by: Sotonye Atemie <satemiej@gmail.com>
Co-authored-by: Dalton Messmer <messmer.dalton@gmail.com>
Co-authored-by: bratpeki <pkatic2003@gmail.com>
Allows detaching a window from LMMS's main window, making things like working on multiple screens easier.
The behavior of detached windows can be customized in the Settings.
Closes#1259
---------
Signed-off-by: Dalton Messmer <messmer.dalton@gmail.com>
Co-authored-by: Hyunjin Song <tteu.ingog@gmail.com>
Co-authored-by: Dalton Messmer <messmer.dalton@gmail.com>
Co-authored-by: SpomJ <mihail_a_m@mail.ru>
Closes#7869
This PR aims to fix linking bugs and it aims to make linking code faster. In the future I would like to replace controller and automation code with linked models, so it is essential for this feature to work as efficiently as possible.
Before this PR:
- AutomatableModels store a list of AutomatableModels that they are linked to.
- setValue() and other functions make recursive calls to themself resulting in the #7869 crash.
- Each AutomatableModel can unlink from other AutomatableModels, unlinking is the inverse operation to linking.
After this PR:
- AutomatableModels store a pointer to an other AutomatableModel making a linked list. The end is connected to the first element resulting in a "ring".
- setValue() and others are now recursion free, the code runs for every linked model, more efficiently than before.
- Each AutomatableModel can NOT unlink form other AutomatableModels, unlinking is NOT the inverse operation to linking. AutomatableModels can unlink themself from the linked list, they can not unlink themself from single models.
---------
Co-authored-by: allejok96 <allejok96@gmail.com>
Fixes#8152
Revert PianoRoll closing when empty (caused issues with detached windows)
Remove TextFloat warning when there are no instruments/multiple clips (showed up when reloading project)
(Keep clip creation for empty projects)
Add an icon and updated message in empty PianoRoll.
Mark PianoRollWindow invalid when there is no clip, making buttons impossible to click
---------
Co-authored-by: Fawn <rubiefawn@gmail.com>
This PR changes the way PatternClips are drawn in include a simple "beat preivew," where each note in any non-empty instrument tracks within the pattern are drawn as short little rectangles on the ClipView. SampleClips and AutomationClips within patterns are not currently supported.
The height of the note boxes changes depending on how many tracks there are in the pattern, and how many of them actually have notes (empty tracks are only drawn half as tall).
There is also some padding at the top and bottom along with a little bit of spacing between each note, both vertically and horizontally. This can be edited in the css, along with the note color.
---------
Co-authored-by: Dalton Messmer <messmer.dalton@gmail.com>
Co-authored-by: Fawn <rubiefawn@gmail.com>
* Centralize standard LMMS plugin logo
Previously, every single plugin would have its own copy of this image.
Now, these plugins pull it from the theme. I'm not sure it's valuable
for this to be themeable, but AFAIK it's the place all the other
non-plugin resources are stored, so that's where it goes for now.
* SVG-ify arrow buttons
These buttons are used in the instrument window, Vestige, and VST
effects. Separate versions of the arrow icons are used for the classic
theme.
* Fix some unrelated SVG formatting and metadata
* Revert accidental change to classic border radius
* Add some XML stuff back to appease Github
LMMS renders these SVGs just fine, but apparently the removal of the
XML declaration completely breaks Github's ability to render the image,
so I am adding these back for the sake of those who want to actually
look at the diff on the website lmao
* Attempt to fix Github SVG previews again (`xmlns`)
* Fix crossover eq band mute button icon size
You may ask, "what does this have to do with the arrow buttons?" and you
would be right to assume this is unrelated. However, I'm already
touching the relevant lines of the stylesheet so I may as well sneak it
in there.
* Add missing metadata to fader_knob.svg
And fix mixed indentation in headphones.svg
* Add missing `xmlns` to fader_knob.svg
GRADIENTS!!!!!!!!!!!!
* Fix classic theme arrow buttons
The originals were right angle chevrons
* Remove unused getters
* 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>
Given these changes, the knife tool now uses `Qt::SplitHCursor`, but `Qt::IBeamCursor` is also a a viable option. I am noting this should substantial concern arise over the appearance of `Qt::SplitHCursor` due to cursor themes, such as the default one applied to applications running under WSL.
This cleans up typos in source comments and some user-facing strings.
Found via `codespell -q 3 -S "./plugins,./src/3rdparty,./data/locale,*.in,*.xpf" -L continous,currenty,globaly,inports,localy,nd,ot,sie,te,trough`
Major changes:
- Remove Gate knob from effects, effectively hard coding its value to zero
- Replace effect RMS calculations with a more efficient way of detecting silent buffers
- Only perform silent buffer detection when `ProcessStatus::ContinueIfNotQuiet` is returned from a plugin AND auto-quit is enabled
Minor changes:
- Remove gate from presets
- Remove gate from .mmp projects
- Move `Effect::processorCount()` to `LadspaEffect`
- Rename `Effect::checkGate` to `Effect::handleAutoQuit`
- Adjust silence threshold for better compatibility with old RMS calculations
- Remove some unnecessary methods from `Effect`
- Reset quiet buffer count in `stopRunning`
- Use positive name for auto-quit boolean
- Simplify `m_autoQuitEnabled` initialization
Allow for splitting and resizing all types of clips (automation, MIDI, sample, pattern, etc) using the knife tool in the Song Editor.
---------
Co-authored-by: szeli1 <143485814+szeli1@users.noreply.github.com>
Co-authored-by: Dalton Messmer <messmer.dalton@gmail.com>
Added the ability to favorite items. This gets added to its own tab named "My Favorites".
---------
Co-authored-by: Sotonye Atemie <sakertooth@gmail.com>
Created and replaced missing/mismatched assets, fixed mixer send arrows causing mixer height to be wrong, tweaked CSS stylesheet to fix active mixer channel being black
* Add mute and solo buttons to instrument windows
* Change mute and solo buttons to optimized CC0 SVG assets
* Icons provided by @StakeoutPunch, button backgrounds provided by
@RebeccaDeField
---------
Co-authored-by: Sotonye Atemie <sakertooth@gmail.com>
Co-authored-by: Rebecca Noel Ati <contactme@rebeccadefield.com>
Co-authored-by: Stakeout Punch <StakeoutPunch@users.noreply.github.com>
* Fix rendering for Vectorscope
The rendering of the Vectorscope is broken on Wayland if the size of the
Vectorscope is increased. This is caused by using a `QImage` to render
the scope traces which is then scaled up.
Introduce a new way to paint the vector scope (goniometer) which simply
paints lines or points that progressively get dimmer and which does not
make use of a QImage anymore.
It supports the following features:
* Log mode
* Zooming
* Rendering the drawing performance
* Selecting a different color for the traces
It does not support:
* HQ Mode: The new implementation provides a performance that's
equivalent to Non-HQ mode and look similar or better than the HQ mode.
* Blurring of old data
* Persistence: Might be implemented by using a factor for the dimming
Rendering of the samples/trances uses the composition mode "Plus" so
that overlapping elements will appear like adding brightness. Painting
the grid and lines is done using the normal composition mode "Source
Over" so that it simply replaces existing pixels.
Painting of the lines/points and the grids and lines is done in a
"signal space", i.e. a transform where elements in the interval of
[-1, 1] feel "natural". The text is painted in "widget space".
* Remove old implementation
Remove HQ mode and persistence. Also remove the legacy option again.
This removes the models, loading, saving and the GUI controls.
Remove all unnecessary members from `VectorView`, adjust the
constructor. Move the implementation of `paintLinesMode` into
`paintEvent`. Remove methods `paintLegacyMode` and `paintLinesMode`.
* Move colors into VectorView
Move the colors out of `VecControls` into `VectorView` as they are
related to presentation.
* Remove friend relationship to VectorView
Remove a friend relationship to `VectorView` from `VecControls` by
introducing const getters for the models.
* Remove VectorView::m_visible
Remove the unnecessary member `m_visible` from `VectorView`. It was not
initialized and only written to but never read.
* Make Vectorscope themeable
Make the Vectorscope themeable by introducing Qt properties for the
relevant colors.
The default theme gets the values from the code whereas the classic
theme gets a trace with amber color.
* Rename m_colorFG
Rename `m_colorFG` to `m_colorTrace`. Adjust the Qt property
accordingly.
Remove local variable `traceColor` from paint method and use member
`m_colorTrace` directly.
* Remove m_colorOutline
Remove unused member `m_colorOutline`.
* Fix horizontal lines on silence
Fix the horizontal lines that are rendered on silence. They seem to be
produced when rendering lines that start and end at the same point.
Therefore we only draw a point if the current and last point are the
same.
* Add some margin to the VectorView
Add some margin to the rendering of the `VectorView` so that the circle
does not touch the bounary of the widget.
* Clean up the layout of the Vectorscope
Clean up the layout of the Vectorscope. The checkboxes are not put on
top of the vector view anymore but are organized in a horizontal layout
beneath it. This gives a much tidier look.
Put the elements of the `TrackOperationsWidget` into layouts. These are:
* The grip that can be used to move tracks
* The gear icon that opens the operations menu
* The mute button
* The solo button
The grip that can be used to move tracks around is extracted into its own class called `TrackGrip`. This has several advantages:
* It can be put into a layout.
* It can render itself at arbitrary sizes by simply repeating its pattern pixmap.
* It can be used in a much more object-oriented way because it emits signals when it is grabbed and released.
* It is responsible for locally updating its cursor state.
The default cursor of the grip now is an open hand which indicates to the users that it can be grabbed. While being grabbed the cursor now is a closed hand.
## Technical details
The class `TrackOperationsWidget` now holds an instance of `TrackGrip` and provides a getter to retrieve it. This getter is used by `TrackView` to connect to the two new signals `grabbed` and `released`. The method `TrackOperationsWidget::paintEvent` now only paints the background as it does not need to paint the grip anymore.
The `TrackView` now handles the grabbing and release of the grip in `TrackView::onTrackGripGrabbed` and `TrackView::onTrackGripReleased`. Because the events and cursor states are now handled by `TrackGrip` this code could be removed from `TrackView::mousePressEvent`.
There was a comment in `TrackView` which indicated that the `TrackOperationsWidget` had to be updated when the track is moved and released because it would hide some elements during the move. The comment and the corresponding code was removed because the operations widget does not hide its elements during moves (this was already the state before the changes made by this commit).
Adjust the style sheets of the classic and default themes with regards to the `QPushButton` that's used to show the gear menu in the `TrackOperationsWidget`. The `>` has been removed because the `QPushButton` is not a direct decendent of the `TrackOperationsWidget` anymore.
### Wrapping of `PixmapButton` in `QWidget`
The PixmapButtons that are used in `TrackOperationsWidget` current have to be wrapped into a `QWidget`. This is necessary due to some strange effect where the PixmapButtons are resized to a size that's larger than their minimum/fixed size when the method `show` is called in `TrackContainerView::realignTracks`. Specifically, with the default theme the buttons are resized from their minimum size of (16, 14) to (26, 26). This then makes them behave not as expected in layouts.
The resizing is not done for QWidgets. Therefore we wrap the PixmapButton in a QWidget which is set to a fixed size that will be able to show the active and inactive pixmap. We can then use the QWidget in layouts without any disturbances.
The resizing only seems to affect the track view hierarchy and is triggered by Qt's internal mechanisms. For example the buttons in the mixer view do not seem to be affected.
If you want to debug this simply override "PixmapButton::resizeEvent" and trigger a break point in there, e.g. whenever the new size is not (16, 14).
### More layout-friendly PixmapButton
Make the `PixmapButton` more friendly for layouts by implementing `minimumSizeHint`. It returns a size that accommodate to show the active and the inactive pixmap.
Also make `sizeHint` return the minimum size hint. The previous implementation would have made layouts jump when the pixmap is toggled with pixmaps of different sizes.
Align the rename line edit for tracks.
Make sure that the rename line edit of the `TrackLabelButton` has the
same font size as the widget itself. Because the font size is defined
via style sheets the font size of the line edit has to be set when the
actual renaming starts and not in the constructor. The reason is that
style sheets are set after the constructor has run.
Rename the local variable `txt` to the more speaking name `trackName`.
Ensure that the line edit is moved to the correct place for different
icon sizes by taking the icon size into account. To make this work this
also has to be done in the `rename` method.
## Other changes
Streamline the default style sheet of `TrackLabelButton` by removing
repeated properties that are inherited from the "main" style sheet, i.e.
that are already part of `lmms--gui--TrackLabelButton`.
Interestingly, the `background-color` property had to be repeated for
`lmms--gui--TrackLabelButton:hover`.
---------
Co-authored-by: Michael Gregorius <michael.gregorius.git@arcor.de>
* Initial Commit
* Refactor code and add new icons
* Fix logical error
* Add smooth scrolling to Song Editor
* Remove unused variable
* Fix scrolling speed and scrollbar width
* Remove QDebug and re-add a newline I deleted in an unrelated file
* Forgot to add files to commit
* Remove unused variable
* Fix Styling
* Fix Styling Again
* Fix Styling Again
* Fix Styling Again
* Add icons for classic theme
* Accidentally committed varying scroll speed with zoom -- removing
* Change abs to std::abs
Co-authored-by: saker <sakertooth@gmail.com>
* Change qMax to std::max and use static_cast
Co-authored-by: saker <sakertooth@gmail.com>
* Simplify stepped auto scrolling
Co-authored-by: saker <sakertooth@gmail.com>
* Remove unnecessary parentheses
* Remove return statement causing the play head line to stop
* Add specific tooltips to auto scrolling button states
* Remove `== true` from SongEditor.cpp
Co-authored-by: saker <sakertooth@gmail.com>
* Make tooltips translatable
Co-authored-by: Dominic Clark <mrdomclark@gmail.com>
* Fix zooming position calculation
* Rename bars to ticks
* Fix rubberband rect size
---------
Co-authored-by: saker <sakertooth@gmail.com>
Co-authored-by: Dominic Clark <mrdomclark@gmail.com>
Add peak indicators to the mixer strips. They show the maximum peak value
that was observed and can be reset by clicking on them.
## Implementation details
The implementation works via a signal/slot mechanism. The `Fader` class
has a new signal `peakChanged` which reports peak values as
amplifications. A new class `PeakIndicator` is added which has a slot
`updatePeak` which is connected to the new signal in `Fader`.
The `PeakIndicator` inherits from `QLabel` and mainly deals with updating
the label text from the current peak value.
Add a `PeakIndicator` instance to `MixerChannelView`. Add a `reset`
method to `MixerChannelView` so that the mixer channel can be reset on
the loading of new projects, etc. The current implementation resets the
peak indicator back to -inf dbFS. The `reset` method is called in
`MixerView::clear`.
Remove the clamping in `Fader::setPeak` so that all peaks are reported.
Emit the new signal if the peak changes.
* some css tweaks for accessibility
* suggestions from review
* classic theme focus
* fix bug where button color disappears on focus
* More scrollbar color changes on hover.
* Commented the hover effect for now.
* Remove handle "hover" effect.
* scrollbar
* revert button active state
* 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
* Render fader levels in code with a gradient
Render the fader level in code using a gradient instead of using pixmaps. The problem with the pixmaps is that they don't "know" how a fader instance is configured with regards to the minimum and maximum value. This means that the display can give quite a wrong impression.
The rendering of levels has been unified in the method `paintLevels`. It can render using dbFS and linear scale. The method `paintLinearLevels` has been removed completely, i.e. there's no more code that renders using pixmaps.
Much of the previous code relied on the size of the background image `fader_background.png`, e.g. the initialization of the size. For now the `Fader` widget is initially resized to the size of that background image as it is present in the default and classic theme (see `Fader::init`). All rendering uses the size of the widget itself to determine where to draw what. This means that the widget is prepared to be resizable.
The method `paintLevels` first renders the background of the level indicators and uses these as clipping paths for all other rendering operations, e.g. for the rendering of the levels themselves. Levels are rendered using a gradient which is defined with the following stops:
* Two stops for the ok levels.
* One stop for warning levels.
* One stop for clipping levels.
Peak indicators do not use the three distinct colors anymore but instead use the color of the gradient at that position of the peak. This makes everything look "smooth".
The code now also renders a marker at unity position, i.e. at position 1.0 in linear levels and 0 dbFS in dbFS scale.
The painting code makes lots of use of the class `PaintHelper`. This class is configured with a minimum and maximum value and can then return linear factors for given values. There are two supported modes:
* Map min to 0 and max to 1
* Map min to 1 and max to 0
It can also compute rectangles that correspond to a given value. These methods can be given rectangles that are supposed to represent the span from min to max. The returned result is then a rectangle that fills the lower part of the source rectangle according to the given value with regards to min and max (`getMeterRect`). Another method returns a rectangle of height 1 which lies inside the given source rectangle at the corresponding level (`getPersistentPeakRect`).
The method `paintLevels` uses a mapping function to map the amplitude values (current peak value, persistent peak, etc.) to the display values. There's one mapper that keeps the original value and it is used to display everything in a linear scale. Another mapper maps everything to dbFS and uses these values as display everything in a dbFS scale. The following values must be mapped for the left and right channel to make this work:
* Min and max display values (min and max peak values)
* The current peak value
* The persistent peak value
* The value for unity, i.e. 1.0 in linear levels and 0 dbFS in dbFS scale.
Remove the method `calculateDisplayPeak` which was used in the old method to render linear levels.
`Fader::setPeak` now uses `std::clamp` instead of doing "manual" comparisons.
The LMMS plugins Compressor, EQ and Delay are still configured to use linear displays. It should be considered to switch them to dbFS/logarithmic displays as well and to remove the code that renders linearly.
* Remove unused pixmaps from `Fader`
Remove the now unused pixmaps for the background and the LEDs from the `Fader` class and remove the files from the default and classic theme directories.
* Rename peak properties and use them to render levels
Rename the peak properties as follows:
* peakGreen -> peakOk
* peakRed -> peakClip
* peakYellow -> peakWarn
The reasoning is that a style might for example use a different color than green to indicate levels that are ok.
Use the properties to initialize the gradient that is used to render the levels.
Initialize the properties to the colors of the current default theme so that it's not mandatory to set them in a style sheet. Up until now they have all been initialized as black.
* Always render the knob in the middle of the fader
Render the knob in the middle of the fader regardless of the width. The previous implementation was dependent on the fader pixmap having a matching width because it always rendered at x=0.
* Set size policy of fader to minimum expanding
Set the size policy of the fader to minimum expanding in both directions. This will make the fader grow in layouts if there is space.
* Default dbFS levels and better peak values
Default to dbFS levels for all faders and set some better minimum and maximum peak values.
* Fix faders of Crossover EQ
Fix the faders of the Crossover EQ which were initialized and rendered much too wide and with a line at unity. The large width also resulted in the knobs being rendered outside of view.
Resize the fader to the minimum size so that it is constructed at a sane default.
Introduce a property that allows to control if the unity line is rendered. The property is available in style sheets and defaults to the unity lines being rendered. Adjust the paint code to evaluate the property.
Initialize the faders of the Crossover EQ such that the unity line is not drawn.
* Remove EqFader constructor with pixmaps
Remove the constructor of `EqFader` that takes the pixmaps to the fader background, leds and knob. The background and leds pixmaps are not used by the base class `Fader` for rendering anymore to make the `Fader` resizable. A pixmap is still used to render the knob but the constructor that takes the knob as an argument does not do anything meaningful with it, i.e. all faders are rendered with the default knob anyway.
Remove the resources for the fader background, leds and knob as they are not used and the knob was the same image as the default knob anyway.
Remove the static pixmaps from the constructor of `EqControlsDialog`. Switch the instantiations of the EQ's faders to use the remaining constructor of `EqFader`. This constructor sets a different fixed size of (23, 116) compared to the removed constructor which set a size of (23, 80). Therefore all faders that used the removed constructor are now set explicitly to a fixed size of (23, 80).
The constructor that's now used also calls a different base constructor than the removed one. The difference between the two base constructors of `Fader` is that one of them sets the member `m_conversionFactor` to 100.0 whereas the other one keeps the default of 1.0. The adjusted faders in `EqControlsDialog` are thus now constructed with the conversion factor set to 100. However, all of them already call `setDisplayConversion` with `false` after construction which results in the conversion factor being reset to 1.0. So the result should be the same as before the changes.
* Remove background and LEDs pixmap from Fader constructor
Remove the parameters for the background and LEDs pixmap from the second `Fader` constructor. Make the knob pixmap parameter in the constructor a const reference. Assign the reference to the knob pixmap of the `Fader` itself. This enables clients to use their own fader knobs as is the case with the Crossover EQ. The EQ now renders using it's own knobs again.
Make the second constructor delegate to the first one. This will additionally set the conversion factor to 100 but this is not a problem with the current code because the only user of the second constructor, the Crossover EQ, already calls `setDisplayConversion` with the parameter set to `false`, hence reinstating a conversion factor of 1.
Remove the resources for the background and LEDs from the Crossover EQ as they are not used anymore. Remove the three QPixmap members from `CrossoverEQControlDialog` as they are not needed. The background and LEDs are not used anyway and the knob is passed in as a constant reference which is copied. Hence we can use a local variable in the constructor of `CrossoverEQControlDialog`.
* Remove the init method from Fader
Remove the `init` method from `Fader` as it is not needed anymore due to the constructor delegation. Tidy up the parameter lists and use of spaces in the constructor.
* Introduce range with solid warn color
Introduce a second point in the gradient for the warn colors so that we get a certain range with the full/solid warn color.
The colors are distributed as follows now. The solid ok range goes from -inf dbFS to -12 dbFS. The warn range goes from -6 dbFS to 0 dbFS. In between the colors are interpolated. Values above 0 dbFS interpolate from the warn color to the clip color.
This is now quite similar to the previous implementation.
# Analysis of the previous pixmap implementation
The pixmap implementation used pixmaps with a height of 116 pixels to map 51 dbFS (-42 dbFS to 9 dbFS) across the whole height. The pixels of the LED pixmap were distributed as follows along the Y-axis:
* Margin: 4
* Red: 18
* Yellow: 14
* Green: 76
* Margin: 4
Due to the margins the actual red, yellow and green areas only represent a range of (1 - (4+4) / 116) * 51 ~ 47,48 dbFS. This range is distributed as follows across the colors:
Red: 7.91 dbFS
Yellow: 6.16 dbFS
Green: 33.41 dbFS
The borders between the colors are located along the following dbFS values:
* Red/yellow: 9 - (4 + 18) / 116 * 51 dbFS ~ -0.67 dbFS
* Yellow/green: 9 - (4 + 18 + 14) / 116 * 51 dbFS ~ -6.83 dbFS
* The green marker is rendered for values above -40.24 dbFS.
* Remove unused method Fader::clips
* Fader: Correctly render arbitrary ranges
Adjust the `Fader` so that it can correctly render arbitrary ranges of min and max peak values, e.g. that it would render a display range of [-12 dbFS, -42 dbFS] correctly.
Until now the gradient was defined to start at the top of the levels rectangle and end at the bottom. As a result the top was always rendered in the "clip" color and the bottom in the "ok" color. However, this is wrong, e.g. if we configure the `Fader` with a max value of -12 dbFS and a min value of -42 dbFS. In that case the whole range of the fader should be rendered with the "ok" color.
The fix is to compute the correct window coordinates of the start and end point of gradient using from the "window" of values that the `Fader` displays and then to map the in-between colors accordingly. See the added comments in the code for more details.
Add the templated helper class `LinearMap` to `lmms_math.h`. The class defines a linear function/map which is initialized using two points. With the `map` function it is then possible to evaluate arbitrary X-coordinates.
* Remove unused methods in PaintHelper
Remove the now unused mapping methods from `PaintHelper`. Their functionality has been replaced with the usage of `LinearMap` in the code.
* Fix some builds
Include `cassert` for some builds that otherwise fail.
* Opaque unity marker with styling option
Make the unity marker opaque by default and enable to style it with the style sheets. None of the two style sheets uses this option though.
* Darker default color for the unity line
* Move code
Move the computation of most mapped values at the top right after the definition of the mapper so that it is readily available in all phases of the painting code.
* Render unity lines in background
Render the unity lines before rendering the levels so that they get overdrawn and do not stick out when they are crossed.
* Don't draw transparent white lines anymore
Don't draw the transparent white lines anymore as they were mostly clipped anyway and only create "smudge".
* Full on clip color at unity
Adjust the gradient so that the full on clip color shows starting at unity. There is only a very short transition from the end of warning to clipping making it look like a solid color "standing" on top of a gradient.
* Fix discrepancy between levels and unity markers
This commit removes the helper class `PaintHelper` and now uses two lambdas to compute the rectangles for the peak indicators and levels. It uses the linear map which maps the peak values (in dbFS or linear) to window coordinates of the widget.
The change fixes a discrepancy in the following implementation for which the full on clip rectangle rendered slightly below the unity marker.
* Fix fader display for Equalizer shelves and peaks
The peak values for the shelves and peaks of the Equalizer plugin are computed in `EqEffect::peakBand`. The previous implementation evaluated the bins of the corresponding frequency spectrum and determined the "loudest" one. The value of this bin was then converted to dbFS and mapped to the interval [0, inf[ where all values less or equal to -60 dbFS were mapped to 0 and a value of 40 dbFS was mapped to 1. So effectively everything was mapped somewhere into [0, 1] yet in a quite "distorted" way because a signal of 40 dbFS resulted in being displayed as unity in the fader.
This commit directly returns the value of the maximum bin, i.e. it does not map first to dbFS and then linearize the result anymore. This should work because the `Fader` class assumes a "linear" input signal and if the value of the bin was previously mapped to dbFS it should have some "linear" character. Please note that this is still somewhat of a "proxy" value because ideally the summed amplitude of all relevant bins in the frequency range would be shown and not just the "loudest" one.
## Other changes
Rename `peakBand` to `linearPeakBand` to make more clear that a linear value is returned.
Handle a potential division by zero by checking the value of `fft->getEnergy()` before using it.
Index into `fft->m_bands` so that no parallel incrementing of the pointer is needed. This also enables the removal of the local variable `b`.
* Improve the rendering of the levels
The levels rendering now more explicitly distinguished between the rendering of the level outline/border and the level meters. The level rectangles are "inset" with regards to the borders so that there is a margin between the level borders and the meter readings. This margin is now also applied to the top and bottom of the levels. Levels are now also rendered as rounded rectangles similar to the level borders.
Only render the levels and peaks if their values are greater than the minimum level.
Make the radius of the rounded rectangles more pronounced by increasing its value from 1 to 2.
Decrease the margins so that the level readings become wider, i.e. so that they are rendered with more pixels.
Add the lambda `computeLevelMarkerRect` so that the rendering of the level markers is more decoupled from the rendering of the peak markers.
* Reduce code repetition
Reduce code repetition in `EqEffect::setBandPeaks` by introducing a lambda. Adjust code formatting.
* Code review changes
Code review changes in `Fader.cpp`. Mostly whitespace adjustments.
Split up the calculation of the meter width to make it more understandable. This also reduces the number of parentheses.
* Use MEMBER instead of READ/WRITE
Use `MEMBER` instead of `READ`/`WRITE` for some properties that are not called explicitly from outside of the class.
* Use default member initializers for Fader
Use default member initializers for the members in `Fader` that have previously been initialized in the constructor list.
* Make code clearer
Make code clearer in `Fader::FadermouseDoubleClickEvent`. Only divide if the dialog was accepted with OK.
Enable to set different colors for the oscilloscope channels:
* Left channel color
* Right channel color
* Color of all other channels
The clipping color is now used per channel, i.e. if the left channel clips but the right does not then only the signal of the left channel is painted in the clipping color.
Enable setting the colors in the style sheets and adjust the style sheets of the default and classic theme accordingly.
# Extend TabWidget's style sheet options
Extend the `TabWidget` class so that the text color of the selected tab
can be set in the style sheet. Adjust the paint method to make use of
the new property.
Adjust the default style sheet as follows:
* Background color of the selected tab is the green of the knobs
* Text color of the selected tab is full on white
Adjust the classic style sheet in such a way that nothing changes, i.e.
the text colors of the selected tab and the other ones are the same.
# Code review style changes
Completely adjust the code style of TabWidget:
* Pointer/reference close to type
* Remove underscores from parameter names
* Remove spaces from parentheses
* Add space after if and for statements
# Remove repeated iterator dereferences
Remove repeated iterator dereferences by introducing variables with speaking names.
Fixes#6730.
Use Qt layouts for the mixer channels. These changes will enable several other improvements, like for example making the mixer and faders resizable, adding peak indicators, etc.
This is a squash commit which consists of the following individual commits:
* Remove extra transparency in send/receive arrows
The extra transparency was conflicting with the positioning of
the arrows in the layout
* Begin reimplementing MixerChannelView
MixerChannelView is now a combination of the
MixerLine with the previous MixerChannelView
* Adjust SendButtonIndicator to use MixerChannelView
* Remove MixerLine
- Move MixerChannelView into src/gui
* Remove MixerView::MixerChannelView
* Remove header of MixerLine
* Change MixerView.h to use MixerChannelView
Change MixerView.h to use MixerChannelView rather than MixerLine
Also do some cleanup, such as removing an unused forward declaration
of QButtonGroup
* Create EffectRackView
+ Set height of sizeHint() using MIXER_CHANNEL_HEIGHT (287)
* Remove include of MixerLine
- Include MixerChannelView
* Phase 1: Adjust MixerView to use new MixerChannelView
* Move children wigets into header file
* Phase 2: Adjust MixerView to use new MixerChannelView
* Phase 3: Adjust MixerView to use new MixerChannelView
* Phase 4: Adjust MixerView to use new MixerChannelView
* Phase 5: Adjust MixerView to use new MixerChannelView
* Phase 5: Adjust MixerView to use new MixerChannelView
* Remove places where MixerChannelView is being deleted
Before, MixerChannelView was not inherited by QWidget,
meaning it could not have a parent and had to be deleted
when necessary. Since the MixerView owns the
new MixerChannelView, this is no longer necessary.
* Replace MixerLine with MixerChannelView
- Include MixerChannelView in MixerView
* Replace setCurrentMixerLine calls with setCurrentMixerChannel around codebase
* Add event handlers in MixerChannelView
* Implement MixerChannelView::eventFilter
* Update theme styles to use MixerChannelView
* Add QColor properties from style
- Set the Qt::WA_StyledBackground attribute on
* Add effect rack to rack layout when adding channel
* Set size for MixerChannelView
- Change nullptr to this for certain widgets
- Some custom widgets may expect there to be a parent
- Add spacing in channel layout
- Increase size of mixer channel
* Retain size when widgets are hidden
* Implement paintEvent
- Rename states in SendReceiveState
* Implement send/receive arrow toggling
- Make maxTextHeight constexpr in elideName
- Remove background changing on mouse press
(is now handled in paintEvent)
* Implement renaming mixer channels
* Implement color functions
* Implement channel moving/removing functions
* Do some cleanup
Not sure if that connection with the mute model was needed, but removing
it did not seem to introduce any issues.
* Include cassert
* Replace references to MixerLine with MixerChannelView
* Reduce height
+ Make m_renameLineEdit transparent
+ Retain size when LCD is hidden
+ Remove stretch after renameLineEdit in layout
* Remove trailing whitespace
* Make m_renameLineEdit read only
+ Transpose m_renameLineEditView rectangle (with 5px offset)
* Set spacing in channel layout back to 0
* Remove sizeHint override and constant size
* Use sizeHint for mixerChannelSize
+ Leave auto fill background to false in MixerChannelView
+ Only set width for EffectRackView
* Set margins to 4 on all sides in MixerChannelView
* Move solo and mute closer to each other
Move the solo and mute buttons closer to each other in the mixer channels.
Technically this is accomplished by putting them into their own layout with minimal margins and spacing.
* Fixes for CodeFactor
* Code review changes
Mostly whitespace and formatting changes: remove tabs, remove spaces in parameter lists, remove underscores from parameter names.
Some lines have been shortened by introducing intermediate variables, e.g. in `MixerChannelView`.
`MixerView` has many changes but only related to whitespace. Spaces have been introduced for if and for statements. Whitespace at round braces has been removed everywhere in the implementation file even if a line was not touched by the intial changes.
Remove duplicate forward declaration of `MixerChannelView`.
* Adjust parameter order in MixerChannelView's constructor
Make the parent `QWidget` the first parameter as it is a Qt convention. The default parameter had to be removed due to this.
* Move styling of rename line edit into style sheets
Move the style of the `QGraphicsView` for the rename line edit from the code into the style sheets of the default and classic theme.
* More code review changes
Fix spaces between types and references/pointers, e.g. use `const QBrush& c` instead of `const QBrush & c`.
Remove underscores from parameter names.
Remove spaces near parentheses.
Replace tabs with spaces.
Introduce intermediate variable to resolve "hanging" + operator.
Replace the connection for the periodic fader updates with one that uses function pointers instead of `SIGNAL` and `SLOT`.
---------
Co-authored-by: Michael Gregorius <michael.gregorius.git@arcor.de>
* Initial Commit
Starts implementing Note Types. The two available types are
RegularNote and StepNote. PianoRoll now paints the color with a
different color for StepNotes. Pattern::addStep now sets the type of the
note to StepNote.
Negative size is still used to signal a step note.
* Update Pattern.cpp to account for the Note::Type
Updates the methods noteAtStep(), addStepNote() and checkType()
from Pattern.cpp to account for the note type and not the note length.
* Update PatternView::paintEvent to draw step notes
PatternView::paintEvent now draws the pattern if the pattern
type is BeatPattern and TCOs aren't fixed (Song Editor). Color used is
still the BeatPattern color (grey) and the conditional doesn't look very
nice and can be improved.
Pattern::beatPatternLength was also updated so it accounts for
the note type not note length. Review this method, as it looks a bit
weird (particularly the second conditional).
* Implements StepNotes setting a NPH with 0 frames
Now, instead of TimePos returning 0 for negative lengths, we
create a NotePlayHandle with 0 frames when the note type is StepNote on
InstrumentTrack::play.
* Improves PatternView::paintEvent conditional
Improves a conditional inside PatternView::paintEvent by
reversing the order in which they are executed.
* Adds upgrade method for backwards compatibility
Adds an upgrade method that converts notes with negative length
to StepNotes, so old projects can be loaded properly.
Explicitly set the Note::RegularNote value as 0.
Make the default "type" value "0", so notes without a type are
loaded as RegularNotes.
* Addresses Veratil's review
- Changes "addStepNote" so "checkType" isn't called twice in a
row.
- Changes style on a one line conditional.
* Uses ternary expression on statement
Reduces number of lines by using ternary expression.
* Addresses PR review (sakertooth)
- Changes class setter to inline
- Uses enum class instead of enum
- Uses auto and const where appropriate
* Finished changes from review (sakertooth)
- Used std::max instead of qMax
- Fixed style on lines changed in the PR
* Uses std::find_if to save codelines
As suggested by sakertooth, by using std::find_if we are able to
simplify the checkType method to two lines.
* Addresses review from sakertooth
- Reverts m_detuning in-class initialization
- Removes testing warning
- Removes unnecessary comment
* Addresses DomClark's review
- Rename the Note Types enum to avoid redundancy
- Uses std::all_of instead of std::find_if on MidiClip checkType
- Rewrites addStepNote so it sets the note type before adding it
to the clip, avoiding having to manually change the type of the clip
after adding the note
* Updates MidiExport to use Note Types
- Now MidiExport is updated to use note types instead of relying
on negative length notes.
- For that change it was necessary to find a way of letting
MidiExport know how long step notes should be. The solution found was to
add an attribute to the Instrument XML called "beatlen", which would
hold the number of frames of the instrument's beat. That would be
converted to ticks, so we could calculate how long the MIDI notes would
have to be to play the whole step note. If the attribute was not found,
the default value of 16 ticks would be used as a length of step notes,
as a fallback.
* Fixes ambiguity on enum usage
Due to changes in the name of enum classes, there was an
ambiguity caused in NotePlayHandle.cpp. That was fixed.
* Addresses new code reviews
- Addresses code review from PhysSong and Messmerd
* Fixes note drawing on Song Editor
- Notes were not being draw on the song editor for BeatClips.
This commit fixes this.
* Adds cassert header to TimePos.cpp
- Adds header to use assert() on TimePos.cpp
* Apply suggestions from code review
Fixes style on some lines
Co-authored-by: Dalton Messmer <33463986+messmerd@users.noreply.github.com>
* Reverts some changes on MidiExport
- Some changes were reverted on MidiExport and InstrumentTrack.
We were storing the beat length on the XML of Instrument Tracks, but in
reality the beat length is a per note attribute, and some instruments
could run into a segmentation fault when calling beat length without a
NotePlayHandle (i.e.: AFP). Because of that I reverted this change, so
the beat length is not stored on the XML anymore, and instead we have a
magic number on the MidiExport class that holds a default beat length
which is actually an upper limit for the MIDI notes of step notes. In
the future we can improve this by finding a way to store the beat length
on the note class to use it instead. The MidiExport logic is not
worsened at all because previously the beat length wasn't even
considered during export (it was actually improved making the exported
notes extend until the next one instead of cutting shorter).
* Fix the order of included files
---------
Co-authored-by: Dalton Messmer <33463986+messmerd@users.noreply.github.com>
* Added floating-point vorbis BPM tags to files in lmms/data/samples/beats
* Added rounded BPM to filenames, surrounded by square brackets and separated from the rest of the filename by an underscore