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

fft: Lautstärkeverlauf einzelner Frequenzkomponenten

 

Sepp Ultura
Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 16.09.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 16.09.2011, 13:56     Titel: fft: Lautstärkeverlauf einzelner Frequenzkomponenten
  Antworten mit Zitat      
Hallo Leute

Dies ist mein erster Beitrag hier. Ich kam hierher um ein bisschen nach Hilfe zu schreien.

Ich bin ein Linguistikstudent mit sehr beschränktem Ingenieurs- und Programmierwissen. Ich bin aber akustisch (von den Prinzipien her) etwas bewandert.

Ich möchte gerne mit Hilfe einer fft Funktion ein aufgenommenes Sprachsample (z.B. ein Wort) analysieren und gezielt die Lautstärkeverläufe (Volume Envelopes) einer einzelnen Frequenz, z.B. 80 Hz, in einen Vektor schreiben.

Ich weiss was die fft Funktion macht, kenne auch das Prinzip des windowing und overlap etc. Mir ist es einfach programmiertechnisch ein Rätsel wie ich zu den Lautstärkeverläufen einzelner, vordefinierter Frequenzen komme.

Ich versuche seit Monaten aus der MATLAB Dokumentation schlau zu werden. Aber ich denke, dass mir einfach das Ingenieurswissen dazu fehlt.

Deshalb wäre ich für etwas Hilfe sehr dankbar.

Liebe Grüsse
Matthias
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: 16.09.2011, 14:25     Titel:
  Antworten mit Zitat      
Hallo,

so ganz ist mir noch nicht klar, was du möchtest. Wenn du das Frequenzspektrum deines Sparchsignal darstellst, erhältst du ja in Abhängigkeit der Auflösung des Spektrums bei den diskreten Frequenzen einen Amplitudenwert (bei Lautstärke/Schalldruckpegel evtl. in [dB]). Wie sollen da jetzt bei einer Frequenz mehrere Amplitudenwerte herauskommen?

Kannst du sonst evtl. mal eine bespielhafte Grafik und deinen bisherigen Code posten.

Hast du dir schon dieses Bsp. zur FFT aus der Skript-ecke angesehen:

http://www.gomatlab.de/fft-umfassendes-beispiel-t777.html
Private Nachricht senden Benutzer-Profile anzeigen
 
Sepp Ultura
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 16.09.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 17.09.2011, 11:47     Titel:
  Antworten mit Zitat      
Danke für die schnelle Antwort.

Ich habe mir das angegebene Beispiel schon angesehen bevor ich meinen Beitrag gepostet habe. Aber irgendwie blick ich da nicht so durch, das ist mir wohl schon ein bisschen zu hoch. Laughing

Vielleicht war ich nicht ganz klar bei meinen Ausführungen. Mein bisheriger code ist fast lächerlich und gibt mir lediglich den Plot eines Spektrogramms wieder:

Code:
%data=signal
%fs=sample rate
w=hann(256, 'periodic');
spectrogram(data, w, 128, 256, fs, 'yaxis');
xlabel('Time (Seconds)');


Ich habe auch schon ein bisschen mit den noverlap und nfft werten gespielt.

Was mir aber tatsächlich vorschwebt ist folgendes: Ein Sprachsample ist ja nicht periodisch sondern kontinuierlich. Somit sind ja die Amplitudenwerte einzelner Frequenzen von Zeitpunkt zu Zeitpunkt unterschiedlich hoch. Ich habe das eigentlich sehr schön in der [specgramdemo(data, fs)] gesehen.



Ich habe den Bereich, der mich interessiert rot markiert. Da sieht man ja schön den Lautstärkeverlauf der unten im Spektrogramm ausgewählten Frequenz.

Ich möchte nun genau diese Lautstärkeverläufe ausgewählter Frequenzen in einen Vektor schreiben und diesen im Workspace zugänglich machen. Mit der specgramdemo funktion lande ich in einer Sackgasse, da ich nicht dahinterkomme.

Ich hoffe, dass meine Ausführungen jetzt ein bisschen klarer sind. Ich bedanke mich jetzt schon für Deine Hilfe!

Gruss,
Matthias
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: 17.09.2011, 16:44     Titel:
  Antworten mit Zitat      
Ich bin mir noch nicht ganz sicher, ob ich dich richtig verstanden habe. Nehmen wir mal, du hast ein Signal mit 8192 Messwerten. Die Segmentlänge des Spektrogramms soll 1024 betragen (ergibt 8 Segmente) und der Overlap ist 512 Werte. Du kannst dir auch die Ergebnisvektoren, mit denen das Spektrogramm dargestellt wird, speichern.

Code:

[S, F, T] = spectrogram(data(1:8192), w(1:1024), 512, 1024, fs, 'yaxis');
% Dimension der Ergebnisvektoren:
S(513:8)
F(1:513)
T(1:8)
% Umwandlung des Betrags in dB
S_dB = 20*log10(abs(S)+eps); % eps ist eine kleine Konstante um log(0) zu verhindern

% wenn du nun alle Werte der diskreten Frequenz x haben willst:
% Bsp: suche nächste diskrete Frequenz bei 100 Hz
F_diskret_idx = find(F >= 100,1,'first'); % find liefert den Index
% alle Volumewerte der Frequenz 100 Hz im Zeitbereich von T
Volume_100 = S_dB(F_diskret_idx,1:8);
 
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: 17.09.2011, 18:50     Titel:
  Antworten mit Zitat      
Sorry..ich habe hier einen Fehler gemacht. 8 Segmente ergeben sich bei keinem Overlap...bei 512 Werten sind es dann 15 Segmente.

Code:

% Dimensionen:
S(513:15)
T(1:15)
Volume_100 = S_dB(F_diskret_idx,1:15)
 
Private Nachricht senden Benutzer-Profile anzeigen
 
Sepp Ultura
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 16.09.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 19.09.2011, 12:10     Titel:
  Antworten mit Zitat      
Vielen vielen Dank für Deine Hilfe. Ich denke ich verstehe fast was da vor sich gehen muss! Laughing

Ich habe Deinen Code nun ein bisschen für meine Zwecke anzupassen versucht und bin zu folgendem ergebnis gekommen (das Sample hat eine Länge von 159865 messwerten und eine fs von 44100:

Code:
%import audio data first (data & fs) ---> fs must be 44100
%define FQ: the frequency that you want to extract

%creates the window
w=hann(512, 'periodic');

%analyzes the data via FFT
[S, F, T] = spectrogram(data, w, 256, 512, fs, 'yaxis');

% Umwandlung des Betrags in dB
S_dB = 20*log10(abs(S)+eps); % eps ist eine kleine Konstante um log(0) zu verhindern

% wenn du nun alle Werte der diskreten Frequenz FQ haben willst:
% Bsp: suche n?chste diskrete Frequenz bei 100 Hz
F_diskret_idx = find(F >= FQ,1,'first'); % find liefert den Index
% alle Volumewerte der Frequenz 100 Hz im Zeitbereich von T
Volume_FQ = S_dB(F_diskret_idx,1:623);


Ich hätte da einfach noch eine Frage:

Ich arbeite mit einem importierten Sample mit einer Sample Rate von 44,1 kHz und mit 159865, deshalb habe ich den T index anpassen müssen. Wie kommt man rechnerisch von der Samplelänge, window und overlap grösse zu T? Denn T ist ja auch abhängig von der Sample Länge. Dann müsste ich ja nicht ständig den code anpassen falls ich ein Sample mit anderer Länge importiere.

Ich habe einfach nicht ganz verstanden wie Du in Deinem Beispiel von einer Länge 8192 zu 15 segmenten kommst. Alle meine Rechnungsversuche ergeben bei mir ungerade Zahlen. Die 623 in meinem Beispiel habe ich vom Vektor T, der mir als Ergebnis von
[S, F, T] = spectrogram(data, w, 256, 512, fs, 'yaxis');
im Workspace erscheint entnommen.

Für weitere Hilfe wär ich unendlich dankbar!! Aber vielen vielen Dank schon mal für die bisherige Hilfe. Das ist schon ein grosser Durchbruch für mich!
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: 19.09.2011, 12:24     Titel:
  Antworten mit Zitat      
Letztendlich wird in der Funktion spectrogram folgendes gemacht:

Code:

% Ist Signallänge gerade?
if mod(length(data),2)
    n = length(data)-1;
else
    n = length(data);
end;
% Werte aus deinem Bsp. mit einer Segementlänge von 512 Werten
nfft = 512;
% Overlap = window_size/2
numoverlap = 256;
% Hann Fenster erstellen
win = Fenster(nfft,'hann');
% Anzahl Segmente bestimmen
k = fix((n-numoverlap)/(length(win)-numoverlap)) ;
H = zeros(nfft,1);
% k. Segmente der Länge nfft transformieren
m = 1;
for i=1:k
    % Fensterung mit Hann window
    signal_win = data(m:nfft+m-1) .* win;
    H(1:nfft) = fft(data_win, nfft);
    % Betrag bilden
    H_pos0(1:(nfft/2)+1,i) = abs(H(1:(nfft/2)+1));
    % nächstes Segement
    m = m + nfft - numoverlap;
end

% Auflösung des Spektrum
df=fs/nfft;
% Frequenzvektor
f = [0:nfft/2]*df;
% Zeitvektor
t = [0:k-1]*numoverlap/fs;
% Spektrogramm darstellen
...
 


Du kannst es ja auch so machen:

Code:
Volume_FQ = S_dB(F_diskret_idx,1:length(T));
Private Nachricht senden Benutzer-Profile anzeigen
 
Sepp Ultura
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 16.09.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 19.09.2011, 13:33     Titel:
  Antworten mit Zitat      
Vielen vielen Dank für Deine Hilfe!! Ich bin Dir unendlich dankbar. Das bedeutet für mich ein Quantensprung.

Zitat:

Du kannst es ja auch so machen:

Code:
Volume_FQ = S_dB(F_diskret_idx,1:length(T));


Ich hab nun meinen Code so adaptiert. So kann ich mit allen beliebigen Samples arbeiten.

Das einzige was nun bleibt ist folgendes: Wenn ich jetzt das Ergebnis Volume_FQ als Graphik anzeigen lasse (über die plot funktion) erscheinen auf der Y Achse schön die dB werte. Auf der X Achse logischerweise der Vektor T (halt in seiner durch die Samplelänge definierten Länge). Kann ich dies nun, auch in abhängigkeit mit der ursprünglichen Samplelänge und der Samplerate, wieder in Sekunden anzeigen lassen? Und wenn ja, wie?

Ach, hätte ich doch nur ein Technisches Studium als Background. Sorry für die vielleicht blöden Fragen.
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: 19.09.2011, 16:02     Titel:
  Antworten mit Zitat      
Zitat:
Kann ich dies nun, auch in abhängigkeit mit der ursprünglichen Samplelänge und der Samplerate, wieder in Sekunden anzeigen lassen? Und wenn ja, wie?


Das verstehe ich nicht Question Es sind doch auch im Spektrogramm Sekunden auf der Zeitachse und die Samplerate hat sich auch nicht geändert.
Private Nachricht senden Benutzer-Profile anzeigen
 
Sepp Ultura
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 16.09.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 19.09.2011, 16:49     Titel:
  Antworten mit Zitat      
Ja, wenn ich mir das blosse spectrogramm ansehe schon. Aber wenn ich meinen Volume_FQ plotte zeigt es mir anstatt der sekunden die jeweiligen messfenster als zeitachse an. In meinem beispiel von 0 bis 623. Ist für mich ja auch logisch, denn Volume_FQ hat ja auch 623 werte.

Ich mache das einfach über:
Code:


Meine Frage ist, ob es möglich ist, die Zeitachse in sekunden und nicht in den Segmentwerten anzeigen zu lassen.

Ich schreibe das vom iphone aus. Ich werde die Graphik noch nach liefern die ich erhalte über Volume_FQ.

Aber danke nochmal!
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: 19.09.2011, 17:05     Titel:
  Antworten mit Zitat      
Und warum nutzt du nicht einfach den Zeitvektor T von spectrogram() ? Sie haben doch die gleiche Länge.

Code:
plot(T,Volume_FQ);
Private Nachricht senden Benutzer-Profile anzeigen
 
Sepp Ultura
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 16.09.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 20.09.2011, 00:40     Titel:
  Antworten mit Zitat      
Wow! Super! Da wäre ich jetzt nicht darauf gekommen..

Mein Problem ist gelöst! Vielen vielen vielen Dank!!

Darf ich Dich und das Forum als Referenz in meiner Arbeit angeben? Laughing

Ich werde jetzt noch ein bisschen mit Fenstergrössen und Overlaps experimentieren. Denn so wie ich das verstanden habe ist es ja ein Dilemma zwischen Zeit- und Frequenzgenauigkeit..

Ich danke tausend mal für die Hilfe! Sehr wahrscheinlich werde ich irgendeinmal noch mit ein paar anderen Fragen zurückkommen. Wink

Matthias
Private Nachricht senden Benutzer-Profile anzeigen
 
Pipo

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 20.10.2016, 15:25     Titel: Berechnung nicht mit Spectrogram
  Antworten mit Zitat      
Hallo zusammen

Ich habe genau dasselbe versucht, hat auch geklappt.

Nun meine Frage: Kann ich das auch anders berechnen, also nicht mit der Funktion Spectrogram?
Spectrogram rechnet mit dem gesamten Signal und ich habe drei Frequenzen herausgepickt und über die Zeit geplottet. Das ist sehr viel Rechenaufwand.

Mit einer fft oder pwelch fehlt mir ja irgendwie der Bezug zur Zeit.
Ich stecke fest, hoffe jemand kann mir einen Denkanstoss geben.

Gruss
Philipp
 
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.