[sdiy] karplus-strong drum synthesis
Joel B
onephatcat at earthlink.net
Sat Aug 20 23:58:57 CEST 2011
On Aug 20, 2011, at 1:43 PM, Olivier Gillet wrote:
> On which page is the equation you are trying to implement? I can't
> find anything in the paper resembling the equation you give.
>
The one on page 46, under the heading "Drum Algorithm". The equation was my mathematically illiterate attempt to render what I thought i saw in the equation on that page.
> Karplus strong synthesis is always done in a circular buffer, so when
> looking at the past samples you "wrap around" the buffer. One way to
> look at it is to say you're doing wavetable synthesis while constantly
> filtering the wavetable as it is being played.
>
> A practical implementation of the algorithm on page 46 would be:
>
> allocate a 2 * p array A and fill it with random numbers.
Would that be random 16 bit integers for 16 bit sound?
> ptr = 0
> for each sample:
> if rnd > blend:
> A[ptr] = 0.5 * (A[ (ptr + p) % (2 * p)] + A[(ptr + p - 1) % (2 * p)]
% in this context is the modulo function if I'm not mistaken?
> else:
> A[ptr] = -0.5 * (A[(ptr + p) % (2 * p)] + A[(ptr + p - 1) % (2 * p)]
> output = A[ptr]
> ptr = (ptr + 1) % (2 * p)
so this is how you do the wrapping on the wavetable. Very nice, no "if ptr > 880 then ptr=0" statement.
if the pitch is A440, then that would be an array of size 880 samples.
so, in a VB like language:
//create an array
a=[]
//create output array
out=[]
//set value of p
p=440
//fill array with random numbers
for i=0 to p*2
a[i]=rnd(65536)-32768
next i
blend=0.3 //pick arbitrary number less than 1 as experiment
outputLength=11024
while i < outputLength
r=rnd(65536)-32768
//seems perhaps redundant to run a second random number generator when we already have an array full of random numbers?
if r > blend
//if blend is usually < 1 and rnd is either a positive or negative integer, seems like this is to determine if we dealing with positive or negative number
a[i]=0.5*(a[(i+p) mod (2*p)] +a[(i+p-1) mod (2*p)])
else
a[i]=-0.5*(a[i+p) mod (2*p)]+a[(i+p-1) %(2*p)])
end if
out[i]=a[i]
i=(i+1) mod (2*p)
end while
Assuming I've translated all that correctly, my question is: is the second rnd function needed, or can use "if a[i] < blend" ?
- Joel
More information about the Synth-diy
mailing list