[Fpga-synth] Delay Line Theory

Magnus Danielson magnus at rubidium.dyndns.org
Tue Aug 14 20:22:49 CEST 2007


From: Scott Gravenhorst <music.maker at gte.net>
Subject: [Fpga-synth] Delay Line Theory
Date: Tue, 14 Aug 2007 10:27:40 -0700
Message-ID: <200708141727.l7EHRbf5015596 at linux7.lan>

> I've looked on the net for examples of delay line implementation using a
> RAM, but there doesn't seem to be anything.  I manufactured my own method
> based on "clock math".  The void of information leads me to one of two
> conclusions - 1) it's as simple as I think it is - or 2) it's IP that
> nobody wants to divulge because it's so cool.
> 
> I just did a little experiment that I thought would show the error of my
> ways, but it does not (I suspected my wrapping algorithm).
> 
> This new little project doesn't use an arithmetic wrap algorithm.  It makes
> the length of the delay line the entire RAM address space.  This allows me
> to let the system simply wrap back to zero after the maximum address
> instead of using arithmetic to compute when to wrap to address zero.
> 
> I set up a pointer (ptr) that is the end point (for read) and start point
> (for write) of the delay line.  I also have a pickup offset value (PU) that
> is added to ptr to access the location of the pickup.
> 
> In a nutshell, the state machine first accesses and stores in a register
> the pickup using ptr+PU as the RAM address (where binary wrapping will
> happen).  Next, the data pointed to by ptr is accessed to feed the input
> register of the filter.  At the same clock edge, the filter's output is
> written to the location in RAM pointed to by ptr, storing the previous
> cycle's IIR output in the RAM.  Lastly, in it's own state, ptr is
> incremented by one and allowed to simply overflow.
> 
> To my understanding, this should result in a fixed length waveguide that
> resonates when impulsed and where PU should access a location that is a
> constant number of locations away from ptr (given that PU is not changing).
>  The output should then be the same frequency, regardless of the value of
> PU as long as it is constant.  I'd expect doppler _while_ PU is changing,
> but after it's stopped changing the frequency should return to the natural
> resonant frequency. 
> 
> Do I have this right?  Because it surely isn't working like that.  When I
> increase the value of PU, the pitch rises and remains higher even after PU
> stops changing. 

For each sample you want to do these operations:

mem[wptr] = in
rptr = wptr + PU
out = mem[rptr]
wptr = wptr + 1

This will give you correct delays as long as your delays are even integer
multiples of the sample period and you are not chaning the delay (PU).
Shifts in PU will naturally give rise to doppler-like effects.

Your problem seems to be that you do rptr = rptr + PU or something.

> Please someone tell me that my understanding of this is muddled...

Yes, obviously! :-D

No, it *IS* simple as long as you stick to delays being integer multiples of
samples. If you attempt to break that, then you are in trouble. Smooth shifts
in delay require interpolation in delay, but interpolation in samples does not
make a good sound, so there you need to work on it.

If you use a delay in a feedback loop and then shift the delay, you are on your
own!!!

Cheers,
Magnus


More information about the Fpga-synth mailing list