Zipper Noise

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

texture wrote:looks like he's got a fixed length buffer, and reads it using a floating point index. In order to do so, you use the float to determine two samples that are 'either side' of your fractional index. Then you interpolate between them using the fractional position between the two samples.
nice.

Forever,




Kim.

Post

That's what I proposed ;)
Linear is good at the beginning. If you want something better, you have to change the interpolation because the signal is in [0Hz, 24kHz] - sampling at 48KHz -, and linear interpolation can make it exceed this band, so you have to interpolate in this band - well, that's a change of an epsilon, but for purists... -

[edit] I forgot something : if the signal exceed the total band, it will fold up on the same band and add noise. - Shanon Whitetaker theorem -

Post

thanks again for the comments , guys.

i'm getting a clearer picture in my head now :)

Post

looks like he's got a fixed length buffer, and reads it using a floating point index.
that's it.
I'll add that since I've inserted a LP filter in the loop as part of the effect, aliasing doesn't matter that much for me, even if foldover occurs it will be mainly located in the HF and thus highly attenuated by the filter.

another (well known) tip concerning the RingBuffer:
I use a buffer whose size is rounded to the next power of 2, thus the (int) index can be wrapped using a bit mask instead of a modulo.

cheers

--remy

Post

mdsp wrote: another (well known) tip concerning the RingBuffer:
I use a buffer whose size is rounded to the next power of 2, thus the (int) index can be wrapped using a bit mask instead of a modulo.
I've used the bitmask wrapping method before, not thought of using a modulo before - I'd always used an 'if'. Nice little trick :D

For anyone who doesn't realise what this is, say you have an iterator, for a buffer:

++i %= buffersize; // wraps when i == buffersize, no 'if'

Post

texture wrote:
++i %= buffersize; // wraps when i == buffersize, no 'if'
thanks for reminding of why I hate C++ :hihi:

pre-increment i then i becomes equal to the remainder after i is divide by the buffersize. all in one bite-sized chunk .... :spew:

it's a corking technique, though :) so thanks for posting :!:

Post

It's more readable in two lines, even if the compilers can read the one line version. :D

Post

scuzzphut wrote:pre-increment i then i becomes equal to the remainder after i is divide by the buffersize. all in one bite-sized chunk .... :spew:
:lol: Thats what I love about it!!

Post

scuzzphut wrote:
texture wrote:
++i %= buffersize; // wraps when i == buffersize, no 'if'
thanks for reminding of why I hate C++ :hihi:
So I suppose you won't be a fan of using the whole expression as an index to the buffer?

buffer[++i %= buffersize] = insample;

:D

Forever,




Kim.

Post

:shock: :o :shock: :o :shock: :o

I'll go and crawl back under my chair now :lol:

Imagine trying to read that at 3am when you're tracking down a bug.

"WTF ? Who wrote this impenetrable gobbledegook?"...
....
...

"oh..... it was me
:oops: "

Post

scuzzphut wrote::shock: :o :shock: :o :shock: :o

I'll go and crawl back under my chair now :lol:

Imagine trying to read that at 3am when you're tracking down a bug.

"WTF ? Who wrote this impenetrable gobbledegook?"...
....
...

"oh..... it was me
:oops: "
That's why you write with a 3:1 comments to code ratio!

Forever,




Kim.

Post

Well, that's why I write it in 3 lines, because I don't want to many comments, but rather a readabl code - comments are useless if I can't understand the code -

Post

I write it on 3 lines, then add another 8 lines of comments anyway :D :P

Post

(1) What exactly do you mean by fractional delay line?

Code: Select all

delay = new float [32768];//circular buffer
float read;
int write;

for (int i=0;i<sampleframes;i++)
{
delay[write] = *input++;
write=(write+1)&(32768-1);

read = (float)write-(delay_ms * SampleRate)/1000;/read

if (read<0) read+=32768;

int current = (int) read; //use truncate(), make sure you round down, instead nearest;
int next = (current+1)&(32768-1);

*output++ = delay[current] + (delay[next]-delay[current])* read - (int) current;//linear interpolation
}

This is how fractional delay works... You can optimize it ofcourse. It may contain bugs!
(2) So when you read from the buffer, you do a simple linear interpolation between the current sample and the next sample, right? Doesn't that halve the frequency response - i.e. isn't that a form of lpf ?
Linear interpolation aliases a little. Use better interpolation. A LPF uses input and output samples too ... You just use input samples here.
(3) So your buffer is a fixed length and you read it at varying speeds using an interpolation algorithm to adjust the buffer read pointer? Am I understanding this right?
Yep.
Cheers.
A.F.

Post

Such code doesn't need comments, it's rather clear ;)
- and an error I spotted was corrected before I could write something about it, so ;) -

Post Reply

Return to “DSP and Plugin Development”