Commit Graph

8050 Commits

Author SHA1 Message Date
Pascal
d5f5d00a6f Fix shifting of sample waveform during zoom (#7222)
The original code was doing division in `int`, which causes lost of accuracy and results in the waveform randomly shifting when zooming in and out.

This should fix it by casting variables to `float` before dividing, as well as keeping the values in `float` type.

The pull request also changes some type declaration to explicit to increase readability
2024-05-01 20:13:55 -04:00
Michael Gregorius
9ca9143f5b Fix upgrade routine for BPM renamings (#7235)
Fix the upgrade routine that was introduced with pull request #6747 which added the BPM value to some file names.

This also simplifies the implementation by using a map.

Note: this also removes the code about the prefix `factorysample:`. If it is used in some files these entries will also have to be added to the map.
2024-05-01 18:03:35 +02:00
Michael Gregorius
bb6a77aa0f Only set sample clips for valid files (#7224)
Check if a non-empty buffer was loaded and only set the sample clip if that's the case.

## Other changes

Move setting the song to modified towards the core in the context of `SampleClip`. Previously the `SampleClipView` did this but it's none of it's business.

Introduce `SampleClip::changeLengthToSampleLength` which changes the length of the clip to the length of the sample. This was also previously done by the view which is again the wrong place to do the necessary calculations. An unnecessary `static_cast` was removed while carrying over the code.

Add the method `SampleClip::hasSampleFileLoaded` which checks if the loaded sample corresponds to a given file name.

Fix code formatting.
2024-04-29 19:22:37 +02:00
Michael Gregorius
c0a4df49a2 Lb302: Consistent decay in time (#7230)
The previous implementation of Lb302`s decay used a fixed decay factor that was multiplied with the signal until the minimum threshold of 1/65536 was crossed. This fixed factor resulted in different lengths in time for different sample rates.

This is fixed by computing the decay factor by taking the sample rate into account as well. The new static method `computeDecayFactor` computes the factor that is needed to make a signal decay from 1 to a given attenuation over a given time.

The parameters used in the call to that method in `Lb302Synth::process` have been fine-tuned such that, at a sample rate of 44.1 kHz, they result in a factor very close to the previous hard-coded factor of 0.99897516.
2024-04-29 16:47:17 +02:00
Michael Gregorius
86363819c5 Fix Kicker's release stage (#7226)
When applying its release stage Kicker did not take the frames before the release into account but instead always applied the release to the full buffer. This potentially lead to a jump in the attenuation values instead of a clean linear decay.

See #7225 for more details.
2024-04-27 21:17:12 +02:00
Michael Gregorius
5c0db46a60 Streamline instrument flags (#7227)
## Instrument flags as a property of an instrument
The instruments flags (single streamed, MIDI based, not bendable) are properties of an instrument that do not change over time. Therefore the flags are made a property of the instrument which is initialized at construction time.

Adjust the constructors of all instruments which overrode the `flags` method to pass their flags into the `Instrument` constructor.

## Add helper methods for flags
Add helper methods for the flags. This makes the code more concise and readable and clients do not need to know the technical details on how to evaluate a flag.

## Remove the flags methods
Remove the flags methods to make it an implementation detail on how the flags are managed.
2024-04-27 17:45:55 +02:00
Rossmaxx
6c846684cd Replace call QT5_WRAP_UI with CMAKE_AUTOUIC (#7200) 2024-04-27 16:21:09 +01:00
saker
a53e5ba2f6 Remove high quality mode from codebase (#7219)
Many, many years ago (93a456c), high quality mode was merely disabled after it was noted that it can be problematic rather than being completely removed. Remove it from the codebase so we can get rid of some code and clean things up a bit.
2024-04-27 07:59:02 -04:00
Michael Gregorius
71dd300f43 Instrument release time in milliseconds (#7217)
Make instruments report their release time in milliseconds so that it becomes independent of the sample rate and sounds the same at any sample rate.

Technically this is done by removing the virtual keyword from `desiredReleaseFrames` so that it cannot be overridden anymore. The method now only serves to compute the number of frames from the given release time in milliseconds.

A new virtual method `desiredReleaseTimeMs` is added which instruments can override. The default returns 0 ms just like the default implementation previously returned 0 frames.

The method `computeReleaseTimeMsByFrameCount` is added for instruments that still use a hard coded release in frames. As of now this is only `SidInstrument`.

Add the helper method `getSampleRate` to `Instrument`.

Adjust several instruments to report their release times in milliseconds. The times are computed by taking the release in frames and assuming a sample rate of 44.1 kHz. In most cases the times are rounded to a "nice" next value, e.g.:
*  64 frames -> 1.5 ms (66 frames)
* 128 frames -> 3.0 ms (132 frames)
* 512 frames -> 12. ms (529 frames)
* 1000 frames -> 23 ms (1014 samples)

In parentheses the number of frames are shown which result from the rounded number of milliseconds when converted back assuming a sample rate of 44.1 kHz. The difference should not be noticeable in existing projects.

Remove the overrides for instruments that return the same value as the base class `Instrument` anyway. These are:
* GigPlayer
* Lb302
* Sf2Player

For `MonstroInstrument` the implementation is adjusted to behave in a very similar way. First the maximum of the envelope release times is computed. These are already available in milliseconds. Then the maximum of that value and 1.5 ms is taken and returned as the result.
2024-04-24 20:23:36 +02:00
Kevin Zander
62e2a39a7e SlicerT::findSlices - check if lower_bound did not find anything 2024-04-23 17:02:23 -05:00
Dominic Clark
bda042e1eb Add native system semaphore and Windows shared memory (#7212) 2024-04-20 23:21:29 +01:00
Rossmaxx
df11a98902 Bump Qt minimum version to 5.9 (#7204)
* bump qt minimum version to 5.9

* cleanup cmake checks

* Remove the obsoleted check.

* Missed this while removing the check.
2024-04-17 21:51:58 -04:00
Michael Gregorius
d5e1d9e853 Move icon determination into TrackLabelButton again (#7209)
Move icon determination into TrackLabelButton again

Fully undo the changes made in commit 88e0e94dcd because the intermediate revert made in commit 04ecf73395 seems to have led to a performance problem due to the icon being set over and over again in `TrackLabelButton::paintEvent`.

The original intention of the changes made in pull request #7114 was to remove the painting code that dynamically determines the icon over and over again. Ideally the icon that is used by an instrument should be somewhat of a "static" property that should be known very early on when an instrument view is created. There should not be any need to dynamically resolve the icon over and over, especially not in a button class very far down in the widget hierarchy. However, due to technical reasons this is not the case in the current code. See pull request #7132 for more details.
2024-04-17 19:21:23 +02:00
Michael Gregorius
d2c2a80506 Update CMT submodule / Upgrade code for CMT delays (#7206)
## Bump CMT to d8bf8084aa3
Bump the CMT submodule to commit d8bf8084aa3 which contains the underlying fixes for issue #5167.

The CMT delay uses `sprintf` calls to generate the technical names and display names of the delays. These calls are locale dependent. As a consequence for example the feedback delay might have been saved either as "fbdelay_0.1s" (point) or "fbdelay_0,1s" (comma) in a save file.

The CMT fix makes sure that all delays use points in their names and thus that they now always report the same name strings.

## Add upgrade routine for CMT delays
Add an upgrade routine for CMT delays which works in conjunction with the upgraded CMT submodule. Because the delays will now always report their name with points old save files which might contain versions with the comma must be upgraded to a name with a point.
2024-04-14 18:03:39 +02:00
Dominic Clark
d3ab31558c Support VSTs on Linux even if Wine is unavailable (#7205) 2024-04-14 12:54:10 +01:00
Michael Gregorius
815f88dd09 Scalable LFO graph (#7203)
## Scalable LFO graph
Make the rendering of the LFO graph scalable. Change the fixed size to a minimum size. Adjust the rendering code such that it uses the width and height of the widget instead of the background pixmap.

Only draw only poly line once instead of many line segments. Collect the points in the for-loop to be able to do so. This makes the code a bit more understandable because we now compute exacly one point per iteration in the for-loop.

Use the same interpolation for the line color like in the envelope graph.

Rename some variables to make them consistent with the other code.

Remove the member `m_params` which is not used anyway. This also allows for the removal of the overridden `modelChanged` method.

## Use "Hz" instead of "ms/LFO"
Use the more common unit "Hz" to display the frequency of the LFO instead of "ms/LFO". The frequency is always displayed with three digits after the decimal separator to prevent "jumps".

## Take "Freq * 100" into account
This commit fixes a bug where the "Freq * 100" option was not taken into account when computing and displaying the frequency of the LFO.

## Keep info text legible
Draw a slightly transparent black rectangle underneath the text to keep it legible, e.g. for high frequencies with an LFO amount of 1 which results in a very bright and dense graph.

## Extract drawing of info text into method
Extract the drawing of the info text into its own private method `drawInfoText`.
2024-04-14 10:31:27 +02:00
Michael Gregorius
8e40038a2d Scalable envelope graph (#7194)
Make the graph scalable by adjusting the painting code of the envelope so that it does not assume fixed widths and heights anymore. Remove the setting of a fixed size from the envelope graph and only set a minimum size.

Make three scaling modes available which can be selected via a context menu in the graph:
* "Dynamic": This modes corresponds to the rendering strategy of the previous implementation. Initially 80/182 of the available width is used as the maximum width per segment. This can be interpreted like a "zoomed" version of the absolute mode. If the needed space becomes larger than the full width though then it falls back to relative rendering.
* "Absolute": Each of the five segments is assigned 1/5 of the available width. The envelopes will always fit but might appear small depending of the current settings. This is a good mode to compare envelopes though.
* "Relative": If there is at least one non-zero segment then the whole width is always used to present the envelope.

The default scaling mode is "Dynamic".

## Technical details

The new painting code is more or less divided into two parts. The first part calculates `QPointF` instances for the different points. In the second part these points are then used to draw the lines and markers. This makes the actual rendering code much more straight forward, readable and maintainable.

The interpolation between the line color of an inactive and an active envelope has also been restructured so that it is much more obvious that we are doing an interpolation in the first place. The colors at both ends of the interpolation are explicit now and can therefore be adjusted much easier. The actual color interpolation is done in the helper function `interpolateInRgb` which is provided by the new class `ColorHelper`. This class will later also be needed when the LFO graph is made scalable.

The line is rendered as a polyline instead of single line segments.

The drawing of the markers has been abstracted into a lambda (with some outside captures though) so that it can be easily adjusted if necessary. The markers are rendered as circles instead of rectangles because that looks much nicer especially when the widget is rendered at a larger size.

The width of the lines and marker outlines is determined using the size of the widget so that it scales with the size.

A `lerp` function has been added to `lmms_math.h`.
2024-04-11 17:49:00 +02:00
Levin Oehlmann
1f5f28fd8a Don't auto-quantize notes when recording MIDI input (#6714)
* Don't auto-quantize notes when recording MIDI input.

* Add midi:autoquantize to config file and a widget to set it in the MIDI settings.

* Quantize notes during recording if midi:autoquantize is enabled.

* Apply suggestions from code review: Formatting

Style formatting

Co-authored-by: saker <sakertooth@gmail.com>

* Cache the auto quantization setting in a PianoRoll member variable, and update it on ConfigManager::valueChanged()

* Apply suggestions from code review: Formatting & temp variable

One formatting change, and reusing an existing variable instead of introducting a new local one.

Co-authored-by: saker <sakertooth@gmail.com>
Co-authored-by: IanCaio <iancaio_dev@hotmail.com>

* Update src/gui/modals/SetupDialog.cpp

Good catch.

Co-authored-by: IanCaio <iancaio_dev@hotmail.com>

* Fix logic bug in PianoRoll's midi/autoquantize value observer.

* Use '!' instead of 'not' to please MSVC.

* autoquantize: Add an explicit check for consistency with the rest of the PR, and give the setting a default value in SetupDialog constructor.

* Integrate MIDI auto-quantize checkbox into the resizable layout, and add a tool tip.

---------

Co-authored-by: saker <sakertooth@gmail.com>
Co-authored-by: IanCaio <iancaio_dev@hotmail.com>
2024-04-08 19:17:26 -04:00
Michael Gregorius
2472e9ee4e GUI adjustments around base velocity (#7196)
Change the label of the group box from "CUSTOM BASE VELOCITY" to "VELOCITY MAPPING".

Remove the long explanation text from the group box and add the following tool tip for the LcdSpinBox: "MIDI notes at this velocity correspond to 100% note velocity."

Change the label of the spin box from "BASE VELOCITY" to "MIDI VELOCITY" because that's what the value actually represents.
2024-04-05 17:24:28 +02:00
Michael Gregorius
922eb7f2ba Fix NaNs for some dbFS value displays (-∞ dbFS) (#7142)
Fix some NaNs in the context of the display of dbFS values when "View > Volume as dbFS" is checked. They occur during the display of the current value when a mixer fader or the volume knob of an instrument is pulled down completely.

The fix is to detect these cases and to display "-∞ dbFS".

Also fix a problem with the editor where dbFS values can be entered for volume knobs. When the knob is turned completely to the left and the amplification is 0 then the initially displayed value is set to -96 dBFS, i.e. the lower limit that is shown in the dialog. This is done because the dialog likely cannot handle displaying or entering "-∞".
2024-04-05 13:15:48 +02:00
Michael Gregorius
ba4fda7c97 Scalable consistent faders with themeable gradients, marker at unity, dbFS by default (#7045)
* 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.
2024-04-05 12:48:46 +02:00
Michael Gregorius
d447cb0648 Use layouts for the instrument sound shaping tab / Extract classes for Envelope and LFO graphs (#7193)
Move the envelope and LFO graphs into their own classes.

Besides the improved code organization this step had to be done to be able to use layouts in `EnvelopeAndLfoView`. The class previously had fixed layouts mixed with custom rendering in the paint event. Mouse events are now also handled in both new classes instead of in `EnvelopeAndLfoView`.

## Layouts in EnvelopeAndLfoView
Use layouts to align the elements of the `EnvelopeAndLfoView`. This removes lots of hard-coded values. Add helper lambdas for the repeated creation of `Knob` and `PixmapButton` instances.

The spacing that is explicitly introduced between the envelope and LFO should be removed once there is a more open layout.

## Layouts for InstrumentSoundShapingView
Use layouts to align the elements of the `InstrumentSoundShapingView`.

## Info text improvements in LFO graph
Draw the info text at around 20% of the LFO graph's height. This prepares the dialog to be scaled later.

Write "1000 ms/LFO" instead of "ms/LFO: 1000" with a larger gap.

## Accessors for EnvelopeAndLfoParameters
Make the enum `LfoShape` in `EnvelopeAndLfoParameters` public so that it can be used without friend declarations. Add accessor methods for the model of the LFO.

## Other improvements
* Adjust include orders
* Variable initialization in headers
* Prevention of most vexing parses
2024-04-05 11:25:39 +02:00
Michael Gregorius
20fec28bef Font size adjustments (#7185)
Adjust and rename the function `pointSize` so that it sets the font size in pixels. Rename `pointSize` to `adjustedToPixelSize` because that's what it does now. It returns a font adjusted to a given pixel size. Rename `fontPointer` to `font` because it's not a pointer but a copy. Rename `fontSize` to simply `size`.

This works if the intended model is that users use global fractional scaling. In that case pixel sized fonts are also scaled so that they should stay legible for different screen sizes and pixel densities.

## Adjust plugins with regards to adjustedToPixelSize

Adjust the plugins with regards to the use of `adjustedToPixelSize`.

Remove the explicit setting of the font size of combo boxes in the following places to make the combo boxes consistent:
* `AudioFileProcessorView.cpp`
* `DualFilterControlDialog.cpp`
* `Monstro.cpp` (does not even seem to use text)
* `Mallets.cpp`

Remove calls to `adjustedToPixelSize` in the following places because they can deal with different font sizes:
* `LadspaBrowser.cpp`

Set an explicit point sized font size for the "Show GUI" button in `ZynAddSubFx.cpp`

Increase the font size of the buttons in the Vestige plugin and reduce code repetition by introducing a single variable for the font size.

I was not able to find out where the font in `VstEffectControlDialog.cpp` is shown. So it is left as is for now.

## Adjust the font sizes in the area of GUI editors and instruments.

Increase the font size to 10 pixels in the following places:
* Effect view: "Controls" button and the display of the effect name at the bottom
* Automation editor: Min and max value display to the left of the editor
* InstrumentFunctionViews: Labels "Chord:", "Direction:" and "Mode:"
* InstrumentMidiIOView: Message display "Specify the velocity normalization base for MIDI-based instruments at 100% note velocity."
* InstrumentSoundShapingView: Message display "Envelopes, LFOs and filters are not supported by the current instrument."
* InstrumentTuningView: Message display "Enables the use of global transposition"

Increase the font size to 12 pixels in the mixer channel view, i.e. the display of the channel name.

Render messages in system font size in the following areas because there should be enough space for almost all sizes:
* Automation editor: Message display "Please open an automation clip by double-clicking on it!"
* Piano roll: Message display "Please open a clip by double-clicking on it!"

Use the application font for the line edit that can be used to change the instrument name.

Remove overrides which explicitly set the font size for LED check boxes in:
* EnvelopeAndLfoView: Labels "FREQ x 100" and "MODULATE ENV AMOUNT"

Remove overrides which explicitly set the font size for combo boxes in:
* InstrumentSoundShapingView: Filter combo box

## Adjust font sizes in widgets

Adjust the font sizes in the area of the custom GUI widgets.

Increase and unify the pixel font size to 10 pixels in the following classes:
* `ComboBox`
* `GroupBox`
* `Knob`
* `LcdFloatSpinBox`
* `LcdWidget`
* `LedCheckBox`
* `Oscilloscope`: Display of "Click to enable"
* `TabWidget`

Shorten the text in `EnvelopeAndLfoView` from "MODULATE ENV AMOUNT" to "MOD ENV AMOUNT" to make it fit with the new font size of `LedCheckBox`.

Remove the setting of the font size in pixels from `MeterDialog` because it's displayed in a layout and can accommodate all font sizes. Note: the dialog can be triggered from a LADSPA plugin with tempo sync, e.g. "Allpass delay line". Right click on the time parameter and select "Tempo Sync > Custom..." from the context menu.

Remove the setting of the font size in `TabBar` as none of the added `TabButton` instances displays text in the first place.

Remove the setting of the font size in `TabWidget::addTab` because the font size is already set in the constructor. It would be an unexpected size effect of setting a tab anyway. Remove a duplicate call to setting the font size in `TabWidget::paintEvent`.

Remove unnecessary includes of `gui_templates.h` wherever this is possible now.

## Direct use of setPixelSize

Directly use `setPixelSize` when drawing the "Note Velocity" and "Note Panning" strings as they will likely never be drawn using point sizes.
2024-04-04 21:40:31 +02:00
Oskar Wallgren
b14f8ab8fd Refactor ArpDirection::Down and ArpDirection::DownAndUp (#7007)
Fixes an issue with the arpeggiation when it is set to go downwards and the cycle is over 0.
2024-04-03 19:14:00 -04:00
Michael Gregorius
9dd7f4dde4 Remove "GENERAL SETTINGS" tab (#7188)
Remove the "GENERAL SETTINGS" tab from the instrument track and sample track window.

This removes clutter as well as dependencies to the non-scalable `TabWidget`.

Remove superfluous calls to `setSpacing` which have set the default value of 6.

Use the default content margins of (9, 9, 9, 9) instead of (8, 8, 8, 8).
2024-04-01 20:06:18 +02:00
Michael Gregorius
5d5d8f8f14 Only repaint LcdWidget if necessary (#7187)
Some analysis done with Callgrind showed that the `LcdWidget` spends quite some time repainting itself even when nothing has changed. Some widget instances are used in song update contexts where `LcdWidget::setValue` is called 60 times per second.

This commit fixes the problem by only updating the `LcdWidget` if its value really has changed.

Adjust the condition in the if-clause so that it becomes clearer what's the interval of interest.
2024-04-01 14:57:43 +02:00
Michael Gregorius
c271d28314 Ensure that build and target are directories in .gitignore (#6884)
Ensure that `build` and `target` are directories in `.gitignore`.
2024-03-30 19:04:57 +01:00
Michael Gregorius
b622fa2206 Conditionally remove use of QApplication::desktop in ComboBox.cpp (#7179)
Prepare the application for Qt6 by conditionally removing the use of `QApplication::desktop` in `ComboBox.cpp`. The method was already deprecated in Qt5 and is removed in Qt6.

Instead the method `QWidget::screen` is used now if the Qt version is equal to or newer than 5.14 (because the method was only introduced with that version). Fall back to `QApplication::desktop` if an older version is detected during the build. This is for example the case for the CI builds which are based on Ubuntu 18.04.

Generalize the check if the menu can be shown in the screen. The code now also does handles the case where the menu would go out of screen along the X axis.

Also remove the unused include `embed.h`.
2024-03-30 16:30:21 +01:00
Michael Gregorius
a98c700911 Optimize map accesses in LadspaManager (#7173)
Some methods in `LadspaManager` performed repeated searches through the map by first calling `contains` and then by actually fetching the entry. This is fixed by using `find` on the map. It returns an iterator which can directly provide the result or indicate that nothing was found. That way the map is only searched once.
2024-03-30 08:53:08 +01:00
Kevin Zander
9c591b178f PianoRoll::paintEvent: don't shadow member variable (#7181) 2024-03-30 01:15:26 -04:00
Lost Robot
03f885abc2 Fix B/B Track Label Button (#7177)
* Fix Pattern Track Label Button
2024-03-29 12:39:56 -05:00
saker
bad57356d7 Fix infinite loop in InstrumentPlayHandle::play (#7176) 2024-03-29 12:36:20 -04:00
saker
b2f2fc4ad1 Revisit the initialization for local variables (#7143)
* clang-tidy: Apply cppcoreguidelines-init-variables everywhere (treating NaNs as zeros)

* Initialize msec and tick outside switch

* Update plugins/Vestige/Vestige.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update plugins/Vestige/Vestige.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update plugins/Vestige/Vestige.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update plugins/VstEffect/VstEffectControls.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/core/DrumSynth.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update plugins/VstEffect/VstEffectControls.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update plugins/VstEffect/VstEffectControls.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/core/DrumSynth.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/core/DrumSynth.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/core/DrumSynth.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/core/DrumSynth.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/core/DrumSynth.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/core/DrumSynth.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Use initialization with =

* Use tabs

* Use static_cast

* Update DrumSynth.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update DrumSynth.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update DrumSynth.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/core/DrumSynth.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Do not use tabs for alignment in src/core/DrumSynth.cpp

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

* Move x variable inside loop

* Use ternary operator for b variable

* Revert "Use tabs"

This reverts commit 07afd8a83f58b539c3673310b2aad4b63c9198a0.

* Remove unnecessary variables in XpressiveView

* Simplify initialization in Plugin

* Combine declaration and initialization in EqCurve

* Combine declaration and initialization in Song

* Combine declaration and initialization in AudioAlsa

* Combine declaration and initialization in EqCurve (again)

* Missed some

* Undo changes made to non-LMMS files

* Undo indentation changes in SidInstrument.cpp

* Combine declaration with assignment in IoHelper

* Combine declaration with assignment using auto in Carla

* Combine declaration with assignment

* Combine declaration with assignment in BasicFilters

* Simplify assignments in AudioFileProcessorWaveView::zoom

* Simplify out sample variable in BitInvader

* Remove sampleLength variable in DelayEffect

* Move gain variable in DynamicsProcessor

* Combine peak variable declaration with assignment in EqSpectrumView

* Move left/right lfo variables in for loop in FlangerEffect

* Use ternary operator for group variable in LadspaControlDialog

* Combine declaration with assignment in Lb302

* Combine declaration with assignment in MidiExport

* Combine declaration with assignment in MidiFile

* Combine declaration with assignment in MidiImport

* Use ternary operator for vel_adjusted variable in OpulenZ

* Move tmpL and dcblkL variables in for loop in ReverbSC

* Combine declaration with initialization in SlicerT

* Combine declaration with assignment in SaSpectrumView

* Combine declaration with assignment in SaWaterfallView

* Combine declaration with assignment in StereoEnhancerEffect

* Combine declaration with assignment in VibratingString

* Combine declaration with assignment in VstEffectControls

* Combine declaration with assignment in Xpressive

* Combine declaration with assignment in AutomatableModel

* Combine declaration with assignment in AutomationClip

* Move sample variable in for loop in BandLimitedWave

* Combine declaration with assignment in DataFile

* Combine declaration with assignment in DrumSynth

* Combine declaration with assignment in Effect

* Remove redundant assignment to nphsLeft in InstrumentPlayHandle

* Combine declaration with assignment in LadspaManager

* Combine declaration with assignment in LinkedModelGroups

* Combine declaration with assignment in MemoryHelper

* Combine declaration with assignment in AudioAlsa

* Combine declaration with assignment in AudioFileOgg

* Combine declaration with assignment in AudioPortAudio

* Combine declaration with assignment in AudioSoundIo

* Combine declaration with assignment in Lv2Evbuf

* Combine declaration with assignment in Lv2Proc

* Combine declaration with assignment in main

* Combine declaration with assignment in MidiAlsaRaw

* Combine declaration with assignment in MidiAlsaSeq

* Combine declaration with assignment in MidiController

* Combine declaration with assignment in MidiJack

* Combine declaration with assignment in MidiSndio

* Combine declaration with assignment in ControlLayout

* Combine declaration with assignment in MainWindow

* Combine declaration with assignment in ProjectNotes

* Use ternary operator for nextValue variable in AutomationClipView

* Combine declaration with assignment in AutomationEditor

* Move length variable in for-loop in PianoRoll

* Combine declaration with assignment in ControllerConnectionDialog

* Combine declaration with assignment in Graph

* Combine declaration with assignment in LcdFloatSpinBox

* Combine declaration with assignment in TimeDisplayWidget

* Remove currentNote variable in InstrumentTrack

* Combine declaration with assignment in DrumSynth (again)

* Use ternary operator for factor variable in BitInvader

* Use ternary operator for highestBandwich variable in EqCurve

Bandwich?

* Move sum variable into for loop in Graph

* Fix format in MidiSndio

* Fixup a few more

* Cleanup error variables

* Use ternary operators and combine declaration with initialization

* Combine declaration with initialization

* Update plugins/LadspaEffect/LadspaControlDialog.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update plugins/OpulenZ/OpulenZ.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update plugins/SpectrumAnalyzer/SaProcessor.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/core/midi/MidiAlsaRaw.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/gui/MainWindow.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/gui/clips/AutomationClipView.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/gui/editors/AutomationEditor.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/gui/widgets/Fader.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Move static_cast conversion into separate variable

* Use real index when interpolating

* Remove empty line

* Make helpBtn a private member

* Move controller type into separate variable

* Fix format of DrumSynth::waveform function

* Use tabs and static_cast

* Remove redundant if branch

* Refactor using static_cast/reinterpret_cast

* Add std namespace prefix

* Store repeated conditional into boolean variable

* Cast to int before assigning to m_currentLength

* Rename note_frames to noteFrames

* Update src/core/Controller.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/core/DrumSynth.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Update src/gui/widgets/Graph.cpp

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Revert changes that initialized variables redudantly

For situations where the initialization is
more complex or passed into a function
by a pointer, we dont need to do
initialization ourselves since it is
already done for us, just in a different way.

* Remove redundant err variable

* Remove explicit check of err variable

* Clean up changes and address review

* Do not initialize to 0/nullptr when not needed

* Wrap condition in parentheses for readability

---------

Co-authored-by: Kevin Zander <veratil@gmail.com>
Co-authored-by: Dalton Messmer <messmer.dalton@gmail.com>
2024-03-28 17:21:31 -04:00
Oskar Wallgren
6f5f2c2ddd Fix glitch in SlicerT (#7174) 2024-03-28 18:13:32 +01:00
Lost Robot
682be4e82a Fix DynamicsProcessor bugs (#7168) 2024-03-27 09:00:49 -04:00
Rossmaxx
286d15724a Refactor gui_templates.h (#7159)
* remove the gui_templates header where functions not used

* refactor and replace template with function argument

* refactor: merge pointSizeF function with pointSize

* removed template per michael's review

* use std::max for more readability

* remove the QDesktopWidget header

* cleanup arguments and remove parentheses from return
2024-03-27 08:59:27 -04:00
Michael Gregorius
a41da81554 Enable different colors for oscilloscope channels (#7155)
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.
2024-03-26 20:19:52 +01:00
Lost Robot
45fd326787 Make Compressor background themeable (#7157) 2024-03-26 09:10:26 -07:00
Alexander Medvedev
66081ba1b1 CMake: Replace EXEC_PROGRAM with execute_process (#7166)
* CMake: Replace EXEC_PROGRAM with execute_process

exec_program is Deprecated since version 3.0: Use the execute_process() command instead.
2024-03-26 09:49:13 -05:00
Lassi
0e1eb712d8 Bump project year (#7167) 2024-03-26 10:16:47 -04:00
Kevin Zander
c2fdb8cfd2 Move confirmation to remove mixer channels outside MixerView::deleteChannel #7154)
Moves the confirmation to remove mixer channels outside of `MixerView::deleteChannel` and into `MixerChannelView::removeChannel`. This is so that the confirmation only applies when the user uses the context menu to remove a channel, which is important since no confirmation should apply when, for example, the mixer view is cleared with calls to `MixerView::clear`.
2024-03-25 19:22:37 -04:00
saker
9ff63a5f5a Set mixer channel LCD when its index changes (#7160) 2024-03-24 18:05:15 -04:00
Alexander Medvedev
3e19d1335f Update carla (#7149) 2024-03-20 13:43:41 -04:00
Alexander Medvedev
3f5ac806e9 Update jack2 (#7147) 2024-03-16 19:53:40 -04:00
TechnoPorg
af7431be99 Add GitHub issue forms for bug reports and feature requests (#7102) 2024-03-16 21:53:22 +00:00
Rossmaxx
4120a04d0b Replace QRegExp with QRegularExpression (#7133)
* replace QRegExp with QRegularExpression (find n replace)

* follow up to fix errors

* removed rpmalloc

* Fix compilation for qt5, to be fixed when qt6 fully supported.

Co-authored-by: Kevin Zander <veratil@gmail.com>

* Added QtGlobal header for version finding fix

* Use the other syntax to try fix compilation.

* Check for 5.12 instead.

* Fix the header

* Attempt at fixing it further.

* Use version checks properly in header file

* Use QT_VERSION_CHECK macro in sources

* Apply suggestions from messmerd's review

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

---------

Co-authored-by: Kevin Zander <veratil@gmail.com>
Co-authored-by: Dalton Messmer <messmer.dalton@gmail.com>
2024-03-16 14:34:01 +09:00
saker
b9ebc24e13 Check if m_peakSum is less than or equal to 0 again (#7146) 2024-03-15 21:40:15 -04:00
Michael Gregorius
04ecf73395 Fix missing icons for some instruments (#7132)
Revert some of the changes made in commit 88e0e94dcd. The underlying idea was that the `InstrumentTrackView` should be responsible for assigning the icon that's shown by its `TrackLabelButton`. However, this does not work because in some cases the `InstrumentTrack` that's passed into `InstrumentTrackView::determinePixmap` does not have an `Instrument` assigned. This in turn seems to be caused due to initalizations that are running in parallel in different threads.

Here are the steps to reproduce the threading problem (line numbers refer to commit 360254f):
1. Set a break point in line 1054 of `InstrumentTrack`, i.e. the line in `InstrumentTrack::loadInstrument` where `m_instrument` is being assigned to.
2. Set a break point in `InstrumentTrackView::determinePixmap`, e.g. inside of the first if statement.
3. Drop an instance of "Sf2 Player" onto the Song Editor.
4. The first break point in `InstrumentTrack` is hit in a thread called "lmms::Instrumen" (shown like that in my debugger). Try to step over it.
5. The second break point in `InstrumentTrackView` now gets hit before the code is stepped over. This time we are in the thread called "lmms". I guess this is the GUI main thread.
6. Continue execution.

If you now switch to the application then the icon is shown. I guess the debugger is halted long enough in the main thread so that the InstrumentTrack gets an instrument assigned in another thread.

If you delete/disable the break point in `InstrumentTrack::determinePixmap` and follow the coarse steps above then the icon is not shown because the track has no instrument.

The current fix still delegates to the `InstrumentTrackView` to determine the pixmap in hopes that one day there will be a better solution where the parent component can be fully responsible for its child component.

Fixes #7116.
2024-03-13 20:00:58 +01:00
Dalton Messmer
37073af494 Update to latest commit 2024-03-12 20:11:26 -05:00
Dalton Messmer
238974253d Update game-music-emu submodule 2024-03-12 20:11:26 -05:00