Forum: Digitale Signalverarbeitung / DSP / Machine Learning Vom Spektrogramm zurück zum Audiosignal


von A. S. (rava)


Angehängte Dateien:

Lesenswert?

Vor einigen Wochen habe ich Fragen zu Spektrogrammen gestellt und mich 
dann für meinen ersten Versuch für morlet-wavelets zum Analysieren von 
Audiosignalen entschieden.

Die Sache gefällt mir mittlerweile ganz gut, auch wenn ich einige der 
ursprünglichen Vorgaben, vor allem "Anzahl der Filter" reduzieren 
musste.

Derzeit arbeite ich mit 300 logarithmisch skalierten Frequenzen "freqs" 
zwischen 20Hz und 20kHz. Alle "omegas" sind > 6.0. Mein Testsignal ist 
ein Sinuston, der innerhalb von 1 Sek durch 10 Oktaven steppt.

Meine Wavelets entstehen in python so:
1
    widths = omegas * sample_rate / (2 * freqs * np.pi)  # F
2
    omegas = np.reshape(omegas, (-1, 1))  # F x 1
3
    widths = np.reshape(widths, (-1, 1))  # F x 1
4
5
    # From scipy.morlet2
6
    coords_t = np.reshape(np.arange(0, M) - (M - 1.0) / 2, (1, -1))  # 1 x M
7
    coords_t = coords_t / widths  # F x M
8
9
    wavelets = (
10
        np.exp(1j * coords_t * omegas) * np.exp(-0.5 * (coords_t**2)) * (np.pi ** (-0.25))
11
    )  # F x M
12
    wavelets = wavelets / widths  # F x M
13
    return wavelets  # F x M

Besonders wichtig ist hier wohl die vorletzte Zeile, da ich hier nicht 
mit sqrt(widths) sondern mit widths direkt skaliere. Damit weiche ich 
von der scipy-Bibiothek ab, bekomme aber Spektrogramme, die meiner 
Meinung nach gefühlt besser die Lautstärke abbilden.
Der Vergleich mit dem DSP-Spektrukmanalyzer meiner Studiosoundkarte 
bestätigt das.

Jetzt war meine Überlegung, wie ich aus einem damit erzeugten 
Spektrogramm das ursprüngliche Signal wieder herstellen könnte.

Das beste, was ich bisher erreichen konnte ist dieser Code:
1
        intermed = spectrogram  # F x T
2
        intermed *= np.reshape(np.sqrt(freqs), (-1, 1))
3
        intermed = np.mean(intermed, axis=0)
4
        intermed = np.real(intermed)
5
        audio = intermed

Allerdings ist die Amplitude des Signals wieder leicht frequenzabhängig.
Kann jemand erkennen, was noch fehlt?
Oder ist das prinzipbedingt, da die mittleren Frequenzen einfach von der 
größten Zahl an Wavelets abgedeckt werden?

von J. S. (engineer) Benutzerseite


Lesenswert?

A. S. schrieb:
> die meiner
> Meinung nach gefühlt besser die Lautstärke abbilden.
Wie darf man das verstehen?
Die Lautstärke stimmt (ist ja messbar) und die Qualität nicht?
Bei solchen Transformationen darf man nie vergessen, dass schon die 
Analyse des Signals = Trennung in Frequenzen und Komponenten Artefakte 
einbringt, die dann später wirken.

von A. S. (rava)


Lesenswert?

naja, der Hintergrund ist, dass ich Autodidakt bin und ziemlich verwirrt 
war von Begriffen, die im Netz herumfliegen, wie "Lautstärke", 
"Leistungsdichte", "Energiedichte", etc...

Mein Ziel war deswegen die Intensitäten von meinem RME Digicheck 
nachzubauen. Dazu habe ich einen Sweep mit Amplitude 1 abspielen lassen 
und gesehen, dass in der Spektralanalyse alle "bars" bis auf exakt -10dB 
auspegeln.

Dieses Verhalten wollte ich in python nachbauen. Und daher kommt dieser 
Skalierungfaktor, der aber von der scipy-bibliothek abweicht.


Zu meiner eigentlichen Frage:
https://math.stackexchange.com/a/397647

Hab ich aber nur für Signale hinbekommen, die wenige duzend samples kurz 
sind. Längere Signale rauschen nach der Rekonstruktion sichtbar.

von J. S. (engineer) Benutzerseite


Lesenswert?

A. S. schrieb:
> "Leistungsdichte", "Energiedichte", etc...
Na, da haben wir doch die passende Diskussion:
Beitrag "Re: Ergebnisse einer FFT zusammen fassen"

A. S. schrieb:
> Mein Ziel war deswegen die Intensitäten von meinem RME Digicheck
> nachzubauen.
Klingt interessant. Die Frage ist, wie die Berechnung und speziell das 
im o.g. Beitrag erörterte binning geschieht. Das kann man beliebig genau 
machen oder auch vereinfachen. Ich habe mir da noch keinen Kopf gemacht, 
weil ich zum Vermessen meinen eigenen Analyzer benutze, bei dem ich 
einstellen kann, was ich möchte und weis, was er mir anzeigt. Der 
nuckelt S/PDIF-mässig am Fireface. Digicheck läuft nur, um die Pegel im 
Auge zu behalten.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.