Filtrar mensagem de sinal de voz ruidoso

9

Estou tentando decifrar uma mensagem oculta em um arquivo de áudio muito barulhento (.wav) (acho que é ruído branco com um zangão adicional baixo). A mensagem é um número de seis dígitos . Não tenho mais detalhes sobre o barulho.

Tentei usar um filtro passa-baixo na esperança de que eliminar a maioria das frequências mais altas me permitisse ouvir os números, mas parece que não consigo me livrar do drone baixo o suficiente para ouvir bem a voz. Minha tentativa foi a seguinte (a função empregada freq_space_low_pass_filterestá incluída no final):

[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

Gráfico do espectro do sinal: cenário

user1825494
fonte
você pode nos fornecer uma amostra com a qual está trabalhando? e talvez o seu resultado?
Penelope
Eu não posso carregar as imagens do lote (não pontos suficientes) e não têm nenhuma maneira de ligá-lo para o arquivo
user1825494
11
se você colocar links nos comentários, alguém os editará com prazer. E se você encontrar uma maneira de fazer upload dos arquivos em algum lugar e fornecer o link, volte com isso também.
Penelope
2
O gráfico seria muito mais informativo se fosse plotado log-log. Como é, parece que você tem ruído de banda larga de cerca de 1,5 kHz a 22,5 kHz, com um tom de banda estreita a cerca de 2 kHz. O que presumo é que o sinal de "voz", junto com o que parece ser um deslocamento DC significativo, fica em um "buraco" bastante silencioso. Realmente não deve ser tão difícil isolar com um filtro passa-banda adequado.
Dave Tweed

Respostas:

1

Alguns pontos:

  1. A filtragem no domínio da frequência é complicada e precisa de um algoritmo real, como adição de sobreposição, para evitar aliases no domínio do tempo. É muito mais fácil filtrar diretamente no domínio do tempo: [b, a] = manteiga (1.100 / (SampleRate / 2); y_filtered = filtro (b, a, y); é muito melhor
  2. Você provavelmente quer colocar um filtro de entalhe na frequência do drone
  3. Para ruído estacionário de banda larga, um bom método é a filtragem Wiener ou subtração espectral. Muitos artigos foram publicados sobre isso.
Hilmar
fonte
0

Você mencionou o uso de um filtro passa-baixo, mas como um dos comentadores mencionou, provavelmente faria melhor com um filtro passa-banda para também filtrar o ruído de baixa frequência. Também existem filtros de redução de ruído em bibliotecas de terceiros, se você estiver interessado em soluções pré-existentes.

Etéreo
fonte
0

A voz humana tem algumas peculiaridades que podem ajudar. Por um lado, a voz feminina começa em cerca de 200Hz, mais baixa do sexo masculino, portanto, fazer um filtro passa-alto aqui ajudaria um pouco. Veja também características acústicas que distinguem a voz masculina e feminina .

Além disso, identifique as frequências do drone através de um histograma.

Fazer tudo isso no código é um pouco complicado. Você já considerou algum programa de áudio como o Audacity ?

serv-inc
fonte