|
|
Spektrogramm erstellen aus Wav.datei |
|
Micha1314 |
Gast
|
|
Beiträge: ---
|
|
|
|
Anmeldedatum: ---
|
|
|
|
Wohnort: ---
|
|
|
|
Version: ---
|
|
|
|
|
|
Verfasst am: 05.05.2020, 16:02
Titel: Spektrogramm erstellen aus Wav.datei
|
|
|
|
|
Hallo zusammen,
ich bin neu hier und habe auch schon etliche Beiträge durchgelesen und versucht auf meinen Fall umzuändern doch komme leider nicht so richtig damit klar.
Ebenfalls ist mir die Signalverarbeitung nicht ganz geläufig und bin derzeit noch in der Einarbeitungsphase.
Nun zu meinem Problem.
Ich möchte mithilfe einer Wav.datei, die eine Tonaufnahme eines elektrischen Türöffners wiederspiegelt, herausfinden in welchen Frequenzen sich das Geräusch befindet.
Ich habe die datei bereits geschafft einzulesen, sowie sie zu kürzen, um nur einen kurzen Abschnitt zu betrachten und zu analysieren.
Ebenso habe ich (ich hoffe richtig) eine FFT durchgeführt und möchte nun meine Ergebnisse aus der FFT in einem Spektrogramm darstellen.
Ich habe schon die Funktion spektrogram ausprobiert, doch bekomme nur ein sehr verzerrtes Bild mit dem ich keine schlüsse daraus ziehen kann.
Ich hoffe Ihr könnt mir einen Tipp geben, was ich falsch gemacht habe, bzw wie ich weiter vorgehen sollte.
im Anhang habe ich noch ein Bild meiner Plots angefügt
Ich danke euch schon einmal für euer bemühen und freue mich von euch zu hören.
Liebe Grüße
Micha,
anbei nun mein bisheriger Code:
[code]
clear all
close all
%info= audioinfo('Aufnahme_oL_vorne_auf_Tisch_gekuerzt.WAV')
% Wav-File laden
[y,Fs]= audioread('Aufnahme.WAV');
%y=y(:,1);
% y=y(170000:end,1);% schließen
y=y(1:141000,1);%öfffnen
% subplot(2,1,1
% plot(y)
% xlabel('Sample Number')
% ylabel('Amplitude')
% title('Komplettes Signal des öffnens')
% subplot(2,1,2)
% %Begrenzung wegen FFT
y1=y(42000:44047,1);
% plot(y1)
% xlabel('Sample Number')
% ylabel('Amplitude')
% title('Betrachtetes Signal')
N = length(y); % Anzahlmesswerte
N1= length(y1);% Anzahl Messwerte des kürzeren Ausschnittes
%sound(y,Fs); %abspielen des Signals
%Anzeigen des Signals in eigentlicher Länge und nur den Ausschnitt der
%betrachtet werden soll
figure(1)
subplot(4,1,1)
fmax = Fs/3;
Ta = 1/Fs;
dauer = Ta*(N-1);
t = 0:Ta:dauer;
signal = y - mean(y);
bereich_ext = 42000:44047;
signal_ext=signal(bereich_ext);
t_ext=t(bereich_ext);
plot(t,signal,t_ext,signal_ext,'g');
grid on;
title('Darstellung des wav.Signal')
ylabel('Amplitude');
xlabel('Zeit in s');
subplot(4,1,2)
plot(0:1/Fs:(N1-1)/Fs,y1);
grid on;
title('Darstellung Ausschnitt im Zeitbereich');
ylabel('Amplitude');
xlabel('Zeit in s');
%fft mit verstärkung des Signals(Amplitude)
subplot(4,1,3)
f=linspace(0,fmax,N1);
% f2 = (0:N1-1)*(Fs/N1)/10; andere Variante für Frequenzvektor Erzeugung
G=abs(fft(y1,N1));
plot(f(1:N1/2),G(1:N1/2))
grid on
xlabel('Frequenz in Hz');
ylabel('Amplitude des Signals');
title('FFT Ausschnitt verstärkte Amplitude');
subplot(4,1,4)
fn = Fs/6; % Frequenz bis Hörbereich.
df = Fs/N1/3; % Frequenzauflösung des Spektrums
% Frequenzvektor: Darstellung bis Hörschwelle.
fv = 0: df : fn;
m = length(y1); % original sample length and number of samples
n = pow2(nextpow2(m)); % transform length dadurch wird die Leistung des FFT erhöht (pow2für BAsis 2 Potenz-und Skalierungs-Gleitkommazahlen und nextpow2 für den exponent der nächsthöeren Potenz von 2)
y = fft(y1,n); % DFT of signal
f = (0:n-1)*(fn)/1000;
f_fft=linspace(0,fmax,n);
power = abs(y).^2/n; %Normierte größe daher ^2/n
% FFT Segmentlänge und Fensterlänge
% kleine Sgementlänge nfft -> feinere Frequenz- aber schlechte
% Zeitauflösung
nfft = N1/8; % Segmentlänge (8 ist glaube ich der Standardwert bei spectrogram)
% Overlap = window_size/2
numoverlap = nfft/4; % Anzahl der Messwerte, die sich zwei benachbarte Segmente überlappen
% figure(2)
% % [S,F,T]=spectrogram(y1,nfft,numoverlap,fv,fn);
% Spektrogramm nun selber erzeugen
% surf(F,T,20*log10(abs(S'+eps)));
% view(0,15);
% colormap(spring)
% colorbar
% set(gca,'FontSize',16);
% title('Darstellung Spektrogramm');
% zlabel('Amplitude in dB');
% xlabel('Frequenz in Hz');
% ylabel('Zeit in s');
[/code]
Beschreibung: |
|
Download |
Dateiname: |
Plots .jpg |
Dateigröße: |
366.8 KB |
Heruntergeladen: |
343 mal |
|
|
|
|
|
|
Verfasst am: 06.05.2020, 12:14
Titel:
|
|
|
|
|
Hallo Micha,
ich glaube, dass du im Prinzip im richtigen Weg bist. Also, erst werden die Daten eingelesen, dann wird ein Frequenzraum mittels der Abtastfrequenz gebaut und letztens wird das Spektrum im Frequenzraum mittels des FFT Algorithmus konstruiert.
Nur ein Paar Anmerkungen zu deinem Code,
Wenn Fs die Abtastfrequenz ist, dann können Frequenzen des Analogsignals bis Fs/2 repräsentiert werden (Abtasttheorem). Also, höhere als Fs/2 Frequenzen des Analogsignals, wenn vorhanden, können nicht im abgetasteten Signal repräsentiert werden. Ich würde dann vorschlagen, die obige Codezeile durch
fmax = Fs/2;
zu ersetzen.
Zitat: |
plot(f(1:N1/2),G(1:N1/2)) |
Obwohl du den Frequenzraum mit der richtigen Größe gebaut hast, nutzt du nur die Häfte des Räumes für das Graph, also f(1:N1/2). Der fft Algorithmus funktioniert effizienter wenn die Zahl der angewendeten Pünkte als Exponent von 2 ausgewählt wird. Deswegen würde ich vorschlagen den Frequenzraum in folgender Art zu bauen,
N1FFT = 2 ^ nextpow2(N1);
f=linspace(0,fmax,N1FFT/2 + 1);
wobei N1 ist die Länge des reduzierten Signals, wie du es schon hast. Letztens würde ich das Spektrum des Signales im Frequenzraum in folgender Art plotten,
G=abs(fft(y1,N1FFT));
plot(f,G(1:N1FFT/2 + 1))
So hat man die richtige Spanne der Frequenzen des Signals. Dann können die jeweilige Frequenzen durch die Peaks unterschieden werden.
Da ein Signal künstliches Geräusch beinhalten könnte, wäre es in manchen Fällen sinnvoll das Signal zu filtern. Das könnte beispielsweise mit dem gleitenden Mittelwert gemacht werden,
windowSize = 20;
b = (1/windowSize)*ones(1,windowSize);
a = 1;
y1 = filter(b, a, y1);
Dazu würde ich das Link https://de.mathworks.com/help/matlab/ref/filter.html zitieren. Man sollte mit der Fensterlänge spielen um die gewünschte Glättung des Signals zu bekommen, weil zu viel Glättung zum Verlust wichtiger Eigenschaften des Signals führen kann.
Zitat: |
Ich habe schon die Funktion spektrogram ausprobiert, doch bekomme nur ein sehr verzerrtes Bild mit dem ich keine schlüsse daraus ziehen kann. |
Dazu würde ich vorschlagen die Funktion spectrogram mit einem Fenster aufzurufen.
Wenn kein Fenster explizit definiert wird, wird das Hamming Fenster genutzt,
spectrogram(y, a, [], N1FFT, Fs, 'yaxis');
wobei a ist die Länge der unterliegenden Segmente. Man sollte mit dieser Länge spielen um den gewünschten Kompromiss zwischen Zeit- und Frequenz-auflösung zu finden.
Ein anderes Fenster wäre dann das Kaiser Fenster, was beispielsweise wie folgt aufgerufen werden kann,
spectrogram(y,kaiser(128,18 ), [], N1FFT, Fs, 'yaxis');
wobei (128, 18 ) Anwendungsabhängige Parameter des Kaiser Fensters sind. Mehr über Fenster findest du unter https://de.mathworks.com/help/signal/ug/windows.html.
Ich hoffe, dass meine Erklärung hilfreich war.
Liebe Grüße,
Andreas
_________________
Dr.-Ing. Andreas Apostolatos
|
|
|
|
|
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
|
|
Impressum
| Nutzungsbedingungen
| Datenschutz
| FAQ
| 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.
|
|