Implementieren wir eine Phasenempfindlichkeitsmaske (PSM) in Python, die einen Filter (Maske) erstellt, der das gewünschte Signal aus dem beobachteten Signal extrahiert, wenn das gewünschte Signal bekannt ist. Es handelt sich um das Design einer Sprachmaske im STFT-Bereich, die eine grundlegende Sprachverbesserung darstellt.
$ x $ Beobachtungssignal
$ s $ gewünschtes Signal
$ n $ Andere Signale
Ich will $ s $ irgendwie.
Die Grundidee der Sprachverbesserung ist
$ X $: $ x $ STFT $ S $: $ s $ STFT $ \ hat {S} $: Abgeleitetes gewünschtes Signal $ s $
$ G $: Zeitfrequenzmaske (Matrixelemente sind reelle Werte von $ 0 \ leq x \ leq 1 $)
Das gewünschte Signal $ \ hat {S} $ wird geschätzt, indem das beobachtete Signal $ X $ mit der Zeitfrequenzmaske $ G $ multipliziert wird, die auf irgendeine Weise (Adamar-Produkt) für jedes Element der Matrix erzeugt wurde. Es gibt verschiedene Möglichkeiten, die Zeitfrequenzmaske $ G $ zu erstellen, beispielsweise ein Gewinnerfilter, der das gewünschte Signal extrahiert, indem die im gewünschten Signal enthaltene Frequenz verstärkt und andere Signale gedämpft werden.
Die Betonung der Schallquelle ist ein Problem bei der Schätzung von $ s $ aus $ x $.
PSM.py
#Berechnung
import numpy as np
#Sprachverarbeitung
import librosa
import librosa.display
#Datenanzeige
from IPython.display import display, Audio
# Original Data
#Original-Audiodatei
voice, rate = librosa.load("voice.wav", sr=rate)
#Original-Audiodatei mit Rauschen hinzugefügt
noise, _ = librosa.load("noise.wav", sr=rate)
# STFT
#STFT-Parameter
n_fft = 1024*4 #Rahmenlänge(Anzahl von Beispielen)
win_length = n_fft #Länge der Fensterfunktion(Anzahl von Beispielen)
hop_length = win_length // 4 #Hopfenlänge(Anzahl von Beispielen)
sr = rate #Abtastrate[Hz]
f_voice = librosa.stft(voice, n_fft=n_fft, win_length=win_length, hop_length=hop_length)
f_noise = librosa.stft(noise, n_fft=n_fft, win_length=win_length, hop_length=hop_length)
#PSM
X, S = f_noise, f_voice #Beobachtungssignal, gewünschtes Signal
A = (np.abs(S) / np.abs(X)) * np.cos((np.angle(S)-np.angle(X)))
B = np.where(A < 0, 0, A)
G = np.where(B > 1, 1, B)
#Spektrogrammanzeige
# librosa.display.specshow(G, y_axis='log', x_axis='time', sr=sr, hop_length=hop_length)
#Maskenanpassung
_data = f_cafe * G #Adamar Produkt
data = librosa.istft(_test,win_length=win_length, hop_length=hop_length)
#Anzeige der abgeschlossenen Stimme
# display(Audio(test, rate=rate))
Audiodateien können nicht auf Qiita veröffentlicht werden. Probieren Sie es also selbst aus. Ich werde sie alle zusammen in einer Zusammenarbeit oder so etwas veröffentlichen.
Hier repräsentieren $ \ sigma_x ^ 2 $ und $ \ sigma_d ^ 2 $ die Streuung der jeweiligen Spektren des gewünschten Signals und des Rauschsignals. (Möglicherweise spektrale Streuung nach Frequenzbereich)
Mit anderen Worten, Sie können den Teil auswählen, in dem niemand als Geräusch spricht, und ihn als D verwenden. Der Bruchteil dieser Dispersion wird zum Gewinnerfilter.
win.py
s=voice #Gewünschtes Signal
d=noise #Beobachtungssignal
axis = 1
#Beobachtungssignal
_, _, X = stft(d,fs = rate,nperseg=nperseg,noverlap = noverlap)
#Streuung des gewünschten Signals
_, _, S = stft(s,fs = rate,nperseg=nperseg,noverlap = noverlap)
sigma_s=np.square(np.var(S,axis = axis))
#Geräuschverteilung
noise_start = time2tap(8,rate)
noise_end = time2tap(9,rate)
_noise = d[noise_start:noise_end]
_, _, D = stft(_noise,fs = rate,nperseg=nperseg,noverlap = noverlap)
sigma_d=np.square(np.var(D,axis = axis))
#Filtererzeugung
W = sigma_s / (sigma_s + sigma_d) #Damit ist eine Echtzeitverarbeitung möglich
G = np.tile(W,(63,1)).T
#Filteranpassung
ret = G * X
ret = ret / np.amax(ret)
_,test = istft(ret,fs=rate)
display(Audio(test,rate=rate))
display(Audio(d, rate=rate3))
Verbesserung der Klangquelle und Phasensteuerung basierend auf Deep Learning
Recommended Posts