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.