web-dev-qa-db-fra.com

Supprimer le bruit du fichier wav, MATLAB

Je n'ai utilisé MATLAB que comme calculatrice, donc je ne connais pas aussi bien le programme. J'espère qu'une personne gentille pourra me guider sur le chemin puisque Google n'est actuellement pas mon ami.

J'ai un fichier wav dans le lien ci-dessous, où il y a une voix humaine et du bruit en arrière-plan. Je veux que le bruit soit supprimé. Y a-t-il quelqu'un qui peut me dire comment le faire dans MATLAB?

https://www.dropbox.com/s/3vtd5ehjt2zfuj7/Hold.wav

14
user3338501

C'est une solution assez imparfaite, d'autant plus qu'une partie du bruit est intégrée dans la même gamme de fréquences que la voix que vous entendez dans le fichier, mais ici, rien ne va. Ce dont je parlais en ce qui concerne le spectre de fréquences, c'est que si vous entendez le son, le bruit de fond a un bourdonnement très faible. Cela réside dans la gamme de fréquences basses du spectre, tandis que la voix a une fréquence plus élevée. En tant que tel, nous pouvons appliquer un filtre passe-bande pour se débarrasser du faible bruit, capturer la majeure partie de la voix et toutes les fréquences bruyantes du côté supérieur seront être annulé également.

Voici les étapes que j'ai faites:

  1. Lisez le fichier audio en utilisant audioread .
  2. Jouez le son d'origine pour que je puisse entendre à quoi cela ressemble. Pour ce faire, créez un objet audioplayer .
  3. Tracé des canaux gauche et droit pour jeter un œil au signal sonore dans le domaine temporel ... s'il donne des indices. En regardant les canaux, ils semblent tous deux être les mêmes, il semble donc que ce n'était qu'un seul microphone mappé sur les deux canaux.
  4. J'ai pris la transformée de Fourier et j'ai vu la distribution de fréquence.
  5. En utilisant (4), j'ai calculé approximativement où je devrais couper les fréquences.
  6. Conçu un filtre passe-bande qui coupe ces fréquences.
  7. Filtré le signal puis joué en construisant un autre objet audioplayer.

Allons-y alors!


Étape 1

%% Read in the file
clearvars;
close all;
[f,fs] = audioread('Hold.wav');

audioread lira pour vous un fichier audio. Spécifiez simplement le fichier que vous voulez dans le ''. Assurez-vous également que votre répertoire de travail est celui où ce fichier est stocké. clearvars, close all faites le ménage pour nous. Il ferme toutes nos fenêtres (le cas échéant) et efface toutes nos variables dans l'espace de travail MATLAB. f serait le signal lu dans MATLAB tandis que fs est la fréquence d'échantillonnage de votre signal. f voici une matrice 2D. La première colonne est le canal gauche tandis que la seconde est le canal droit. En général, le nombre total de canaux dans votre fichier audio est indiqué par le nombre total de colonnes de cette matrice lues via audioread.

Étape 2

%% Play original file
pOrig = audioplayer(f,fs);
pOrig.play;

Cette étape vous permettra de créer un objet audioplayer qui prend le signal que vous lisez (f), avec la fréquence d'échantillonnage fs et génère un objet stocké dans pOrig. Vous utilisez ensuite pOrig.play pour lire le fichier dans MATLAB afin que vous puissiez l'entendre.

Étape 3

%% Plot both audio channels
N = size(f,1); % Determine total number of samples in audio file
figure;
subplot(2,1,1);
stem(1:N, f(:,1));
title('Left Channel');
subplot(2,1,2);
stem(1:N, f(:,2));
title('Right Channel');

stem est un moyen de tracer des points discrets dans MATLAB. Chaque point dans le temps a un cercle dessiné au point avec une ligne verticale tracée de l'axe horizontal à ce point dans le temps. subplot est un moyen de placer plusieurs figures dans la même fenêtre. Je n'entrerai pas dans les détails ici, mais vous pouvez en savoir plus sur le fonctionnement de subplot en faisant référence à ce billet StackOverflow que j'ai écrit ici . Le code ci-dessus produit le graphique ci-dessous:

signals

Le code ci-dessus est assez simple. Je trace simplement chaque canal individuellement dans chaque sous-intrigue.

Étape 4

%% Plot the spectrum
df = fs / N;
w = (-(N/2):(N/2)-1)*df;
y = fft(f(:,1), N) / N; % For normalizing, but not needed for our analysis
y2 = fftshift(y);
figure;
plot(w,abs(y2));

Le code qui aura l'air le plus effrayant est le code ci-dessus. Si vous vous souvenez des signaux et des systèmes, la fréquence maximale qui est représentée dans notre signal est la fréquence d'échantillonnage divisée par 2. Cela s'appelle le Nyquist fréquence . La fréquence d'échantillonnage de votre fichier audio est de 48000 Hz, ce qui signifie que la fréquence maximale représentée dans votre fichier audio est de 24000 Hz. fft signifie Transformation de Fourier rapide . Considérez-le comme un moyen très efficace de calculer la transformée de Fourier. La formule traditionnelle requiert que vous effectuiez plusieurs sommations pour chaque élément de votre sortie. La FFT calculera cela efficacement en nécessitant beaucoup moins d'opérations et vous donnera toujours le même résultat.

Nous utilisons fft pour jeter un œil au spectre de fréquences de notre signal. Vous appelez fft en spécifiant le signal d'entrée souhaité comme premier paramètre, suivi du nombre de points que vous souhaitez évaluer avec le second paramètre. Il est habituel que vous spécifiez le nombre de points dans votre FFT comme étant la longueur du signal. Je fais cela en vérifiant pour voir combien de lignes nous avons dans notre matrice sonore. Lorsque vous tracez le spectre de fréquences, je viens de prendre un canal pour simplifier les choses car l'autre canal est le même. Cela sert de première entrée dans fft. Gardez également à l'esprit que j'ai divisé par N car c'est la bonne façon de normaliser le signal. Cependant, parce que nous voulons juste prendre un instantané de ce à quoi ressemble le domaine fréquentiel, vous n'avez pas vraiment besoin de le faire. Cependant, si vous prévoyez de l'utiliser pour calculer quelque chose plus tard, vous devez absolument le faire.

J'ai écrit du code supplémentaire car le spectre par défaut est non centré . J'ai utilisé fftshift pour que le centre mappe à 0 Hz, tandis que la gauche s'étend de 0 à -24000Hz tandis que la droite s'étend de 0 à 24000 Hz. C'est intuitivement comment je vois le spectre de fréquences. Vous pouvez considérer les fréquences négatives comme des fréquences qui se propagent dans la direction opposée. Idéalement, la distribution de fréquence pour une fréquence négative devrait être égale à la fréquence positive. Lorsque vous tracez le spectre de fréquences, il vous indique la contribution de cette fréquence à la sortie. Cela est défini par la magnitude du signal. Vous trouvez cela en prenant la fonction abs . La sortie que vous obtenez est indiquée ci-dessous.

enter image description here

Si vous regardez l'intrigue, il y a beaucoup de pics autour de la plage de basses fréquences. Cela correspond à votre fredonnement alors que la voix correspond probablement à la gamme de fréquences la plus élevée et il n'y en a pas beaucoup car il n'y a pas beaucoup de voix entendue.

Étape # 5

Par essais et erreurs et en regardant l'étape 5, j'ai pensé que tout à partir de 700 Hz et plus correspond au bruit de ronflement tandis que les contributions de bruit plus élevées vont de 12000 Hz et plus.

Étape # 6

Vous pouvez utiliser la fonction butter de la boîte à outils de traitement du signal pour vous aider à concevoir un filtre passe-bande. Cependant, si vous n'avez pas cette boîte à outils, reportez-vous à ce post StackOverflow sur la façon dont la fonction créée par l'utilisateur permet d'atteindre la même chose. Cependant, l'ordre pour ce filtre n'est que de 2. En supposant que vous ayez la fonction butter disponible, vous devez déterminer l'ordre dans lequel vous voulez que votre filtre. Plus l'ordre est élevé, plus il fera de travail. Je choisis n = 7 pour commencer. Vous devez également normaliser vos fréquences afin que la fréquence de Nyquist mappe à 1, tandis que tout le reste mappe entre 0 et 1. Une fois que vous avez fait cela, vous pouvez appelez butter comme ceci:

[b,a] = butter(n, [beginFreq, endFreq], 'bandpass');

L'indicateur bandpass signifie que vous souhaitez concevoir un filtre passe-bande, beginFreq et endFreq mapper sur la fréquence de début et de fin normalisée que vous souhaitez pour le filtre passe-bande. Dans notre cas, c'est beginFreq = 700 / Nyquist et endFreq = 12000 / Nyquist. b,a sont les coefficients utilisés pour un filtre qui vous aideront à effectuer cette tâche. Vous en aurez besoin pour la prochaine étape.

%% Design a bandpass filter that filters out between 700 to 12000 Hz
n = 7;
beginFreq = 700 / (fs/2);
endFreq = 12000 / (fs/2);
[b,a] = butter(n, [beginFreq, endFreq], 'bandpass');

Étape # 7

%% Filter the signal
fOut = filter(b, a, f);

%% Construct audioplayer object and play
p = audioplayer(fOut, fs);
p.play;

Vous utilisez filter pour filtrer votre signal en utilisant ce que vous avez obtenu à l'étape 6. fOut sera votre signal filtré. Si vous voulez l'entendre jouer, vous pouvez construire et audioplayer sur la base de ce signal de sortie à la même fréquence d'échantillonnage que l'entrée. Vous utilisez ensuite p.play pour l'entendre dans MATLAB.

Essayez tout cela et voyez comment tout cela fonctionne. Vous aurez probablement besoin de jouer le plus dans les étapes # 6 et # 7. Ce n'est pas une solution parfaite, mais assez pour vous aider à démarrer, j'espère.

Bonne chance!

41
rayryeng