Fractional Delay Line

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

So i'm trying to implement a fractional delay line so that I can make use of interpolation however i'm having trouble getting my head around it all can anyone help me understand this?

So with the code below, if I return y it's a standard delay with no interpolation, however if I enable linear interpolation it sounds completely different?! :S

Code: Select all

	float buffer[22050];

	float delay;
	float feedback;

	float delaylen;
	float recipdelaylen;

	float delayindex;

	void initdelay(float fDelay, float fFeedBack)
	{
		delayindex = 0.f;

		delay = fDelay;
		feedback = fFeedBack;
		
		delaylen = fDelay * (SAMPLE_RATE - 1.f);
		recipdelaylen = 1.f / delaylen;
	}


    float delayline(float x)
    {
		const UINT32 iy = int(delayindex * delaylen);
		const float y = buffer[iy];
		
		buffer[int(delayindex * delaylen)] = x + y * feedback;
		delayindex += recipdelaylen;
		
		if(delayindex >= 1.0f)
			delayindex = 0.f;
		//wrap(delayindex);

		//return y;
		return LinearInterpolate(y, m_data[iy+1], delayindex - int(delayindex));
    }

Post

Without interpolation, the fractional part of delay length is meaningless. Is there actually a problem? "It sounds different" isn't a lot to go on...

Post

asomers wrote:Without interpolation, the fractional part of delay length is meaningless. Is there actually a problem? "It sounds different" isn't a lot to go on...
Right, yes sorry.

Basically it would seem the linear interpolation is somehow attenuating the delay at higher sampling rate than the input audio.

Basically im trying to resolve Zipper Noise, which is apparentally done via a fractional delay line with interpolation although i'm unsure how this is implemented.

I must be doing the interpolation incorrectly?

Btw I just realised these threads have more than one page, the extra pages I will read now may shed some more light. Apologies I would have not posted this so early if I had realised this:
http://www.kvraudio.com/forum/viewtopic ... c&start=15
http://www.kvraudio.com/forum/viewtopic.php?p=523053

Post

shLONG wrote:Basically it would seem the linear interpolation is somehow attenuating the delay at higher sampling rate than the input audio.
Not sure what you mean here. linear interpolation is a kind of lowpass filter, so maybe that's what you're experiencing?
Basically im trying to resolve Zipper Noise, which is apparentally done via a fractional delay line with interpolation although i'm unsure how this is implemented.
Interpolation will remove zipper but also create pitch artifacts. Usually interpolation is used for 'tape' delays and modulation effects. If you only want to remove zipper noise, you could do something clever with two delay lines and cross-fading.
I must be doing the interpolation incorrectly?
Couldn't say as you haven't posted the code.

I was in a similar position a while back and posted a working delay line class, maybe you should give that a whirl: http://www.kvraudio.com/forum/viewtopic ... highlight=

Post

asomers wrote: If you only want to remove zipper noise, you could do something clever with two delay lines and cross-fading.
That is basically what Interpolation does. IMHO the Datorropapers are "must reads" when working with interpolation filters.

Post

Code: Select all

if(delayindex >= 1.0f) 
  delayindex = 0.f;
No.

this will give you more zipper noises at a lower rate, it's a reset rather than a wrap. Had you said

Code: Select all

if(delayindex >= 1.0f) 
  delayindex -= 1.f;
I wouldn't have posted. [I often use while (delayindex>=1.f) {delayindex-=1.f;} just in case I got the increment calculation wrong in a blur of tea; the processing difference is negligible - one more comparison]

Also, I feel you might have the order of things wrong..
Process:
> Read sub-sample/interpolated value from delay line.
> Write to delay new value + (value read * feedback)
> return value read

It looks like you are reading a value from close to where you're intending, but not quite; then inserting that along with the new sample. The read index is moved using a naive sawtooth. You're then returning a different sample to the one read - this will cause varying amounts of lowpassing and high modulation chorussing/phasing. Not to say that's a bad thing; you could probably tune it to being a pretty neat effect, but doesn't look like that's what you're after.

HTH
DSP
Image

Post

Oh, you might want to investigate the recipdelaylen as increment as well..

If the write position is moving forward by one sample at a time, is there any good read why the read position shouldn't as well? I can see that you are essentially scaling the read & write as a normalised value - work out whether this is something you really want to be doing. There may be good reason for doing it in some circumstances (a form of resampling, for instance), but I have a feeling you're probably after something that is working at the samplerate provided, and as such moving by one sample at a time will give you the fidelity your users might be hoping for.

I could be wrong, of course.
Image

Post Reply

Return to “DSP and Plugin Development”