Implémentons un masque de sensibilité de phase (PSM) en Python qui crée un filtre (masque) qui extrait le signal souhaité du signal observé lorsque le signal souhaité est connu. Il s'agit d'une conception d'un masque vocal dans la zone STFT, qui est une amélioration de la voix super basique.
$ x $ Signal d'observation
$ s $ signal souhaité
$ n $ Autres signaux
Je veux en quelque sorte $ s $.
L'idée de base de l'amélioration de la voix est
$ X $: $ x $ STFT $ S $: $ s $ STFT $ \ hat {S} $: signal désiré inféré $ s $
$ G $: Masque de fréquence temporelle (les éléments de la matrice sont des valeurs réelles de $ 0 \ leq x \ leq 1 $)
Le signal souhaité $ \ hat {S} $ est estimé en multipliant le signal observé $ X $ par le masque de fréquence temporelle $ G $ créé par certains moyens (produit adamar) pour chaque élément de la matrice. Il existe différentes manières de réaliser le masque temps-fréquence $ G $, comme un filtre gagnant qui extrait le signal souhaité en amplifiant la fréquence contenue dans le signal souhaité et en atténuant d'autres signaux.
L'accentuation de la source sonore est un problème d'estimation de $ s $ à partir de $ x $.
PSM.py
#Calcul
import numpy as np
#Traitement de la voix
import librosa
import librosa.display
#Affichage des données
from IPython.display import display, Audio
# Original Data
#Fichier audio original
voice, rate = librosa.load("voice.wav", sr=rate)
#Fichier audio original avec bruit ajouté
noise, _ = librosa.load("noise.wav", sr=rate)
# STFT
#Paramètre STFT
n_fft = 1024*4 #Longueur du cadre(Le nombre d'échantillons)
win_length = n_fft #Longueur de la fonction de fenêtre(Le nombre d'échantillons)
hop_length = win_length // 4 #Longueur de saut(Le nombre d'échantillons)
sr = rate #Taux d'échantillonnage[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 #Signal d'observation, signal souhaité
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)
#Affichage du spectrogramme
# librosa.display.specshow(G, y_axis='log', x_axis='time', sr=sr, hop_length=hop_length)
#Adaptation du masque
_data = f_cafe * G #Produit Adamar
data = librosa.istft(_test,win_length=win_length, hop_length=hop_length)
#Affichage de la voix terminée
# display(Audio(test, rate=rate))
Les fichiers audio ne peuvent pas être publiés sur Qiita, veuillez donc l'essayer vous-même. Je les publierai tous ensemble dans une collaboration ou quelque chose comme ça.
Ici, $ \ sigma_x ^ 2 $ et $ \ sigma_d ^ 2 $ représentent la dispersion des spectres respectifs du signal désiré et du signal de bruit. (Peut-être une dispersion spectrale par région de fréquence)
En d'autres termes, vous pouvez sélectionner la partie où personne ne parle comme bruit et l'utiliser comme D. La partie fractionnaire de cette dispersion devient le filtre gagnant.
win.py
s=voice #Signal souhaité
d=noise #Signal d'observation
axis = 1
#Signal d'observation
_, _, X = stft(d,fs = rate,nperseg=nperseg,noverlap = noverlap)
#Dispersion du signal souhaité
_, _, S = stft(s,fs = rate,nperseg=nperseg,noverlap = noverlap)
sigma_s=np.square(np.var(S,axis = axis))
#répartition du bruit
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))
#Génération de filtres
W = sigma_s / (sigma_s + sigma_d) #Avec juste cela, le traitement en temps réel est possible
G = np.tile(W,(63,1)).T
#Adaptation du filtre
ret = G * X
ret = ret / np.amax(ret)
_,test = istft(ret,fs=rate)
display(Audio(test,rate=rate))
display(Audio(d, rate=rate3))
Amélioration de la source sonore et contrôle de phase basé sur l'apprentissage en profondeur
Recommended Posts