Vom Spektrogramm zurück zum Audiosignal

OP #7210520
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?
Angehängte Dateien:
OP
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.
Persönliche Seite
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.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 4 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.