Filtrer le message du signal vocal bruyant

9

J'essaie de déchiffrer un message caché dans un fichier audio très bruyant (.wav) (je pense que c'est du bruit blanc avec un drone bas supplémentaire). Le message est un nombre à six chiffres . Je n'ai pas d'autres détails sur le bruit.

J'ai essayé d'utiliser un filtre passe-bas dans l'espoir que l'élimination de la plupart des fréquences plus élevées me permettrait d'entendre les chiffres, mais il me semble que je ne peux pas me débarrasser également d'une quantité suffisante du drone bas pour entendre assez bien la voix. Ma tentative était la suivante (la fonction employée freq_space_low_pass_filterest incluse à la fin):

[data, SampleRate, NbitsPerSample]=wavread('noisy_msg6.wav');

y=data(:,1); % we will work only with one channel in this demo 
N=length(y); %number of sample points
t=( (1:N)*1/SampleRate ).'; % time spacing is 1/SampleRate and we want column vector

Y=fft(y);

spectrum_freq=fourier_frequencies(SampleRate, N);

Freq3db=100;
[spectrum_filtered,g_vs_freq]=freq_space_low_pass_filter(Y, SampleRate, Freq3db);


y_filtered=ifft(spectrum_filtered);

y_filtered=real(y_filtered);



wavwrite(y_filtered/(0.1+max(y_filtered)), SampleRate, NbitsPerSample,
         'noisy_msg6_filtered.wav');

%%%%%%%%down sampling%%%%%%%%

indexes=(abs(spectrum_freq) < 10*Freq3db);
spectrum_freq_down_sampled = spectrum_freq(indexes);
spectrum_down_sampled = spectrum_filtered(indexes);
N_down_sampled = length(spectrum_down_sampled);

spectrum_down_sampled=spectrum_down_sampled*N_down_sampled/N;

SampleRate_down_sampled=SampleRate*N_down_sampled/N;

y_down_sampled=real(ifft(spectrum_down_sampled));
t_down_sampled = ( (1:N_down_sampled)*1/SampleRate_down_sampled ).';

sound(y_down_sampled, SampleRate_down_sampled)

function [spectrum_filtered,g]=freq_space_low_pass_filter(spectrum, SampleRate, Freq3db)
%% applies low pass filter in the frequency domain
% spectrum - result of fft on time series data (column vector is expected)
% SampleRate - measured in Hz, 1/dt where dt spacing of the points in time domain
% Freq3db - desired 3db roll off point in Hz

N=length(spectrum);

function G=filter_gain(freq, Freq3db)
    G=1./(1+1i*freq/Freq3db); % this corresponds to low pass RC filter
end

spectrum_freq=fourier_frequencies(SampleRate, N);

% calculate filter gain for each spectrum frequency
g=filter_gain(spectrum_freq, Freq3db);
spectrum_filtered=spectrum.*g;
end

Tracé du spectre du signal: image

user1825494
la source
pouvez-vous nous fournir un échantillon avec lequel vous travaillez? et peut-être votre résultat?
penelope
Je ne peux pas télécharger les images du tracé (pas assez de points) et je n'ai aucun moyen de vous lier au fichier
user1825494
1
si vous mettez des liens dans les commentaires, quelqu'un les éditera avec plaisir. Et si vous trouvez un moyen de télécharger les fichiers quelque part et de fournir un lien, revenez-y également.
penelope
2
Le graphique serait beaucoup plus informatif s'il était tracé log-log. En l'état, il semble que vous ayez un bruit à large bande d'environ 1,5 kHz à 22,5 kHz, avec une tonalité à bande étroite à environ 2 kHz. Ce que je présume, c'est que le signal "vocal", avec ce qui semble être un décalage CC important, se trouve dans un "trou" assez calme. Il ne devrait vraiment pas être si difficile d'isoler avec un filtre passe-bande approprié.
Dave Tweed

Réponses:

1

Quelques points:

  1. Le filtrage dans le domaine fréquentiel est compliqué et nécessite un véritable algorithme comme l'ajout de chevauchement pour éviter l'aliasing du domaine temporel. Il est beaucoup plus facile de filtrer directement dans le domaine temporel: [b, a] = beurre (1 100 / (SampleRate / 2); y_filtered = filtre (b, a, y); est beaucoup mieux
  2. Vous voulez probablement mettre un filtre coupe-bande sur la fréquence du drone
  3. Pour le bruit stationnaire à large bande, une bonne méthode est le filtrage de Wiener ou la soustraction spectrale. De nombreux articles ont été publiés à ce sujet.
Hilmar
la source
0

Vous mentionnez l'utilisation d'un filtre passe-bas, mais comme l'un des commentateurs l'a mentionné, vous feriez probablement mieux avec un filtre passe-bande pour filtrer également le bruit basse fréquence. Il existe également des filtres de réduction du bruit dans les bibliothèques tierces si vous êtes intéressé par des solutions préexistantes.

Éthéré
la source
0

La voix humaine a quelques particularités qui pourraient aider. D'une part, la voix féminine commence à environ 200 Hz, les hommes plus bas, donc faire un filtre passe-haut ici aiderait un peu. Voir aussi les caractéristiques acoustiques distinguant la voix masculine et féminine .

De plus, identifiez les fréquences des drones via un histogramme.

Faire tout cela dans le code est un peu lourd. Avez-vous envisagé un programme audio comme Audacity ?

serv-inc
la source