The internal waveforms of the class Oscillator produces the wrong amplitude when the input is a
negative phase. When doing PM or FM, negative phases may occur. When a negative phase is e.g. passed
to the the saw sample, it produces values less than -1.0, hence going out of range.
Converted all fraction calls to absFraction calls.
Removed the +2 in the function Oscillator::recalcPhase. The comment here was that it was needed to avoid
negative phases in case of PM. But by converting fraction to absFraction in the waveforms, negative phases
are not an issue anymore. On top of that the m_phase variable gains about 2 extra bits in precision.
As side effect of that, it improves the behaviour of the issue #2047 - TripleOscillator: Oscillators are getting out of sync.
Though I did not investigate it thoroughly over different notes and samplerates.
Add documentation to the fraction and absFraction functions in lmms_math.h as it was not immediately clear by the name what the
functions do. Correct the implementation of the functions in case the flag __INTEL_COMPILER is set. (floorf rounds always down).
* Fix for Icons and comboboxes mismatch in arpeggiator in Instrument Editor #5494
(https://github.com/LMMS/lmms/issues/5494)
Introduce a static const int variable for the default height of a ComboBox.
Set this height already in the constructor of the ComboBox object.
Update all modules setting the height of a ComboBox object to make use of the new constant.
* Replace 'const int' by 'constexpr int' after review.
* Enable mixer color-coding
* Cleanup
* Fix warnings
* Improvements
* Improvements
* Use ColorChooser instead of QColorDialog
* Fix default palette being out of range
* Remove a redundant function
* Rename and make stuff efficient
* Comment on the code
* Make things more efficient
* Fix breaking builds
* Improvements
* Improvements pt. 2
* Improvements pt. 3
* Improvements pt. 4
* Improvements pt. 5
* Apply suggestions from code review
Co-authored-by: Hyunjin Song <tteu.ingog@gmail.com>
Co-authored-by: Hyunjin Song <tteu.ingog@gmail.com>
* Starts implementing the feature
The idea of this branch is to allow actions triggered through the context menu of a TCO on the song editor to affect all the selected TCOs. With this commit, only the "Mute/unmute" action affects all selected TCOs, while the others retain their old behavior (only affect the TCO that owns the context menu).
For that, a method was created that processes all actions (the triggered action is parsed as a parameter to the method). In the case of the "Mute" action, it checks if the song editor has selected TCOs, and if it does it mutes/unmutes all of them.
* Allows selected TCOs to be removed too
Now the "Remove" action from the context menu will remove all selected TCOs if there are any.
* Starts implementing selected TCO cut and copy
Now, when multiple TCOs are selected, the context menu actions Cut and Copy will write a DataFile to the clipboard containing the TCO information, so it can later be used to paste it.
The Paste action now checks if there's data in the QApplication clipboard. If there is, it will later paste the TCOs (for now it just prints the data with qWarning). If there's not, it uses the regular TCO paste method that uses the internal LMMS clipboard. Because it now have to decide between the QApplication clipboard and the LMMS internal clipboard, the Clipboard::copy() method now clears anything in the QApplication clipboard, making it empty so LMMS can know it should use the internal clipboard instead in that situation.
Adds safety checks for the selected TCO views.
* Overloads TCW paste selection methods
This commit is a step towards implementing the paste feature of the TCO context menu. It overloads the TrackContentWidget::canPasteSelection and TrackContentWidget::pasteSelection methods so they can be called without having a QDropEvent (only the QMimeData with the copied TCOs information). The overloaded canPasteSelection(MidiTime, QMimeData, bool) method required a third argument which says whether pasting over the same bar should be allowed or not, because it shouldn't when the QDropEvent comes from the same application but should when it doesn't. That is defined in the canPasteSelection(MidiTime, QDropEvent) method.
Also, the pasteSelection(MidiTime, QDropEvent) isn't optimal, since it calls canPasteSelection twice (more details in the comments, but it's basically because the two canPasteSelection methods can return different values depending on the origin of QDropEvent). This could later be fixed by calling canPasteSelection before pasteSelection and removing it from inside the method altogether.
Next step is to add the "tco_" key to the mimeData on the Copy/Cut operations and implementing the paste operation using those methods.
* Adds the TCO type to the clipboard
Adds the key with the TCO type ("tco_" + type number + ":" + TCO Data XML) to the clipboard, so it can be later used by the canPasteSelection and pasteSelection methods.
* Apply changes to "src/tracks/SampleTrack.cpp"
Change the SampleTCOView::contextMenuEvent() method so it behaves the same way as the TrackContentObjectView::contextMenuEvent() method. For that, I had to change the ContextMenuAction enum and the contextMenuAction methods to be protected instead of private, so SampleTCOView can access it.
* Implement the paste action
Now that the canPasteSelection and pasteSelection methods were overloaded, it was possible to implement the paste action using the same logic as the Drag&Drop copy/paste.
Other small changes:
- Removes the TCO views AFTER creating the TCO data file, instead of before (which probably resulted in an empty data file).
- Uses the StringPairDrag::mimeType() instead of Clipboard::mimeType() since that's the one the methods from StringPairDrag.cpp recognizes.
* Removes QDebug header
Forgot to remove the QDebug header on the last commit.
* Creates a Context Menu on the TCW for "paste"
Now it's possible to paste a selection of copied TCOs anywhere in the TCW, as long as the rules to paste are met (same rules as Drag&Drop copy/paste). If the rules are not met the "Paste" menu action shows but is disabled.
* Small code refactoring
Saving a few lines of code.
* Avoids double call to canPasteSelection
This commit adds a third parameter to the pasteSelection overloaded method, which will define whether we whould skip the canPasteSelection check. The only situation where we will want to skip it is if we are calling pasteSelection from inside the other pasteSelection method, which will already have checked it. Because of that the default value is false.
Organizes comments as well.
* Separates methods for the actions on selections
Now the remove, copy, cut, paste and toggle mute actions have a separate method for applying them to selections, which are then called from the contextMenuAction method. That made the code more organized and the contextMenuAction method smaller.
Also, the mouse shortcuts for muting and removing (CTRL+middle button, middle button, CTRL+right button) now apply the action on selections as well.
* Fixes small bug and reorganize code
Fixes a small bug where using a mouse shortcut or choosing an action on a TCO that is not selected while other TCOs were selected would result in the selection being affected.
Also reorganizes the code so the conditional for choosing between the selection action and the individual action stays inside the method.
* Move logic to the action methods
Since the methods that called the action+Selection() methods didn't need the list of selectableObjects, I moved it to the inside of the action+Selection() methods and removed the parameter from them.
* Changes logic structure and labels
As suggested by Spekular, the logic structure was changed. Now, the mousePressEvent and contextMenuAction methods determine whether the action should happen to a selection of TCOs or an individual TCO. The list of TCOs to be affected populate a QVector list called "active", which is parsed to the action method that will apply the action to each object in the list.
I changed the method names to removeActive, cutActive, copyActive and toggleMuteActive, since I believe that better describe the behavior. The paste method is still called pasteSelection for now, because the paste behavior isn't related to the active TCOs but to the content of the clipboard.
The contextMenuEvent method on both src/core/Track.cpp and src/tracks/SampleTrack.cpp were changed so they also check if the right-clicked TCO is part of a selection or an individual TCO, and the labels for the actions are changed to better describe the behavior (i.e.: "Delete" for individual TCO and "Delete selection" for multiple TCOs).
* Make removeActive and toggleMuteActive static
removeActive and toggleMuteActive methods are now static so they can be called from anywhere in the code since they don't require a TCO view instance to work. That makes it possible for them to be used in the future if any feature requires this type of action to be called from out of a TCO view instance.
The same couldn't be done for the copyActive and cutActive methods because those require an instance of the TCO view to call them, since when copying to the clipboard some metadata is written using information from the object instance.
* Renamed TCO View paste method
I renamed the TCO View paste method from pasteSelection to just paste, since the TCO view doesn't currently have a paste method (only the TCO class). It's also a name that accurately describes the action: it will paste either a group of TCOVs or a single TCOV on the current TCOV.
I also moved the logic for deciding between the multiple TCOV paste and single TCOV paste inside the paste method.
* Moves repeated code to a new method
This commit adds another method to TrackContentObjectView called getClickedTCOs, which will return a QVector with the TCO views that are supposed to be affected by a context menu action (either the individual right-clicked TCO or the selection of TCOs). Code was updated on the other methods to make use of this new method.
Method names for actions that affect multiple TCOs were changed. Instead of calling them copyActive, cutActive, toggleMuteActive and removeActive, they are just called copy, cut, toggleMute and remove, hence they are overloaded methods for those actions that affect multiple TCOs (their differenciation is the arguments list, which is a QVector list for those).
* Avoid unnecessary calls to getClickedTCOs()
We use a ternary operator inside TrackContentObjectView::mousePressEvent to avoid unnecessary calls to getClickedTCOs when the list is not going to be used.
The contextMenuEvent method on both Track.cpp and SampleTrack.cpp was reformated to use a more appropriate indentation and spacing between method calls.
* Fix indenting in a ternary operator assignment
* Rework PianoRoll paintEvent + some extras
* Split out PositionLine class to own file
* Refactor PianoRoll Q_PROPERTYs
* Reduce code by using Q_PROPERTY's MEMBER function and removing getter/setter functions
After looking at the getters and setters, they did nothing different than what direct
access would allow. Nothing outside of PianoRoll used the public functions as well.
Considering these factors we can reduce the number of functions by 2x the number of
Q_PROPERTIES, and go with direct access instead.
* Remove need for keyboard pixmaps
With the recent change to allow zooming vertically, aligning pixmaps is a PITA. Since
we have themes which can take brushes and colors, it would be simpler to take a solid
color or a gradient with some extra style properties to resize the keys and text colors.
While it will slightly be a downgrade from pixmaps since they can be anything really,
this will allow us to customize the piano roll further moving forward.
* Added the ability to update margins for TimeLineWidget and StepRecorderWidget
These take a X coordinate, which was hardcoded to WHITE_KEY_WIDTH, and never looked
back. Now we can adjust on the fly if we need to. Currently this just allows us to
shift the left margin to the style-defined white key width.
* Fix phantom pixmaps when PianoRoll not focused
* Update PositionLine class changes related to #5543
* Changes the toggleSolo method
- Changes the toggleSolo method so it doesn't mute automation tracks (keeps their original state)
* Stop restoring Automation Track's mute values
- Since Automation Tracks are not affected by enabling solo on other tracks, there's no need (and it's even counter intuitive) to restore their previous mute value.
- Reduces a line by using "else if".
* Saves two lines merging 2 conditionals in 1
* Adds the new solo behavior as a new LED button
To allow the user choosing between the old solo behavior and the new one, a new LED button was added which will be used to enable the solo keeping the automation tracks states, while the red LED will enable the solo with the current behavior.
Changes to the code:
- Added a purple LED image that will be used on the new button.
- Increased the default width of the widget that holds the mute and solo buttons so the third one fits.
- Changed the positioning of the LEDs on both the standard and compact track modes to accomodate them.
- Added a new model called m_soloAutomationsModel, which is connected to the new LED button (m_soloAutomationsBtn). This will dictate the behavior of the toggleSolo method.
- The red LED calls the toggleSolo method as before. The purple LED will change the m_soloAutomationsModel value and toggle the red LED, which will then call toggleSolo. But since the value of m_soloAutomationsModel will be different, the new behavior will be used on the method.
* Revert "Adds the new solo behavior as a new LED button"
This reverts commit fdbc8b2712.
After consulting fellow users and devs about this change to the PR, it was decided that adding a third button for the new solo behavior was not the best approach. This reverts the commit so we go back to just changing the solo behavior. Later an option can be added on LMMS settings to choose between the old and new behaviors.
* Adds an option to use the legacy solo behavior
This commit adds an option on LMMS settings (saved to the config file) to go back to the legacy behavior of the track solo button. The option can be found on Settings>General>"Use solo legacy behavior"
Changes to the code:
- Since there's a change to the configuration file, an upgrade method was created (upgrade_1_3_0) to add the value to the config XML if it isn't already present (safety check).
- An attribute is added to the DOM structure of the app configuration under the "app" tag, called "sololegacybehavior", which can be either 0 or 1.
- Changes were made to include/SetupDialog.h, include/ConfigManager.h and src/core/ConfigManager.cpp to implement this new configuration option.
- The toggleSolo method was changed to behave according to the value of the "sololegacybehavior" configuration.
* Changes the description of the solo setting
Changes the description of the solo setting on the Setup Dialog from "Use solo legacy behavior" to "Mute automation tracks during solo" since the latter is more descriptive and new users wouldn't be confused about what the legacy behavior was.
* Merges "if"s and "if-else"s where possible
A conditional could be merged by using the "||" logical operator and there was a "if" nested inside an "else" that could be merged into a single "if-else".
Very small code format change (keeping code block curly braces in separate lines).
* Uses default value instead of upgrading ConfigFile
Instead of using an upgrade method on the ConfigManager class to set a value to the sololegacybehavior parameter, we now use a default value on every call to ConfigManager::value that requests it.
* Removes repetitive method call
To make the loop more efficient, a local variable was created to hold the behavior of the solo selected in the setup dialog, instead of calling the ConfigManager::value method repeated times.
Observation:
Since no code was added/removed from ConfigManager.cpp, it was restored to its original state. There's however a TAB character in a blank line on line 145, which was there at the beginning of this PR but removed during it. It was written again in this commit to remove ConfigManager.cpp from the "Files changed" list.
* Saves one line of code and adds a comment
* Create PathUtils
* Replace old SampleBuffer calls
* Fix automatic track names
* Fix things
* Remove accidental duplicate file
* Add includes
* More incldues
* PhysSong's code review + style
* Fix vestige loading?
Seems more reasonable to convert from relative on load and to relative on save than vice versa.
* Typo fix
* More Bases
* Enable more bases
* Add missing semicolons in prefixes
* Nicer sample track tooltip
* Use correct directories
"userXDir" gives the default dir for ladspa, sf2, and gig. "xDir" gives the user dir.
* Make relative to both default and custom locations
Part 1
* Make relative to both default and custom locations
Part 2
* Typofix
* Typofix
* Fix upgrade function after base renaming
* Fix Tests
* Update tests/src/core/RelativePathsTest.cpp
Co-Authored-By: Hyunjin Song <tteu.ingog@gmail.com>
* Choose UserXBase over DefaultXBase if identical
toShortestRelative sticks with the first base found if two bases give the same path length. By placing UserXBase Bases before DefaultXBase Bases in the relativeBases vector, toShortestRelative will prioritize them.
* Ensure baseLocation always has trailing slash
Otherwise, a user configuring a path without one will break things.
* Move loc declaration out of switch
* Semicolon
* Apply suggestions from code review...
* Include PathUtil and sort includes
* More granular includes
* Apply suggestions from code review
Co-Authored-By: Hyunjin Song <tteu.ingog@gmail.com>
* Update include/PathUtil.h
* Leave empty paths alone
* Fix stupid merge
* Really fix merge. Hopefully
* Switch Base from enum to class enum
* Don't pass Base by reference
* Use QStringLiteral for static QString allocation in basePrefix method
* Make VST loading more similar to previous implementation
* Fix tests after enum change
* Attempt to fix VST loading, nicer name for sample clips
* Fix last review comment
Don't append a "/" that will be removed by cleanPath later
* Apply suggestions from code review
Co-authored-by: Dominic Clark <mrdomclark@gmail.com>
Co-authored-by: Hyunjin Song <tteu.ingog@gmail.com>
Co-authored-by: Dominic Clark <mrdomclark@gmail.com>
* Set default behaviour, correct spelling
* Set default behaviour, correct spelling
* Store stop behaviour in project
* Change how state is saved & loaded
* Change to use enum
* Enable fullscreen with hotkey & hotkey to toggle maximise in internal window
* Fix an obvious blunder
* Add fullscreen menu entry
* Change Alt+F11 to Shift+F11 (fix Windows bug)
* Move F5-F10 to Ctrl+F*, fullscreen by F11 and fix Linux bug
* Remove wrongly placed "fullscreen" attribute
* Remove temporary fixes for redundant bug
* Rename maximise to maximize
* Rename maximise to maximize
* Use fullscreen icon instead of maximise icon
* Actually include the icon in the commit
* Replace .svg icon with .png 16x16 icon
* Migrate editor hotkeys to Ctrl+1-7
* Limit note length to quantization value
Draging a note to it's minimum value of 1 will add this new length to
the note if you later choose to stretch it which will not be clearly
visible in the Piano Roll unless you zoom in a bit. Limit the note
length to the quantization value and use <Alt> key to override and set
a smaller value.
* Update src/gui/editors/PianoRoll.cpp
Co-authored-by: Spekular <Spekular@users.noreply.github.com>
* Remember min note length if shorter than quantization()
* Find note length modulo quantization, pick smallest from selected notes
* Comment on and improve m_minResizeLen calculation
Co-authored-by: Oskar Wallgren <oskar.wallgren13@gmail.com>
* src/gui/editors/SongEditor.cpp
* Gradient can be toggled and color can be changed.
* Made playback line (and tail) transparent to mouse clicks
* Gradient disappears when paused/stopped; tail length depends on zoom
* Fixes bug where gradient appears when a pattern is played; style corrections
* Cleaned up code
* Rename m_zoomLevels to s_zoomLevels
* Finalising code
* Make positionLine class independent of parent zooming model
* Edit a bug fix to make it more efficient
* Rename m_x and finalise positionLine code
* Rename m_x and finalise positionLine changes
* Rename X to playHeadPos
* Make better use of getSelectedNotes() in PianoRoll.cpp
* Save and reuse selected note vector more often
* Apply review suggestions
Thanks to @Veratil
* Comment, style, consistency
- Changes method name from cloneBBTrackPattern to clonePattern
- Small fix on the comments
- Adds a TODO comment regarding reusing the code from TrackOperationsWidget as a reference, so we can later figure out a way to not repeat the code
Adds a button on the BBEditor that clones the current BB track pattern, but without also cloning the song editor TCOs. That can be useful when an user is editing drumlines and wants to make a section with a slight variation for example.
Now it's possible to forward received MIDI events with their original channel, either to another track or to the instrument plugin itself. To do that, the user must select the channel "--" on the MIDI output widget. In that case, all MIDI events will be forwarded with their original channel, and the MIDI events produced by the track itself will be sent with the default channel.
This PR fixes issues on systems where `QCursor::setPos()` has no effect
or is not reliable. These issues included knobs moving to fast on some
operating systems. Affected widgets are `Knob` and `LcdSpinBox`.
With this PR, on all operating systems, the `setPos` calls are removed and
the cursor is not hidden anymore, so the mouse keeps moving normally
when changing values of one of the widgets.
As now the previous pointer position keeps moving (instead of being reset
to the original position using `QCursor::setPos`), the mathematics that
translate pointer pixel distance to `Knob`/`LcdSpinBox` value increase
have to be changed:
* The `Knob` transition function is now linear and uses a new factor.
* `LcdSpinBox` now uses float values and saves the current float remainder
(this is actually a separate issue revealed by this fix), leading to a fluent,
non hanging movement.
Implementation of the Lv2 core, except for CV ports. No features or
extensions are supported yet.
You can now generate sound using Lv2 instruments (restricted to non-piano)
or effects.
For an explenation about the new classes, see Lv2Manager.h
This atomically unsets the MidiJack reference in AudioJack right before
MidiJack is destroyed. This avoids AudioJack using a destroyed MidiJack
object.
This patch
* makes `m_stopped` atomic
* initializes `m_stopped` correctly to `true`
* moves the initialization of `m_stopped` to the point where jack ports
are already connected
When selecting a Piano Key to mark semitones in the Piano Roll we
select key from the y position of the pop-up menu and not the mouse.
Incidentally these two are most often the same as the menu builds
from the mouse y positon and down. If there is room for it. If there
is no room downward it will create the menu so the lower part of the
frame aligns with the mouse y position.
Fixed by creating a variable to hold the pressed key before creating
the menu.