Re: [music-dsp] Glitch/Alias free modulated delay
Let suppose that I fix the errors In the algorithm. Is this sufficient for a quality delay time Modulation? Or will I need more advance technics? That's a matter of opinion :-) My opinion is that the hermite interpolation you're using here (I didn't check to see if it's implemented correctly!) is more than adequate for modulated delay effects like chorus - I suspect a lot of commercial effects have used linear interpolation. Steven Cook. -Original Message- From: Nuno Santos Sent: Thursday, March 19, 2015 6:28 PM To: A discussion list for music-related DSP Subject: Re: [music-dsp] Glitch/Alias free modulated delay Hi, Thanks for your replies. What I hear is definitely related with the modulation. The artefacts are audible every time the modulation is applied: manually or automatically (please not that I have an interpolator for manual parameter changes to avoid abrupt changes). I think I was already applying an Hermit interpolation. This is my delay read function. void IDelay::read(IAudioSample *output) { float t = _time+_modulation*_modulationRange; if (t(_size-1)) t=_size-1; float sf; #if 0 sf = _buffer[int(readIndex(t,0))]; #else float const y_1= _buffer[int(readIndex(t,-1))]; float const y0 = _buffer[int(readIndex(t,0))]; float const y1 = _buffer[int(readIndex(t,1))]; float const y2 = _buffer[int(readIndex(t,2))]; float const x=readIndex(t,0)-int(readIndex(t,0)); float const c0 = y0; float const c1 = 0.5f*(y1-y_1); float const c2 = y_1 - 2.5f*y0 + 2.0f*y1 - 0.5f*y2; float const c3 = 0.5f*(y2-y_1) + 1.5f*(y0-y1); sf=((c3*x+c2)*x+c1)*x+c0; #endif *output = sf; } float IDelay::readIndex(float t, int offset) { float index=_writeIndex-t+offset; if (index0) index+=_size; return index; } Thanks, Regards, Nuno On 19 Mar 2015, at 18:12, David Olofson da...@olofson.net wrote: On Thu, Mar 19, 2015 at 6:15 PM, Nuno Santos nunosan...@imaginando.pt wrote: [...] If I use interpolation for buffer access I experience less glitch and more alias. What type of interpolation are you using? I would think you need something better than linear interpolation for this. I'd try Hermite. That should be sufficient for slow modulation, although theoretically, you *should* bandlimit the signal as soon as you play it back faster than the original sample rate. For more extreme effects (which effectively means you're sometimes playing back audio at a substantially higher sample rate than that of your audio stream), you may need a proper bandlimited resampler. (Apply a brickwall filter before the interpolation, and/or oversample the interpolator.) -- //David Olofson - Consultant, Developer, Artist, Open Source Advocate .--- Games, examples, libraries, scripting, sound, music, graphics ---. | http://consulting.olofson.net http://olofsonarcade.com | '-' -- dupswapdrop -- the music-dsp mailing list and website: subscription info, FAQ, source code archive, list archive, book reviews, dsp links http://music.columbia.edu/cmc/music-dsp http://music.columbia.edu/mailman/listinfo/music-dsp -- dupswapdrop -- the music-dsp mailing list and website: subscription info, FAQ, source code archive, list archive, book reviews, dsp links http://music.columbia.edu/cmc/music-dsp http://music.columbia.edu/mailman/listinfo/music-dsp -- dupswapdrop -- the music-dsp mailing list and website: subscription info, FAQ, source code archive, list archive, book reviews, dsp links http://music.columbia.edu/cmc/music-dsp http://music.columbia.edu/mailman/listinfo/music-dsp -- dupswapdrop -- the music-dsp mailing list and website: subscription info, FAQ, source code archive, list archive, book reviews, dsp links http://music.columbia.edu/cmc/music-dsp http://music.columbia.edu/mailman/listinfo/music-dsp -- dupswapdrop -- the music-dsp mailing list and website: subscription info, FAQ, source code archive, list archive, book reviews, dsp links http://music.columbia.edu/cmc/music-dsp http://music.columbia.edu/mailman/listinfo/music-dsp
Re: [music-dsp] Glitch/Alias free modulated delay
Suggestion: Make it work with linear interpolation first. The implementation is extremely simple—it won’t take much of your time to try it—and you’ll eliminate most of the problems (buffer wrap, etc.) without getting confused about whether your interpolation scheme is the fault. Plus, you’ll have a baseline to compare higher-order improvements with. Linear interpolation sounds better than most people would guess, with typical musical input (musical interments usually have weaker upper harmonics), so you’ll have a better idea of whether you’re getting your money’s worth with more elaborate methods. On Mar 20, 2015, at 2:10 PM, Nuno Santos nunosan...@imaginando.pt wrote: On 20 Mar 2015, at 18:58, Alan Wolfe alan.wo...@gmail.com wrote: One thing to watch out for is to make sure you are not looking backwards AND forwards in time, but only looking BACK in time. This is how I calculate the read index: float t=_writeIndex-_time-_modulation*_modulationRange; if(t0) t+=_size; When you say you have an LFO going from -1 to 1 that makes me think you might be going FORWARD in the buffer as well as backwards, which would definitely cause audible problems. I have tried to rescale the LFO to fit between 0 and 1 and it doing the same artefacts: // this where delay gets updated with lfo float lfo = (_lfo.step()-1.f)/2.f; delay.setModulation(lfo); your LFO really should go between -1 and 0, you then multiply that value by the number of samples in your buffer (minus 1 if needed, depending on your design and timing in your code), and then subtract that value from your write index into the buffer, making sure to handle the case of going negative, where your subtracted offset is greater than your current write index. I even tried to change from _time+_modulation*_modulationRange to _time-_modulation*_modulationRange Exactly the same issues…. :/ -- dupswapdrop -- the music-dsp mailing list and website: subscription info, FAQ, source code archive, list archive, book reviews, dsp links http://music.columbia.edu/cmc/music-dsp http://music.columbia.edu/mailman/listinfo/music-dsp
Re: [music-dsp] Glitch/Alias free modulated delay
Interpolating the sample value is not sufficient to eliminate artifacts. You also need to eliminate glitches that occur when jumping from one time value to another. In other words: no matter how good your sample-value interpolation is, you will still introduce artifacts when changing the delay time. A steep low-pass filter going into the delay line would be one way to solve this. (this is the idea of bandlimiting alluded to earlier in this discussion.) I can say from experience that you absolutely must take this into account, but, if memory serves (which it may not), the quality of interpolation and filtering is not that important. I am pretty sure I've written code to handle both cases using something super simple and efficient like linear interpolation and it sounded surprisingly good, which is to say everyone else on the project thought it sounded great, and that was enough to consider it done on that particular project. HTH On Fri, Mar 20, 2015 at 6:43 AM, Steven Cook stevenpaulc...@tiscali.co.uk wrote: Let suppose that I fix the errors In the algorithm. Is this sufficient for a quality delay time Modulation? Or will I need more advance technics? That's a matter of opinion :-) My opinion is that the hermite interpolation you're using here (I didn't check to see if it's implemented correctly!) is more than adequate for modulated delay effects like chorus - I suspect a lot of commercial effects have used linear interpolation. Steven Cook. -Original Message- From: Nuno Santos Sent: Thursday, March 19, 2015 6:28 PM To: A discussion list for music-related DSP Subject: Re: [music-dsp] Glitch/Alias free modulated delay Hi, Thanks for your replies. What I hear is definitely related with the modulation. The artefacts are audible every time the modulation is applied: manually or automatically (please not that I have an interpolator for manual parameter changes to avoid abrupt changes). I think I was already applying an Hermit interpolation. This is my delay read function. void IDelay::read(IAudioSample *output) { float t = _time+_modulation*_modulationRange; if (t(_size-1)) t=_size-1; float sf; #if 0 sf = _buffer[int(readIndex(t,0))]; #else float const y_1= _buffer[int(readIndex(t,-1))]; float const y0 = _buffer[int(readIndex(t,0))]; float const y1 = _buffer[int(readIndex(t,1))]; float const y2 = _buffer[int(readIndex(t,2))]; float const x=readIndex(t,0)-int(readIndex(t,0)); float const c0 = y0; float const c1 = 0.5f*(y1-y_1); float const c2 = y_1 - 2.5f*y0 + 2.0f*y1 - 0.5f*y2; float const c3 = 0.5f*(y2-y_1) + 1.5f*(y0-y1); sf=((c3*x+c2)*x+c1)*x+c0; #endif *output = sf; } float IDelay::readIndex(float t, int offset) { float index=_writeIndex-t+offset; if (index0) index+=_size; return index; } Thanks, Regards, Nuno On 19 Mar 2015, at 18:12, David Olofson da...@olofson.net wrote: On Thu, Mar 19, 2015 at 6:15 PM, Nuno Santos nunosan...@imaginando.pt wrote: [...] If I use interpolation for buffer access I experience less glitch and more alias. What type of interpolation are you using? I would think you need something better than linear interpolation for this. I'd try Hermite. That should be sufficient for slow modulation, although theoretically, you *should* bandlimit the signal as soon as you play it back faster than the original sample rate. For more extreme effects (which effectively means you're sometimes playing back audio at a substantially higher sample rate than that of your audio stream), you may need a proper bandlimited resampler. (Apply a brickwall filter before the interpolation, and/or oversample the interpolator.) -- //David Olofson - Consultant, Developer, Artist, Open Source Advocate .--- Games, examples, libraries, scripting, sound, music, graphics ---. | http://consulting.olofson.net http://olofsonarcade.com | '-' -- dupswapdrop -- the music-dsp mailing list and website: subscription info, FAQ, source code archive, list archive, book reviews, dsp links http://music.columbia.edu/cmc/music-dsp http://music.columbia.edu/mailman/listinfo/music-dsp -- dupswapdrop -- the music-dsp mailing list and website: subscription info, FAQ, source code archive, list archive, book reviews, dsp links http://music.columbia.edu/cmc/music-dsp http://music.columbia.edu/mailman/listinfo/music-dsp -- dupswapdrop -- the music-dsp mailing list and website: subscription info, FAQ, source code archive, list archive, book reviews, dsp links http://music.columbia.edu/cmc/music-dsp http://music.columbia.edu/mailman/listinfo/music-dsp -- dupswapdrop -- the music-dsp mailing list and website: subscription info, FAQ, source code archive, list archive, book reviews, dsp links http://music.columbia.edu/cmc/music-dsp
Re: [music-dsp] Glitch/Alias free modulated delay
On 20 Mar 2015, at 18:58, Alan Wolfe alan.wo...@gmail.com wrote: One thing to watch out for is to make sure you are not looking backwards AND forwards in time, but only looking BACK in time. This is how I calculate the read index: float t=_writeIndex-_time-_modulation*_modulationRange; if(t0) t+=_size; When you say you have an LFO going from -1 to 1 that makes me think you might be going FORWARD in the buffer as well as backwards, which would definitely cause audible problems. I have tried to rescale the LFO to fit between 0 and 1 and it doing the same artefacts: // this where delay gets updated with lfo float lfo = (_lfo.step()-1.f)/2.f; delay.setModulation(lfo); your LFO really should go between -1 and 0, you then multiply that value by the number of samples in your buffer (minus 1 if needed, depending on your design and timing in your code), and then subtract that value from your write index into the buffer, making sure to handle the case of going negative, where your subtracted offset is greater than your current write index. I even tried to change from _time+_modulation*_modulationRange to _time-_modulation*_modulationRange Exactly the same issues…. :/ On Fri, Mar 20, 2015 at 11:51 AM, Marco Lo Monaco marco.lomon...@teletu.it wrote: How often do you update the LFO? Every buffersize (32/64 samples)? M. -Messaggio originale- Da: music-dsp-boun...@music.columbia.edu [mailto:music-dsp- boun...@music.columbia.edu] Per conto di Nuno Santos Inviato: venerdì 20 marzo 2015 19:06 A: A discussion list for music-related DSP Oggetto: Re: [music-dsp] Glitch/Alias free modulated delay Hi, Today I have used a piece of code which is on musicdsp for testing this out again. http://musicdsp.org/archive.php?classid=4#98 http://musicdsp.org/archive.php?classid=4#98 I was able to have a delay changing in time without any kind of artefact or glitch. However I have only managed to get this results by changing the parameter by myself. When I say, manually moving the parameter by myself I say that I update a property which will be linearly interpolated in time (500ms). When I try to apply the modulation which is a value between -1 and 1, that comes from an LFO, I always end up with artefacts and noise I don’t understand why it works so well when I move the parameter value (which is also changing constantly due to interpolation, and it doesn’t work when I apply the modulation with the lo… Any ideas? This is my current code void IDelay::read(IAudioSample *output) { double t=double(_writeIndex)-_time; // works perfectly moving the handle manually with the value being interpolated before getting the variable _time; //double t=double(_writeIndex)-_time+_modulation*_modulationRange; // clip lookback buffer-bound if(t0.0) t=_size+t; // compute interpolation left-floor int const index0=int(t); // compute interpolation right-floor int index_1=index0-1; int index1=index0+1; int index2=index0+2; // clip interp. buffer-bound if(index_10)index_1=_size-1; if(index1=_size)index1=0; if(index2=_size)index2=0; // get neighbourgh samples float const y_1= _buffer[index_1]; float const y0 = _buffer[index0]; float const y1 = _buffer[index1]; float const y2 = _buffer[index2]; // compute interpolation x float const x=(float)t-(float)index0; // calculate float const c0 = y0; float const c1 = 0.5f*(y1-y_1); float const c2 = y_1 - 2.5f*y0 + 2.0f*y1 - 0.5f*y2; float const c3 = 0.5f*(y2-y_1) + 1.5f*(y0-y1); *output=((c3*x+c2)*x+c1)*x+c0; } On 20 Mar 2015, at 14:20, Bjorn Roche bj...@shimmeo.com mailto:bj...@shimmeo.com wrote: Interpolating the sample value is not sufficient to eliminate artifacts. You also need to eliminate glitches that occur when jumping from one time value to another. In other words: no matter how good your sample-value interpolation is, you will still introduce artifacts when changing the delay time. A steep low-pass filter going into the delay line would be one way to solve this. (this is the idea of bandlimiting alluded to earlier in this discussion.) I can say from experience that you absolutely must take this into account, but, if memory serves (which it may not), the quality of interpolation and filtering is not that important. I am pretty sure I've written code to handle both cases using something super simple and efficient like linear interpolation and it sounded surprisingly good, which is to say everyone else on the project thought it sounded great, and that was enough to consider it done on that particular project. HTH On Fri, Mar 20, 2015 at 6:43 AM, Steven Cook stevenpaulc...@tiscali.co.uk mailto:stevenpaulc...@tiscali.co.uk wrote: Let suppose that I fix the errors In the algorithm. Is this sufficient for a quality delay time Modulation? Or will I
[music-dsp] R: Glitch/Alias free modulated delay
How often do you update the LFO? Every buffersize (32/64 samples)? M. -Messaggio originale- Da: music-dsp-boun...@music.columbia.edu [mailto:music-dsp- boun...@music.columbia.edu] Per conto di Nuno Santos Inviato: venerdì 20 marzo 2015 19:06 A: A discussion list for music-related DSP Oggetto: Re: [music-dsp] Glitch/Alias free modulated delay Hi, Today I have used a piece of code which is on musicdsp for testing this out again. http://musicdsp.org/archive.php?classid=4#98 http://musicdsp.org/archive.php?classid=4#98 I was able to have a delay changing in time without any kind of artefact or glitch. However I have only managed to get this results by changing the parameter by myself. When I say, manually moving the parameter by myself I say that I update a property which will be linearly interpolated in time (500ms). When I try to apply the modulation which is a value between -1 and 1, that comes from an LFO, I always end up with artefacts and noise I don’t understand why it works so well when I move the parameter value (which is also changing constantly due to interpolation, and it doesn’t work when I apply the modulation with the lo… Any ideas? This is my current code void IDelay::read(IAudioSample *output) { double t=double(_writeIndex)-_time; // works perfectly moving the handle manually with the value being interpolated before getting the variable _time; //double t=double(_writeIndex)-_time+_modulation*_modulationRange; // clip lookback buffer-bound if(t0.0) t=_size+t; // compute interpolation left-floor int const index0=int(t); // compute interpolation right-floor int index_1=index0-1; int index1=index0+1; int index2=index0+2; // clip interp. buffer-bound if(index_10)index_1=_size-1; if(index1=_size)index1=0; if(index2=_size)index2=0; // get neighbourgh samples float const y_1= _buffer[index_1]; float const y0 = _buffer[index0]; float const y1 = _buffer[index1]; float const y2 = _buffer[index2]; // compute interpolation x float const x=(float)t-(float)index0; // calculate float const c0 = y0; float const c1 = 0.5f*(y1-y_1); float const c2 = y_1 - 2.5f*y0 + 2.0f*y1 - 0.5f*y2; float const c3 = 0.5f*(y2-y_1) + 1.5f*(y0-y1); *output=((c3*x+c2)*x+c1)*x+c0; } On 20 Mar 2015, at 14:20, Bjorn Roche bj...@shimmeo.com mailto:bj...@shimmeo.com wrote: Interpolating the sample value is not sufficient to eliminate artifacts. You also need to eliminate glitches that occur when jumping from one time value to another. In other words: no matter how good your sample-value interpolation is, you will still introduce artifacts when changing the delay time. A steep low-pass filter going into the delay line would be one way to solve this. (this is the idea of bandlimiting alluded to earlier in this discussion.) I can say from experience that you absolutely must take this into account, but, if memory serves (which it may not), the quality of interpolation and filtering is not that important. I am pretty sure I've written code to handle both cases using something super simple and efficient like linear interpolation and it sounded surprisingly good, which is to say everyone else on the project thought it sounded great, and that was enough to consider it done on that particular project. HTH On Fri, Mar 20, 2015 at 6:43 AM, Steven Cook stevenpaulc...@tiscali.co.uk mailto:stevenpaulc...@tiscali.co.uk wrote: Let suppose that I fix the errors In the algorithm. Is this sufficient for a quality delay time Modulation? Or will I need more advance technics? That's a matter of opinion :-) My opinion is that the hermite interpolation you're using here (I didn't check to see if it's implemented correctly!) is more than adequate for modulated delay effects like chorus - I suspect a lot of commercial effects have used linear interpolation. Steven Cook. -Original Message- From: Nuno Santos Sent: Thursday, March 19, 2015 6:28 PM To: A discussion list for music-related DSP Subject: Re: [music-dsp] Glitch/Alias free modulated delay Hi, Thanks for your replies. What I hear is definitely related with the modulation. The artefacts are audible every time the modulation is applied: manually or automatically (please not that I have an interpolator for manual parameter changes to avoid abrupt changes). I think I was already applying an Hermit interpolation. This is my delay read function. void IDelay::read(IAudioSample *output) { float t = _time+_modulation*_modulationRange; if (t(_size-1)) t=_size-1; float sf; #if 0 sf = _buffer[int(readIndex(t,0))]; #else float const y_1= _buffer[int(readIndex(t,-1))]; float const y0 = _buffer[int(readIndex(t,0))]; float const y1 =
Re: [music-dsp] R: Glitch/Alias free modulated delay
One thing to watch out for is to make sure you are not looking backwards AND forwards in time, but only looking BACK in time. When you say you have an LFO going from -1 to 1 that makes me think you might be going FORWARD in the buffer as well as backwards, which would definitely cause audible problems. your LFO really should go between -1 and 0, you then multiply that value by the number of samples in your buffer (minus 1 if needed, depending on your design and timing in your code), and then subtract that value from your write index into the buffer, making sure to handle the case of going negative, where your subtracted offset is greater than your current write index. On Fri, Mar 20, 2015 at 11:51 AM, Marco Lo Monaco marco.lomon...@teletu.it wrote: How often do you update the LFO? Every buffersize (32/64 samples)? M. -Messaggio originale- Da: music-dsp-boun...@music.columbia.edu [mailto:music-dsp- boun...@music.columbia.edu] Per conto di Nuno Santos Inviato: venerdì 20 marzo 2015 19:06 A: A discussion list for music-related DSP Oggetto: Re: [music-dsp] Glitch/Alias free modulated delay Hi, Today I have used a piece of code which is on musicdsp for testing this out again. http://musicdsp.org/archive.php?classid=4#98 http://musicdsp.org/archive.php?classid=4#98 I was able to have a delay changing in time without any kind of artefact or glitch. However I have only managed to get this results by changing the parameter by myself. When I say, manually moving the parameter by myself I say that I update a property which will be linearly interpolated in time (500ms). When I try to apply the modulation which is a value between -1 and 1, that comes from an LFO, I always end up with artefacts and noise I don’t understand why it works so well when I move the parameter value (which is also changing constantly due to interpolation, and it doesn’t work when I apply the modulation with the lo… Any ideas? This is my current code void IDelay::read(IAudioSample *output) { double t=double(_writeIndex)-_time; // works perfectly moving the handle manually with the value being interpolated before getting the variable _time; //double t=double(_writeIndex)-_time+_modulation*_modulationRange; // clip lookback buffer-bound if(t0.0) t=_size+t; // compute interpolation left-floor int const index0=int(t); // compute interpolation right-floor int index_1=index0-1; int index1=index0+1; int index2=index0+2; // clip interp. buffer-bound if(index_10)index_1=_size-1; if(index1=_size)index1=0; if(index2=_size)index2=0; // get neighbourgh samples float const y_1= _buffer[index_1]; float const y0 = _buffer[index0]; float const y1 = _buffer[index1]; float const y2 = _buffer[index2]; // compute interpolation x float const x=(float)t-(float)index0; // calculate float const c0 = y0; float const c1 = 0.5f*(y1-y_1); float const c2 = y_1 - 2.5f*y0 + 2.0f*y1 - 0.5f*y2; float const c3 = 0.5f*(y2-y_1) + 1.5f*(y0-y1); *output=((c3*x+c2)*x+c1)*x+c0; } On 20 Mar 2015, at 14:20, Bjorn Roche bj...@shimmeo.com mailto:bj...@shimmeo.com wrote: Interpolating the sample value is not sufficient to eliminate artifacts. You also need to eliminate glitches that occur when jumping from one time value to another. In other words: no matter how good your sample-value interpolation is, you will still introduce artifacts when changing the delay time. A steep low-pass filter going into the delay line would be one way to solve this. (this is the idea of bandlimiting alluded to earlier in this discussion.) I can say from experience that you absolutely must take this into account, but, if memory serves (which it may not), the quality of interpolation and filtering is not that important. I am pretty sure I've written code to handle both cases using something super simple and efficient like linear interpolation and it sounded surprisingly good, which is to say everyone else on the project thought it sounded great, and that was enough to consider it done on that particular project. HTH On Fri, Mar 20, 2015 at 6:43 AM, Steven Cook stevenpaulc...@tiscali.co.uk mailto:stevenpaulc...@tiscali.co.uk wrote: Let suppose that I fix the errors In the algorithm. Is this sufficient for a quality delay time Modulation? Or will I need more advance technics? That's a matter of opinion :-) My opinion is that the hermite interpolation you're using here (I didn't check to see if it's implemented correctly!) is more than adequate for modulated delay effects like chorus - I suspect a lot of commercial effects have used linear interpolation. Steven Cook. -Original Message- From: Nuno Santos Sent: Thursday, March 19, 2015 6:28 PM To: A discussion list for music-related DSP Subject: Re: [music-dsp]
Re: [music-dsp] Glitch/Alias free modulated delay
Hi, Today I have used a piece of code which is on musicdsp for testing this out again. http://musicdsp.org/archive.php?classid=4#98 http://musicdsp.org/archive.php?classid=4#98 I was able to have a delay changing in time without any kind of artefact or glitch. However I have only managed to get this results by changing the parameter by myself. When I say, manually moving the parameter by myself I say that I update a property which will be linearly interpolated in time (500ms). When I try to apply the modulation which is a value between -1 and 1, that comes from an LFO, I always end up with artefacts and noise I don’t understand why it works so well when I move the parameter value (which is also changing constantly due to interpolation, and it doesn’t work when I apply the modulation with the lo… Any ideas? This is my current code void IDelay::read(IAudioSample *output) { double t=double(_writeIndex)-_time; // works perfectly moving the handle manually with the value being interpolated before getting the variable _time; //double t=double(_writeIndex)-_time+_modulation*_modulationRange; // clip lookback buffer-bound if(t0.0) t=_size+t; // compute interpolation left-floor int const index0=int(t); // compute interpolation right-floor int index_1=index0-1; int index1=index0+1; int index2=index0+2; // clip interp. buffer-bound if(index_10)index_1=_size-1; if(index1=_size)index1=0; if(index2=_size)index2=0; // get neighbourgh samples float const y_1= _buffer[index_1]; float const y0 = _buffer[index0]; float const y1 = _buffer[index1]; float const y2 = _buffer[index2]; // compute interpolation x float const x=(float)t-(float)index0; // calculate float const c0 = y0; float const c1 = 0.5f*(y1-y_1); float const c2 = y_1 - 2.5f*y0 + 2.0f*y1 - 0.5f*y2; float const c3 = 0.5f*(y2-y_1) + 1.5f*(y0-y1); *output=((c3*x+c2)*x+c1)*x+c0; } On 20 Mar 2015, at 14:20, Bjorn Roche bj...@shimmeo.com mailto:bj...@shimmeo.com wrote: Interpolating the sample value is not sufficient to eliminate artifacts. You also need to eliminate glitches that occur when jumping from one time value to another. In other words: no matter how good your sample-value interpolation is, you will still introduce artifacts when changing the delay time. A steep low-pass filter going into the delay line would be one way to solve this. (this is the idea of bandlimiting alluded to earlier in this discussion.) I can say from experience that you absolutely must take this into account, but, if memory serves (which it may not), the quality of interpolation and filtering is not that important. I am pretty sure I've written code to handle both cases using something super simple and efficient like linear interpolation and it sounded surprisingly good, which is to say everyone else on the project thought it sounded great, and that was enough to consider it done on that particular project. HTH On Fri, Mar 20, 2015 at 6:43 AM, Steven Cook stevenpaulc...@tiscali.co.uk mailto:stevenpaulc...@tiscali.co.uk wrote: Let suppose that I fix the errors In the algorithm. Is this sufficient for a quality delay time Modulation? Or will I need more advance technics? That's a matter of opinion :-) My opinion is that the hermite interpolation you're using here (I didn't check to see if it's implemented correctly!) is more than adequate for modulated delay effects like chorus - I suspect a lot of commercial effects have used linear interpolation. Steven Cook. -Original Message- From: Nuno Santos Sent: Thursday, March 19, 2015 6:28 PM To: A discussion list for music-related DSP Subject: Re: [music-dsp] Glitch/Alias free modulated delay Hi, Thanks for your replies. What I hear is definitely related with the modulation. The artefacts are audible every time the modulation is applied: manually or automatically (please not that I have an interpolator for manual parameter changes to avoid abrupt changes). I think I was already applying an Hermit interpolation. This is my delay read function. void IDelay::read(IAudioSample *output) { float t = _time+_modulation*_modulationRange; if (t(_size-1)) t=_size-1; float sf; #if 0 sf = _buffer[int(readIndex(t,0))]; #else float const y_1= _buffer[int(readIndex(t,-1))]; float const y0 = _buffer[int(readIndex(t,0))]; float const y1 = _buffer[int(readIndex(t,1))]; float const y2 = _buffer[int(readIndex(t,2))]; float const x=readIndex(t,0)-int(readIndex(t,0)); float const c0 = y0; float const c1 = 0.5f*(y1-y_1); float const c2 = y_1 - 2.5f*y0 + 2.0f*y1 - 0.5f*y2; float const c3 = 0.5f*(y2-y_1) + 1.5f*(y0-y1); sf=((c3*x+c2)*x+c1)*x+c0; #endif *output = sf; } float IDelay::readIndex(float t, int offset) { float index=_writeIndex-t+offset; if (index0) index+=_size;
Re: [music-dsp] R: Glitch/Alias free modulated delay
On 3/20/15 2:58 PM, Alan Wolfe wrote: One thing to watch out for is to make sure you are not looking backwards AND forwards in time, but only looking BACK in time. right!! pretty hard to cross into the future with a real-time alg (because there ain't no future, it's really wrapping around your delay buffer to the distant past). you *can* cross into the future with a non-real-time alg (it's also not really the future since it was recorded long ago). When you say you have an LFO going from -1 to 1 that makes me think you might be going FORWARD in the buffer as well as backwards, which would definitely cause audible problems. your LFO really should go between -1 and 0, maybe not quite to 0 since there will be other samples needed for the Hermite interpolation. the delay must be more than 1 sample for 4-sample, 3rd-order polynomial interpolation. i wish the OP could check his Hermite alg to see if it's consistent with what i wrote in an earlier reply. i just didn't want to blast it out, but i guess i could. if the alg is implemented i incorrectly, who knows what that would sound like. perhaps the OP should try it first with linear interpolation to see if there are glitches due to discontinuities. then improve the interpolation. -- r b-j r...@audioimagination.com Imagination is more important than knowledge. -- dupswapdrop -- the music-dsp mailing list and website: subscription info, FAQ, source code archive, list archive, book reviews, dsp links http://music.columbia.edu/cmc/music-dsp http://music.columbia.edu/mailman/listinfo/music-dsp
Re: [music-dsp] Glitch/Alias free modulated delay
On 3/20/15 10:20 AM, Bjorn Roche wrote: Interpolating the sample value is not sufficient to eliminate artifacts. You also need to eliminate glitches that occur when jumping from one time value to another. what do you mean? do you mean the normal speed-up-the-tape effect when smoothly decreasing the amount of delay? or do you mean when an integer sample index boundary is crossed? In other words: no matter how good your sample-value interpolation is, you will still introduce artifacts when changing the delay time depending on your answer to the above, i am not sure i agree with this. -- r b-j r...@audioimagination.com Imagination is more important than knowledge. -- dupswapdrop -- the music-dsp mailing list and website: subscription info, FAQ, source code archive, list archive, book reviews, dsp links http://music.columbia.edu/cmc/music-dsp http://music.columbia.edu/mailman/listinfo/music-dsp
Re: [music-dsp] Glitch/Alias free modulated delay
This part is still wrong: // clip interp. buffer-bound if(index_10)index_1=_size-1; if(index1=_size)index1=0; if(index2=_size)index2=0; index1 index2 are both set to 0. This looks suspicious: //double t=double(_writeIndex)-_time+_modulation*_modulationRange; You're subtracting _time but adding _modulation: are you sure _modulation is negative, or did you mean to do: //double t=double(_writeIndex)-(_time+_modulation*_modulationRange); Regards, Steven Cook. -Original Message- From: Nuno Santos Sent: Friday, March 20, 2015 6:05 PM To: A discussion list for music-related DSP Subject: Re: [music-dsp] Glitch/Alias free modulated delay Hi, Today I have used a piece of code which is on musicdsp for testing this out again. http://musicdsp.org/archive.php?classid=4#98 http://musicdsp.org/archive.php?classid=4#98 I was able to have a delay changing in time without any kind of artefact or glitch. However I have only managed to get this results by changing the parameter by myself. When I say, manually moving the parameter by myself I say that I update a property which will be linearly interpolated in time (500ms). When I try to apply the modulation which is a value between -1 and 1, that comes from an LFO, I always end up with artefacts and noise I don’t understand why it works so well when I move the parameter value (which is also changing constantly due to interpolation, and it doesn’t work when I apply the modulation with the lo… Any ideas? This is my current code void IDelay::read(IAudioSample *output) { double t=double(_writeIndex)-_time; // works perfectly moving the handle manually with the value being interpolated before getting the variable _time; //double t=double(_writeIndex)-_time+_modulation*_modulationRange; // clip lookback buffer-bound if(t0.0) t=_size+t; // compute interpolation left-floor int const index0=int(t); // compute interpolation right-floor int index_1=index0-1; int index1=index0+1; int index2=index0+2; // clip interp. buffer-bound if(index_10)index_1=_size-1; if(index1=_size)index1=0; if(index2=_size)index2=0; // get neighbourgh samples float const y_1= _buffer[index_1]; float const y0 = _buffer[index0]; float const y1 = _buffer[index1]; float const y2 = _buffer[index2]; // compute interpolation x float const x=(float)t-(float)index0; // calculate float const c0 = y0; float const c1 = 0.5f*(y1-y_1); float const c2 = y_1 - 2.5f*y0 + 2.0f*y1 - 0.5f*y2; float const c3 = 0.5f*(y2-y_1) + 1.5f*(y0-y1); *output=((c3*x+c2)*x+c1)*x+c0; } On 20 Mar 2015, at 14:20, Bjorn Roche bj...@shimmeo.com mailto:bj...@shimmeo.com wrote: Interpolating the sample value is not sufficient to eliminate artifacts. You also need to eliminate glitches that occur when jumping from one time value to another. In other words: no matter how good your sample-value interpolation is, you will still introduce artifacts when changing the delay time. A steep low-pass filter going into the delay line would be one way to solve this. (this is the idea of bandlimiting alluded to earlier in this discussion.) I can say from experience that you absolutely must take this into account, but, if memory serves (which it may not), the quality of interpolation and filtering is not that important. I am pretty sure I've written code to handle both cases using something super simple and efficient like linear interpolation and it sounded surprisingly good, which is to say everyone else on the project thought it sounded great, and that was enough to consider it done on that particular project. HTH On Fri, Mar 20, 2015 at 6:43 AM, Steven Cook stevenpaulc...@tiscali.co.uk mailto:stevenpaulc...@tiscali.co.uk wrote: Let suppose that I fix the errors In the algorithm. Is this sufficient for a quality delay time Modulation? Or will I need more advance technics? That's a matter of opinion :-) My opinion is that the hermite interpolation you're using here (I didn't check to see if it's implemented correctly!) is more than adequate for modulated delay effects like chorus - I suspect a lot of commercial effects have used linear interpolation. Steven Cook. -Original Message- From: Nuno Santos Sent: Thursday, March 19, 2015 6:28 PM To: A discussion list for music-related DSP Subject: Re: [music-dsp] Glitch/Alias free modulated delay Hi, Thanks for your replies. What I hear is definitely related with the modulation. The artefacts are audible every time the modulation is applied: manually or automatically (please not that I have an interpolator for manual parameter changes to avoid abrupt changes). I think I was already applying an Hermit interpolation. This is my delay read function. void IDelay::read(IAudioSample *output) { float t = _time+_modulation*_modulationRange; if (t(_size-1)) t=_size-1; float sf; #if 0 sf = _buffer[int(readIndex(t,0))]; #else