# Karplus–Strong algoritm

http://en.wikipedia.org/wiki/Karplus–Strong_string_synthesis

ok I just want to make sure I understand how this works.
you have N with = fs/fo .
fs is sampling rate = 44100Hz
Fo is the note you want to play like 440hz

then you make an array of N sizes and full it up with random value between 0.5 and -0.5
then you outputs the array from 0 to N then after N you do this

output = the 1st value of Array and the second value of the Array / by 2 * 0.995

and you keep doing this until output is 0?
is that right ?

this is mt class :

``````using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NAudio.Wave;

namespace test
{
class Guitar : WaveStream
{
public Guitar()
{
Frequency = 0;
n2 = 0;
n3 = 0;
n4 = 0;
rnd1 = new System.Random();
t = 0;
decay = 0.995;
}
public double Frequency { get; set; }
public double Amplitude { get; set; }
static int n2;
static int n3;
static int n4;
public long Bufferlength { get; set; }
private long position;
float[] X;
float[] temp;
public override long Length { get { return Bufferlength; } }
public override WaveFormat WaveFormat { get { return WaveFormat.CreateIeeeFloatWaveFormat(44100, 2); } }
Random rnd1;
static int t;
double decay;

public override long Position
{
get
{
// we'll just return the number of bytes read so far
return position;
}
set
{
position = value;
}
}

// buffer size is 52920 and so is sampleCount
// oddset is 0
public override int Read(byte[] buffer, int offset, int sampleCount)
{
// Bufferlength set to the min I want the sound to play for

int N = (int)(44100D / Frequency); // size of buffer for the karplus-strong algorithm
float sum;// temp holding place
// below only happens once
// it make the karplus-strong algorithm buffer
if (n2 == 0) // flag
{
X = new float[N];
temp = new float[N + 1];
for (int i = 0; i < N; i++)
{
X[i] = (float)(0.1 * rnd1.Next(-5, 5)) + (float)(0.5 * Math.Sin(i * Frequency * Math.PI / 44100D));// random number from -0.5 - 0.5
//  X[i] = (float)(0.5 * Math.Sin(i * Frequency * Math.PI / 44100D));
}
n2 = 1; // flag
}
// karplus-strong algorithm low pass filer
for (int r = 0; r < sampleCount / 4; r++)
{
if (t == (N - 1))
{
t = 0;
n4 = 1;
}
if (n3 >= Bufferlength && t == 0)
{
//    Dispose(); // stop playing
//  return 0; // stop playing
}
if (n4 == 0)
{
sum = X[t];
temp[t] = sum;
}
else
{
sum = (float)(X[t] + ((temp[t] + temp[t + 1]) * 0.5 * decay));// low pass filter and decay factor of 0,996
temp[t] = sum;

}
t++; // counter this is a  static  counter
decay = decay - 0.00009;
// send sum to the butter that so it can be played later
byte[] bytes = BitConverter.GetBytes(sum);
buffer[r * 4 + 0] = bytes[0];
buffer[r * 4 + 1] = bytes[1];
buffer[r * 4 + 2] = bytes[2];
buffer[r * 4 + 3] = bytes[3];
n3++;
}
return sampleCount;// end of Read sound start playing now
}

}
}
``````

My sound does not stop
it get to a point where the number in the buffer just repeat…
that is wrong right ?

Yes that’s wrong.

The expected behaviour for Karplus–Strong synthesis is that the sound decays. For that to work, the overall gain must be less than 1.
Sorry, I’ve no idea about your code, but there is an implementation of Karplus-Strong algorithm in “Nyquist” code here, if that is any use to you:

``````;;; Simple KARPLUS-STRONG
;;; coded by Pedro Jose Morales
;;; pmorales@iele-ab.uclm.es

; NYQUIST code for simple Karplus-Strong algorithm

(setf *pmorales-path* (current-path))

(setf ks-class
(send class :new '(cnt total-cnt z-1output output delay-line len total-len)))

(send ks-class :answer :isnew '(pitch dur)
'((setf len (round (/ *sound-srate* (step-to-hz pitch))))
(setf total-len (* *sound-srate* dur))
(setf delay-line (snd-samples (noise (/ (step-to-hz pitch))) len))
(setf cnt 0)
(setf total-cnt 0)
(setf z-1output 0.0)
(setf output 0.0)))

'((setf output (aref delay-line cnt))
(setf (aref delay-line cnt) (/ (+ output z-1output) 2.0))
(setf z-1output output)
(setf cnt (if (= (1- len) cnt) 0 (1+ cnt)))
(setf total-cnt (1+ total-cnt))
(if (= total-cnt total-len) NIL output)))

(defun ks (pitch dur)
(let (obj (d (get-duration dur)))
(setf obj (send ks-class :new pitch d))
(snd-fromobject *rslt* *sound-srate* obj)))

(defun ks-env (pitch dur)
(mult (pwe dur 0.064)
(ks pitch dur)))

;(ss (seq (ks a4 1.0) (ks b4 1.0) (ks c5 3.0)))

(ss (seq (ks-env a3 1.0) (ks-env b3 1.0)))
``````

(example taken from the CMU Nyquist documentation)