-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix PeakController attack/decay, lerp between samples (#7383) #7566
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
Conversation
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.
sakertooth
left a comment
There was a problem hiding this 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.
|
Does this have any effect on old projects which use PeakController? |
|
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. |
…ples (LMMS#7566) Historically, the PeakController has had issues like attack/decay knobs acting like on/off switches, and audio artifacts like buzzing or clicking. This patch aims to address those issues. The PeakController previously used lerp (linear interpolation) when looping through the sample buffer, which was in updateValueBuffer. This lerp utilized attack/decay values from control knobs. This is not the correct place to utilize attack/decay because the only temporal data available to the function is the frame and sample size. Therefore the coefficient should simply be the sample rate instead. Between each sample, processImpl would set m_lastSample to the RMS without any sort of lerp. This resulted in m_lastSample producing stair-like patterns over time, rather than a smooth line. For context, m_lastSample is used to set the value of whatever is connected to the PeakController. The basic lerp formula is: m_lastSample = m_lastSample + ((1 - attack) * (RMS - m_lastSample)) This is useful because an attack of 0 sets m_lastSample to RMS, whereas an attack of 1 would set m_lastSample to m_lastSample. This means our attack/decay knobs can be used on a range from "snap to the next value immediately" to "never stray from the last value". * Remove attack/decay from PeakController frame lerp. * Set frame lerp coefficient to 100.0 / sample_rate to fix buzzing. * Add lerp between samples for PeakController to fix stairstep bug. * The newly added lerp utilizes (1 - attack or decay) as the coefficient, which means the knobs actually do something now.
|
In the actual |
Prior to commit b5de1d5, audible zipper artifacts were present when using the PeakController on a bus to control the volume of another bus for sidechain compression. The bus that had its volume reduced was the one which produced audible artifacts. Commit b5de1d5 introduced LERP to PeakController to smooth out its signal, which eliminated the zipper artifacts. However, this had the side effect of increased latency even when both attack and decay settings were set to zero. Until a more robust solution is implemented, reverting this change eliminates the latency by eliminating the lerp, but reintroduces audible zipper artifacts.
Prior to commit b5de1d5, audible zipper artifacts were present when using the PeakController on a bus to control the volume of another bus for sidechain compression. The bus that had its volume reduced was the one which produced audible artifacts. Commit b5de1d5 introduced LERP to PeakController to smooth out its signal, which eliminated the zipper artifacts. However, this had the side effect of increased latency even when both attack and decay settings were set to zero. Until a more robust solution is implemented, reverting this change eliminates the latency by eliminating the lerp, but reintroduces audible zipper artifacts.
Prior to commit b5de1d5, audible zipper artifacts were present when using the PeakController on a bus to control the volume of another bus for sidechain compression. The bus that had its volume reduced was the one which produced audible artifacts. Commit b5de1d5 introduced LERP to PeakController to smooth out its signal, which eliminated the zipper artifacts. However, this had the side effect of increased latency even when both attack and decay settings were set to zero. Until a more robust solution is implemented, reverting this change eliminates the latency by eliminating the lerp, but reintroduces audible zipper artifacts.
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".
Fixes #7383