Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Scalable LFO graph #7203

Merged
merged 7 commits into from
Apr 14, 2024
Merged

Conversation

michaelgregorius
Copy link
Contributor

Make the rendering of the LFO graph scalable. Change the fixed size to a minimum size. Adjust the rendering code such that it uses the width and height of the widget instead of the background pixmap.

Use "Hz" instead of "ms/LFO"

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

Keep info text legible

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

Take "Freq * 100" into account

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

Screenshots

ScalableLFOScalableLFO-FreqX100

Implementation details

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

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

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

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

Extract the drawing of the info text into its own private method drawInfoText.

Make the rendering of the LFO graph scalable. Change the fixed size to a minimum size. Adjust the rendering code such that it uses the width and height of the widget instead of the background pixmap.

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

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

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

Remove the member `m_params` which is not used anyway. This also allows for the removal of the overridden `modelChanged` method.
Use the more common unit "Hz" to display the frequency of the LFO instead of "ms/LFO". The frequency is always displayed with three digits after the decimal separator to prevent "jumps".
This commit fixes a bug where the "Freq * 100" option was not taken into account when computing and displaying the frequency of the LFO.
Draw a slightly transparent black rectangle underneath the text to keep it legible, e.g. for high frequencies with an LFO amount of 1 which results in a very bright and dense graph.
Extract the drawing of the info text into its own private method `drawInfoText`.
Copy link
Contributor

@Veratil Veratil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! I wonder if it would be possible to cache the polyline so we don't have to compute it every time? Only need to redraw on parameter changes or resize right?

src/gui/instrument/LfoGraph.cpp Show resolved Hide resolved
src/gui/instrument/LfoGraph.cpp Outdated Show resolved Hide resolved
@michaelgregorius
Copy link
Contributor Author

Looks good! I wonder if it would be possible to cache the polyline so we don't have to compute it every time? Only need to redraw on parameter changes or resize right?

I assume you mean to cache a QPixmap of the drawn polyline? I think this should be something for another PR. The same should be considered for the envelope lines then.

What is the way to catch parameter changes in LMMS by the way? I guess I would have to connect to a signal of the model(s)?

@Veratil
Copy link
Contributor

Veratil commented Apr 13, 2024

I assume you mean to cache a QPixmap of the drawn polyline? I think this should be something for another PR. The same should be considered for the envelope lines then.

The pixmap is definitely a better choice than the polyline itself. 😁 Definitely another PR. I know Qt does some caching of its own though, so we'd have to check if it's going though the loop when nothing is updating.

What is the way to catch parameter changes in LMMS by the way? I guess I would have to connect to a signal of the model(s)?

It would be signals, yeah. We might have to add some extras, but it's out of scope.

The subtraction of the predelay from the current sample was inlined in a statement. This is removed with this commit.
@michaelgregorius
Copy link
Contributor Author

I assume you mean to cache a QPixmap of the drawn polyline? I think this should be something for another PR. The same should be considered for the envelope lines then.

The pixmap is definitely a better choice than the polyline itself. 😁 Definitely another PR. I know Qt does some caching of its own though, so we'd have to check if it's going though the loop when nothing is updating.

It only updates then a damaged region is detected, i.e. if you cover part of the widget and then uncover it. There are some GUI elements which are tied to a timer so that they are updated 60 times a second but the graphs are not in that elusive group.

@Veratil
Copy link
Contributor

Veratil commented Apr 13, 2024

It only updates then a damaged region is detected, i.e. if you cover part of the widget and then uncover it.

That's what we hope at least. We have a lot of custom stuff which causes repainting, for instance just moving the mouse in the PianoRoll schedules a paintEvent.

@michaelgregorius
Copy link
Contributor Author

It only updates then a damaged region is detected, i.e. if you cover part of the widget and then uncover it.

That's what we hope at least. We have a lot of custom stuff which causes repainting, for instance just moving the mouse in the PianoRoll schedules a paintEvent.

I guess the reason is because it is implemented as one big thing that paints everything instead of being composed of parent and child widgets which could react more specifically to certain events. I have just checked and PianoRoll.cpp is peppered with update calls.

@michaelgregorius michaelgregorius merged commit 815f88d into LMMS:master Apr 14, 2024
9 checks passed
@michaelgregorius michaelgregorius deleted the ScalableLfoGraph branch April 14, 2024 08:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants