Verfasst am: 28.10.2011, 19:16
Titel: Grundfrequenz eines aufgenommen Sprachsignals bestimmen
Hallo zusammen,
ich hoffe ich bin hier richtig und finde hier antworten.
Ich versuche ein Programm zu schreiben, mit dem ich Sprache aufnehmen kann (z.B. das Wort "Maus") und dann davon ein Spektrogramm und ein Spektrum zu erstellen und dann, das ist die eignetliche Aufgabe, die Grundfreuquenz von der Sprache zu ermitteln.
Ich habe in Matlab nun das Gui erstellt und kann nun auch aufnehmen und das Spektrogramm und Spektrum erzeugen. Hoffe bis hierhin ist das richtig.
Aber nun komm ich leider nicht weiter. Ich weiß nicht wie ich an die Grundfrequenz rangehen soll um diese zu ermitteln.
Kann mir da jmd helfen. Was Matlab anbelangt bin ich noch recht unerfahren...!
Unten mal mein Code, den ich bisher habe. Allerdings bin ich mir noch nicht mal sicher ob ich die richtige Spektrum Funktion gewählt habe.
Achja, meine Idee, die Grundfrequenz zu bestimmen, wäre im Spektrum den ersten Ausschlag zu suchen. Aber ich weiß leider nicht wie ich das machen soll.
(Hinzu kommt, das die Grundfrequenz laufend neu berechnet werden soll)
Glaub ich müsste noch mit nem (Hamming-) Fenster arbeiten aber auch da wirds bei mir schwierig.
Vielen, vielen Dank für Lösungsansätze, Tips und Hinweise.
--------------------------------------------------------------------------
% Play back the recording.
play(RecordObj);
% "playblocking" = Play, and do not return control until playback % completes.
--------------------------------------------------------------------------
%Deklaration
x = myRecording;
Zum Thema Spektrogramm: Wenn man die Harmonischen des Sprachsignals sehen will, benötigt man ein Schmalbandspektrogramm mit einer Frequenzauflösung df i.d.R. von unter 50 Hz.
df = Fs/nfft mit nfft = Fensterlänge
Fs gibst du ja hier mit 44.1 kHz an, weshalb ich nicht verstehe, warum du der Funktion spectrogram dann nur noch 1 kHz übergibst?
Ich bleib mal bei den angegeben 44.1 kHz für die Abtastfrequenz. Wenn also df unter 50 Hz für ein Schmalbandspektrogramm sein muss, lässt sich daraus die Fensterlänge nfft bestimmen.
nfft = Fs/df = 44.1kHz/50Hz = 882 Werte
Da man für die Fensterlänge aber üblicherweise eine 2er Potenz wählt (damit die FFT verwendet wird), würde ich nfft = 1024 vorschlagen, womit deine Auflösung bei rund 43 Hz liegt. Wenn du für den Übergabeparameter window ebenfalls nur einen Wert angibst, wird standardmäßig ein Hamming window verwendet. Den Overlab würde ich erst mal auf nfft/2 setzen und später noch anpassen.
Wie du siehst, kann dir die Funktion auch die Segmente S der einzelnen Spektren zurückgeben. S ist eine Matrix der Länge (nfft/2)+1 x k, wobei k die Anzahl der Segmente ist. k ist von der Fensterlänge/windowlänge, der Signallänge n von x und dem noverlab abhängig.
Code:
k = fix((n-numoverlap)/(length(window)-numoverlap)) ;
(nfft/2)+1 ist der positive Frequenzbereich eines Segments von 0...Fs/2 [Hz]. Diese Segmente könntest du jetzt nach der Grundfrequenz durchsuchen. Allerdings bin ich da jetzt auch erstmal überfragt, wie man das per Algorithmus macht. Das Ablesen aus dem Spektrogramm ist ja simple...aber nur die Daten zu durchsuchen, ist dann schon nicht mehr trivial. Mit der Suche nach dem ersten Maximum scheitert man meist. Was ist das erste Maximum? Da müsste man sonst einen bestimmten Pegel als Minimum bestimmen, wonach man dann die Maxima untersucht.
Das es nicht wirklich bei der Problematik hilft, ist mir schon klar. Wenn man mal ein wenig zu dem Thema googelt, wird schnell klar, dass es hier eben keine triviale Lösung gibt .
Vermutlich ist das Spektrogramm auch nicht mal der richtige Weg, da dies eher für die optische Auswertung gedacht ist. Die Grundfreq. ist dort zwar sichtbar, aber eben nicht so einfach in den Daten mittels Algorithmus findbar. Es gibt z.B. ein Patent, wo sie durch Autokorrelation ermittelt wird.
Bei der Suche der Grundfreq im Spektrogramm oder PSD könnte es evtl. auch helfen, nicht nur danach zu suchen, sondern z.B. 2 Harmonische zu erfassen (die ja ein ganzzahliges Verhältnis haben) und daraus dann einen groben Frequenzbereich der Grundfrequenz zu bestimmen und dort anschließend genauer zu suchen.
Nur eine Frage, weil ich neugierig bin: Wie kamst Du auf die Idee "clear all" in das Programm einzufügen?
Es entfernt alle geladenen Funktionen aus dem Speicher und das erneute Einlesen ist in Matlab sehr zeitaufwändig. Zudem gehen dabei alle persitent gespeicherten Variablen verloren und die Funktionen müssen neu initialisiert werden. "clear all" ist deswegen ein massiver Nachteil für die Programmgeschwindigkeit und der häufige Einsatz bei Anfänger verblüfft mich immer wieder. Hat Dir jemand dazu geraten?
"clear variables" löscht zumindest nur die lokalen Variablen. In einem Script kann das hilfreich sein, wenn man sehr grobe Bugs darin hat. Aber eigentlich sollte man solche Bugs besser von MLint finden lassen und dann beheben.
Gruß, Jan
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 29.11.2011, 22:46
Titel:
am einfachsten kannst du die grundfrequenz mithilfe einer autokorrelation
bestimmen, das erste nebenmaximum neben dem hauptmaximum stellt die grundfrequenz da...
das kannst du dir einfach im entsprechenden frequenzbereich (zB. 100 - 400 Hz) suchen,
dann den index verschieben (weil nur in bestimmten frequenzbereich gesucht wurde) und in frequenz (grundfrequenz = abstastrate/(verschobener index)) umrechnen
Einstellungen und Berechtigungen
Du kannst Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum posten Du kannst Dateien in diesem Forum herunterladen
MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.