mirror of
https://github.com/LMMS/lmms.git
synced 2026-03-11 02:26:19 -04:00
1e6a902dd32e9bf4dbf57e17913bdd67acecfaad
2340 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
6c4d458599 | Migrate to CTest (#7062) | ||
|
|
629ba0362b |
Fix mixer channel updates on solo/mute (#7055)
* Fix mixer channel updates on solo/mute
Fix the update of the mixer channels whenever a channel is soloed or muted.
The solution is rather "brutal" as it updates all mixer channel views when one of the models changes.
Introduce private helper method `MixerView::updateAllMixerChannels`. It calls the `update` method on each `MixerChannelView` so that they can get repainted.
Call `updateAllMixerChannels` at the end of the existing method `toggledSolo`.
Introduce a new method `MixerView::toggledMute` which is called whenever the mute model of a channel changes. It also updates all mixer channels.
Fixes #7054.
* Improve mixer channel update for mute events
Improve the mixer channel update for mute events by not delegating to `MixerView` like for the solo case. Instead the `MixerChannelView` now has its own `toggledMute` slot which simply updates the widget on changes to the mute model.
Also fix `MixerChannelView::setChannelIndex` by disconnecting from the signals of the previous mixer channel and connecting to the signals for the new one.
Remove `toggledMute` from `MixerView`.
The solo implementation is kept as is because it also triggers changes to the core model. So the chain seems to be:
* Solo button clicked in mixer channel view
* Button changes solo model
* Solo model signals to mixer view which was connected via the mixer channel view
* Mixer view performs changes in the other core models
* All mixer channels are updated.
Are better chain would first update the core models and then update the GUI from the changes:
* Solo button clicked in mixer channel view
* Button changes solo model
* Solo model signals to core mixer, i.e. not a view!
* Mixer view performs changes in the other core models
* Changed models emit signal to GUI elements
* Revert "Improve mixer channel update for mute events"
This reverts commit
|
||
|
|
b67c53ad29 | Fix sliding of waveform when drawing sample in reverse (#7063) | ||
|
|
85399c12c2 |
Abstraction in MixerChannelView (#7057)
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`. |
||
|
|
d945ac1cbe | Fix scaling of PixmapButton in layouts (#7053) | ||
|
|
56e7f7de50 | Add setSampleRate to BasicFilters and update LOMM allpass sample rate (#7048) | ||
|
|
4049cc29d3 |
Fix Fader pixmaps (#7041)
|
||
|
|
36cb0ed7ca |
Extend TabWidget's style sheet options
# Extend TabWidget's style sheet options Extend the `TabWidget` class so that the text color of the selected tab can be set in the style sheet. Adjust the paint method to make use of the new property. Adjust the default style sheet as follows: * Background color of the selected tab is the green of the knobs * Text color of the selected tab is full on white Adjust the classic style sheet in such a way that nothing changes, i.e. the text colors of the selected tab and the other ones are the same. # Code review style changes Completely adjust the code style of TabWidget: * Pointer/reference close to type * Remove underscores from parameter names * Remove spaces from parentheses * Add space after if and for statements # Remove repeated iterator dereferences Remove repeated iterator dereferences by introducing variables with speaking names. Fixes #6730. |
||
|
|
6b21dc7896 |
Use Qt layouts for mixer channels (#6591)
Use Qt layouts for the mixer channels. These changes will enable several other improvements, like for example making the mixer and faders resizable, adding peak indicators, etc. This is a squash commit which consists of the following individual commits: * Remove extra transparency in send/receive arrows The extra transparency was conflicting with the positioning of the arrows in the layout * Begin reimplementing MixerChannelView MixerChannelView is now a combination of the MixerLine with the previous MixerChannelView * Adjust SendButtonIndicator to use MixerChannelView * Remove MixerLine - Move MixerChannelView into src/gui * Remove MixerView::MixerChannelView * Remove header of MixerLine * Change MixerView.h to use MixerChannelView Change MixerView.h to use MixerChannelView rather than MixerLine Also do some cleanup, such as removing an unused forward declaration of QButtonGroup * Create EffectRackView + Set height of sizeHint() using MIXER_CHANNEL_HEIGHT (287) * Remove include of MixerLine - Include MixerChannelView * Phase 1: Adjust MixerView to use new MixerChannelView * Move children wigets into header file * Phase 2: Adjust MixerView to use new MixerChannelView * Phase 3: Adjust MixerView to use new MixerChannelView * Phase 4: Adjust MixerView to use new MixerChannelView * Phase 5: Adjust MixerView to use new MixerChannelView * Phase 5: Adjust MixerView to use new MixerChannelView * Remove places where MixerChannelView is being deleted Before, MixerChannelView was not inherited by QWidget, meaning it could not have a parent and had to be deleted when necessary. Since the MixerView owns the new MixerChannelView, this is no longer necessary. * Replace MixerLine with MixerChannelView - Include MixerChannelView in MixerView * Replace setCurrentMixerLine calls with setCurrentMixerChannel around codebase * Add event handlers in MixerChannelView * Implement MixerChannelView::eventFilter * Update theme styles to use MixerChannelView * Add QColor properties from style - Set the Qt::WA_StyledBackground attribute on * Add effect rack to rack layout when adding channel * Set size for MixerChannelView - Change nullptr to this for certain widgets - Some custom widgets may expect there to be a parent - Add spacing in channel layout - Increase size of mixer channel * Retain size when widgets are hidden * Implement paintEvent - Rename states in SendReceiveState * Implement send/receive arrow toggling - Make maxTextHeight constexpr in elideName - Remove background changing on mouse press (is now handled in paintEvent) * Implement renaming mixer channels * Implement color functions * Implement channel moving/removing functions * Do some cleanup Not sure if that connection with the mute model was needed, but removing it did not seem to introduce any issues. * Include cassert * Replace references to MixerLine with MixerChannelView * Reduce height + Make m_renameLineEdit transparent + Retain size when LCD is hidden + Remove stretch after renameLineEdit in layout * Remove trailing whitespace * Make m_renameLineEdit read only + Transpose m_renameLineEditView rectangle (with 5px offset) * Set spacing in channel layout back to 0 * Remove sizeHint override and constant size * Use sizeHint for mixerChannelSize + Leave auto fill background to false in MixerChannelView + Only set width for EffectRackView * Set margins to 4 on all sides in MixerChannelView * Move solo and mute closer to each other Move the solo and mute buttons closer to each other in the mixer channels. Technically this is accomplished by putting them into their own layout with minimal margins and spacing. * Fixes for CodeFactor * Code review changes Mostly whitespace and formatting changes: remove tabs, remove spaces in parameter lists, remove underscores from parameter names. Some lines have been shortened by introducing intermediate variables, e.g. in `MixerChannelView`. `MixerView` has many changes but only related to whitespace. Spaces have been introduced for if and for statements. Whitespace at round braces has been removed everywhere in the implementation file even if a line was not touched by the intial changes. Remove duplicate forward declaration of `MixerChannelView`. * Adjust parameter order in MixerChannelView's constructor Make the parent `QWidget` the first parameter as it is a Qt convention. The default parameter had to be removed due to this. * Move styling of rename line edit into style sheets Move the style of the `QGraphicsView` for the rename line edit from the code into the style sheets of the default and classic theme. * More code review changes Fix spaces between types and references/pointers, e.g. use `const QBrush& c` instead of `const QBrush & c`. Remove underscores from parameter names. Remove spaces near parentheses. Replace tabs with spaces. Introduce intermediate variable to resolve "hanging" + operator. Replace the connection for the periodic fader updates with one that uses function pointers instead of `SIGNAL` and `SLOT`. --------- Co-authored-by: Michael Gregorius <michael.gregorius.git@arcor.de> |
||
|
|
4eba656bd3 |
New loop marker shortcuts, attempt 2 (#6382)
Co-authored-by: Dominic Clark <mrdomclark@gmail.com> |
||
|
|
ce722dd6b6 |
Refactor `SampleBuffer` (#6610)
* 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 |
||
|
|
f3d3a1421e |
Split TimeLineWidget into core and GUI parts (#7004)
|
||
|
|
c2811aebef |
Ghost notes for the automation editor (#6940)
Show ghost notes or sample track as a visual aid in the Automation Editor. --------- Co-authored-by: IanCaio <iancaio_dev@hotmail.com> |
||
|
|
3a928d80b2 |
Enforce lazy loading for FileBrowser (#6996)
|
||
|
|
dc8c49a539 |
Use std::optional for colour interfaces and storage (#6991)
|
||
|
|
aa050ae0b7 |
Fix memory leaks (#6879)
* 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 |
||
|
|
fad0011508 |
Analyze and improve search in the file browser (again) (#6985)
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. |
||
|
|
17c919879f |
Implement Note Types (#5902)
* Initial Commit Starts implementing Note Types. The two available types are RegularNote and StepNote. PianoRoll now paints the color with a different color for StepNotes. Pattern::addStep now sets the type of the note to StepNote. Negative size is still used to signal a step note. * Update Pattern.cpp to account for the Note::Type Updates the methods noteAtStep(), addStepNote() and checkType() from Pattern.cpp to account for the note type and not the note length. * Update PatternView::paintEvent to draw step notes PatternView::paintEvent now draws the pattern if the pattern type is BeatPattern and TCOs aren't fixed (Song Editor). Color used is still the BeatPattern color (grey) and the conditional doesn't look very nice and can be improved. Pattern::beatPatternLength was also updated so it accounts for the note type not note length. Review this method, as it looks a bit weird (particularly the second conditional). * Implements StepNotes setting a NPH with 0 frames Now, instead of TimePos returning 0 for negative lengths, we create a NotePlayHandle with 0 frames when the note type is StepNote on InstrumentTrack::play. * Improves PatternView::paintEvent conditional Improves a conditional inside PatternView::paintEvent by reversing the order in which they are executed. * Adds upgrade method for backwards compatibility Adds an upgrade method that converts notes with negative length to StepNotes, so old projects can be loaded properly. Explicitly set the Note::RegularNote value as 0. Make the default "type" value "0", so notes without a type are loaded as RegularNotes. * Addresses Veratil's review - Changes "addStepNote" so "checkType" isn't called twice in a row. - Changes style on a one line conditional. * Uses ternary expression on statement Reduces number of lines by using ternary expression. * Addresses PR review (sakertooth) - Changes class setter to inline - Uses enum class instead of enum - Uses auto and const where appropriate * Finished changes from review (sakertooth) - Used std::max instead of qMax - Fixed style on lines changed in the PR * Uses std::find_if to save codelines As suggested by sakertooth, by using std::find_if we are able to simplify the checkType method to two lines. * Addresses review from sakertooth - Reverts m_detuning in-class initialization - Removes testing warning - Removes unnecessary comment * Addresses DomClark's review - Rename the Note Types enum to avoid redundancy - Uses std::all_of instead of std::find_if on MidiClip checkType - Rewrites addStepNote so it sets the note type before adding it to the clip, avoiding having to manually change the type of the clip after adding the note * Updates MidiExport to use Note Types - Now MidiExport is updated to use note types instead of relying on negative length notes. - For that change it was necessary to find a way of letting MidiExport know how long step notes should be. The solution found was to add an attribute to the Instrument XML called "beatlen", which would hold the number of frames of the instrument's beat. That would be converted to ticks, so we could calculate how long the MIDI notes would have to be to play the whole step note. If the attribute was not found, the default value of 16 ticks would be used as a length of step notes, as a fallback. * Fixes ambiguity on enum usage Due to changes in the name of enum classes, there was an ambiguity caused in NotePlayHandle.cpp. That was fixed. * Addresses new code reviews - Addresses code review from PhysSong and Messmerd * Fixes note drawing on Song Editor - Notes were not being draw on the song editor for BeatClips. This commit fixes this. * Adds cassert header to TimePos.cpp - Adds header to use assert() on TimePos.cpp * Apply suggestions from code review Fixes style on some lines Co-authored-by: Dalton Messmer <33463986+messmerd@users.noreply.github.com> * Reverts some changes on MidiExport - Some changes were reverted on MidiExport and InstrumentTrack. We were storing the beat length on the XML of Instrument Tracks, but in reality the beat length is a per note attribute, and some instruments could run into a segmentation fault when calling beat length without a NotePlayHandle (i.e.: AFP). Because of that I reverted this change, so the beat length is not stored on the XML anymore, and instead we have a magic number on the MidiExport class that holds a default beat length which is actually an upper limit for the MIDI notes of step notes. In the future we can improve this by finding a way to store the beat length on the note class to use it instead. The MidiExport logic is not worsened at all because previously the beat length wasn't even considered during export (it was actually improved making the exported notes extend until the next one instead of cutting shorter). * Fix the order of included files --------- Co-authored-by: Dalton Messmer <33463986+messmerd@users.noreply.github.com> |
||
|
|
7268827624 |
Revamp synchronization with the audio engine (#6881)
The revamp consists of one lock. When the audio thread needs to render audio or another thread wants to run a change, acquiring the lock grants mutual exclusion to do one of the two. The intention is that this will provide stronger guarantees that changes do not run concurrently with the audio thread, as well as having the synchronization mechanism itself be free of data races (verified with TSan). |
||
|
|
a64bbc7633 |
Add BPM tags to built-in beat loops (#5439) (#6747)
* Added floating-point vorbis BPM tags to files in lmms/data/samples/beats * Added rounded BPM to filenames, surrounded by square brackets and separated from the rest of the filename by an underscore |
||
|
|
609c008a71 |
Keep master bus color on FX Mixer when switching project
Fixes #6398 |
||
|
|
ecc5ff8ca7 |
Fixes #6753: Lv2 help window issues (#6957)
This fixes at least three issues: * Help window is not synched with window manager's `X`-button * Help window is not being closed on track destruction or on closing the plugin window * Trims help window strings and force-adds a newline, because `QLabel::sizeHint` sometimes computes too small values. Now, together with #6956, all help windows fit their strings. Some help windows are too large by one line, but this seems better than forcing the user to resize them if they are too small by one line. |
||
|
|
652b1fa57a |
SubWindow: Increase to respect child's sizeHint (#6956)
Before this commit, on creation, `SubWindow` gets resized to exactly the children's `sizeHint`. This makes the child too small, since the `SubWindow` already contains a title bar and borders. With this commit, the `SubWindow` is calculated such that after rendering, the child window gets exactly the `size` that its `sizeHint` has previously suggested. Most of LMMS widgets are not resizable, but the Lv2 help window is a good example to test this out. The help windows now in most cases contain enough space to fit the help text. In some cases, it still does not fit, though debug prints show that the `size` matches the `sizeHint`. |
||
|
|
5c37aa2e2e |
Fixes #6786: Lv2Proc: Fix losing automation on export (#6944)
This PR is a about reloading an `Lv2Proc`, e.g. in case of a sample rate change. Prior to this PR, #6419 handled this by first saving the models into XML, then destroying and re-initializing the whole `Lv2Proc` and finally reloading the saved XML. However, #6786 shows that the automation is not properly restored in such a case. This PR thus attempts to not destroy the automatable models, just everything else. This is done by moving `Lv2Proc::createPorts` into the CTOR before calling `Lv2Proc::initPlugin`, which makes `initPlugin()` and `shutdownPlugin()` proper inverses of each other (note that in jalv, the ports are also created before the features are). The new class `Lv2ProcSuspender` adds an RAII interface for reloading the `Lv2Proc`. Note that another, possibly more clean approach would be to separate the features and the plugin from the models ("controls"), to then only destroy the features and the plugin. This could be done by having `Lv2Effect` contain an `Lv2Proc` and `Lv2FxControls` contain an `Lv2ProcControls`. Then the effect classes are the usual way round, and you still maintain the separation between processor and controls in the core LV2 code. (Similarly for the instrument, except we don't have a processor/control split for instruments, so an instance of each class would be contained within the same instrument instance.) - Thanks for this proposal to @DomClark . |
||
|
|
379acb970b | Lv2Proc: Fix shutdown routine (#6944) | ||
|
|
c779521730 |
Add slicer plugin (#6857)
* extremly basic slicer, note playback and gui works * very simple peak detection working * basic phase vocoder implementation, no effects yet * phase vocoder slight rewrite * pitch shifting works more or less * basic timeshift working * PV timeshift working (no pitch shift) * basic functions work (UI, editing, playback) * slice editor Ui working * fundamental functionality done * Everything basic works fully * cleanup and code guidelines * more file cleanup * Tried fixing multi slice playback (still broken) * remove includes, add license * code factoring issues * more code factoring * fixed multinote playback and bpm check * UI performance improvments + code style * initial UI changes + more code style * threadsafe(maybe) + UI finished * preparing for dinamic timeshifting * dynamic timeshifting start * realtime time scaling (no stereo) * stereo added, very slow * playback performance improvments * Roxas new UI start * fixed cmake * Waveform UI finished * Roxas UI knobs + layout * Spectral flux onset detection * build + PV fixes * clang-format formatting * slice snap + better defaults * windows build fixes * windows build fixes part 2 * Fixed slice bug + Waveform code cleanup * UI button text + reorder + file cleanup * Added knob colors * comments + code cleanup * var names fit convention * PV better windowing * waveform zoom * Minor style fixes. * Initial artistic rebalancing of the plugin artwork. * PV phase ghosting fix * Use base note as keyboard slice start * Good draft of Artwork, renamed bg to artwork * Removed soft glow. * Fixed load crashes + findSlices cleanup * Added sync button * added pitch shifting, sometimes crashes * pitch fixes * MacOs build fixes * use linear interpolation * copyright + div by 0 fixes * Fixed rare crash + name changes + license * review: memcpy, no array, LMMS header, name change * static constexpr added * static vars to public + LMMS guards * remove references in classes * remove constexpr and parent pointer in waveform * std::array for fft * fixed wrong name in style * remove c style casts * use src_process * use note vector for return * Moved PhaseVocoder into core * removed PV from plugin * remove pointers in waveform * clang-format again * Use std:: + review suggestions Co-authored-by: Dalton Messmer <33463986+messmerd@users.noreply.github.com> Co-authored-by: saker <sakertooth@gmail.com> * More review changes * new signal slot + more review * Fixed pitch shifting * Fixed buffer overflow in PV * Fixed mouse bug + better empty screen * Small editor refactor + improvments * Editor playback visual + small fixes * Roxas UI improvments * initial timeshift removing * Remove timeshift + slice refactor * Removed unused files * Fix export bug * Fix zoom bug * Review changes SakerTooth#2 * Remove most comments * Performance + click to load * update PlaybackState + zerocross snapping * Fix windows build issue * Review + version * Fixed fade out bug * Use cosine interpolation * Apply suggestions from code review Co-authored-by: Dalton Messmer <33463986+messmerd@users.noreply.github.com> * More review changes * Renamed files * Full sample only at base note * Fix memory leak Co-authored-by: Dalton Messmer <33463986+messmerd@users.noreply.github.com> * Style fixes --------- Co-authored-by: Katherine Pratt <consolegrl@gmail.com> Co-authored-by: Dalton Messmer <33463986+messmerd@users.noreply.github.com> Co-authored-by: saker <sakertooth@gmail.com> |
||
|
|
5596abb66a |
Improve search performance in FileBrowser (#6962)
Improves the search performance of the file browser by delegating the search to a worker thread. The main thread then builds the tree and displays it to the user. |
||
|
|
89c98a77a5 | LOMM (upward/downward multiband compressor) (#6925) | ||
|
|
f6eacb31ba |
AudioJack: Style fixes
These were done with `clang-format`, and slight patching where `clang-format` was a bit weird. |
||
|
|
c6ed4a274a |
First version of a new dynamic LADSPA control dialog (#2068)
Introduce a new version of the LADSPA control dialog which uses "bar controllers" and arranges them in a grid layout. Long parameter names are elided long if needed. The new dialog is implemented in the class `LadspaMatrixControlDialog`.
Note: it is still possible to reactivate the old dialog as it has not been removed yet. You can do so in `plugins/LadspaEffect/LadspaControls.h` by replacing the implementation of `createView()` with the following:
```
gui::EffectControlDialog* createView() override
{
return new gui::LadspaControlDialog( this );
}
```
Introduce the new base class `FloatModelEditorBase`. It serves as the base widget for widgets that manipulate a float model and provides some base functionalities like context menus, edit dialogs, mouse handling, etc. Currently `BarModelEditor` and `Knob` inherit from `FloatModelEditorBase`. Therefore lots of code was moved from `Knob` to `FloatModelEditorBase`.
`BarModelEditor` supports style sheets. See the changes in style.css for the available options and their usage.
Extend `LedCheckBox` so that it adds support to render the text with the default font in the default size. The class now supports two modes:
* Legacy mode
* Non-legacy mode
Legacy mode is the default and renders the LedCheckBox as before. The font is set to 7 pixels and all the text is rendered with a shadow.
Non-legacy mode uses the current font to render the text. The text is rendered without a shadow and the pixmap is centered vertically to the left side of the text. Non-legacy mode is currently only used in the context of the matrix LADSPA dialog. Toggle options are rendered using it as well as the "Link Channels" button.
Add `TempoSyncBarModelEditor` which adds a tempo sync option to a `BarModelEditor`. Please note that the code was mostly copied and adjusted from the `TempoSyncKnob` class. It was not attempted yet to unify some of the code because with the current design it seems to be a road to "inheritance hell". A better solution might be to refactor the code so that it becomes more composable.
What follows are the individual commit messages of the 64 commits that have been squashed into a single merge commit.
* First version of a new dynamic LADSPA control dialog
The new dialog shows the LADSPA controls in a matrix layout. Each row
corresponds to a LADSPA parameter. Each parameter can have several
channels which can be linked. Each channel has its own row of controls.
The class LadspaMatrixControlView was added by copying and modifying
LadspaControlView to get rid of the link buttons which are associated
with some controls and some labels.
* Remove trailing whitespaces
* Merge fix
* Use the new connect syntax
* Remove empty destructors
* Use override keyword
* Reformat a bit
* Use nullptr
* Use range-based loops
* Add BarModelEditor and improve layouts
Add the new class `BarModelEditor` which is intended to become a new way
to adjust values of float models.
Simplify the layout in `LadspaMatrixControlDialog` by removing some
nested layouts. Remove the "Parameters" column.
Adjust `LadspaMatrixControlView` to implement the following changes:
* Show the name of the control next to toggle buttons (`LedCheckBox`).
* Use the new `BarModelEditor` for integer and float types.
* SHow the name of the control next to time based parameters that use
`TempoSyncKnob`.
The names are shown so that the "Parameters" column can be removed.
Technical details
------------------
The class `LadspaMatrixControlDialog` now creates a widget that contains
the matrix layout with the controls. This widget is then added to a
scroll area. The layout is populated in the new method
`arrangeControls`.
Add some helper methods to `LadspaMatrixControlDialog` which retrieve
the `LadspaControls` instance and the number of channels.
Add the implementation of `BarModelEditor` to `src/gui/CMakeLists.txt`.
TODOs
------
Extract common code out of the `Knob` class so that it can be reused by
`BarModelEditor`.
* Use factory to create LADSPA control widgets
Replace the class `LadspaMatrixControlView` with the factory class
`LadspaWidgetFactory`. The former was a widget that wrapped the widget
representation of a LADSPA control in yet another widget with a layout.
The factory simply returns the configured widget so that it can be
incorporated directly in layouts or other widgets.
Adjust `LadspaMatrixControlDialog` so that it uses the
`LadspaWidgetFactory` instead of the `LadspaMatrixControlView`.
* Initial version of FloatModelEditorBase
Create an initial version of `FloatModelEditorBase`. It is intended to
become the base widget for all widgets that manipulate a float model and
provides some base functionalities like context menus, edit dialogs,
mouse handling, etc.
The initial version is a copy of `Knob`. The enum and its values have
been suffixed with "Temp" as they will be removed later anyway. Same
applies for the function `convertPixmapToGrayScaleTemp`.
* Remove Knob related code from FloatModelEditorBase
First removal of Knob related code from FloatModelEditorBase.
* Remove setHtmlLabel
* Remove enum for knob types
* Remove label related code
Remove setLabel and the members m_label and m_isHtmlLabel.
* Remove several Qt properties
* Remove angle related members and methods
* Remove unused members and includes
* Clean up includes
* Make BarModelEditor inherit from FloatModelEditorBase
Make `BarModelEditor` inherit from `FloatModelEditorBase` so that it
inherits all shared functionality. Currently the class mostly implements
size related methods and overrides the paint method.
* Move LadspaWidgetFactory to LadspaEffect
Move the class `LadspaWidgetFactory` to the project LadspaEffect to make
it hopefully compile with mingw32 and mingw64.
Interestingly the code compiled and worked under Linux and MacOS.
* Code adjustments after scripted checks
Add an include guard and an additional `#pragme once`. Add comments to
closing namespace scopes.
* Export BarModelEditor
Export BarModelEditor so that for example the LadspaEffect project/
plugin can use it.
* Improve rendering of bar model editor
Increase the margin from 2 to 3 so that we have a more prominent border
around the filled area.
Fix a problem in the rendering code which led to situations where the
bar was drawn to the left of the start position for small values.
Return a more exact minimum size hint.
* Elide long parameter names
Elide long parameter names if needed.
* Enable horizontal direction of manipulation
Extend `FloatModelEditorBase` so that it also allows manipulation of the
values when the mouse is moved in horizontal directions. The default is
to use the vertical direction.
Make use of this new feature in `BarModelEditor` which now reacts to
horizontal movements when changing values.
* Represent enum parameters using the bar widget
The implementation of the current LADSPA dialog in master uses knobs to
represent enum parameters. Therefore it should also work with the new
bar widget.
This gets rid of many labels with the parameter name followed by
"(unsupported)".
* Remove TODO in LadspaWidgetFactory
* Render text of LedCheckBox with default font
Extend LedCheckBox so that it adds support to render the text with the
default font in the default size. The class now supports two modes:
* Legacy mode
* Non-legacy mode
Legacy mode is the default and renders the LedCheckBox as before. The
font is set to 7 pixels and all the text is rendered with a shadow.
Non-legacy mode uses the current font to render the text. The text is
rendered without a shadow and the pixmap is centered vertically to the
left side of the text.
The non-legacy mode is currently only used in the context of the matrix
LADSPA dialog. Toggle options are rendered using it as well as the "Link
Channels" button.
* Use "yellow" LEDs for bool parameters
Use "yellow" LEDs (which are actually blue) for dynamically added bool
parameters so that the dialog is consistent with regards to the LED
colors. The "Link Channels" button also uses a "yellow" LED.
* Fix Qt5 builds
Fix the Qt5 builds which do not know horizontalAdvance as a member of
FontMetrics.
Also refactor LedCheckBox::onTextUpdated to make it more compact.
* Style sheets for BarModelEditor
Add style sheets options for BarModelEditor. See the changes in
style.css for the available options and their usage.
The members that can be manipulated by the style sheet options are
initialized accoriding to the palette so that the BarModelEditor should
also render something useful if no style is set.
Adjust the paintEvent method to use the style sheet brushes and colors.
* Layout optimizations
Set the vertical scroll bar to always show so that the controls do not
move around if the scroll bar is hidden or shown.
Set the margin of the grid layout to 0 so that the whole dialog becomes
tighter.
* Get rid of initial scroll bars
Make sure that the widget is shown without a scrollbar whenever possible
using the following rules.
If the widget fits on the workspace we use the height of the widget as
the minimum size of the scroll area. This will ensure that the scrollbar
is not shown initially (and never will be).
If the widget is larger than the workspace then we want it to mostly
cover the workspace. In that case the minimum height is set to 90 % of
the workspace.
* Switch to a green theme
Switch to a green theme to better match the default theme.
* Adjust classic theme
Adjust the classic theme so that it renders the bars in a legible way.
* Fixes for CodeFactor
Remove virtual keyword from methods that are marked as override.
Remove whitespaces that make CodeFactor unhappy. One of these fixes
includes moving the implementation of
LadspaMatrixControlDialog::isResizable into the cpp file.
* CodeFactor is still unhappy
Remove a blank line after the constructor.
* Center align time based controls
Align time based controls, i.e. knobs, in the center.
The implementation defeats the purpose of the widget factory a bit but
it makes the design look nicer.
* Fix build
Fix the build by adjusting the enums. I added the changes while writing
the commit message for the merge commit but they did not make it.
* Attempt at CodeFactor warning
Try to make the last CodeFactor warning disappear.
* Add bar controller with tempo sync option
Add `TempoSyncBarModelEditor` which adds a tempo sync option to a `BarModelEditor`. Please note that the code was mostly copied and adjusted from the `TempoSyncKnob` class. It was not attempted yet to unify some of the code because with the current design it seems to be a road to "inheritance hell". A better solution might be to refactor the code so that it is more composable.
Another option might be to move the tempo sync functionality into a class like `FloatModelEditorBase`. Although this would not be a 100% right place either because `TempoSyncKnobModel` inherits from `FloatModel`. In that case we'd have specialized code in a generic base class.
Adjust `LadspaWidgetFactory` so that it now returns an instance of a `TempoSyncBarModelEditor` instead of a `TempoSyncKnob`.
Remove the extra layout code from `LadspaMatrixControlDialog.cpp` as most things are bar editors now.
Adjust `TempoSyncKnobModel` so we do not have to make `TempoSyncBarModelEditor` a friend of it.
* Another attempt to please CodeFactor
Have another attempt to fix CodeFactor's complaints about `LadspaMatrixControlDialog.h`.
* Coding conventions, blanks and blank lines
Remove lots of unnecessary white space. Remove blank lines. Remove leading underscores from parameters.
Remove line breaks in `TempoSyncBarModelEditor.cpp` to make the code more readable. Remove repeated method calls by introducing local variables.
* Break down complex method
Break down the complex method `TempoSyncBarModelEditor::updateDescAndIcon` by delegating to the new methods `updateTextDescription` and `updateIcon`.
* Another attempt to please CodeFactor
Another attempt to fix `LadspaMatrixControlDialog.h` to please CodeFactor.
* Work on TODOs
The TODO "Assumes that all processors are equal..." has been turned into a comment when we start iterating over the channels. If the channels are not of the same structure this would likely also have been a problem in the old implementation.
The TODO "Use a factory..." has been removed as this is already done.
The include of `FloatModelEditorBase.h` in LadspaWidgetFactory has been removed.
* Modifier keys for mouse wheel adjustments
Integrate the changes of commit
|
||
|
|
d5e6ac6dc5 |
Lv2Proc: Delay setting worker iface (Fixes #6946) (#6947)
* Lv2Proc: Delay worker iface (Fixes #6946) (#6947) This delays passing the `LV2_Worker_Interface` to the `Lv2Worker` class, because prior to the patch, the instance, which provides the interface, has not been initialized yet, which resulted in a segfault. * Update src/core/lv2/Lv2Worker.cpp Co-authored-by: Dalton Messmer <33463986+messmerd@users.noreply.github.com> * setIface -> setInterface * `if(` -> `if (` * Update src/core/lv2/Lv2Proc.cpp Co-authored-by: saker <sakertooth@gmail.com> * Rework, editorial, from @sakertooth * Fixup: `interface` is reserved on MSVC https://stackoverflow.com/a/25234279 * Apply suggestions from code review Co-authored-by: saker <sakertooth@gmail.com> * Initialize handle/interface as nullptr --------- Co-authored-by: Dalton Messmer <33463986+messmerd@users.noreply.github.com> Co-authored-by: saker <sakertooth@gmail.com> |
||
|
|
63d03fa3a7 |
Fix Uninitialized Value Conditional Jump
Introduced in #5970 , `CPULoadWidget::m_stepSize` is uninitialized, leading to valgrind warnings: ``` ==9429== Conditional jump or move depends on uninitialised value(s) ==9429== at 0x3715A9: int const& std::max<int>(int const&, int const&) (stl_algobase.h:262) ==9429== by 0x59E3BB: lmms::gui::CPULoadWidget::stepSize() const (CPULoadWidget.h:59) ==9429== by 0x59DA2E: lmms::gui::CPULoadWidget::paintEvent(QPaintEvent*) (CPULoadWidget.cpp:78) ``` Even though `grep` shows: ``` data/themes/classic/style.css: qproperty-stepSize: 4; data/themes/default/style.css: qproperty-stepSize: 1; ``` It seems like the issue is caused by paint events occurring even before the style sheet has been applied. In order to fix this, and to be future proof with style sheets which do not set it, we initialize `CPULoadWidget::m_stepSize` to `1`. |
||
|
|
ca9e98959d |
Fix LcdFloatSpinBox mouse behavior and negative values (#6923)
* Fix LcdFloatSpinBox mouse behavior and negative values |
||
|
|
999c10e4b3 |
Adds feature to edit tangents of Cubic Hermite progressions (#5924)
Enables the editing of a node's tangents of Cubic Hermite progressions. * First commit This commit introduces the use of AutomationNodes instead of just floats for keeping the automation values. The AutomationNodes will give more flexibility when it comes to storing extra information about the values (and make it possible to have multiple progression types in the future). Now the tangents are stored on the node, requiring one less timeMap on the automation pattern. Some methods had to be changed for that, since before they used const_iterator, which wouldn't allow us to change the tangent values. TODO: - Check TODO comments that were added in places of the code I had some doubts about. - Maybe change the timeMap to hold pointers to AutomationNodes and not actual instances. - In some pieces of the code, I check if the AutomationNode already exists before setting its value or creating another node. I think that's unnecessary since if I create another node and assign it to the current existing one it could just clone its value. (That would not be valid for pointers to AutomationNodes, so that's something to consider when deciding between the two). - I still didn't find a good solution for renaming QMap::iterator method from "value()" to something else, so now we have lines that look a bit odd like "it.value().getValue()", because value() is actually returning the node, and getValue() is getting the node's automation value. * Implements inValue/outValue on Automation Nodes This commit is a big change in comparison to the previous one. Automation nodes now have a inValue and outValue instead of a single value. The inValue represents the core value of the node, which is used for incoming progressions. The outValue represents the value of the node for progressions starting from that node on. In practice, the true value of the node is the inValue and outValue represents a way of creating discrete jumps in a node's position. By default inValue and outValue are the same. The user will then be allowed to change the outValue to create those discrete jumps. Because their values might be different, we now need two tangents for a single node: One for the curve coming before the node and one for the curve coming after the node. So instead of a single tangent variable, we now have inTangent and outTangent. If inValue and outValue are the same, so are inTangent and outTangent, but if they are different both are calculated according to the curve before and after the node. On the Automation Editor, the inValue of the node is represented by our default blue circle, while the outValue is represented by a red circle with 80% alpha (we should add a variable to the Automation Editor class to hold the color of this second circle in the future). Lots of comments were added on the modified files to explain the existing methods where changes were required (not only explaining the logic of the methods but the reason behind using inValue or outValue on them). Lots of TODO comments were also added as placeholders for changes that could or should be done before the finishing of this PR (or after it). For now only the logic for the nodes was added, but there's still no way for the user to change outValues (on the next commit a small placeholder shortcut will be added to do that for testing purposes). The drawing of the notes detuning on the piano roll was updated to account for the discrete jumps. The drawing of the pattern TCO was updated to account for the discrete jumps. The drawing of the pattern on the AutomationEditor was updated to account for the discrete jumps. IMPORTANT: - There were changes to the loadSettings and saveSettings of AutomationPatterns, to account for inValues and outValues, but I didn't create an upgrade routine yet. Some behavior that is important to mention: - Most operations on nodes (drawing, moving, X/Y flipping, and even selection copy/paste, apparently not fully finished) ignore the outValue, basically reseting it to the inValue. So when an user moves a node with a discrete jump, for example, that discrete jump will be lost and the user will need to set it again. Obviously in the future we might want to keep that information, but that isn't a critical issue, just a behavior that can be improved later by upgrading the code. - Later on we might want to connect a signal to the AutomationNode class, so it calls generateTangents when node data is changed. - When an object is disconnected from an automation pattern and it has to rescale the values so they fit the new range of values (max and min) the outValue is reset, meaning all discrete jumps are lost. This behavior will be changed in the future. Things that I think are also important noting: - Mainly in the src/gui/editor/AutomationEditor.cpp file there were lots of codes that apparently are related to a feature that is not yet finished (moving/cutting/copying/pasting selections of automation values). This doesn't sound good unless it's currently being worked on. I tried my best to update the current code to comply to the use of AutomationNodes so their developing can be picked up from a unbroken state. As with other operations involving AutomationNodes, they only account for the inValue discarding any discrete jumps that were present. - I added comments on some logic that seemed flawed in the src/gui/editor/AutomationEditor.cpp file so it can be reviewed. It's beyond the scope of this PR, but since I had to read and change a lot on that file I thought it was pertinent to at least comment those observations. * Fixes and refactor code on AutomationEditor.cpp While implementing the automation nodes, I noticed AutomatinEditor.cpp had some issues regarding flawed logic, code style convention, code that could comply to DRY paradigm, conditions that resulted in Undefined Behavior and unused legacy code. That's probably due to how old some changes are, they probably reflect a much different state of LMMS's code base. To make the transition to automation nodes a better one and avoid having to rework everything later I'm using the fact I have to get in touch with most of this code to try to fix some things. This commit starts refactoring AutomationEditor::mousePressEvent and AutomationEditor::mouseMoveEvent. There are still things to be improved on both but I'll slowly commit them so I can have better versioning control of the PR. Some changes worth noting: - A new action was created in the AutomationEditor class for drawing lines, since its logic was too mixed up with the logic of drawing and dragging a single node. - Changed most variable names to fit the current code style (just very few left to change). - Improved comments explaining the code. - Created a separate method for checking if the mouse position is sitting over an existing node (previously this code was repeated inside the event method and it had flaws on its logic, most of the times returning that the user didn't click a node even when he/she clicked one). Method is called getNodeAt(x,y,r), r being the "radius" to be considered (not actually a radius, the area is actually a square). Some changes that are still planned: - Removing legacy code for features that weren't finished (select and move selection) if it's agreed. - Adding some logic to the DRAW_LINE action so it can be even improved. - Not forgetting the main focus of the PR, adding a way for the user to edit the outValue of nodes. * Avoids unnecessary check in putValue When adding a value to a particular time, instead of checking if there's a node there already and manually setting its value, we just assign it with a new AutomationNode. QMap silently removes the existing node and adds the new one. * Adds upgrade routine for the automation nodes Adds an upgrade method for the change in the automation nodes settings. The "value" attribute of the <time> element is deleted and assigned to the "inValue" and "outValue" attributes. Now older project files can be loaded properly. * Allows dragging outValues on the Automation Editor This commit introduces a way for the user to drag outValues on the Automation Editor, by Alt+clicking the outValue red node and dragging up and down. A new action was added for that purpose, called MOVE_OUTVALUE. When the user clicks a outValue sphere with the Alt modifier, m_action is set to MOVE_OUTVALUE, and the time position of the node being affected is stored on m_draggedOutValueKey. That is later used on the mouseMoveEvent to update the outValue of the node. Removed repeated code on the mouseReleaseEvent and removed excessive blank lines after a method. Things to keep in mind when testing through this commit's build: - Creating/Moving an automation node resets the outValue - When the outValue is changed, generateTangents isn't called automatically. So you'll notice that after adding another automation node the curves change (that's because after the new node being added the tangents are then recalculated). Still lots of work ahead! * Small fix inside AutomationPattern.cpp Unnecessary loop was removed with call to appropriate method. * Creates separate files for AutomationNode Creates a separate header and source file for the AutomationNode class. * Adds more members to AutomationNode Adds 2 new members to the AutomationNode class: m_pattern - A pointer to the pattern this node belongs to m_key - The time position (timeMap key) of this node The constructors (and places they were used) were updated accordingly. AutomationNode was also made a friend class of AutomationPattern so it can access private/protected methods from its pointer. This will be later used to allow AutomationNode's to call generateTangents once their values are updated. Small fix on a code block related to moving selections inside the mouseMoveEvent from AutomationEditor. * Removes unused code from AutomationEditor This commit removes code that was not currently used in the AutomationEditor. Most of it was related to a feature I believe was once functional but broke along the way, but the code was not cleaned up in an effort to fix it later. The feature allowed selecting and moving/cutting/copying/pasting/removing values from the automation pattern. It added up to lots of lines of code, which so far I was keeping up to date to the changes. However, I believe (and others devs agree) that rewritting this code later might be a better approach than trying to fix what we currently have, so I'm removing the obsolete code. The git history will allow us to reference back to it when implementing the feature again and this will make it harder for this PR to introduce bugs because a certain affected feature couldn't be tested. It also makes reviewing easier, for there are less affected code to cover. For reviewing purposes: I used a single commit for removing the mentioned code, so its diff in relation to the previous commit should give a good idea of everything that was removed. * Changes to the outValues now update the tangents The methods that change the inValue and outValue of nodes now also generate new tangents for the previous, current and next nodes (the ones affected), so now when the user drags the node outValue the curve is updated accordingly. * Keeps discrete jumps when flipping patterns Adds a method to the automation node that returns the valueOffset between inValue and outValue. AutomationPattern::putValue now has an extra parameter called outValueOffset (defaults to 0), so when it adds a node to the timeMap the outValue is set according to this offset. flipY() will calculate the offset and invert it, so the discrete jumps are kept but flipped vertically as well. flipX() doesn't need to calculate this offset because it uses the outValue itself. Obs: I believe cleanObjects() was meant to be called everytime AutomationPattern::flipX() is called, but it was inside a conditional that would only call it on some situations. I moved it outside of the conditional. * Allows reseting outValues on the AutomationEditor User can now reset the outValue of nodes on a very analogous way to removing nodes but with the Alt key pressed. Alt + right clicking over the node (or dragging over an area), or Alt + clicking on it on Erase mode (or dragging over an area) will reset the outValues of the nodes. To do that, two new actions were created: ERASE_VALUES (for the regular node removing) and RESET_OUTVALUES (for the outValues reseting). Those are checked for in the moveMouseEvent, which acts accordingly. The removePoints() method was removed and two new methods were added instead: removeNodes() and resetNodes(), which will remove nodes on a tick range or reset them respectivately. The AutomationNode.h and AutomationNode.cpp files were fixed to fit the current code style conventions. The other files were kept as is, so they can be changed all at once at the end of the PR. Change requests made by Veratil were done. * Makes so dragging nodes keep the outValue This commit makes a small change to setDragValue. When starting the drag (m_dragging == false), it checks if the time position being dragged already has a node. If it does, then the offset between inValue and offValue is stored on m_dragOutValueOffset so it can be used on the putValue calls, keeping the offset. If there isn't a node in the time position, m_dragOutValueOffset is set to 0. * Fixes code style on modified code Fixes the modified code to comply to current code style convention. I tried to keep the changes exclusive to the lines modified by this PR (to keep the diff cleaner), but I might have fixed a couple of other because either they were hard to differentiate on the current diff or because they were too close in context. But still, tried to keep changes mostly to the lines actually changed by the PR. * Adds a QProperty for the node outValue color Adds a CSS property for the outValue color and renames the one used for the inValue color so they are consistent. Colors were added to classic and default themes. The original inValue colors were kept, but to fit with the outValue node they had a little bit of transparency added. * Adds doxygen comments on methods Adds doxygen comments explaining methods that were either introduced by this PR or which had parameters modified by this PR. Changes valueAt(timeMap::iterator, int offset) method, so it can handle offsets equal to 0 properly. This method is currently never used with an offset of 0 (because this case scenario is handled before this method is called), but it was a simply modification so I just added the conditional to make it possible to use an offset of 0. * Refactor flipX and flipY methods AutomationPattern::flipX and AutomationPattern::flipY had some issues to the logic that caused UBs (from accessing an iterator past QMap::end()) and possibly misbehaviors when flipping an empty pattern. Both were refactored to fix those noted issues. * Add a new edit mode to Automation Editor Adds another editing mode to Automation Editor (DRAW_OUTVALUES), specific to deal with node outValues. The Pixmap being used is the same as the DRAW edit mode for now. The way it works now: DRAW Mode (Shortcut SHIFT+D) Shift + Left click = Draws lines of nodes Left click = Draws/Drag node Right click = Remove nodes ERASE Mode (Shortcut SHIFT+E) Left click = Remove nodes Right click = Reset outValues DRAW_OUTVALUES Mode (Shortcut SHIFT+C) Left click = Drags outValue Right click = Reset outValues Now using a switch statement on the events to make things more organized. * Improves the Draw OutValue edit mode Now, instead of only being able to change an outValue by clicking over the sphere representing it, the user can also click on any time on the pattern: If the quantized time of the place he clicked has a node, the outValue of its node will be set to the value where the mouse click happened and the outValue will start being dragged. Very similar to the way it works for the node itself on the draw mode. * Adds mutex to AutomationPattern Adds a recursive mutex to the AutomationPattern class and locks it on every method that access the member variables. Also rename the mutex from the AutomationEditor class and add locks to some methods that didn't have it before (except on methods that don't access member variables). * Veratil's review changes Applies changes requested by Veratil: - Replaces NULL with nullptr where necessary on AutomationEditor.cpp - Fixes spacing on the mutex commit (plus some other places) - Changes some if blocks to one liners - Replace while with do-while on some places, since the condition was already checked for earlier on the method. - Moves getNodeAt call a level up on the block, since it's called on both conditionals below. - Fixes identation on some code inside AutomationEditor::mousePressEvent. - Adds explicits blocks on a switch statement. Even though this was not necessary for that particular one (because there was no variable declaration inside it) it helps keeping it consistent with another switch statement that happened earlier. I also added a break statement to the last case of a switch (even though it was not needed, it's safer to avoid mistakes in the future with new cases being added). * Changes the inValue sphere to be draw first The red sphere representing the outValue was drawed after the blue sphere representing the inValue. Because of that, if they had the same value the red sphere would be on top. For the user, it makes more sense to be able to see the blue sphere representing the input value on top instead. This commit changes the order of the drawing. * Changes comments and variables names Fixes some comments pointed out on Spekular's review. Changes the AutomationNode's variable m_key to m_pos (leaving a comment on the header reminding that it matches the timeMap key). Removes comments related to removed code. Fixes code style on a pointer declaration. * Changes QProperty variables to use MEMBER Instead of creating a getter and setter for each QProperty, we use MEMBER instead and access those variables directly. * Overloads some AutomationNode's operators Overloads compound assignment operators +=, -=, *= and /= for AutomationNodes, making it so they affect the inValue and outValue of the node being assigned. Changes AutomationPattern::flipY() so it uses the new operators. * Improves getNodeAt method Makes the AutomationEditor::getNodeAt method more efficient, by exiting if the node we are checking is already past the position we given (since the nodes are ordered in the timeMap, all subsequent nodes will also be past the position). Now instead of returning the last node that is inside the coordinates, it returns the first. Also improves AutomationEditor::mousePressEvent to avoid getNodeAt being called twice unnecessarily. * Changes behavior of setDragValue Now, instead of keeping the offset between the inValue and outValue while dragging a node, setDragValue will either keep the current outValue intact, or move it together with the inValue if they are the same. The putValue method now doesn't have an offset parameter. If we want to put a node with an outValue different from the inValue we use putValues instead. * Moves getNodeAt to an upper level, reducing lines Creates a boolean before the m_editMode switch, that will be true if the action being processed affects outValues and false if it affects inValues. That way we can move the statement clickedNode=getNodeAt() before the switch-case, reducing repeated lines. * Changes icon of Draw OutValue edit mode Changes the icon for the Draw OutValue tool and toolbar action, so it's different from the Draw mode. Just a placeholder until a visual artist come up with something better or we change the controls. * Removes unnecessary non-const methods Some getter methods had declarations for both const and non-const object types, when just the const one were needed (no changes to the object are made). The unnecessary ones were removed. Also fixes formatting on operator /= method. * Fixes formatting and doxygen comments Fixes doxygen comments on AutomationPattern.cpp and AutomationEditor.cpp (also changes one so it uses the same format as the rest of the file). Fixes some formatting issues (removal of excessive tabs, changing some statements to be one line instead of multiple lines, fixing of spacing, use of one line ifs, removal of unnecessary else on a method, use of ternary expressions, etc). * Adds helper macros for AutomationNodes Adds 3 macros to the AutomationNode header file: INVAL, OUTVAL and POS, which return the InValue, OutValue and Key of a node respectively. This improved redability and made statements shorter on the AutomationPattern.cpp code. Macros weren't added for InTangent and OutTangent, since those are only used once in the code (and INTAN/OUTTAN might not have their meaning as obvious as INVAL/OUTVAL). * Removes tabs from ternary operator Removed tabs to improve formatting on a ternary operator as requested and also removed a comment that doesn't seem necessary. * Update files to use AutomationNode macros Other files besides "AutomationPattern.cpp" also included the AutomationNode.h header and handled automation nodes, but they weren't using the macros. Those were updated to use INVAL, OUTVAL and POS macros. Two conditionals were changed to one liners for consistency. * Addresses my own code review This commit addresses some fixes from a review I made from the code on Github and also one requested change from Veratil. Changes: - Fixes code style issues. - Adds a helper MACRO to return the offset between the inValue and outValue of a node and use it where getValueOffset was called. - Removes conditional that was not needed inside AutomationPattern::valueAt. - Updates InlineAutomation.h to use the helper MACROs and account for the outValue when deciding whether to save or discard an inline automation. - Adds TODO comments on two loops present on src/code/AutomationPattern.cpp that could be optimized. - Fixes some comments. - Uses INVAL(it) instead of valueAt(POS(it)) on the flip methods when possible. - Adds a resetOutValue() method to AutomationNode and use it where convenient. - Fixes a small "bug" where flipping a pattern from the TCO context menu, when the pattern is smaller than the TCO, would use the inValue of the last node for the node created at the end of the TCO instead of the outValue (which is the value that the position would have if the pattern continued). * Addresses Veratil's review - Fixes some code style issues - Changes to improve readability at some snippets - Uses if one-liners when convenient - On a polynomial expression inside AutomationPattern::valueAt, uses some variables to improve readability (those will be optimized out by the compiler) - Removes unnecessary casting on alignedX variable inside AutomationEditor::mousePressEvent (it was also using C-style casting instead of static_cast) * Adds helper MACROs for node tangents Adds INTAN and OUTTAN macros to retrieve a node's InTangent and OutTangent respectively, and replace calls to getInTangent/getOutTangent with those macros. * Fixes header inclusion order * Removes mutex from AutomationEditor Now that there's a mutex protecting the AutomationPattern on its own methods, there's no need to have a mutex on the AutomationEditor class. The editor's member variables don't need to be protected because LMMS's UI runs from a single thread. This commit removes the m_patternEditorMutex. * Locks mutex on AutomationPattern copy assignment On the copy assignment constructor of AutomationPattern, the values were being copied from the other pattern without locking its mutex, which could result in race conditions. Now the constructor locks the other pattern's mutex. Other small changes: - Removes unnecessary comments and fix others. - Uses the OFFSET macro on the generateTangents method. - Uses the resetOutValue() method on AutomationEditor::mousePressEvent, in a place where I forgot to change it. * Changes resetOutValue() so it generates tangents Changes the AutomationNode::resetOutValue() method so it calls setOutValue() instead of directly setting the m_outValue, since the latter will also take care of generating tangents. Fixes small bug where reseting outValues would not recalculate the tangents. * Changes some methods to use for loops AutomationEditor::removeNodes and AutomationEditor::resetNodes were previously using while loops where for loops are much more well suited. Both methods were changed to use those instead. * Move removeNodes/resetNodes to AutomationPattern - Renames AutomationPattern::removeValue to AutomationPattern::removeNode. - Moves AutomationEditor::removeNodes and AutomationEditor::resetNodes to AutomationPattern, since they are more suited there and could be reused in other areas of code that need to remove a range of nodes. * Optimizes loop inside putValue/putValues There was a TODO comment about a loop that could be optimized inside putValue/putValues. It went through all the ticks in the surrounding values instead of just going through the nodes that were in that range. Now that the removeNodes/resetNodes methods are part of the AutomationPattern we can use them to optimize the loop. Changes: - removeNodes/resetNodes will remove or reset a node if a range with start == end is given (before it would return). - The loop was replaced with a call to removeNodes from newTime + 1 to newTime + quantization() - 1 (which will cover the nodes that are between the quantization limits). We add a conditional that quantization() is greater than 1 to avoid a bug where the added node is removed by that call because we get a range from [newTime + 1, newTime]. * Adds comment to mysterious calculation There was a calculation on the drawAutomationPoint method that wasn't really obvious at first glance. Thanks to @PhysSong, a comment was added explaining the reasoning behind the calculation. * Reduces indentation on getNodeAt Reduces one indentation level on AutomationEditor::getNodeAt() by reversing the conditional. Fixes style on switch statements. * Applies Veratil suggestions Condense two code blocks in a single one by using a ternary operator on the only variable that changed between them. Comment out a "else" block that currently doesn't have anything (placeholder for future code). Format a for statement in multiple lines to improve readability. * Updates comment from changed code Updates comment to better match the recently changed code. * Uses lambda functions to extract code Uses two helper lambda functions inside AutomationEditor::mousePressEvent to extract code and use fewer lines on places where it's repeated. * Fixes behavior of AutomationPattern::flipX To truly flip a pattern horizontally, we also needed to swap the inValues and outValues of the nodes being flipped. This commit fixes that behavior by including the swap when necessary. Also adds a TODO comment regarding the behavior of the generateTangents method when the difference between inValue and outValue is very small. * Changes pattern XML for backwards compatibility Changes the inValue attribute name on the XML from "inValue" to "value" to make projects created with the new automation pattern partially backwards compatible (outValues will still not be loaded obviously, but the inValues will be loaded as the regular pattern values we had before). * Fixes bug on AutomationPattern::resetNodes Fixes bug on AutomationPattern::resetNodes: If it was called with tick0 == tick1, m_timeMap.find() return value was being used to call resetOutValue. When QMap::find() doesn't find a value it returns QMap::end() though, resulting in a SegFault. Fixed by checking if the return value is QMap::end() first. * Adds drawing of automation node tangents This introduces a method on the AutomationEditor that draws a line and an ellipse representing the inTangent and outTangent of Automation Nodes, so they can be visualized on the Cubic Hermite progression. The tangents are not yet editable. * Adds mode to edit tangents Adds the edit mode that will be used to edit tangents. For now there's no functionality, only the GUI elements were added. * Adds comment about copy-assignment Adds a note about the default copy-assignment from AutomationNode being used on the AutomationPattern constructor. If any dynamic allocated resources are added to the class, an user-defined copy-assignment constructor should be used instead. Also changes the position of an arithmetics operator on a multiline statement for readability. * Changes flipY logic and address PhysSong review This commit addresses PhysSong review: - An if-statement was replaced with a ternary operator on AutomationEditor::paintEvent(). - One comment was improved on PianoRow::drawDetuningInfo() to make it clearer that drawing cubic hermit curves as straight lines is just a temporary thing. - While applying the requested changes on the AutomationPattern::flipY() method, I noticed that even though it accepted any integer values as min and max, the current logic (both on master and on the previous commit from this PR) would only work if the range was [-max,+max] or [0,+max]. If min was -5 and max 10 for example, the flipping could return us a pattern with values out of range. This commit replaces the logic with an improved one that now relies on the distance between the node and the edges of the range instead, thus working for any range instead of those two mentioned earlier. The new logic also attend to the request of using a for-loop and also using in-place operations. * Implements the dragging of node tangents Implements the action of dragging node tangents. A method called getClosestNode returns the node that is closest to the mouse X position. Then the action begins, with the tick of the node having its tangent dragged stored in a local variable. It's also calculated whether we are dragging the inTangent or outTangent. The new tangent is calculated as the tangent between the current mouse position and the automation node. * Saves tangent information from automation patterns Now saves the tangent values of automation pattern nodes. While loading, for backwards compatibility, if any node doesn't have tangent information the tangents are generated. Else, they are loaded from the project file and kept. Dragging a node still resets all tangents. Moving an outValue resets the tangents from the surrounding nodes. * Implements the locking of tangents Now when the used manually edits a node's tangent, the node locks both its tangents so they aren't recalculated by AutomationPattern::generateTangents(). When the used resets the tangents of a node (by right clicking close to it on the edit tangents mode) they are unlocked again, and are allowed to be recalculated. This information is saved on the project file as well. A macro was added to quickly return whether a node's tangents are locked. AutomationEditor was made a friend class of AutomationPattern to enable it to call generateTangents when a node's tangent is reset. * Checks only for inTan on the LoadSettings When loading an automation node, when checking if we have tangent information we only have to check for either inTan or outTan, because if we have one we will have the other. * Adds a convenient way to reset multiple tangents Now right clicking and dragging on Edit Tangents mode will reset multiple tangents (similar to how it works for the reseting and removal of nodes). * Fixes small bug on generateTangents AutomationPattern::generateTangents() expects that a valid node is given. While generating the amount of tangents requested, it avoids going out of bound by checking if the node after the one being iterated is the end of the timeMap, then setting the tangents to 0 and returning. That worked fine before, but now we skip nodes that have their tangents locked, so it could happen that the last tangent was locked and skipped and we end up iterating m_timeMap.end(). This was causing a segmentation fault if we edited the tangents of the last node and added a new node after it. To avoid that, a second conditional was added to the for-loop to check if the current node is the end of the timemap. * Fixes bug with Edit Tangents shortcut Bug found by @superpaik. I was setting the Edit Tangents shortcut to the Draw OutValues mode, overriding its correct shortcut and leaving Edit Tangents with none. * Disables Edit Tan mode on other progressions The Edit tangents mode is now disabled when the user switches to a different progression mode and reenabled when it changes back to Cubic Hermite mode. * Keep tangents when dragging nodes As requested by @superpaik after testing, logic was added to the AutomationPattern::setDragValue method to keep a node's tangents if they were locked. First, the method checks if the tangents were locked in the first drag iteration and store its values if they were. Then, everytime the dragging routine puts a new value in the timemap, it will set its tangents and lock them if needed. * Changes tangent calculation behavior Changes the behavior of the tangent calculation for the Edit Tangent mode. The new behavior will be submitted for testing to see if it's considered better than the previous one, and reverted if it isn't. Also fixes a possible division by 0 bug. * Fixes undo/redo with tangents editing The tangents editing logic was missing adding a journalling checkpoint, hence the undo/redo wasn't working properly. This commit fixes it. * Uses function to check if tangents can be edited As per requested by PR review, instead of checking if the automation clip uses Cubic Hermite progression to allow changing tangents, we now instead use a method that will return true if the current progression type allows tangent editing. That way it's easier to allow tangent editing for new progression types that might be added in the future. * Fixes bug reported by zonkmachine - The Edit Tangents button was not updating correctly when the clip was changed inside the automation editor. This was fixed by making the update routine a separate method and calling it on the places necessary (when changing progression modes and when changing clips). - Some suggestions from messmerd PR review were also included. * A couple review requests forgotten - Just adds 2 more review requested changes that were forgotten in the previous commit. * Address Sakertooth's review * Adresses Sakertooth's review * Address Sakertooth's review - Simplifies method that updates the edit tangent button on the automation editor --------- Co-authored-by: Hyunjin Song <tteu.ingog@gmail.com> |
||
|
|
85310e75d3 |
Order of includes and forward declarations
Fix the alphabetical order of all includes and forward declarations. |
||
|
|
339ee6d1e9 |
Merge remote-tracking branch 'upstream/master' into 2510-SetupDialogWithLayouts-MasterMerge
Merge master to integrate the changes of: * |
||
|
|
8fb9c3e6a2 |
Fix warnings in Clang build (#6893)
* Fix unused variable warning * Fix implicit conversion warning * Fix unused lambda capture in DataFile.cpp * Fix implicit conversions in InstrumentFunctions.cpp * Fix operator precedence bug in Flags.h * Fix unused variable warning in Lv2UridMap.h * Fix unused lambda capture in MixerView.cpp * Fix unused lambda captures in SetupDialog.cpp * Fix unused lambda capture in TrackOperationsWidget.cpp * Fix MSVC build * Fix style * Remove unused member variable in Lv2UridMap.h |
||
|
|
33d1baddc0 | Implement Lv2 Worker (#6484) | ||
|
|
94608eaad1 |
Lv2Proc: Sort scale point maps (#6859)
lilv can return the scale points in randomized order, and so the linked models (of stereo effects wit 2 `Lv2Proc`) may have different scale points. This would mean that the same combo enumeration value would have different float values in linked models. This problem is fixed by sorting the scale values. Also, it is more natural for users if scale points are enumerated in a numerical order. |
||
|
|
7aca8ae726 |
SetupDialog: Warn of unusual buffersizes
This displays a warning dialog if the users requests unusual buffersizes: - buffersizes less than 32 - buffersizes which are not a (natural number) power of 2 This commit also replaces some `setGeometry` stuff by `QBoxLayout`. |
||
|
|
61b612634d | Add plugin blacklist for buffersize<=32 | ||
|
|
d97377b640 |
Lv2: Improve LED widget's digit calculation
This improves the way digits are calculated for display in `Lv2ViewProc`: - More than 2 digits are now recognized - Minus signs are now recognized - Tests have been added |
||
|
|
c309d8bd11 | Lv2ViewProc: Improve variable names | ||
|
|
f0aa2862d7 | Updated MIDI CC handling not to count from 1 (#6774) | ||
|
|
07229b6404 | Show error message when loading an invalid sample file (#6286) | ||
|
|
73f9f36c9a |
Code review changes
Remove whitespace in methods and add it to the parenthesis of some statements. Remove underscores from parameter names. Remove usage of `this` pointer. Add `auto` keyword to shorten line length in `InstrumentPlayHandle::play`. Move `const_cast` of `NotePlayHandle` closer to the `process` method as this method is the reason that the cast is needed in the first place. One might also add a version of `nphsOfInstrumentTrack` that returns a non-const result but it seems to be a general problem of a missing clear responsibility so I keep it as is. |
||
|
|
d3d710e0ad |
Remove identical calls to InstrumentTrack::processAudioBuffer
Remove identical calls to `InstrumentTrack::processAudioBuffer` which appear in the overridden implementations of `Instrument::play` and `Instrument::playNotes`. Instead the call to `processAudioBuffer` has been moved into `InstrumentPlayHandle::play` and `InstrumentTrack::playNote`. These two methods call the aforementioned methods of `Instrument`. Especially in the case of `InstrumentTrack::playNote` the previous implementation resulted in some unncessary "ping pong" where `InstrumentTrack` called a method on an `Instrument` which then in turn called a method on `InstrumentTrack`. And this was done in almost every instrument.
In `InstrumentTrack::playNote` an additional check was added which only calls `processAudioBuffer` if the buffer is not `nullptr`. The reason is that under certain circumstances `PlayHandle::doProcessing` calls the `play` method by explicitly passing a `nullptr` as the buffer. This behavior was added with commit
|
||
|
|
b64912cd57 |
fixes #6354: Sample and Hold for LFO Controller (#6850)
* fixes #6354: Sample and Hold for LFO Controller LFO controller's "white noise" wave shape didn't respect the frequency knob at all, so Sample-and-Hold was added to extend the functionality of the LFO Controller with this random waveshape. The original functionallity can still be accessed by setting the FREQ knob to minimum (0.01) --------- Co-authored-by: Kevin Zander <veratil@gmail.com> Co-authored-by: saker <sakertooth@gmail.com> |
||
|
|
a8d765f8d5 |
Make files visible when searching in `FileBrowser` (#6845)
* Change the title for SideBarWidgets to be vertically centered related to icon and with no underlining * Update src/gui/SideBarWidget.cpp Co-authored-by: saker <sakertooth@gmail.com> * Updating FileBrowser display when searching : showing matching files * Correcting increment and removing duplicated calls * Correcting reload tree when filter is activated --------- Co-authored-by: saker <sakertooth@gmail.com> |
||
|
|
de062d6c54 |
Show detailed CPU load information in a tool-tip (#5970)
* Profiler rework * Workaround for GCC bug * Rollback QFile removal * Use enum instead of a plain index to describe detailed stats * Use the GCC workaround code for all compilers to avoid redundancy * Update and fix comments * Implement suggestions from review * Split AudioEngine::renderNextBuffer() into separate functions, fix old formatting * Remove QFile include * Revert formatting changes * Apply suggestion from review (remove unnecessary template parameter) * Revert more formatting changes * Convert DetailType to enum class * DetailType enum class improvements suggested in review * Use std::atomic for m_detailLoad * RAII-style profiler probes * Apply suggestions from code review Co-authored-by: Dominic Clark <mrdomclark@gmail.com> * Fix namespace comment * Improve CPU load widget precision and use floats for load computations * Atomic m_cpuLoad * Add custom step size support for CPULoadWidget * Apply suggestions from review (convert the profiler probe into a nested class, other small changes) * Do not limit stored load averages to 100% --------- Co-authored-by: sakertooth <sakertooth@gmail.com> Co-authored-by: Dominic Clark <mrdomclark@gmail.com> |