smoothing parameter changes, how is it done in DAWs?
-
- KVRer
- Topic Starter
- 21 posts since 13 Aug, 2014
Hi,
I am currently working on my first real synthesizer/sequencer application (c++) and I am at the point where most features are implemented. however, the paramter-smoothing was something I left open until now.
I am using a simple class for smoothing parameters, which I found in the web. It's a one-pole LPF with the following parameters:
b1 = 0.99;
a0 = 1.0 - b1 = 0.01;
For every sample, I calculate the parameter like this:
float last = parameter * b + (last * a);
return last;
All of my parameters which are send to the signal processing are in a range of 0 to 1, if not, they are clipped.
My stereo-delay effect updates both delay-lines ever sample, they are set to 100 to 1000ms, so [0,1] is scalled up to [100,900].
The problem I am having is that most parameters get smoothed with the low pass and there are no unwanted noises when moving gui-elements around, however the delay-effect sounds even more distorted then without any parameter smoothing.
So the question is: what could I use for smoothing this parameter? I've compared it with abletons simple delay and this thing doesn't make any noise at all when turning the dial like crazy!
Thanks in advance!
I am currently working on my first real synthesizer/sequencer application (c++) and I am at the point where most features are implemented. however, the paramter-smoothing was something I left open until now.
I am using a simple class for smoothing parameters, which I found in the web. It's a one-pole LPF with the following parameters:
b1 = 0.99;
a0 = 1.0 - b1 = 0.01;
For every sample, I calculate the parameter like this:
float last = parameter * b + (last * a);
return last;
All of my parameters which are send to the signal processing are in a range of 0 to 1, if not, they are clipped.
My stereo-delay effect updates both delay-lines ever sample, they are set to 100 to 1000ms, so [0,1] is scalled up to [100,900].
The problem I am having is that most parameters get smoothed with the low pass and there are no unwanted noises when moving gui-elements around, however the delay-effect sounds even more distorted then without any parameter smoothing.
So the question is: what could I use for smoothing this parameter? I've compared it with abletons simple delay and this thing doesn't make any noise at all when turning the dial like crazy!
Thanks in advance!
- Beware the Quoth
- 33173 posts since 4 Sep, 2001 from R'lyeh Oceanic Amusement Park and Funfair
From what you're saying, you're modulating the length of your delay line, yes? But what is changing the delay line length actually doing, algorithm wise? Are you making the buffer longer? If so, how? Changing the start/end points within a larger buffer? Changing the effective read rate on a fixed buffer size? What's catering for intermediate values (ie interpolation)? Yada yada.WRodewald wrote:My stereo-delay effect updates both delay-lines ever sample, they are set to 100 to 1000ms, so [0,1] is scalled up to [100,900].
The problem I am having is that most parameters get smoothed with the low pass and there are no unwanted noises when moving gui-elements around, however the delay-effect sounds even more distorted then without any parameter smoothing.
Your delay line algorithm needs to cater for modulation of its length. Without knowing what you've done in that respect its kinda impossible to work out what's going wrong.
my other modular synth is a bugbrand
-
- KVRer
- Topic Starter
- 21 posts since 13 Aug, 2014
Hi,
I use the synthesis toolkit for my low level signal processing. The setDelayLength()-function only calculates bounds and so on but doesn't realloc the buffer. Here is the docu for the delay-line: https://ccrma.stanford.edu/software/stk ... elayA.html
I use the same class with a chorus effect and it doesn't make problemce since the range is quite a bit shorter. It's an allpass-interpolation.
When I took a look on the parameters, the biggest jumps in delay-length (in samples) in the middle of the change was around 300 samples.
Here is the full function, the first part is a debug-only part I guess, debug isn't active right now and the delay length should be in bounds.
I use the synthesis toolkit for my low level signal processing. The setDelayLength()-function only calculates bounds and so on but doesn't realloc the buffer. Here is the docu for the delay-line: https://ccrma.stanford.edu/software/stk ... elayA.html
I use the same class with a chorus effect and it doesn't make problemce since the range is quite a bit shorter. It's an allpass-interpolation.
When I took a look on the parameters, the biggest jumps in delay-length (in samples) in the middle of the change was around 300 samples.
Here is the full function, the first part is a debug-only part I guess, debug isn't active right now and the delay length should be in bounds.
Code: Select all
void DelayA :: setDelay( StkFloat delay )
{
unsigned long length = inputs_.size();
if ( delay + 1 > length ) { // The value is too big.
oStream_ << "DelayA::setDelay: argument (" << delay << ") greater than maximum!";
handleError( StkError::WARNING ); return;
}
if ( delay < 0.5 ) {
oStream_ << "DelayA::setDelay: argument (" << delay << ") less than 0.5 not possible!";
handleError( StkError::WARNING );
}
StkFloat outPointer = inPoint_ - delay + 1.0; // outPoint chases inpoint
delay_ = delay;
while ( outPointer < 0 )
outPointer += length; // modulo maximum length
outPoint_ = (long) outPointer; // integer part
if ( outPoint_ == length ) outPoint_ = 0;
alpha_ = 1.0 + outPoint_ - outPointer; // fractional part
if ( alpha_ < 0.5 ) {
// The optimal range for alpha is about 0.5 - 1.5 in order to
// achieve the flattest phase delay response.
outPoint_ += 1;
if ( outPoint_ >= length ) outPoint_ -= length;
alpha_ += (StkFloat) 1.0;
}
coeff_ = (1.0 - alpha_) / (1.0 + alpha_); // coefficient for allpass
}
- KVRAF
- 2554 posts since 4 Sep, 2006 from 127.0.0.1
make sure your one-pole LP is working properly
the "last" variable is its memory, which has to be remembered, so you cannot define it locally in the function
declare that variable as a member, and make sure to initialize its value on startup
and the coefficients for that filter.. you should know that the way they are hardcoded means that the speed of the LP filter would change if you change the sampling rate
you could calculate the coeffs as in frequency, using this formula:
b1 = exp(-2 * pi * (f/samplerate));
a0 = 1.0-b1;
"f" is the frequency in Hz.. for parameter smoothing, try somethings like 5 to 50Hz -ish... really, adjust to taste there
the "last" variable is its memory, which has to be remembered, so you cannot define it locally in the function
declare that variable as a member, and make sure to initialize its value on startup
and the coefficients for that filter.. you should know that the way they are hardcoded means that the speed of the LP filter would change if you change the sampling rate
you could calculate the coeffs as in frequency, using this formula:
b1 = exp(-2 * pi * (f/samplerate));
a0 = 1.0-b1;
"f" is the frequency in Hz.. for parameter smoothing, try somethings like 5 to 50Hz -ish... really, adjust to taste there
It doesn't matter how it sounds..
..as long as it has BASS and it's LOUD!
irc.libera.chat >>> #kvr
..as long as it has BASS and it's LOUD!
irc.libera.chat >>> #kvr
-
- KVRer
- Topic Starter
- 21 posts since 13 Aug, 2014
Hi,
I have used exactly this calculation for the coefficients before but changed it to minimise possible problem sources. Also, my sample Rate is fixed in the application (for now) so hardcoding the coefficients should do the trick for now.
The lowpass workes fine, there is barely any noise left from parameter change. Only the delay effect with the long delay line still makes problem.
I have used exactly this calculation for the coefficients before but changed it to minimise possible problem sources. Also, my sample Rate is fixed in the application (for now) so hardcoding the coefficients should do the trick for now.
The lowpass workes fine, there is barely any noise left from parameter change. Only the delay effect with the long delay line still makes problem.
- KVRian
- 1091 posts since 8 Feb, 2012 from South - Africa
Allpass interpolation is great for small delay changes and smooth modulation but it is an IIR filter, large delay changes will cause clicking. Your choices are: 1) Use a FIR interpolator, linear, hermite etc. 2) Duck the delay volume while changing. 3) Try to eliminate the clicks the hard way:WRodewald wrote:Hi,
I have used exactly this calculation for the coefficients before but changed it to minimise possible problem sources. Also, my sample Rate is fixed in the application (for now) so hardcoding the coefficients should do the trick for now.
The lowpass workes fine, there is barely any noise left from parameter change. Only the delay effect with the long delay line still makes problem.
http://quod.lib.umich.edu/cgi/p/pod/dod ... 2.1995.096
Personally I'd just use option no.1.
-
- Banned
- 12368 posts since 30 Apr, 2002 from i might peeramid
this could produce denormaling in the case where the parameter is reduced to zero. it sounds like you have some other factor acting on your length (...) as suggested scope, multithreading?
you come and go, you come and go. amitabha neither a follower nor a leader be tagore "where roads are made i lose my way" where there is certainty, consideration is absent.
-
- KVRer
- Topic Starter
- 21 posts since 13 Aug, 2014
Hi,
sorry for the late response. I was working on the project, so It's basicly done right now.
I think I will switch to a linear interpolating delay line then. I realy have to learn more about the in depth dsp parts like this.
@xoxos, I don't realy undderstand your post (english isn't my native language). The audio processing is done In a high prio thread which only doesn the signal processing.
Parameter changes are done in another thread. However, this thread only switches the parameter before it gets filtered. The actuall parameter change is done in the dsp-thread again. (I hope you know what I mean, not good in explaining stuff. )
Best regards
sorry for the late response. I was working on the project, so It's basicly done right now.
I think I will switch to a linear interpolating delay line then. I realy have to learn more about the in depth dsp parts like this.
@xoxos, I don't realy undderstand your post (english isn't my native language). The audio processing is done In a high prio thread which only doesn the signal processing.
Parameter changes are done in another thread. However, this thread only switches the parameter before it gets filtered. The actuall parameter change is done in the dsp-thread again. (I hope you know what I mean, not good in explaining stuff. )
Best regards