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

Fix PeakController attack/decay, lerp between samples (#7383) #7566

Merged
merged 1 commit into from
Oct 28, 2024

Conversation

cyberrumor
Copy link
Contributor

@cyberrumor cyberrumor commented Oct 26, 2024

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

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

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

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

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

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

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

Fixes #7383

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

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

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

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

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

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

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

@sakertooth sakertooth left a comment

Choose a reason for hiding this comment

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

Tested the PR and the changes seem to have fixed the issues mentioned. The attack and release knobs work more appropriately than current master from what I can tell. The code changes themselves also look good to me, though I do have a question.

src/core/PeakController.cpp Show resolved Hide resolved
@sakertooth sakertooth merged commit b5de1d5 into LMMS:master Oct 28, 2024
11 checks passed
@regulus79
Copy link
Contributor

Does this have any effect on old projects which use PeakController?

@cyberrumor
Copy link
Contributor Author

Unfortunately yes. Attack/decay now works differently, so old projects may have to adjust those values to achieve the same effect.

Additionally, if old projects were utilizing the buzzing/zipper artifacts as a desired result, that sound will have to be achieved via some other strategy now.

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.

Peak Controller Attack/Decay isn't a smooth curve
3 participants