Amélioration de la voix avec le masque de sensibilité de phase (PSM) avec Python

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.

Formulation de l'accentuation de la source sonore

x = s + n
$ 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 \hat{S} = G \odot X

$ 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 $.

Masque de sensibilité de phase (PSM)

G = T[(|S| \oslash |X|) \odot cos(\angle S - \angle X)] ^1 _0 T[x]^1_0=min(max(x,0),1)

code

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))

Résumé

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.

prime

Réduction du bruit à l'aide du filtre gagnant

\hat{X} = E[X|Y] = \frac{\sigma_x ^2}{\sigma_x ^2 + \sigma_d ^2} Y

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))

Les références

Amélioration de la source sonore et contrôle de phase basé sur l'apprentissage en profondeur

Recommended Posts

Amélioration de la voix avec le masque de sensibilité de phase (PSM) avec Python
Utiliser la synthèse vocale Windows 10 avec Python
Reconnaissance vocale en anglais avec python [speech to text]
Introduction facile de la reconnaissance vocale avec Python
Le moyen le plus simple de synthétiser la voix avec python
Statistiques avec python
Python avec Go
Twilio avec Python
Intégrer avec Python
Jouez avec 2016-Python
AES256 avec python
Testé avec Python
python commence par ()
avec syntaxe (Python)
Bingo avec python
Zundokokiyoshi avec python
Excel avec Python
Micro-ordinateur avec Python
Cast avec python