Synthesizing harmonic tones with Karplus Strong I'm building my own MIDI synth.

I have to create a decent sounding tone for every note on the piano keyboard (A-1 through C7, or MIDI 21 through 21+88=109)

I've been using a basic ring resonator, where I create a ring of the right size (for example, sampling at 44.1 kHz the ring for A440 a.k.a. concert pitch would be 44100/440 i.e. 100.25 ~ 100 samples), fill it with static (values between -1 and +1) and then walk through it, averaging consecutive values.

The problem is that A-1 rumbles for 30 seconds, whereas C7 dies almost instantly.

I never noticed this problem before as I was working with a much smaller range; &lt; two octaves.

Attempting to balance out the decays by multiplying by a suitable decay constant, say X[n] = .995*(X[n-1] + X[n-2])/2, where I choose the constant carefully for each note, is also failing.

Problem here is that even with decay=1.0, a high note still disappears almost instantly.  And it makes sense thinking about it; if the ring is only 10 samples,  even in 1/100sec we have covered 440 samples i.e. 44 revolutions, which will have smeared everything pretty close to 0.

One method I tried is feeding energy into the ring; creating a buffer of static enveloped by an exponential decay, and feeding this buffer into the ring.   It isn't working very well.

What I found works better is linear interpolation, so instead of doing ( X[n-1] + X[n-2] ) / 2, I do maybe:

0.98 * X[n-1]  +  0.02 * X[n-2] for a high note,  and 
0.6 * X[n-1]  +  0.4 * X[n-2]  for a note lower down


etc. 

But now the question is: how to choose the interpolation factor depending on the note?

I need a much better model to work with.

I think I also need to implement fractional delay; 

Samp[ N ] += k *  Samp[ N - L ], 


and if L = 10.2 say, I would have to do:

Samp[ N ] += k * ( 0.8 * Samp[10]  +  0.2 * Samp[ 11 ] )


so that is a completely different linear interpolation.

So my main question is: How to mathematically determine the necessary interpolation factor for a given note, so that all notes have an equal decay?

Supplementary questions are:
 - do I need to use a decay constant in addition to adjusting the interpolation?
 - is my understanding of fractional delay sufficient to get a working result?  

If anyone knows of any resource for simulating a harmonic tone that is reasonably accessible, please do put it in as an answer. I've looked through JOS's resources, but he writes at a very advanced level, and I have difficulty understanding the material.

π

PS I can't find an appropriate tag;  pitch, note, gen*, tone, synth*, none of these are available.
First, note that the behaviour in which high-pitched notes disappear faster than low-pitched notes is found in many musical instruments. You might better not totally compensate for that.

One way I got the behaviour I wanted out of Karplus-Strong was the following:


I add an additional exponential decay for the lowest notes - a "loss" factor so that x[n] = loss * (x[n] + x[n - 1]) / 2
For the highest notes, I randomly decide whether I will do a buffer update or not ; with an increasingly high probability for the "no update" event as pitch increases.


To avoid dealing with fractional delays - and to get any kind of pitch modulation I want (but also to simplify the code), I use a ring buffer of the nearest power of 2 (for example, 128 samples for A4) and then do a linearly interpolated read from it. One can see this as a wavetable oscillator whose lookup table is dynamically modified/refreshed as the phase increment counter moves through it.