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

Sinusschwingung Amplitude/Volumen

 

Sepp Ultura
Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 16.09.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 27.09.2011, 14:10     Titel: Sinusschwingung Amplitude/Volumen
  Antworten mit Zitat      
Hallo allerseits.. Ich hab da noch mal eine Frage:

Ich kann ja mit folgendem Code eine Sinusschwingung erstellen mit den in den Kommentaren vordefinierten Werten:

Code:
% INPUT VARIABLES:
% le = length in senconds
% fs = sample rate
% fq = frequency of the resulting sine wave
% vm = amplitude

% create time vector with length 'le' in seconds
T=0:(1/fs):le;

% generate sine signal 's' with frequency 'fq'in Hz
s=vm*sin((fq*2)*pi*T);


Nun ist es der Wert 'vm', der mich interessiert. Um im Audiobereich zu arbeiten begrenze ich den Wert auf einen Bereich von 0-1. Das definiert ja dann die Amplitude.

Wenn ich nun eine Analyse des resultierenden Audiovektors mache, erhalte ich u.u. auch die Volumenwerte des Signals, in dB.

Nun meine Frage: kann ich das auch rückwärts machen. Sagen wir, ich möchte eine Sinusschwingung generieren mit einem Volumen von -10 dB. Kann ich diese -10 dB irgendwie in meinen bisherigen Code integrieren, so dass mir diese -10 dB den wert 'vm' ergeben?

Für einen Rat wäre ich sehr dankbar!
Liebe Grüsse,
Matthias
Private Nachricht senden Benutzer-Profile anzeigen


gjp578
Forum-Anfänger

Forum-Anfänger


Beiträge: 17
Anmeldedatum: 23.03.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 27.09.2011, 17:30     Titel:
  Antworten mit Zitat      
hab noch keine Erfahrung mit Audiosignale
aber ist 1 nicht equal 0 dB?
was ich auch nicht verstehe ist, die erzeugte sinus funktion hat negative Zahlen, wie kann man die negativen Zahlen in db umwandeln?
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: 27.09.2011, 18:45     Titel:
  Antworten mit Zitat      
Ich bin auch ein "Laie" aber eine Schwingung im Audiobereich ist normalerweise zwischen 1 und -1. Alles darüber (positiv und negativ) wird geclipt. Sie schwingt immer um den 0-Punkt und positive und negative Werte ergeben die selbe Schwingungsenergie. Oder so ähnlich.

Wie beim Lautsprecher: +1=Membran voll raus, -1=Membran voll rein.

Und es gibt eben mehrere dB Skalierungen. In der Tontechnik arbeite ich mit 0 dB als Referenz und arbeite abwärts. Was ich bei der FFT analyse aber erhalte sind dB, die den Schalldruck angeben. Oder so. Da blicke ich auch noch nicht ganz durch. Das studiere ich momentan.

Was ich will: bei der FFT Analyse erhalte ich Volumenwerte zwischen ~ -80 und ~ +50. Genau diese dB Werte möchte ich nun in meinen Code als Wert für die Amplitude der Sinusschwingung implementieren. Geht das? Und wenn ja, wie?
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: 27.09.2011, 18:48     Titel:
  Antworten mit Zitat      
Ich verstehe nicht was du machen möchtest? Was meinst du mit rückwärts...vom Frequenzspektrum zum Zeitsignal?

dB ist doch nur eine logarithmische Skalierung... -10 dB = 0.1
dB ist aber dimensionslos und hat immer einen Bezugswert. Bei einem Spannungspegel z.B: Lu = 20*ln(U/U0) [dBu]
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: 27.09.2011, 19:02     Titel:
  Antworten mit Zitat      
Dass dB ein relativer Messwert ist mir klar. Auch dass es eine logarithmische Skalierung ist.

Wenn ich z.B. ein Spektrogramm eines Audiosignals betrachte sehe ich z.B. bei 300 Hz einen Spitzenwert von +30 dB. Ich will nun eine Sinusschwingung generieren mit einem Volumen von +30 dB.

Du schreibst, dass -10 dB = 0.1 ergibt. 0.1 wäre ja dann kompatibel zum Wert 'vm' in meinem Code. Vielleicht habe ich auch rechnerisch ein Riesenproblem in meinem Kopf. Denn:

-10 dB = 0.1
??? dB = 1.0

Wie geht diese logarithmische Skalierung? Ich denke die Mathematik ist mein Problem.. Wink
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: 27.09.2011, 19:25     Titel:
  Antworten mit Zitat      
Sorry...ich habe einen Fehler gemacht. -10 dB = 0.1 gilt bei Leistungspegeln...
Lp = 10 * ln(P/P0) [dB]

Für die oben genannte Formel (Lu = 20*ln(U/U0)) gilt bei Spannungspegel:

60dB = 1000
40dB = 100
20dB = 10
0dB = 1
-20dB = 0.1
-40dB = 0.01
-60dB = 0.001

Die Umrechnung von [dBu] in die Spannung U wäre dann:

U = U0 * 10^(Lu/20) [V]
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: 28.09.2011, 10:54     Titel:
  Antworten mit Zitat      
Ok, danke für die Formel. Aber das Problem ist noch nicht gelöst:
Mein originales Sample hat einen Spitzenwert von 0.57/-0.57 (ich habe es nicht normalisiert). Die Spektralanalyse ergibt mir einen Spitzenvolumenwert von 27.5532 dB.

Das wäre dann nach Deiner Tabelle ein Wert von über 10. Das überschreitet ja den Spitzenwert im Originalsample bei Weitem. Wie kann das sein? Ich kann ja keine Audiovektoren erstellen, die den Wert 1 überschreiten. Da wird alles über 1 geclipt.

Oder bin ich immer noch zu unklar?
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.09.2011, 11:17     Titel:
  Antworten mit Zitat      
Zitat:
Mein originales Sample hat einen Spitzenwert von 0.57/-0.57 (ich habe es nicht normalisiert). Die Spektralanalyse ergibt mir einen Spitzenvolumenwert von 27.5532 dB.


Dann erkläre doch bitte erst mal wie du auf diesen dB Wert kommst. Bei einem Sinus mit der genannten Amplitude

Code:
y = 0.57*sin(2*pi*10*t)


und einer Frequenz von 10 Hz, erhält man bei einem Frequenzspektrum mittels FFT (kein Leakage vorausgesetzt), einen Peak genau bei 10 Hz mit einem Amplitudenwert von 0.57 oder -4.88 dB. Falls nicht, stimmt die Skalierung nicht. Wenn du hier allerdings den Wert aus dem Spektrogramm angibst (danach hattest du ja in einem anderen Thread auch gefragt), kann ich dir nicht helfen. In der Matlab Funktion spectrogram() gibt es ja keine Skalierung und ich hatte dir einen möglichen Ansatz genannt. Evtl. zeigt sich nun, dass dieser falsch ist...auf Grund der überlappenden Segmente. Ich habe nach wie vor auch keine Erklärung finden können, war spectrogram die Amplitudenwerte nicht skaliert.

Die Umrechnung in dB und umgehrt ist jedenfalls korrekt.
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: 28.09.2011, 11:21     Titel:
  Antworten mit Zitat      
EDIT: Ich habe dieses Post geschrieben bevor ich deine letzte Antwort gesehen habe.

Zitat:
Noch mal zur Klarifizierung:

Ich habe folgendes Audiosample mit Samplerate (fs) von 44100 Hz:



Dann benutze ich folgenden Code, um die Volumenverläufe bestimmter Frequenzen zu extrahieren (nur eine Annäherung an die tatsächliche Frequenz):

Code:
% This program is used to extract the volume envelope of a predefined
% frequency (FQ) (it only returns an estimate around that frequency)

% import audio data first (data & fs)
% define FQ: the frequency that you want to extract

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

% analyzes the data via FFT
% spectrogram(data, window, noverlap, nfft(fftlength), fs)
[S, F, T] = spectrogram(data, w, 128, 256, fs, 'yaxis');

% conversion of the values in S into dB
S_dB = 20*log10(abs(S)+eps); % eps is a small constant to prevent log(0)

% now look for all the values of the discrete frequency FQ
% look for the closest discrete frequency next to x Hz (x=FQ)
F_discrete_idx = find(F >= FQ,1,'first'); % find delivers the index

% all amplitude values of the discrete frequency FQ along the time axis of T
volume_FQ = S_dB(F_discrete_idx,1:length(T));


Ich definiere jetzt FQ mal als 100 Hz. Da erhalte ich dann als resultat den Vektor 'volume_FQ'. Dieser hat den Spitzenwert von 27.5532 dB. Und sieht so aus:



Meine Frage jetzt: Wie kommt der Algorytmus vom Originalsample zu diesem Wert in dB? Und wie komme ich wieder zurück? Denn mit den ursprünglichen Werten in der Matrix 'S' zu rechnen erscheint mir merkwürdig und das funktioniert irgendwie nicht.

Ich möchte eine Sinuschwingung generieren, die bei einer Spektralanalyse ein Volumen von 27.5532 dB (ungefähr) ergibt, die aber im Audiovektor irgendwo zwischen den erlaubten Werten -1 und 1 liegt. Ausgangspunkt bleiben diese 27.5532 dB. Irgendwelche Rechnungsrundungen kann ich mir leisten und kann ich vernachlässigen.
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: 28.09.2011, 11:29     Titel:
  Antworten mit Zitat      
DSP hat Folgendes geschrieben:

Dann erkläre doch bitte erst mal wie du auf diesen dB Wert kommst.

Das habe ich mitlerweile nachgeliefert. Sorry für die zeitliche Überlappung.

DSP hat Folgendes geschrieben:
In der Matlab Funktion spectrogram() gibt es ja keine Skalierung und ich hatte dir einen möglichen Ansatz genannt. Evtl. zeigt sich nun, dass dieser falsch ist...auf Grund der überlappenden Segmente. Ich habe nach wie vor auch keine Erklärung finden können, war spectrogram die Amplitudenwerte nicht skaliert.

Vielleicht ist ja die spectrogram() Funktion nicht geeignet für meine Anwendung und ich brauche eine andere Herangehensweise.
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.09.2011, 11:30     Titel:
  Antworten mit Zitat      
In S bzw. Volume_FQ sind die Werte aber unskaliert...hast du mal getestet, was sich denn für dB-Werte ergeben, wenn du sie wie nach meinen beiden Vorschlägen skalierst?

Ich verstehe hier ohnehin noch nicht, was du hier machen willst...warum extrahierst du eine bestimmte Frequenz aus dem Spektrum? Warum der Zeitbezug bzw. reicht ein Frequenzspektrum mittels FFT nicht auch aus?
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: 28.09.2011, 11:45     Titel:
  Antworten mit Zitat      
Also wenn ich dich richtig verstanden habe, sind S und S_dB das selbe. Nur ist S_dB skaliert?

Dann könnte ich eigentlich auch mit S Arbeiten und mir den Weg zu S_dB sparen?
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.09.2011, 11:58     Titel:
  Antworten mit Zitat      
S ist nicht in dB...

Ich meine mit skalieren aber etwas anderes...schau doch noch mal auf die beiden Vorschläge von mir in dem anderen Thread. Da sollte S durch die Segmentlänge geteilt werden bzw. ich hatte noch eine zweite Variante mit N/2 gepostet. Erst dann kommt die Umrechnung in dB. Nun würde mich mal interessieren, ob sich dann die -4.88 dB ergeben Wink.

Ich hatte dir in dem anderen Thread ebenfalls die Berechnung von S bzw. den Aufbau der Funktion spectrogram() in einem Code gezeigt. Daraus sollte ja klar werden, wie S entsteht. Wenn du von diesem Spektrum wieder in den Zeitbereich willst, musst du mit der ifft() anstatt der fft() arbeiten.
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: 30.09.2011, 11:34     Titel:
  Antworten mit Zitat      
Sorry für die späte Antwort. Ich habe mich noch mals über meine Codes gestürzt und bin zum Schluss gekommen, dass mir die spectrogram() funktion nicht die gewünschten Ergebnisse liefert. Sprich, sie sind zwar richtig, aber ich kann mit den Volumenwerten nichts anfangen.

Ich habe nun mit Hilfe der Matlab Hilfefunktion und Deinem Beispiel (was spectrogram() tut) einen neuen Code geschrieben, der mir überraschenderweise genau die Resultate liefert, die ich haben will. Die tatsächlichen Amplitudenwerte liegen genau zwischen 0 und 1. Ich habe den Code mit einer einfachen Sinuschwingung bei 10kHz getestet und die ergebnisse stimmen.

Nur bei der Fensterung verliere ich Amplitude. Ist ja auch logisch, denn der durchschnittliche Amplitudenwert sinkt ja durch die Fensterung. Ich kann das zur Zeit aber vernachlässigen, da sie ja alle proportional sinken. D.h. das Verhältnis zueinander stimmt. Vielleicht gibt es ja einen Weg, dies auszugleichen.

Hier ist mein neuer Code:

Code:
% this program returns 'abspec', the amplitude of the component frequencies of
% the signal 'data'

% INPUT VARIABLES:
% data = signal vector
% fs = sampling rate

% reverse axes of vector 'data'
s = data';

% check if signal lenght is an equal number
if mod(length(s),2)
    n = length(s)-1;
else
    n = length(s);
end;

% length of the fft
nfft = 256;

% window overlap value
numoverlap = 128;

% create hann window
win = hann(nfft, 'periodic');

% determine amount of segments
k = fix((n-numoverlap)/(length(win)-numoverlap));

% create the time vector for entire signal
t=0:((n/fs)/(k-1)):(n/fs);

% create frequency vector
f = fs/2*linspace(0,1,nfft/2+1);

% determine size of 'abspec' vector
abspec = zeros(length(f),k);

m=1;

for i=1:k
    % windowing of the segment
    w_s = s(m:nfft+m-1).*win';

    % calculate the fft of the windowed signal 's_w'
    spec = fft(w_s,nfft)/nfft;
   
    % return absolute values of 'spec'
    abspec(1:(nfft/2)+1,i) = 2*abs(spec(1:nfft/2+1));
   
    % next segment
    m = m+nfft-numoverlap;
end
 


Ich denke ich bin jetz da wo ich hinwollte. Die ursprüngliche Frage des Threads hat sich ja somit erübrigt und ich kann mit diesen Werten arbeiten.

Ich danke nochmals Tausend mal für die Anregungen und die schnelle Hilfeleistung!!

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: 30.09.2011, 12:09     Titel:
  Antworten mit Zitat      
Offensichtlich hast du in dem anderen Thread nicht verstanden, was ich mit Skalierung meinte. Der hier angegebene Code rechnet auch nichts anderes als spectrogram(), nur dass du noch zusätzlich skalierst und auf die Umrechnung in dB verzichtest. Allerdings machst du hier noch 2 Fehler, was ich aber schon in dem anderen Thread erklärt hatte.

Der Gleichsignalanteil (DC) und die Amplitude bei der Nyquistfrequenz stimmen so nicht. Sie werden nicht mit 2 multipliziert Wink.

Code:
[S, F, T] = spectrogram(data, w, 128, 256, fs, 'yaxis');
S = abs(S);
S_scale = [S(1,:)/N;S(2:end-1,:)/(N/2);S(end,:)/N];
% ob nun N/2 oder 2*S(2:end-1,: )/N ist ja gleich
 


Das sollte ja dann das Gleiche liefern, wie der obere Code. Mal abgesehen davon, das bei spectrogram der letzte Werte bei ungerader Anzahl nicht abgeschnitten wird.

Für die Amplitudenkorrektur durch die Fensterung kannst du mal folgendes testen...so wird es bei einem Frequenzspektrum mittels FFT gemacht. Wenn also die identische Skalierung beim Spektrogramm und dem Frequenzspektrum passt, sollte das so auch gehen.

Code:
% windowing of the segment
    w_s = s(m:nfft+m-1).*win' * nfft / sum(win);
Private Nachricht senden Benutzer-Profile anzeigen
 
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.