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

Cepstrum wieder in Spektrum umwandeln

 

pullmoll89

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 29.05.2012, 17:49     Titel: Cepstrum wieder in Spektrum umwandeln
  Antworten mit Zitat      
Hallo,

ich sitze gerade an einer Funktion, die ein Audiosignal einliest, das Cepstrum berechnet und an dem dann einige Veränderungen vorgenommen werden sollen. Als Ausgabe soll wieder ein Audiosignal erstellt werden.
Zum Testen habe ich das Cepstrum erstmal unverändert übergeben.

Zur Überprüfung lasse ich den Amplitudengang des eingelesenen und des aus dem Cepstrum rückgerechneten Signals plotten. Die Plots liefern augenscheinlich dasselbe Ergebnis.

Aber ein Audiosignal kann ich daraus nicht wiederherstellen. Ersetze ich im Code zur Erstellung der Wavedatei 'neu_fft' durch 'x_fft', funktioniert das jedoch.

Daher vermute ich, dass bei der Umwandlung des Cepstrums zurück in das Spektrum etwas nicht stimmt.

Für eure Anregungen und Hilfen wäre ich dankbar! Smile

Code:
function [] = test()
% Signal einlesen
[signal fs] = wavread('./audio/test.wav');

% Parameter
N = 1024;
freq = 0:fs/N:fs/2;

% Spektrum und log-Amplitudengang des Signals
x_fft = fft(signal);
x_amp = abs(x_fft);
x_amp_scale = [x_amp(1)/N; x_amp(2:N/2)/(N/2); x_amp((N/2)+1)/N];
x_log = 20*log10(x_amp_scale);

% Cepstrum berechnen
signal_ceps = rceps(signal);
% sollte gleichbedeutend sein mit:
% signal_ceps = real(ifft(log(abs(fft(signal)))));

% Cepstrum-Operationen ...
neu_ceps = signal_ceps;

% Spektrum aus Cepstrum wiederherstellen
neu_fft = exp(fft(neu_ceps));

% neues Spektrum und log-Amplitudengang
neu_amp = abs(neu_fft);
neu_amp_scale = [neu_amp(1)/N; neu_amp(2:N/2)/(N/2); neu_amp((N/2)+1)/N];
neu_log = 20*log10(neu_amp_scale);


% Vergleich plotten
subplot 211
plot(freq,x_log);
xlabel('Frequency [Hz]');
ylabel('Amplitude [dB]');
subplot 212
plot(freq,neu_log);
xlabel('Frequency [Hz]');
ylabel('Amplitude [dB]');

% Wavedatei erstellen
neu_sound = real(ifft(neu_fft));
wavwrite(neu_sound,fs,'./audio/output.wav');

end


untitled.jpg
 Beschreibung:
Vergleichs-Plot

Download
 Dateiname:  untitled.jpg
 Dateigröße:  43.01 KB
 Heruntergeladen:  961 mal


pullmoll89

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 29.05.2012, 21:17     Titel:
  Antworten mit Zitat      
Hallo,

ich habe den Fehler gefunden! Das hat mich tatsächlich einen ganzen Tag gekostet, zu merken, dass es mit dem komplexen Cepstrum cceps funktioniert^^ Very Happy

Code:
signal_ceps = cceps(signal);
 
 
pullmoll89

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 30.05.2012, 09:55     Titel: Cepstrum zusammensetzen
  Antworten mit Zitat      
Guten Morgen,

nachdem die Wiederherstellung des Audiosignals nun ja funktioniert, möchte ich gerne mit dem Cepstrum arbeiten.

Ich möchte das Cepstrum aus zwei verschiedenen zusammensetzen:
Den einen Teil aus Signal X, den anderen aus Signal Y. Ein threshold bestimmt die Teilung.

Wenn ich DANN allerdings das Audiosignal wiederherstellen will, wird das ganz seltsam:
    nehme ich nur den ersten Koeffizienten von Signal X, ist der output derselbe wie Y, jedoch wesentlich leiser

    für alle anderen thresholds ist der Output nicht abspielbar, und das Spektrum liegt in vierstelligen Amplitudenbereichen (in dB!).


Hat jemand eine Idee, woran das liegen könnte? Falsche Skalierung?
 
DSP
Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 13.06.2012, 11:37     Titel:
  Antworten mit Zitat      
Ich bin leider auch noch nicht dahinter gekommen. Bist du evtl. schon weiter?

Allerdings kann ich deine Rücktransformation vom Cepstrum ins Spektrum nicht nachvollziehen.

Code:

% Spektrum aus Cepstrum wiederherstellen
neu_fft = exp(fft(neu_ceps));
 


Das liefert mir nicht das ursprüngliche Spektrum wieder. Die Funktion icceps liefert mir das richtige Ergebnis.

Code:
neu_fft = icceps(neu_ceps)
Private Nachricht senden Benutzer-Profile anzeigen
 
pullmoll89

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 13.06.2012, 21:50     Titel:
  Antworten mit Zitat      
DSP hat Folgendes geschrieben:
Das liefert mir nicht das ursprüngliche Spektrum wieder. Die Funktion icceps liefert mir das richtige Ergebnis.

Code:
neu_fft = icceps(neu_ceps)


Mit icceps bekomme ich keine vernünftigen Ergebnisse.
Zur Erstellung des Cepstrums nutze ich mittlerweile nicht mehr rceps(), sondern ifft(log(abs(fft(signal)))).
Die Wiederherstellung erfolgt dann per exp(fft(out_ceps,fft_size)) und liefert offensichtlich das richtige Spektrum.

Was hast du denn für einen Code drum herum?
 
DSP
Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 14.06.2012, 10:47     Titel:
  Antworten mit Zitat      
Ich muss zugeben, dass dieses Thema für mich Neuland ist. Ich lese mich da gerade erst ein. Gleichzeitig musste ich aber auch feststellen, dass diese Herangehensweise mir nicht wirklich weiterhilft. Ich wollte mit dem Cepstrum mein Spektrum glätten. Da meine Signale aber keine signifikanten Stellen im Cepstrum aufweisen (es handelt sich nicht um ein Audiosignal), nutzt mir der Vorteil, welcher durch die Logarithmierung entsteht leider nichts. Oder ich übersehe hier auch noch einiges...

Nun aber zu meinem Einwand. Ich muss dir Recht geben, dass die Funktion icceps leider nicht das richtige Ergebnis liefert, wenn man dieses zurückgewandelte Spektrum wieder in den Zeitbereich transformiert. So weit ich das nun verstanden habe, kommt aber ohnehin nicht das identische Zeitsignal wieder, da ja die Phaseninformation durch das Transformieren ins Cepstrum verloren geht. Allerdings bin ich doch sehr verwundert über des Betragsspektrum von s2_lift2 nach der Rücktransformation aus dem Cepstrum. s2_lift hingegen, stimmt mit dem original Spektrum überein. Wandelt man dieses s2_lift aber wieder in den Zeitbereich entsteht "Müll", während s2_lift2 bis auf eine Phasenverschiebung mit s2 übereinstimmt.

Hier mein code...als Testsignal habe ich einfach ein sinus mit Echo = s2. Die Funktion FFT_h_da hast du zwar nicht, da passiert aber nichts weiter aufregendes. Es ist mit dem "umfassenden FFT Bsp" hier in der Skriptecke zu vergleichen.

Code:

clear;
Ts = 0.001;
Fs = 1/Ts;
N = 1024;
df = Fs/N;
t = 0:Ts:(N-1)*Ts;
f = 20*df;
s1 = sin(2*pi*f*t);
% Echo
s2 = s1 + 0.5*[zeros(1,256) s1(1:768)];

figure(1)
plot(t,s1,t,s2)
grid on;


% komplexes Cepstrum berechnen
c = cceps(s2);

% Lifter
% Test mit Hamming Fenster
indx = find(t<0.235,1,'last');
win = rectwin(2*indx);
%win = hamming(2*indx);
lifter = [win(indx:end); zeros((N/2)-indx-1,1)];

clifter = cceps(lifter);
c_lift = c;%(c(1:N/2) .* lifter');
% Glätten des Spektrums durch "Tiefpassfilterung des Cepstrums"
% einfacher herangehensweise durch Löschen der hohen Anteile =
% Rechteckfenster
%c_lift(indx+1:end-indx+1) = 0;

s2_lift = icceps(c_lift);
s2_lift2 = exp(fft(c_lift));
s3 = real(ifft((s2_lift)));
s4 = real(ifft((s2_lift2)));

figure(2)
plot(1:length(c),20*log10(real(c)),'b',1:length(c_lift),20*log10(real(c_lift)),'r--');
xlabel('Quefrency');
ylabel('amplitude cepstrum')
grid on;


figure(3)
[ Fy, mag, mag_dB, phase1, fv, indx ] = FFT_h_da( s2, Ts, N, 0, Fs/2) ;
plot(fv(indx),mag_dB,'b.-') ; hold on;
[ Fy, mag, mag_dB, phase1, fv, indx ] = FFT_h_da( s2_lift, Ts, N, 0, Fs/2) ;
plot(fv(indx),mag_dB,'r--') ; hold on;
[ Fy, mag, mag_dB, phase1, fv, indx ] = FFT_h_da( s2_lift2, Ts, N, 0, Fs/2) ;
plot(fv(indx),mag_dB,'g') ; hold on;
axis([0 Fs/2 -120 40]);
xlabel('Frequenz in [Hz]') ;
ylabel('Magnitude in [dB]') ;
legend('original Signal mit Echo','icceps(...)','exp(fft(...))')
grid on;

figure(4)
plot(t,s2,'b',t(1:length(s3)),s3,'r',t(1:length(s4)),s4,'g');
xlabel('Zeit')
ylabel('Amplitude')
legend('original Signal mit Echo','ifft(icceps(...))','ifft(exp(fft(...)))')
grid on;

pause;
close all;
 


Auf den beiden Plots sieht man aber auf was ich hinaus will. Rot und blau stimmen im Freq.bereich überein. Das grüne Spektrum kann ich aber überhaupt nicht nachvollziehen. Bei der Rücktransf. in den Zeitbereich liefert dann aber dieses merkwürdige Spektrum annähernd s2 wieder, während aus dem roten Spektrum "Müll" entsteht.

figure4_zeitbereich.JPG
 Beschreibung:

Download
 Dateiname:  figure4_zeitbereich.JPG
 Dateigröße:  169.54 KB
 Heruntergeladen:  943 mal
figure3_frequenzbereich.JPG
 Beschreibung:

Download
 Dateiname:  figure3_frequenzbereich.JPG
 Dateigröße:  193.45 KB
 Heruntergeladen:  981 mal
Private Nachricht senden Benutzer-Profile anzeigen
 
pullmoll89

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 14.06.2012, 15:56     Titel:
  Antworten mit Zitat      
Also ich habe gestern auch nochmal hin und her probiert mit den verschiedensten Möglichkeiten der Implementierung für das Cepstrum. Das Zusammenstellen und Rücktransformieren funktioniert jedoch mittlerweile. Allerdings nicht sehr zufriedenstellend, weil das Rauschen immernoch präsent ist, da fällt mir nur gerade nichts zu ein.

Glätten und Audiosignale sind ansonsten auch mein Arbeitsbereich Wink
Im Moment glätte ich mit dem in Matlab integrierten LPC, davor hatte ich mich aber auch anch Cepstrum-Glättung umgesehen und dazu eine ganz hilfreiche Masterarbeit gefunden:
www.rs-met.com/documents/dsp/Magisterarbeit.pdf

Den darin beschriebenen Algorithmus in der verbesserten Form habe ich mal nachgebaut und der lief auch sehr ordentlich. Ich hab ihn dir mal angehangen.

Wenn du mir den Code der fft_h_da Funktion zeigst, kann ich deinen Code auch laufen lassen.

Gruß

envelope_ceps.m
 Beschreibung:

Download
 Dateiname:  envelope_ceps.m
 Dateigröße:  1.07 KB
 Heruntergeladen:  647 mal
 
DSP
Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 15.06.2012, 10:19     Titel:
  Antworten mit Zitat      
Danke für den Link und den m-file...ich werde mir das später mal genauer anschauen.

Die Funktion FFT_h_da kann ich nicht veröffentlichen, da hier noch einige andere Sachen über das Betragsspektrum hinaus erfolgen. Ich habe mal nur zur Darstellung des Spektrums die Fkt. verkürzt.

Code:

function [mag, mag_dB, fv] = FFT_betragsspektrum( signal, nfft, fa) ;
% Input:
% signal = Signal im Zeitbereich
% nfft = Anzahl Messwerte für fft
% wenn nfft > length(sig) -> fft(sig,nfft) führt Zeropadding durch
% fa = Abtastfreq.
% Output:
% Magnitude des Spektrums linear und dB skaliert
% Frequenzvektor fv in [Hz] von 0...fa/2

% un-,gerade Anzahl Messwerte?
if mod(nfft,2) == 0;
    k = (nfft/2) + 1;
else
    nfft = nfft + 1;
    k = (nfft/2) + 1;
end

fn = fa/2; % Nyquistfreq.
df = fa/nfft; % Frequenzauflösung des Spektrums
% Frequenzvektor: Darstellung bis Nyquistfreq.
fv = 0: df : fn;

sig = signal(:);

% Signal transformieren
Fy = fft(sig,nfft);
 
%   Betrag - nur positives Freq.spektrum  
Fy_pos0 = abs(Fy(1:k));
 
%   Skalierung  
mag = [Fy_pos0(1)/nfft ;Fy_pos0(2:k-1)/(nfft/2);Fy_pos0(k)/nfft];
% dB
mag_dB = 20*log10(mag + eps); % eps = kleine Konstante zur Vermeidung von log(0)
 


In meinen oberen Code muss dann natürlich unter figure(3) der Funktionsaufruf geändert werden.

Code:

...

figure(3)
[mag, mag_dB, fv] = FFT_betragsspektrum( s2, N, Fs) ;
plot(fv,mag_dB,'b.-') ; hold on;
[mag, mag_dB, fv] = FFT_betragsspektrum( s2_lift, N, Fs) ;
plot(fv,mag_dB,'r--') ; hold on;
[mag, mag_dB, fv] = FFT_betragsspektrum( s2_lift2, N, Fs) ;
plot(fv,mag_dB,'g') ; hold on;
axis([0 Fs/2 -120 40]);
xlabel('Frequenz in [Hz]') ;
ylabel('Magnitude in [dB]') ;
legend('original Signal mit Echo','icceps(...)','exp(fft(...))')
grid on;

...
 
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.07.2012, 10:43     Titel:
  Antworten mit Zitat      
Die Masterarbeit hat mir ehrlich gesagt überhaupt nicht weitergeholfen.

Hast du hier noch neue Erkenntnisse sammeln können bzw. kannst mir evtl. meine Fragen beantworten? Das rücktransformierte Spektrum aus dem Cepstrum ergibt für mich keinen Sinn (siehe Plots). Ebenso die Ergebnisse der Rücktransformation in den Zeitbereich.

Kann man denn überhaupt das Zeitsignal nach den Transformationen wieder herstellen?
Private Nachricht senden Benutzer-Profile anzeigen
 
pullmoll89

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 16.07.2012, 11:10     Titel:
  Antworten mit Zitat      
Hey.

Ja, ich habe mittlerweile herausgefunden, wie es funktioniert. Zumindest läuft das bei mir so richtig^^

Um die Funktion cceps() zu beutzen musst du folgende folgende Änderungen machen:
Code:
[c,delay] = cceps(s2);

delay liefert dir die Verzögerung, die bei der Berechnung auftritt.
Um das Zeitsignal dann wiederherzustellen:
Code:
s2_lift = icceps(c_lift,delay);

Die Spektren von s2 und s2_lift sehen dann immer noch so aus wie in deinem Plot, d.h. sie sind gleich.
s2_lift ist dann aber schon das Zeitsignal, muss also nicht weiter behandelt werden [ real(ifft(...)) ] und stimmt dann im letzten Plot mit s2 überein.


Ich berechne meine Glättung bzw. Einhüllende allerdings mit der exp()-Variante.
Code:
signal_ceps = ifft(log(abs(signal_fft)),fft_size);
signal_ceps_low = [signal_ceps(1:threshold) zeros(1,length(signal_ceps)-2*threshold) signal_ceps(end-threshold+1:end)];
signal_fft_low = exp(fft(signal_ceps_low,fft_size));
signal_env = 20*log10(abs(signal_fft_low)+eps);

Das Cepstrum meines Ausgangssignals füge ich dann aus Einzelteilen zusammen, wobei du beachten musst, dass das Cepstrum zweiseitig ist, d.h. die niedrigen Koeffizienten befinden sich z.b. links und rechts (wie in der Berechnung oben).
Und mit
Code:
out_fft = exp(fft(out_ceps,fft_size)+eps);

erhalte ich dann wieder die FFT.

Ich hoffe das war verständlich soweit *g*
 
DSP
Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 16.07.2012, 13:39     Titel:
  Antworten mit Zitat      
Danke für die Antwort! Ich werde das später mal im meinem Code umsetzen...

Hast du evtl. auch ein Bsp. für die Erstellung und Verwendung eines Lifters.
Wird hier das Cepstrum einfach mit dem Lifter multipliziert?
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.07.2012, 13:11     Titel:
  Antworten mit Zitat      
Ich habe gestern abend mal deine Vorschläge getestet.

Mit der Erweiterung für cceps bzw. icceps stimmen nun die Ergebnisse.

Allerdings erreiche ich mit den Einzelschritten nicht wieder das orig. Signal im Zeitbereich nach den Transformationen.

Ich nehme mal an, dass es mit der Phaseninformation zu tun hat, die du hier ja gar nicht berücksichtigst. Offensichtlich bist du daran ja auch gar nicht interessiert. In der Doku zu cceps wird ja auch der interne Weg der Funktion beschrieben, wobei eine Funktion rcunwrap verwendet wird, die in MatLab gar nicht zugänglich ist.

Code:

h = fft(x);
logh = log(abs(h)) + sqrt(-1)*rcunwrap(angle(h));
y = real(ifft(logh));
 


In so fern wundert es nicht, dass ich das Zeitsignal wie in meinem Codebsp. nicht wieder rekonstruieren kann.

Code:

clear;
Ts = 0.001;
Fs = 1/Ts;
N = 1024;
df = Fs/N;
t = 0:Ts:(N-1)*Ts;
f = 20*df;
s1 = sin(2*pi*f*t);
% Echo
s2 = s1 + 0.5*[zeros(1,256) s1(1:768)];

figure(1)
plot(t,s1,t,s2)
xlabel('Zeit in s')
ylabel('Amplitude')
legend('original Signal ohne Echo','original Signal mit Echo')
title('Zeitbereich')
grid on;


% komplexes Cepstrum berechnen
signal_fft = fft(s2,N);
fft_size = N;
signal_ceps = ifft(log(abs(signal_fft)),fft_size);

% einfache Filterung mit Rechteck-window
threshold = 160;
signal_ceps_low = [signal_ceps(1:threshold) zeros(1,length(signal_ceps)-2*threshold) signal_ceps(end-threshold+1:end)];

% zurück zum Spektrum - Signal wird für Rücktransf. in Zeitbereich
% verwendet
signal_fft_low = exp(fft(signal_ceps_low,fft_size))';

% Skalierung für Darstellung des Spektrums - nur pos. Freq.-bereich
k = fft_size/2 + 1;
betrag = abs(signal_fft_low);
mag = [betrag(1)/fft_size; betrag(2:k-1)/(fft_size/2); betrag(k)/fft_size];
% dB
signal_env = 20*log10(mag + eps); % eps = kleine Konstante zur Vermeidung von log(0)
%signal_env2 = 20*log10(abs(signal_fft_low)+eps);

% Funktionstest Einhüllende
[ env_log ] = envelope_ceps( signal_fft_low, threshold )

figure(2)
% Darstellung des Cepstrums
plot(1:length(signal_ceps),20*log10(signal_ceps),'b',1:length(signal_ceps_low),20*log10(signal_ceps_low),'r--');
xlabel('Quefrency');
ylabel('amplitude cepstrum')
title('cepstrum')
legend('Cepstrum von s2', 'signal_ceps_low')
grid on;

figure(3)
% Spektrum von s2 darstellen
[mag, mag_dB, fv] = FFT_betragsspektrum( s2, N, Fs) ;
plot(fv,mag_dB,'b.-') ; hold on;
% Spektrum der Signale zurück aus Cepstrum
plot(fv,signal_env,'r--') ; hold on;
plot(fv,env_log,'g--') ; hold on;
%axis([0 Fs/2 -120 40]);
xlabel('Frequenz in [Hz]') ;
ylabel('Magnitude in [dB]') ;
legend('original Signal mit Echo','Signal mit Rechteckfenster bearbeitet','Env. Funktion')
title('Betragsspektrum')
grid on;

figure(4)
% Wieder in Zeitbereich - im Cepstrum verändertes Signal
s2_lift = ifft(signal_fft_low,fft_size);
plot(t,s1,'g',t,s2,'b',t(1:length(s2_lift)),s2_lift,'r.-');
xlabel('Zeit')
ylabel('Amplitude')
legend('original Signal ohne Echo','original Signal mit Echo','Signal - Cepstrum bearbeitet')
title('Zeitbereich')
grid on;

pause;
close all;
 


Ich habe auch mal die Funktion Envelope getestet. Wobei ich damit auch nichts anfangen kann. Wie ich schon schrieb, befasse ich mich nicht mit Audiosignalen und benötige deshalb auch keine Einhüllende meines Spektrums. Ich bin an einer Glättung meines Spektrums interessiert. Durch das einfache Löschen von Bereichen, wie du es vornimmst, komme ich aber auch nicht weiter. Außerdem fehlt mir ein Kriterium für die Wahl des Threshold. Hier wird meine Signalfreq. von s1 eher noch verstärkt, was ich nicht gebrauchen kann. Mir geht es um die Trennung/ Verarbeitung von Signalen, die multiplikativ verbunden sind. Durch den Wechsel ins Cepstrum wird dieser Zusammenhang ja zu einer Addition und somit ist eine Filterung wiederum möglich. Ich benötige hier aber andere Filtertypen und konnte leider für das Lifting wie auch die Erstellung des Lifters keine Bsp. finden, weshalb ich nun danach gefragt habe.

Erstellt man hier einfach die Impulsantwort des Filters im Zeitbereich und transformiert sie dann ins Cepstrum?

Ich hoffe du kannst mir hier noch weiterhelfen...aber dennoch vielen Dank für die bisherige Unterstützung.
Private Nachricht senden Benutzer-Profile anzeigen
 
pullmoll89

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 17.07.2012, 15:05     Titel:
  Antworten mit Zitat      
Also was den Lifter angeht, da kenne ich mich gar nicht mit aus.

Aber ich glaube, du kannst das Signal generell nicht wiederherstellen, wenn du nur die signal_ceps_low nimmst, und den Rest zu Null setzt.
In meinem Falle berechne ich so die Einhüllende ohne Probleme, aber zur Rekonstruktion tausche ich die unteren Cepstrum-Koeffizienten gegen andere aus, sodass alle wieder da sind.

Dann habe ich bei mir auch keine Probleme mit der Rekosntruktion im Zeitbereich.
 
DSP
Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 17.07.2012, 16:44     Titel:
  Antworten mit Zitat      
pullmoll89 hat Folgendes geschrieben:
...aber zur Rekonstruktion tausche ich die unteren Cepstrum-Koeffizienten gegen andere aus, sodass alle wieder da sind.


Kannst du das mal genauer erklären?

Code:

signal_ceps_low = [signal_ceps(1:threshold) zeros(1,length(signal_ceps)-2*threshold) signal_ceps(end-threshold+1:end)];
 


In diesem Teil löscht du in der Mitte des Signals ab der Stelle threshold. Da der Vektor wie bei der FFT für ein beidseitiges Cepstrum (Spektrum) gilt, ist der Vektor gespiegelt und das Ende entspricht dem Anfgang. Deshalb bleibt das Ende ab end-threshold auch unverändert.

Da hier aber nur der Betrag von signal_fft für signal_ceps genutzt wird, kann die Phaseninformation nicht wieder hergestellt werden. Was du hier nicht zeigst, wie out_ceps zusammengestellt ist.

Code:
ifft(signal_fft_low)


rekonstruiert das Zeitsignal nicht mehr, selbst wenn Threshold so gewählt wird, dass signal_ceps_low = signal_ceps ist und damit das Signal unverändert bleibt.
Private Nachricht senden Benutzer-Profile anzeigen
 
pullmoll89

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 17.07.2012, 20:07     Titel:
  Antworten mit Zitat      
Mit dem signal_ceps_low berechne ich nur die Einhüllende. Dazu genügt das zu-Null-setzen der höheren Koeffizienten, die sich (da zweisietig) ja in der Mitte befinden. Höhere Koeffizienten im Cepstrum bedeuten ein feineres Signal mit mehr Artefakten etc.

"Austausch" heißt in meinem Falle, dass ich die niedrigen Koeffizienten ersetze. Und zwar habe ich als Input ein Sprachsignal mit Windrauschen. Im Output wird das geschätzte Rauschen dann durch die Cepstrum-Koeffizienten von Referenzwerten ersetzt, um das Rauschen danach herausfiltern zu können.

Mein Code zur Bearbeitung des Signals sieht im Groben so aus:
Code:
% aktueller Abschnitt des Signals (inkl. Fensterung)
signal_in = signal(cnt:cnt+block_size-1).*hann_win;
signal_in_fft = fft(signal_in,fft_size);
signal_in_fft = signal_in_fft(1,1:bins); % redundanten Teil entfernen

% Cepstrum Operationen
signal_ceps = ifft(log(abs(signal_in_fft)+eps),fft_size);
signal_out_ceps = [estimate_ceps(1:threshold) signal_ceps(threshold+1:end-threshold) estimate_ceps(end-threshold+1:end)];
signal_out_fft = exp(fft(signal_out_ceps,fft_size)+eps);

% Signal zurück in den Zeitbereich
% spektral spiegeln, da eben entfernt
signal_fft_tmp = [signal_out_fft, conj(signal_out_fft(bins-1:-1:2))];
% inverse diskrete fft
signal_tmp = real(ifft(signal_fft_tmp,fft_size));
% zero-padding entfernen und Fensterung
signal_tmp = signal_tmp(1,1:block_size).*hann_win;
% zusammenfügen
signal_out(cnt:cnt+block_size-1) = signal_out(cnt:cnt+block_size-1) + signal_tmp;
 

Für mein Einsatzgebiet reicht bei einer fft_size = 512 ein threshold von 30. Der nichtredundate Teil der FFT ist bin = fft_size/2+1.

Wenn ich da nun einen threshold von 0 wähle, besteht das Spektrum signal_out_fft nur aus dem Eingangsspektrum und in der Filterung wird alles komplett entfernt (da Eingang und Ausgang gleich sind); das Signal scheint also richtig wiederhergestellt zu werden.
 
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.