Weißes Rauschen zu einer Audiodatei hinzufügen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Mulham Maat
User
Beiträge: 9
Registriert: Donnerstag 21. April 2022, 18:59

Guten Tag,
Wie ich zu einer Audiodatei ein Geräusch hinzufügen?
Ich habe Audiodatei sample1.wav ausgelesen:

import scipy.io.wavfile as wavfile
from scipy.io.wavfile import write
import numpy as np
import matplotlib as plt
import matplotlib.pyplot as plt

fs,data = wavfile.read("sample1.wav")

und ein Weißes Rauschen erzeugt:

mean = 0 #Mittlewert
std = 1 # Standardabweichung
num_samples = len(data) # Länge des Audios
WhiteNoise = np.random.normal(mean, std, size=num_samples)
plt.plot(WhiteNoise)
plt.show()

write("white_noise.wav", 44100, WhiteNoise).

Nun will ich, dass das Weiße Rauschen zu der Audiodatei sample1.wav hinzufügen.
Mein Ansatz war, dass ich beides addiere:

Data_WhiteNoise = data + WhiteNoise
write("sample1_white_noise", 44100, Data_WhiteNoise)

Aber das funktioniert nicht.
Kann mir jemand bitte weiterhelfen
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Was bedeutet "funktioniert nicht"?

Warum schreibst Du `wavfile.read`, aber bei `write` läßt Du das wavfile weg, so dass man beim Lesen nicht weiß, was da eigentlich gescrhieben wird?
Variablennamen schreibt man komplett klein, also white_noise.

Kann es sein, dass Dein Rauschen etwas leise ist? Welchen Maximalwert kann Dein sample1 annehmen und welchen das Rauschen?
Benutzeravatar
__blackjack__
User
Beiträge: 13061
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Mulham Maat: Was genau heisst „hinzufügen“ und was genau heisst „funktioniert nicht“? Gibt es eine Fehlermeldung? Falls ja, welche? Falls nein, was erwartest Du als Ergebnis und was bekommst Du stattdessen?

Sonstige Anmerkungen zum Quelltext: ``as`` beim Importieren ist zum Umbenennen, `wavfile` wird aber gar nicht umbenannt.

Du importierst das `wavfile`-Modul von Scipy und aus dem Modul dann noch mal die `write()`-Funktion und greifst dann auf die `read()`-Funktion über das Modul zu. Warum diese Inkonsistenz? Warum nicht beide Funktionen importieren, oder beide Funktionen über das Modul ansprechen?

Dann wird `matplotlib` als `plt` importiert, was komisch ist und auch gar nicht benutzt wird, beziehungsweise auch gar nicht benutzt werden kann, weil gleich in der nächsten Zeile `plt` wieder überschrieben wird.

Man sollte für Namen keine kryptischen Abkürzungen verwenden. Namen sollen dem Leser verraten was der Wert hinter dem Namen im Programm bedeutet. Bei `fs` komme ich nicht drauf was das bedeuten soll. Das ist die Samplerate, und ich würde den Wert dann auch verwenden, statt an anderer Stelle davon auszugehen, dass es 44,1 kHz sind. Muss ja nicht sein.

Die `normal()`-Funktion sollte man in neuem Code nicht mehr verwenden. Siehe Numpy-Dokumentation.

Für die ersten beiden Argumente werden die Defaultwerte übergeben. Das kann man sich auch sparen. Oder auch gleich die `standard_normal()`-Methode verwenden.

Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase). Also `white_noise` statt `WhiteNoise`.

Bei der Zieldatei hast Du die ".wav"-Endung beim Dateinamen vergessen.

Zwischenstand (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python3
import matplotlib.pyplot as plt
import numpy as np
from scipy.io import wavfile


def main():
    sample_rate, samples = wavfile.read("sample1.wav")
    
    white_noise = np.random.default_rng().standard_normal(len(samples))
    wavfile.write("white_noise.wav", sample_rate, white_noise)
    
    plt.plot(white_noise)
    plt.show()

    wavfile.write("sample1_white_noise.wav", sample_rate, samples + white_noise)


if __name__ == "__main__":
    main()
Probleme sehe ich beim Dateiformat, denn der Code macht nur in einem Fall so Sinn wie er da steht: Wenn die Eingabedatei 32-Bit Gleitkommazahlen als Samplewerte enthält, denn nur dann ist der Wertebereich der Sampledaten -1 bis +1 und passt zu den generierten Samples für das Rauschen.

Und selbst dann hat das addieren ein Problem, denn wenn die Samples einen Wertebereich von -1 bis 1 haben und die Daten vom Rauschen einen Wertebereich von -1 bis 1 haben, dann kommt bei der Addition ein Wertebereich von -2 bis 2 heraus. Zum schreiben der Daten muss das aber wieder in den Bereich von -1 bis 1 gebracht werden sonst, ich nehme mal an werden die Sampling-Daten einfach abgeschnitten beim schreiben.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Mulham Maat
User
Beiträge: 9
Registriert: Donnerstag 21. April 2022, 18:59

@__blackjack__
Mir wurde dieser Fehlercode angezeigt:
ValueError: operands could not be broadcast together with shapes (882000,2) (882000,)
Diesen Fehler konnte ich beheben, in den ich eine eins hinter num_samples geschrieben habe:
WhiteNoise = np.random.normal(mean, std, size=(num_samples, 1))

Mein Code sieht jetzt so auch:
mean = 0 #Mittlewert
std = 1 # Standardabweichung
num_samples = len(data) # Länge des Audios
WhiteNoise = np.random.normal(mean, std, size=(num_samples, 1))
plt.plot(WhiteNoise)
plt.show()

write("white_noise.wav", 44100, WhiteNoise)

Data_WhiteNoise = data + WhiteNoise
write("sample1_white_noise.wav", 44100, Data_WhiteNoise)

Jetzt habe ich das Problem, dass in sample1_white_noise.wav ganz kurz das Weiße Rauschen zu hören ist und dann hört man nicht mehr.
Es soll aber die Audiodatei (sample1.wav) mit dem weißen Rauschen im Hintergrund zuhören sein.
Weiß du vielleicht woran das liegt?

Die Importierung ist schon richtig.
Mit fs ist die Abtastrate gemeint.
Ja gut, man kann stattdessen sample_rate verwenden,
aber ich habe unterschiedliche Seiten gesehen, einige verwenden sample_rate und einige verwenden fs.
Ich habe mich für fs entschieden.
Benutzeravatar
__blackjack__
User
Beiträge: 13061
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Mulham Maat: Nicht alles was so funktioniert ist auch richtig. Inkonsistenzen sind falsch, weil sie das lesen/verstehen erschweren.

Und warum hast Du Dich für `fs` entschieden? Was bedeutet das?

Ansonsten gibt es halt immer noch die beiden angesprochenen Probleme mit dem Wertebereich. Also das nichts in dem Code sicherstellt, dass der Wertebereich von dem Rauschen zu dem Wertebereich der eingelesenen Samples passt, und das selbst wenn die zusammen passen würden, das Ergebnis der Addition diesen Wertebereich sprengen kann, und ziemlich sicher auch sprengen wird.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten