Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge branch 'master' into feature/detach-window #7585

Merged
merged 247 commits into from
Nov 17, 2024

Conversation

messmerd
Copy link
Member

There were some merge conflicts, some of which I may have resolved incorrectly, such as those in SubWindow::adjustTitleBar() (I added TODO comments where I'm not sure the code is correct) and the removal of Editor::closeEvent.

sakertooth and others added 30 commits November 18, 2023 20:47
Improves performance when searching in the file browser (confirmed with profiling using KCacheGrind), adds a search indicator at the bottom to let the user know a search is in progress, blacklists unnecessary system directories (speeding up both the search speed and potentially load times as well by reducing the number of filesystem entries to consider), and fixes an issue that causes not all of the search results to appear.
* Replace knobFModel with std::vector

* Create QPixmap's on the stack

* Assign parent for QGraphicsScene
A call to QGraphicsView::setScene does not make
the view take ownership of the scene.

* Do not allocate QList on the heap

* Use static QPixmap's
The QPixmap's need to be created within the constructor, and not outside
where they are defined, since it can't find them otherwise.
I'm not too sure why.

* Clear m_vi2->knobFModel in destructor

* Use local static QPixmap's

* Do not allocate QPixmap with new in AudioFileProcessor

* Do not allocate QPixmap with new in Nes

* Do not allocate QPixmap with new in Organic

* Do not allocate QPixmap with new in SaControlsDialog

* Do not allocate QPixmap with new in Vestige

* Do not allocate QPixmap with new for FileBrowser

* Do not allocate QPixmap with new in MixerLine

* Do not allocate QPixmap with new in SendButtonIndicator

* Do not allocate QPixmap with new in AutomationClipView

* Do not allocate QPixmap with new in MidiClipView

* Do not allocate QPixmap with new in AutomationEditor

* Do not allocate QPixmap with new in PianoRoll

* Do not allocate QPixmap with new in TimeLineWidget

* Do not allocate QPixmap with new in EnvelopeAndLfoView

* Do not allocate QPixmap with new in PianoView

* Do not allocate QPixmap with new in ComboBox

* Do not allocate QPixmap with new in Fader

* Do not allocate QPixmap with new for LcdWidget

* Do not allocate QPixmap with new for LedCheckbox

* Use m_ as prefix for members

* Use uniform initialization
I already started using uniform initialization for the QPixmap changes
for some reason, so I'm finishing that up.

* Uniform initiaization

* And then he realized he was making copies...

* Do not call QPixmap copy constructor

* Do not call QPixmap copy constructor in SaControlsDialog

* Do not make pixmap's static for Lcd's and Led's

* Initialize pixmaps in-class

* Fix few mistakes and formatting
* rewrite amplifier plugin style

* pomelo

* oroblanco

* grapefruit

* calamlamondin
Show ghost notes or sample track as a visual aid in the Automation Editor.

---------

Co-authored-by: IanCaio <[email protected]>
Fix a floating point exception in the Spectrum Analyzer which occurs if the amplitude is 0. The amplitude is used in the calculation of a logarithm which is not defined for values smaller or equal to 0.

The fix is to replace a value of 0 with the minimum positive float value. Negative values are not handled because it seems that only values greater or equal to 0 are fed into the method. This assumption is asserted in case this ever changes.
* Add refactored SampleBuffer

* Add Sample

* Add SampleLoader

* Integrate changes into AudioSampleRecorder

* Integrate changes into Oscillator

* Integrate changes into SampleClip/SamplePlayHandle

* Integrate changes into Graph

* Remove SampleBuffer include from SampleClipView

* Integrate changes into Patman

* Reduce indirection to sample buffer from Sample

* Integrate changes into AudioFileProcessor

* Remove old SampleBuffer

* Include memory header in TripleOscillator

* Include memory header in Oscillator

* Use atomic_load within SampleClip::sample

* Include memory header in EnvelopeAndLfoParameters

* Use std::atomic_load for most calls to Oscillator::userWaveSample

* Revert accidental change on SamplePlayHandle L.111

* Check if audio file is empty before loading

* Add asserts to Sample

* Add cassert include within Sample

* Adjust assert expressions in Sample

* Remove use of shared ownership for Sample
Sample does not need to be wrapped around a std::shared_ptr.
This was to work with the audio thread, but the audio thread
can instead have their own Sample separate from the UI's Sample,
so changes to the UI's Sample would not leave the audio worker thread
using freed data if it had pointed to it.

* Use ArrayVector in Sample

* Enforce std::atomic_load for users of std::shared_ptr<const SampleBuffer>

* Use requestChangesGuard in ClipView::remove
Fixes data race when deleting SampleClip

* Revert only formatting changes

* Update ClipView::remove comment

* Revert "Remove use of shared ownership for Sample"

This reverts commit 1d45233.
In some cases, you can infact do away with shared ownership
on Sample if there are no writes being made to either of them,
but to make sure changes are reflected to the object in cases
where writes do happen, they should work with the same one.

* Fix heap-use-after-free in Track::loadSettings

* Remove m_buffer asserts

* Refactor play functionality (again)
The responsibility of resampling the buffer
and moving the frame index is now in Sample::play, allowing the removal
of both playSampleRangeLoop and playSampleRangePingPong.

* Change copyright

* Cast processingSampleRate to float
Fixes division by zero error

* Update include/SampleLoader.h

Co-authored-by: Dalton Messmer <[email protected]>

* Update include/SampleLoader.h

Co-authored-by: Dalton Messmer <[email protected]>

* Format SampleLoader.h

* Remove SampleBuffer.h include in SampleRecordHandle.h

* Update src/core/Oscillator.cpp

Co-authored-by: Dalton Messmer <[email protected]>

* Use typeInfo<float> for float equality comparison

Co-authored-by: Dalton Messmer <[email protected]>

* Use std::min in Sample::visualize

Co-authored-by: Dalton Messmer <[email protected]>

* Move in result to m_data

* Use if block in playSampleRange

* Pass in unique_ptr to SampleClip::setSampleBuffer

* Return const QString& from SampleBuffer::audioFile

* Do not pass in unique_ptr by r-value reference

* Use isEmpty() within SampleClipView::updateSample

* Remove use of atomic_store and atomic_load

* Remove ArrayVector comment

* Use array specialization for unique_ptr when managing DrumSynth data
Also made it so that we don't create result
before checking if we failed to decode the file,
potentially saving us an allocation.

* Don't manually delete Clip if it has a Track

* Clean up generateAntiAliasUserWaveTable function
Also, make it so that we actually call this function
when necessary in TripleOscillator.

* Set user wave, even when value is empty
If the value or file is empty, I think showing a
error popup here is ideal.

* Remove whitespace in EnvelopeAndLfoParameters.cpp L#121

* Fix error in c5f7ccb
We still have to delete the Clip's, or else we would just be eating
up memory. But we should first make sure that the Track's no longer
see this Clip in their m_clips vector. This has to happen
as it's own operation because we have to wait for the audio thread(s)
first. This would ensure that Track's do not create
PlayHandle's that would refer to a Clip that is currently
being destroyed. After that, then we call deleteLater on the Clip.

* Convert std::shared_ptr<Sample> to Sample
This conversion does not apply to Patman as there seems to be issues
with it causing heap-use-after-free issues, such as with
PatmanInstrument::unloadCurrentPatch

* Fix segfault when closing LMMS
Song should be deleted before AudioEngine.

* Construct buffer through SampleLoader in FileBrowser's previewFileItem function
+ Remove const qualification in SamplePlayHandle(const QString&)
constructor for m_sample

* Move guard out of removeClip and deleteClips
+ Revert commit 1769ed5 since
this would fix it anyway
(we don't try to lock the engine to
delete the global automation track when closing LMMS now)

* Simplify the switch in play function for loopMode

* Add SampleDecoder

* Add LMMS_HAVE_OGGVORBIS comment

* Fix unused variable error

* Include unordered_map

* Simplify SampleDecoder
Instead of using the extension (which could be wrong) for the file,
we simply loop through all the decoders available. First sndfile because
it covers a lot of formats, then the ogg decoder for the few cases where sndfile
would not work for certain audio codecs, and then the DrumSynth decoder.

* Attempt to fix Mac builds

* Attempt to fix Mac builds take 2

* Add vector include to SampleDecoder

* Add TODO comment about shared ownership with clips

Calls to ClipView::remove may occur at any point, which can cause
a problem when the Track is using the clip about to be removed.
A suitable solution would be to use shared ownership between the Track
and ClipView for the clip. Track's can then simply remove the shared
pointer in their m_clips vector, and ClipView can call reset on the
shared pointer on calls to ClipView::remove.

* Adjust TODO comment
Disregard the shared ownership idea. Since we would be modifying
the collection of Clip's in Track when removing the Clip, the Track
could be iterating said collection while this happens,
causing a bug. In this case, we do actually
want a synchronization mechanism.

However, I didn't mention another separate issue in the TODO comment
that should've been addressed: ~Clip should not be responsible for
actually removing the itself from it's Track. With calls to removeClip,
one would expect that to already occur.

* Remove Sample::playbackSize
Inside SampleClip::sampleLength, we should be using Sample::sampleSize
instead.

* Fix issues involving length of Sample's
SampleClip::sampleLength should be passing the Sample's sample rate to
Engine::framesPerTick.

I also changed sampleDuration to return a std::chrono::milliseconds
instead of an int so that the callers know what time interval
is being used.

* Simplify if condition in src/gui/FileBrowser.cpp

Co-authored-by: Dalton Messmer <[email protected]>

* Simplify if condition in src/core/SampleBuffer.cpp

Co-authored-by: Dalton Messmer <[email protected]>

* Update style in include/Oscillator.h

Co-authored-by: Dalton Messmer <[email protected]>

* Format src/core/SampleDecoder.cpp

Co-authored-by: Dalton Messmer <[email protected]>

* Set the sample rate to be that of the AudioEngine by default

I also removed some checks involving the state of the SampleBuffer.
These functions should expect a valid SampleBuffer each time.
This helps to simplify things since we don't have to validate it
in each function.

* Set single-argument constructors in Sample and SampleBuffer to be explicit

* Do not make a copy when reading result from the decoder

* Add constructor to pass in vector of sampleFrame's directly

* Do a pass by value and move in SampleBuffer.cpp

Co-authored-by: Dalton Messmer <[email protected]>

* Pass vector by value in SampleBuffer.h

Co-authored-by: Dalton Messmer <[email protected]>

* Make Sample(std::shared_ptr) constructor explicit

* Properly draw sample waveform when reversed

* Collect sample not found errors when loading project

Also return empty buffers when trying to load
either an empty file or empty Base64 string

* Use std::make_unique<SampleBuffer> in SampleLoader

* Fix loop modes

* Limit sample duration to [start, end] and not the entire buffer

* Use structured binding to access buffer

* Check if GUI exists before displaying error

* Make Base64 constructor pass in the string instead

* Remove use of QByteArray::fromBase64Encoding

* Inline simple functions in SampleBuffer

* Dynamically include supported audio file types

* Remove redundant inline specifier

Co-authored-by: Dalton Messmer <[email protected]>

* Translate file types

* Cache calls to SampleDecoder::supportedAudioTypes

* Fix translations in SampleLoader (again)
Also ensure that all the file types are listed first.
Also simplified the generation of the list a bit.

* Store static local variable for supported audio types instead of in the header

Co-authored-by: Dalton Messmer <[email protected]>

* Clamp frame index depending on loop mode

* Inline member functions of PlaybackState

* Do not collect errors in SampleLoader when loading projects

Also fix conflicts with surrounding codebase

* Default construct shared pointers to SampleBuffer

* Simplify and optimize Sample::visulaize()

* Remove redundant gui:: prefix

* Rearrange Sample::visualize after optimizations by DanielKauss

* Apply amplification when visualizing sample waveforms

* Set default min and max values to 1 and -1

* Treat waveform as mono signal when visualizing

* Ensure visualization works when framesPerPixel < 1

* Simplify Sample::visualize a bit more

* Fix CPU lag in Sample by using atomics (with relaxed ordering)

Changing any of the frame markers originally took a writer
lock on a mutex.

The problem is that Sample::play took a reader lock first before
executing. Because Sample::play has to wait on the writer, this
created a lot of lag and raised the CPU meter. The solution
would to be to use atomics instead.

* Fix errors from merge

* Fix broken LFO controller functionality

The shared_ptr should have been taken by reference.

* Remove TODO

* Update EnvelopeAndLfoView.cpp

Co-authored-by: Dalton Messmer <[email protected]>

* Update src/gui/clips/SampleClipView.cpp

Co-authored-by: Dalton Messmer <[email protected]>

* Update plugins/SlicerT/SlicerT.cpp

Co-authored-by: Dalton Messmer <[email protected]>

* Update plugins/SlicerT/SlicerT.cpp

Co-authored-by: Dalton Messmer <[email protected]>

* Store shortest relative path in SampleBuffer

* Tie up a few loose ends

* Use sample_rate_t when storing sample rate in SampleBuffer

* Add missing named requirement functions and aliases

* Use sampledata attribute when loading from Base64 in AFP

* Remove initializer for m_userWave in the constructor

* Do not use trailing return syntax when return is void

* Move decoder functionality into unnamed namespace

* Remove redundant gui:: prefix

* Use PathUtil::toAbsolute to simplify code in SampleLoader::openAudioFile

* Fix translations in SampleLoader::openAudioFile

Co-authored-by: DomClark <[email protected]>

* Fix formatting for ternary operator

* Remove redundant inlines

* Resolve UB when decoding from Base64 data in SampleBuffer

* Fix up SampleClip constructors

* Add AudioResampler, a wrapper class around libsamplerate

The wrapper has only been applied to Sample::PlaybackState for now.
AudioResampler should be used by other classes in the future that do
resampling with libsamplerate.

* Move buffer when moving and simplify assignment functions in Sample

* Move Sample::visualize out of Sample and into the GUI namespace

* Initialize supportedAudioTypes in static lambda

* Return shared pointer from SampleLoader

* Create and use static empty SampleBuffer by default

* Fix header guard in SampleWaveform.h

* Remove use of src_clone
CI seems to have an old version of libsamplerate and does not have this method.

* Include memory header in SampleBuffer.h

* Remove mutex and shared_mutex includes in Sample.h

* Attempt to fix string operand error within AudioResampler

* Include string header in AudioResampler.cpp

* Add LMMS_EXPORT for SampleWaveform class declaration

* Add LMMS_EXPORT for AudioResampler class declaration

* Enforce returning std::shared_ptr<const SampleBuffer>

* Restrict the size of the memcpy to the destination size, not the source size

* Do not make resample const

AudioResampler::resample, while seemingly not changing the data of the resampler, still alters its internal state and therefore should not be const.
This is because libsamplerate manages state when
resampling.

* Initialize data.end_of_input

* Add trailing new lines

* Simplify AudioResampler interface

* Fix header guard prefix to LMMS_GUI instead of LMMS

* Remove Sample::resampleSampleRange

---------

Co-authored-by: Dalton Messmer <[email protected]>
Co-authored-by: Daniel Kauss <[email protected]>
Co-authored-by: Dalton Messmer <[email protected]>
Co-authored-by: DomClark <[email protected]>
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 <[email protected]>
Remove the code which computes a minimum height for the LADSPA dialogs. It was intended to make sure that no scrollbar is shown in most cases. However, doing so came at the cost that the computed height was the minimum height as well. Therefore the dialogs took a lot of space on low-res displays and could not be made smaller.

After the removal the behavior is still sane. Small dialogs are shown in full and dialogs which are larger, e.g. "Calf Equalizer 12 Band LADSPA", seem to be sized around half the height of the workspace and show scrollbars.
# 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 LMMS#6730.
Fix the peak update of the LMMS equalizer which accidentally used the same sample twice.

Simplify the `gain` method by removing repeated deferences which made the code hard to read.

Use `std::max` to update the peak values to the maximum of the buffer.
Fixes crashes when using decodeSampleOggVorbis, as well as missing supported audio formats
* Handle divisions by 0 in Lb302

Handle potential division by 0 which in turn lead to floating point exceptions in Lb302. The division can occur in the `process` method if it is called with the member `vco_inc` still initialized to 0. This seems to happen then the Lb302 processes with no notes actually being played.

The offending call is `BandLimitedWave::pdToLen(vco_inc)` which is now prevented when the increment is 0. In the latter case a sample of 0 is produced. This works because in all other cases the Lb302 instance should process a note which in turn sets the increments to something different from 0.

* Fix FPEs in Monstro

Fix some floating point exceptions in `MonstroSynth::renderOutput` that occurred due to calling `BandLimitedWave::pdToLen` with a value of 0. This happened when one of the phase deltas was set to 0, i.e. `pd_l` or `pd_r`. These cases are now checked and produce silence in the corresponding components if the phase delta is set to 0.

* Fix uninitialized variables

Initialize the local variables `len_l` and `len_r` to 0. This fixes compiler warnings a la "error: 'len_r' may be used uninitialized in this function" which are treated as errors on the build server.

* Adjust whitespace of touched code
Fix a crash that occurs when songs are loaded after each other. The crash only occurs if the "participating" songs have at least one other channel besides the master channel.

The crash occurred because the `MixerChannelViews` were not really deleted in `MixerView::refreshDisplay`. As a consequence the parent child relationship was still given between the `MixerView` and the `MixerChannelView`. When a song was loaded the event queue was evaluated which in turn resulted in the method `Fader::knobPosY` being called on a `Fader` which did not have a model anymore.

Fixes LMMS#7046.
* set win32 flag

* added mingw too to win32 flag + dom's suggestions

* revert unnecessary changes i made.

* simplify msys linker flag condition

* removed extra whitespace

* whitespace change 2
Reduce code repetition in `MixerChannelView` by introducing methods that:
* Retrieve the `MixerChannel` that's associated with the view
* Check if the associated channel is the master channel

This abstracts some functionality and also reduces direct usage of the variable `m_channelIndex`.
* fix ladspa browser description (unwanted line breaks), add missing labels to instruments' controls

* some more ui fixes

* translation context + style fixup
…es (LMMS#7064)

The issue occurred because `AudioFileProcessorWaveView::updateSampleRange` was not being called in `AudioFileProcessorWaveView::dropEvent`.
Make the mixer window resizable and allow the effects rack to grow. This enables the users a better overview of the effects used.
sakertooth and others added 29 commits September 18, 2024 11:25
This problem seem to arise due to casting _n->framesLeft() and _n->offset() from an unsigned type (size_t) to a signed type (int). The fix is to use size_t as the type for std::max across the board.
* Move common effect processing code to wrapper method

- Introduce `processImpl` and `sleepImpl` methods, and adapt each effect
plugin to use them
- Use double for RMS out sum in Compressor and LOMM
- Run `checkGate` for GranularPitchShifterEffect
- Minor changes to LadspaEffect
- Remove dynamic allocations and VLAs from VstEffect's process method
- Some minor style/formatting fixes

* Fix VstEffect regression

* GranularPitchShifterEffect should not call `checkGate`

* Apply suggestions from code review

Co-authored-by: saker <[email protected]>

* Follow naming convention for local variables

* Add `MAXIMUM_BUFFER_SIZE` and use it in VstEffect

* Revert "GranularPitchShifterEffect should not call `checkGate`"

This reverts commit 67526f0.

* VstEffect: Simplify setting "Don't Run" state

* Rename `sleepImpl` to `processBypassedImpl`

* Use `MAXIMUM_BUFFER_SIZE` in SetupDialog

* Pass `outSum` as out parameter; Fix LadspaEffect mutex

* Move outSum calculations to wrapper method

* Fix Linux build

* Oops

* Apply suggestions from code review

Co-authored-by: Johannes Lorenz <[email protected]>

* Apply suggestions from code review

Co-authored-by: saker <[email protected]>

---------

Co-authored-by: saker <[email protected]>
Co-authored-by: Johannes Lorenz <[email protected]>
* changed font sizes to better values

* rename gui_templates.h to FontHelper.h

* replace hardcoded values with constants

* make knob labels use small font

* code review from michael

* more consolidation

* Fix text problem in Vectorscope

Fix a problem with cutoff text in Vectorscope. During the constructor
call of `LedCheckBox` the method `LedCheckBox::onTextUpdated` is
triggered which sets a fixed size that fits the pixmap and the text.
After instantiating the two instances in `VecControlsDialog` the
constructor then set a minimum size which overrode the fixed size that
was previously set. This then led to text that was cutoff.

---------

Co-authored-by: Michael Gregorius <[email protected]>
* Add fast fma functions

* Use fast fma functions

* Add fast pow function

* Use fast pow function

* Fix build

* Remove fastFma

* Avoid UB in fastPow

On GCC with -O1 or -O2 optimizations, this new implementation generates
identical assembly to the old union-based implementation
* fix out-of-bounds crash in AudioFileProcessor

by correctly setting m_from and m_to without them interfering with each other

* fixed flattened wave caused by inaccurate math

see PR for before/after

* simply stop drawing AFP waveform when there's no more data

this fixes the single point at the end of waveforms that sometimes shows up

* fixed seemingly insignificant type confusion (?)

execution seemed fine but my debugger started freaking out,
and if gdb is telling me I got a negative-sized vector,
I'd rather fix this issue than speculate "it's probably fine"

* fixed data offset for AFP waveform vis

the data itself isn't reversed, so we have to account for that
Add proportional scrolling to the song editor, piano roll and automation editor. Proportional scrolling means that if for example a certain measure is on the right side of the song editor then it will take a certain number of mouse wheel moves to get it to the left side of the editor. It is the same number of wheel moves regardless of the zoom level.
Fix the problem with empty windows as described in issue LMMS#7412.

The `refocus` method in `MainWindow` is made public so that it can be called from `Editor::closeEvent`. It has also been refactored for better readability.

---------

Co-authored-by: Michael Gregorius <[email protected]>
Co-authored-by: Dalton Messmer <[email protected]>
Removed code that's has been deactivated using `#if 0`.
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 <[email protected]>
## Fix rendering of maximized sub windows

### Adjustments in paintEvent
In `SubWindow::paintEvent` don't paint anything if the sub window is
maximized . Otherwise some gradients are visible behind the maximized
child content.

### Adjustments in adjustTitleBar
In `SubWindow::adjustTitleBar` hide the title label and the buttons if the
sub window is maximized. Always show the title and close button if not
maximized. This is needed to reset the state correctly after
maximization.

Remove some calls to `isMaximized` where we already know that the sub
window is not maximized, i.e. where these calls would always return
`false`.

One adjustment would have resulted in a call to `setHidden(false)`. This
was changed to `setVisible(true)` to get rid of the double negation.

The other `false` would have gotten in an or statement and thus could be
removed completely.

### Add method addTitleButton
Add the helper method `SubWindow::addTitleButton` to reduce code
repetition in the constructor.

### Other changes
Remove a dependency on the `MdiArea` when checking if the sub window is
the active one. Query its own window state to find out if it is active.

When calling `setWindowFlags` in the constructor only adjust the existing
flags with the changes that we actually want to do. It was ensured that
all other flags that have been set before still apply with this change.
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.
Remove the member `PluginView::m_isResizable` and it's associated method `setResizable`. Turn `isResizable` into a virtual method.

The reasoning is that whether or not an effect can be resized depends on its implementation. Therefore does not make sense to have a method like `setResizable`. If the underlying implementation does not support resizing then it would not make sense to call `setResizable(true)`. So `isResizable` now describes the underlying ability of a plugin to resize. It's then up to the clients of that method to decide how to treat the result of `isResizable`, i.e. if they want to make use of the ability to resize or not.
* Optimize dBFS <-> amplitude functions
* Remove QTextCodec

QTextCodec was removed from Qt6 and is only available through the
Qt5Compat module.

QTextCodec was only used by the HydrogenImport plugin when importing old
Hydrogen files that were saved using TinyXML before it supported UTF-8.
HydrogenImport would use QTextCodec to try to get the current encoding
from the locale, and then use that as a best guess for interpreting the
XML data in the unspecified encoding it was saved in. None of this was
ever reliable, since the encoding of the computer that saved the
Hydrogen file might not be the same as the computer running LMMS and
importing that file.

There is no good solution here, so I decided to simply assume the old
Hydrogen files are UTF-8 encoded. The worst that can happen is someone's
ancient Hydrogen files containing non-ASCII text of some random encoding
becomes mojibake'd after importing into LMMS, which is something that
already could have happened.

* Clean up a little
…#7549)

* Inline TimeSig functions

* Inline TimePos functions
…ples (LMMS#7566)

Historically, the PeakController has had issues like attack/decay knobs
acting like on/off switches, and audio artifacts like buzzing or
clicking. This patch aims to address those issues.

The PeakController previously used lerp (linear interpolation) when
looping through the sample buffer, which was in updateValueBuffer. This
lerp utilized attack/decay values from control knobs. This is not the
correct place to utilize attack/decay because the only temporal data
available to the function is the frame and sample size. Therefore the
coefficient should simply be the sample rate instead.

Between each sample, processImpl would set m_lastSample to the RMS
without any sort of lerp. This resulted in m_lastSample producing
stair-like patterns over time, rather than a smooth line.

For context, m_lastSample is used to set the value of whatever is
connected to the PeakController. The basic lerp formula is:

m_lastSample = m_lastSample + ((1 - attack) * (RMS - m_lastSample))

This is useful because an attack of 0 sets m_lastSample to RMS, whereas
an attack of 1 would set m_lastSample to m_lastSample. This means our
attack/decay knobs can be used on a range from "snap to the next value
immediately" to "never stray from the last value".

* Remove attack/decay from PeakController frame lerp.
* Set frame lerp coefficient to 100.0 / sample_rate to fix buzzing.
* Add lerp between samples for PeakController to fix stairstep bug.
* The newly added lerp utilizes (1 - attack or decay) as the
  coefficient, which means the knobs actually do something now.
* Use macOS 13

See: actions/runner-images#10721

* Upgrade to XCode 15.2

XCode 15.2 is the default on macOS 13

* Fix unqualified call to std::move warning

* Fix sprintf deprecated warnings

* Upgrade macOS 14 ARM64 builds to XCode 15.4

See: actions/runner-images#10703

* Fix unused lambda capture warnings in Fader.cpp

* Fix unused variable warnings

* Fix formatting warning

Cannot format `const void*` as a string

* Force lambda conversion to function pointer
* Fixed a bug in the integrate function, that was caused by warning fixes session.

* Xpressive - fixed code style issues.
@messmerd messmerd merged commit 7fbd1f1 into LMMS:feature/detach-window Nov 17, 2024
8 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.