[sdiy] help understanding circular buffers for delay line
dan snazelle
subjectivity at hotmail.com
Sat Mar 3 04:07:57 CET 2012
If you are using a power of 2 buffer length then just use an "&" of
the length - 1 for starters as this will be much easier to code, worry
about optimisation later:
buffer [index & (length - 1)]
so for a fixed integer sample delay you would have:
inpos = (inpos + 1) & (length - 1);
buffer [inpos] = input;
output = buffer [(inpos - delay) & ( length - 1)];
and make sure delay is less than length - 1
Andy
Ok
i just got some time to really study this Andy and I have some questions (surprise)
define length 8000
byte buffer [length]
what is the inpos? is that the same as using a for loop with an i as in matthews example?
and what is delay...is that the J for loop as in matthews example? or is that a delaytime pot?
thanks for your help
> &" of
> the length - 1 for starters as this will be much easier to code, worry
> about optimisation later:
>
> buffer [index & (length - 1)]
>
> so for a fixed integer sample delay you would have:
>
> inpos = (inpos + 1) & (length - 1);
> buffer [inpos] = input;
> output = buffer [(inpos - delay) & ( length - 1)];
>
> and make sure delay is less than length - 1
>
> Andy
>
>
>
> On 2 March 2012 11:53, Matthew Smith <matt at smiffytech.com> wrote:
>>
>> Quoth Dan Snazelle at 02/03/12 12:27...
>> ...
>>
>>> So, these two indexes....are they both driven by "for" loops?(one with an offset?)
>>
>>
>> This is one of those concepts I'd generally try to explain using diagrams. However, let's see what we can do in plain text.
>>
>> For starters, if you haven't already done so, I'd suggest you have a look at this Wikipedia article:
>>
>> http://en.wikipedia.org/wiki/Circular_buffer
>>
>> ...but possibly stopping when you get to the code, as they are using the dreaded malloc which I have, on more than one occasion, been told to avoid when dealing with small micros.
>>
>> Here's a very rough example, without using pointers (which I probably would in Real Life) where I am sampling at 48ksps, 8 bits.
>>
>> # define SIZE_OF_BUFFER 4096
>>
>> unsigned char mybuffer[SIZE_OF_BUFFER];
>> int i=0; // write index
>> int j=0; // read index
>> for (;;)
>> {
>> i++;
>> if (i==SIZE_OF_BUFFER)
>> {
>> i=0; // We are indexing from zero, so 4095->0.
>> }
>>
>> j=i+1;
>> if (j==SIZE_OF_BUFFER)
>> {
>> j=0;
>> }
>>
>> mybuffer[i]=read_dac();
>> write_dac(mybuffer[j]);
>>
>> delay(); // wait until it's time for the next sample.
>> }
>>
>> In real life, to do make this run in time, I'd make this an ISR, rather than an infinite for loop, or use an RTOS.
>>
>> What's happening here is a simple delay. As I haven't initialised mybuffer[], for the first pass through the loop, write_dac() will be
>> spitting out indeterminate values - something that should be avoided in a real implementation.
>>
>> After that first pass through though, what will be read from the buffer into the DAC will be the sample that you wrote in there SIZE_OF_BUFFER iterations ago. (Note that the oldest entry in the buffer is the NEXT position, or zero if we've reached the end.)
>>
>> If we are sampling at 48ksps, this means that the value going to the DAC will be (1/48000) * 4096 = 0.0853 seconds behind what's being read in.
>>
>> To decrease the delay, we change the relationship between i and j.
>>
>> To give the effect of an echo, we can scale the value coming out by, say, shifting it 2 places to the right (divide by 4.) Then we can add it to the signal being written, shift the result 1 place to the right (divide by 2, because we could now have a 9 bit number, having added to the 8 bit number) and then send that to the DAC. So the value coming out is half of what's gone in, plus a quarter of what was there 85ms ago.
>>
>> These are very rough examples (probably with errors!) but I hope they make it a bit more clear.
>>
>> One thing you may have gathered - any significant delay will need a fair amount of RAM to achieve which, in a microcontroller context, will probably involve the use of external RAM. (It's dirt cheap, but does mean an extra chip.)
>>
>> Cheers
>>
>> M
>>
>> --
>> Matthew Smith
>>
>> Business: http://www.smiffytech.com
>> Blog: http://www.smiffysplace.com
>> Linkedin: http://www.linkedin.com/in/smiffy
>> Flickr: http://www.flickr.com/photos/msmiffy
>> Twitter: http://twitter.com/smiffy
>>
>> ABN 16 391 203 815
>>
>> _______________________________________________
>> Synth-diy mailing list
>> Synth-diy at dropmix.xs4all.nl
>> http://dropmix.xs4all.nl/mailman/listinfo/synth-diy
> _______________________________________________
> Synth-diy mailing list
> Synth-diy at dropmix.xs4all.nl
> http://dropmix.xs4all.nl/mailman/listinfo/synth-diy
>
More information about the Synth-diy
mailing list