Der Zustand der Saite wird durch einen Vektor von Auslenkungen als Vektor im Computer abgebildet. Er enthält die Wellenformen, zum Beispiel einen Sägezahn oder einen Sinus usw. Der Tonabnehmer registriert die Auslenkung der Saite an einem festen Ort. Dies läßt sich im Computer dadurch simulieren, dass man einen Zeiger, bzw. den Index (ganze Zahl) des Feldes hoch- oder runterzählt. Dadurch ist die Amplitude der Beschleunigung immer gerade der Wert des Feldes an Index- oder Zeigerstellung .
Es ist also, als ob der Tonabnehmer sich an einer fest ausgelegten Saite immer mit der richtigen Geschwindigkeit auf und ab bewegt. Durch die linearität und explizite Lösung der Wellengleichung ist dieses Abtasten einer beliebigen Wellenform eine korrekte Abbildung des Signals am Tonabnehmer. Was noch fehlt ist die Dämpfung.
Die schwingende Saite kommt nach kurzer Zeit zur Ruhe, d.h. für Es gibt drei Dämpfungsmechanismen, die je nach Situation dominant sein können.
Die Unterschiede sind hörbar: z.B.ist bei Metallsaiten die viskose Dämpfung dominant, bei Darm- oder Nylon Saiten die innere Dämpfung. Deshalb klingen Metallsaiten brillanter, Nylonseiten weicher und dumpfer.
Statt die Dämpfung direkt physikalisch zu modellieren, wird sie im Karplus-Strong-Algorithmus durch eine einfache Mittelung ersetzt. Nach dem Auslesen der Amplitude wird mit und gesetzt. Damit ist garantiert, dass die Amplitude auf 0 abklingt.
Die Implementierung sieht dann wie folgt aus:
/********************************************************************* zupf.cc -- Modellierung einer gezupften Saite Autor : R. Hilfer Zweck : Beispiel zur Vorlesung, demonstriert Karplus-Strong Alg Gebrauch : Eingabe von stdin: frq = Frequenz in Hertz t_max = Gesamtzeit Dateien : Ausgabe auf Datei zupf.raw in binaerem Format Umwandlung mit dem Befehl sox -s -w -r 44100 gharmos.raw gharmos.wav in wav-Format Version : 1.0 (Originalversion) erstellt am 12.10.2000 *********************************************************************/ // Einbinden benoetigter Bibliotheken #include<iostream> #include<fstream> int main() { // Deklarationen double *u; double u_0,uprv,t_max,dt,t,frq; short amp; int plckpt,len,i,iflg,next; // Parameter abfragen und einlesen cout << "Frequenz :"; cin >> frq; cout << "Gesamtdauer :"; cin >> t_max; dt=1./44100.; // Zeitschritt = Abtastrate len = int(44100./frq); // Laenge der Saite plckpt = int(0.1*len); // Zupfpunkt u_0 = 28000; // Anfangsauslenkung t=0.; // Zeit initialisieren // Initialisieren der Saite u = new double[len]; // Speicher bereitstellen for( i=0; i<=plckpt; i++ ){ // Auffuellen mit Saegezahn u[i]=2*u_0*i/plckpt - u_0; } for( i=len-1; i>plckpt; i-- ){ u[i]=2*u_0*(len-1-i)/(len-plckpt) - u_0; } // Vorbereitung der binaeren Ausgabedatei ofstream outfile("zupf.raw",ios::out|ios::binary); i=0; uprv=u[0]; while(t<t_max){ u[i] = u[i]*0.5+uprv*0.5; // Tiefpass = gleitender Mittelwert uprv = u[i]; // Tiefpass: Amplitude zwischenspeichern amp = short(u[i]); // Vorbereitung zur Ausgabe in short outfile.write(&,2); // binaere Ausgabe : 2 byte schreiben t=t+dt; // Zeit hochzaehlen if(i==len-1) i=-1; // Zaehler zuruecksetzen i++; // Index fuer naechste Ausgabe setzen } }
Klicken Sie bitte auf diese Zeile, um den Klang zu hören.
Natürlich ist die Modellierung noch verbesserungsfähig, insbesondere wenn man den Klang einer Gitarre oder ähnlicher Instrumente nachahmen möchte. Es fehlt die gesamte Modellierung des Korpus (Resonator), der Kopplung zwischen Saite und Resonator etc.