WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Grundfrequenz eines aufgenommen Sprachsignals bestimmen

 

badman123
Forum-Newbie

Forum-Newbie


Beiträge: 2
Anmeldedatum: 28.10.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 28.10.2011, 19:16     Titel: Grundfrequenz eines aufgenommen Sprachsignals bestimmen
  Antworten mit Zitat      
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.

MFG
Code:


% Speicher und Fensterinhalt löschen
clear all
clc

% Oberfläche
figure (1)

set(gcf,'menubar','none','units','normalized')
uimenu ('label','&Fenster schließen','callback','close')

% Buttons

Button1 = uicontrol (gcf,...
    'Style','Push',...
    'Position', [10 350 70 30],...
    'String', 'Record',...
    'Callback','Record');        

Button2 = uicontrol (gcf,...
    'Style','Push',...          
    'Position', [10 315 70 30],...
    'String','Play',...        
    'Callback','Play');

Button3 = uicontrol(gcf,...
    'Style','Push',...
    'Position', [10 210 110 30],...
    'String', 'Draw spectogram',...
    'Callback', 'Spectrogramm');

Button4 = uicontrol(gcf,...
    'Style','Push',...
     'Position', [10 175 90 30],...
    'String', 'Draw Spectrum',...
    'Callback', 'SpeKctrum');

Button5 = uicontrol(gcf,...
    'Style','Push',...
     'Position', [10 140 135 30],...
    'String', 'Calculate Grundfrequenz',...
    'Callback', 'pksGF');

% Grafik erstellen

set (gca,...
    'Position',[.4 .1 .5 .8])
   
% Grafikbeschriftung figure (1)

% axis ([1 10 -5 5])
title ('Amplituden-Zeit-Diagramm')
ylabel ('Amplitude')
xlabel ('Zeit [s]')

-------------------------------------------------------------------------

%Deklaration

Fs = 44100;     %Fs = Abtastrate
nbits = 16;     %Bits per sample
nChannels = 1;  %The number of channels: 1 (mono) or 2 (stereo).
length = 3;      %Length of record

%Aufnahme

RecordObj = audiorecorder(Fs, nbits, nChannels);
get(RecordObj);

% Record your voice for 3 seconds.

RecordObj = audiorecorder;
disp('Start speaking...')
recordblocking(RecordObj, length);

%recordblocking = Does not return control until recording completes.

disp('End of Recording!');

% Store data in double-precision (doppelte Genauigkeit) array.
% Scheint wohl der Vektor zu sein
myRecording = getaudiodata(RecordObj);

% Plot the waveform. Linien = -/--/:/-.
%                    Punkte = ./+/*/o/x
%                    Farbe  = r/b/y/g

set (gca,'Position',[.4 .1 .5 .8])

plot(myRecording,'r');

% axis ([1 10 -5 5])

% Grafikbeschriftung

    title ('Amplituden-Zeit-Diagramm')
    ylabel ('Amplitude')
    xlabel ('Zeit [s]')

--------------------------------------------------------------------------
% Play back the recording.
play(RecordObj);

% "playblocking" = Play, and do not return control until playback
% completes.
--------------------------------------------------------------------------
%Deklaration
x = myRecording;

% Spectrogram

figure(2)

spectrogram (x,128,120,128,1E3);
title ('Spectrogram')
view(270,90);
-------------------------------------------------------------------------
%Deklaration
x = myRecording;

%Spectrum --> spectrum.periodogram

figure(3)

Hs = spectrum.periodogram;
psd(Hs,x,'Fs',Fs)
title ('Spectrum.periodogram')

 
Private Nachricht senden Benutzer-Profile anzeigen


DSP
Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 28.10.2011, 20:37     Titel:
  Antworten mit Zitat      
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?

Code:

spectrogram (x,128,120,128,1E3);
S=spectrogram(x,window,noverlap,nfft,fs)
 


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.
Private Nachricht senden Benutzer-Profile anzeigen
 
badman123
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 2
Anmeldedatum: 28.10.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 30.10.2011, 16:56     Titel:
  Antworten mit Zitat      
Hi, vielen Dank erstmal für diese Antwort.

Aber zur Erkennung der Grundfrequenz hats mich leider nicht hingetragen.

Weiß jmd anderes wie ich das in Matlab bewerkstelligen kann?
Private Nachricht senden Benutzer-Profile anzeigen
 
DSP
Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 30.10.2011, 18:18     Titel:
  Antworten mit Zitat      
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 Wink.

http://de.wikipedia.org/wiki/Grundfrequenz

...siehe unter dem Punkt: Sprache!!

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.
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 30.10.2011, 20:29     Titel: Re: Grundfrequenz eines aufgenommen Sprachsignals bestimmen
  Antworten mit Zitat      
Hallo badman123,

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
Private Nachricht senden Benutzer-Profile anzeigen
 
Gast



Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 29.11.2011, 22:46     Titel:
  Antworten mit Zitat      
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
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

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
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2024 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

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.