OK, eines vorweg. Der Code ist in Pascal. Ganz einfach deswegen, da das nicht nur meine Lieblingsprogrammiersprache ist, sondern auch noch leicht von jedem verstanden werden kann. Mir geht es hier nicht darum, einen perfekten Code abzuliefern, sondern darum, einfach mal zu zeigen, wie einfach das geht. Das Programm macht einen einfachen Formant-Vocoder. Ein Vocoder simuliert den Stimmtrakt. Im Prinzip ist das eine Anregung welche aus einem Dirakpuls und Rauschen besteht (Verhältnis einstellbar) und diesen dann durch 2 Filter schickt welche eine Frequenzerhöhung bei einer bestimmten Frequenz (Formant) machen. 2 Formanten reichen für verständliche Sprache bereits aus. Die Filter sind parallelgeschaltet und sind rekursive Filter 2. Ordnung. Vor rekursiven Filtern haben manche Leute Angst, wenn man die redoch in vernünftigen Rahmen betreibt sind die stabil. Filterstruktur: x---->+->------->y |\ | | \ T | \b1| \ | \ T \b2| Also grob gesagt kommt das Signal bei x rein, und dazu wird dann das einfach verzögerte, mit b1 multiplizierte Ausgangssignal addiert, sowie das zweifach verzögerte, mit b2 multiplizierte Ausgangssignal addiert. Vereinfach gesagt bestimmt b2 die Güte des Filters und b1 die Frequenz. Stabil ist der Filter in einem Dreieck mit der Spitze b1=0 und b2=1 sowie der Basis b2=-1 und -2<=b1<=2. Die Eingabe des Programmes ist Dauer Grundfreq Stimmh. Rauschh.Formant1 Formant2 Beispiel: 1 100 1 0 1000 1400 1 100 1 0 500 2300 1 100 1 0 320 3200 1 100 1 0 500 1000 1 100 1 0 320 800 1 100 1 0 700 1800 1 100 1 0 500 1500 1 100 1 0 320 1650 1 100 0 1 3000 3500 1 100 0 1 2000 2500 Das sind mehrere Laute, jeweils eine Sekunde lang. Es beginnt mit A E I O U, Ä Ö Ü und dann kommen 2 experimentelle Frikale. Die Ausgabe ist: Zeit/s seit Dateianfang, Leerzeichen, Abtastwert Das Programm sox kann dieses Format direkt als "dat" verarbeiten. Wenn man mal genau nachsieht, in welchen Wertebereichen die einzelnen Variablen sind, und man die Cosinusse durch Tabellen ersetzt kann man das bestimmt auch mit Festkommaartithmetrik machen und somit problemlos auf einem AVR laufen lassen.
Daisy Daisy give me your answer to.... Der Beginn des berühmten Liedes welches man hier http://chaosradio.ccc.de/ctv037.html in ganzer Länge hören kann.
Hallo Christian! Ich finde Deine Postings sehr interessant und überlege, sie auf einem AVR zu konvertieren. Allerdings woher bekommt man die Parameter für Phoneme? Selber ausprobieren? (Ich habe noch nicht wirklich selber gesucht :-) Gruß, Michael
Micha wrote: > Hallo Christian! > > Ich finde Deine Postings sehr interessant und überlege, sie auf einem > AVR zu konvertieren. Danke > Allerdings woher bekommt man die Parameter für > Phoneme? Selber ausprobieren? (Ich habe noch nicht wirklich selber > gesucht :-) In dem Fall des Musikstücks habe ich die einfach vom Spektrogramm abgelesen. Ansonsten ist die Wikipedia dein Freund. Zumindest bei Vokalen. http://de.wikipedia.org/wiki/Formant > Gruß, Michael
Ohh eins hab ich noch vergessen. Vielleicht ist es sinnvoll das ganze in eine ISR zu stecken. dann kann man die Parameter leichter ändern.
Christian, interessante sache, hatte mich noch nie damit beschäftigt! Ich hab mir mal den Code angesehen, da ist mir aufgefallen, das der implementierte Filter nicht zur textuellen Beschreibung passt: Im code steht: filter1_d1:=y1; lt. Beschreibung würde ich hier ein: filter1_d1:=x; erwarten. Selbiges für den 2ten filter. Die Abbildung des Filters hilft mir da auch nicht weiter ... Gruß Mario
Mario wrote: > Christian, > > interessante sache, hatte mich noch nie damit beschäftigt! Ich hab mir > mal den Code angesehen, da ist mir aufgefallen, das der implementierte > Filter nicht zur textuellen Beschreibung passt: > Im code steht: > filter1_d1:=y1; > > lt. Beschreibung würde ich hier ein: > filter1_d1:=x; > > erwarten. Selbiges für den 2ten filter. Die Abbildung des Filters hilft > mir da auch nicht weiter ... Ahh, das ist ein Implementationsdetail. Würde ich den Wert von X nehmen, so müsste ich X verändern und beide Filter würden zusammenfallen. Ich glaub so kann man das besser darstellen: X--->Y1------> | | | V |f1<-d1 | | | V f2<--d2 Die Summationsstelle ist somit Y1. Das macht den Code einfacher und ich brauche weniger Variablen. > Gruß > Mario
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.