I am new to matlab and I'm trying to filter the noise out of the audio. I tried some filters but can't event get close to lessening the noise.

[originalAudio, Fs] = audioread('original.wav');
[noisyAudio, ~] = audioread('noisy.wav');
t = (0:length(originalAudio)-1)/Fs;
figure;
subplot(2,1,1);
plot(t, originalAudio);
xlabel('Time (s)');
ylabel('Amplitude');
title('Original Audio');
subplot(2,1,2);
plot(t, noisyAudio);
xlabel('Time (s)');
ylabel('Amplitude');
title('Noisy Audio');
N = length(originalAudio);
f = Fs*(0:(N/2))/N;
originalSpec = fft(originalAudio);
noisySpec = fft(noisyAudio);
figure;
subplot(2,1,1);
plot(f, abs(originalSpec(1:N/2+1)));
xlabel('Frequency (Hz)');
ylabel('Magnitude');
title('Original Audio Spectrum');
subplot(2,1,2);
plot(f, abs(noisySpec(1:N/2+1)));
xlabel('Frequency (Hz)');
ylabel('Magnitude');
title('Noisy Audio Spectrum');
fc1 = 2000;
fc2 = 500;
[b1, a1] = butter(6, fc1/(Fs/2), 'low');
[b2, a2] = butter(6, fc2/(Fs/2), 'low');
filteredAudio1 = filter(b1, a1, noisyAudio);
filteredAudio2 = filter(b2, a2, filteredAudio1);
figure;
plot(t, filteredAudio2);
xlabel('Time (s)');
ylabel('Amplitude');
title('Filtered Audio');
filteredSpec2 = fft(filteredAudio2);
figure;
plot(f, abs(filteredSpec2(1:N/2+1)));
xlabel('Frequency (Hz)');
ylabel('Magnitude');
title('Filtered Audio Spectrum');
figure;
subplot(2,1,1);
plot(t, originalAudio);
xlabel('Time (s)');
ylabel('Amplitude');
title('Original Audio');
subplot(2,1,2);
plot(t, filteredAudio2);
xlabel('Time (s)');
ylabel('Amplitude');
title('Filtered Audio (Closest to Original)');
sound(filteredAudio2, Fs);
I have the noisy file and the original file that is attached: I need to make the noisy file as close to the original as possible.

댓글 수: 5

Hi @Godwin Emmanuel, you can actually attach a file here but only these formats are supported:
.bmp, .csv, .fig, .gif, .jpg, .jpeg, .m, .mat, .mdl, .mlapp, .mlx, .sfx, .slx, .sbproj, .pdf, .png, .txt, .xls, .xlsx, .zip
Click the paperclip icon .
Also click the indentation icon to copy/paste your MATLAB code that shows your filter design approach.
The file is the audio file how do I attach them so people can hear it
Use the ‘paperclip’ (just to the right of the icon) and follow the instructions. If it is a non-standard format or extension, use the zip function to enclose it in a .zip file and then post that.

댓글을 달려면 로그인하십시오.

 채택된 답변

If it contains broadband noise, a frequency-selective filter will not be able to eliminate the noise. In that event, experiment with either wavelet denoising or use the sgolayfilt function. The Savitzky-Golay filter is usually effective at eliminating broadband noise, although it requires experimentation. I usually use a 3-degree polynomial and then change the ‘framelen’ value until I get the result I want.
EDIT — (28 Apr 2024 at 15:15)
The ‘noisy’ file definitely has broadband noise, however it may not be possible to filter it back to the original file.
Uz = unzip('Wavfiles.zip')
Uz = 1x3 cell array
{'Wavfiles/'} {'Wavfiles/noisy.wav'} {'Wavfiles/original.wav'}
figure
tiledlayout(4,1)
for k = 1:2
fn = Uz{k+1}
[y{k},Fs(k)] = audioread(fn);
ysize = size(y{k},1);
t{k} = linspace(0, ysize-1, ysize).'/Fs(k);
nexttile
plot(t{k}, y{k})
grid
xlabel('Time')
ylabel('Amplitude')
title(fn)
[FTs1{k},Fv{k}] = FFT1(y{k},t{k});
nexttile
plot(Fv{k}, abs(FTs1{k}))
grid
xlabel('Frequency')
ylabel('Magnitude')
title(fn)
end
fn = 'Wavfiles/noisy.wav'
fn = 'Wavfiles/original.wav'
y1_filt = sgolayfilt(y{1}, 3, 201);
figure
tiledlayout(2,1)
nexttile
plot(t{1}, y{1})
grid
xlabel('Time')
ylabel('Amplitude')
title('Unfiltered')
nexttile
plot(t{2}, y1_filt)
grid
xlabel('Time')
ylabel('Amplitude')
title('Filtered')
function [FTs1,Fv] = FFT1(s,t)
t = t(:);
L = numel(t);
if size(s,2) == L
s = s.';
end
Fs = 1/mean(diff(t));
Fn = Fs/2;
NFFT = 2^nextpow2(L);
FTs = fft((s - mean(s)) .* hann(L).*ones(1,size(s,2)), NFFT)/sum(hann(L));
Fv = Fs*(0:(NFFT/2))/NFFT;
% Fv = linspace(0, 1, NFFT/2+1)*Fn;
Iv = 1:numel(Fv);
FTs1 = FTs(Iv,:);
end
I will consider other possibilities, however this is likely the best I can do with this file. The noise completely swamps the signal.
.

댓글 수: 11

It is broadband noise. How do I Sir use those function in my code?
Unable to perform assignment because brace indexing is not supported for variables of this type.
When I run your code Sir I am having this error. Also how can I make a wav file of the filtered version?
I have run the code and collected the filtered wav file Sir@Star Strider but I can't hear anything on the audio.
I am not certain where the ‘brace indexing’ error gets thrown. If you do not need to use the .zip file, then you may need to change my code to match your files. (I have to use it here because of the way the files are posted. Make appropriate changes to my code to work with your data.)
To save the filtered data, use the audiowrite function using the .wav file extension (suffix).
This is the filtered data and is this what it should sound base on the plot Sir @Star Strider. Or I may have cause something that made it sound like this?
It is not possible to eliminate a significant amount of noise from that file. I doubt that there is any way to recover the original information from it. The noise simply overwhelms the original information.
I used several different values for ‘framelen’ from 11 to 501, and did not get a decent result from any of them.
So this is the best I will get Sir @Star Strider if it is. I thank you very much! and I will pin this as the answer
Btw I edited the file to this
% Unzip the files
try
Uz = unzip('Wavfiles.zip');
catch
error('Failed to unzip the file. Make sure "Wavfiles.zip" exists in the current directory.');
end
% Check if any files were extracted
if isempty(Uz)
error('No files were extracted from the ZIP archive.');
end
% Initialize variables
y = cell(1, 2);
Fs = zeros(1, 2);
t = cell(1, 2);
FTs1 = cell(1, 2);
Fv = cell(1, 2);
% Plotting and analyzing audio files
for k = 1:min(2, numel(Uz)-1)
try
fn = Uz{k+1};
[y{k}, Fs(k)] = audioread(fn);
ysize = size(y{k}, 1);
t{k} = linspace(0, ysize-1, ysize) / Fs(k);
figure;
tiledlayout(2, 1);
% Plot original waveform
nexttile;
plot(t{k}, y{k});
grid on;
xlabel('Time');
ylabel('Amplitude');
title(['Original Audio - ', fn]);
% Calculate and plot frequency spectrum
[FTs1{k}, Fv{k}] = FFT1(y{k}, t{k});
nexttile;
plot(Fv{k}, abs(FTs1{k}));
grid on;
xlabel('Frequency');
ylabel('Magnitude');
title(['Frequency Spectrum - ', fn]);
catch
warning(['Error processing file ', fn]);
end
end
% Smoothing the first audio file
try
y1_filt = sgolayfilt(y{1}, 3, 201);
% Normalize the filtered audio to [-1, 1] range
y1_filt_normalized = y1_filt / max(abs(y1_filt));
filtered_filename = 'filtered_audio.wav'; % Define the filename for the filtered audio
audiowrite(filtered_filename, y1_filt_normalized, Fs(1)); % Save the filtered audio
catch
warning('Error smoothing the first audio file.');
y1_filt_normalized = [];
filtered_filename = '';
end
% Plot unfiltered and filtered audio
figure;
tiledlayout(2, 1);
try
% Plot unfiltered audio
nexttile;
plot(t{1}, y{1});
grid on;
xlabel('Time');
ylabel('Amplitude');
title('Unfiltered Audio');
% Plot filtered audio
nexttile;
if ~isempty(y1_filt_normalized)
plot(t{1}, y1_filt_normalized);
grid on;
xlabel('Time');
ylabel('Amplitude');
title('Filtered Audio');
else
warning('Filtered audio is empty.');
end
catch
warning('Error plotting audio.');
end
function [FTs1, Fv] = FFT1(s, t)
try
t = t(:);
L = numel(t);
if size(s, 2) == L
s = s.';
end
Fs = 1 / mean(diff(t));
Fn = Fs / 2;
NFFT = 2^nextpow2(L);
FTs = fft((s - mean(s)) .* hann(L), NFFT) / sum(hann(L));
Fv = Fs * (0:(NFFT/2)) / NFFT;
Iv = 1:numel(Fv);
FTs1 = FTs(Iv,:);
catch
error('Error in FFT calculation.');
end
end
My pleasure!
That appears to be appropriate.
It is unfortunate that the noise in the file corrupted it so thoroughly. That file resisted everything I could think of to reduce or elilminate the noise.
In practice, what reliable options do we have to attenuate the effect of broadband noise before it corrupts the original audio during measurement? Restoring the original audio from the noise-corrupted audio seems like a challenging task, although I acknowledge that noise-corrupted audio is still audible to humans to a certain extent.
If we train an AI Voice Classifier using the original audio, do you think it would be capable of improving the intelligibility of the audio by reconstructing certain parts of the signal?
@Godwin Emmanuel — Thank you!
@Sam Chak — That could work. I don’t have sufficient experience with A.I. audio processing to attempt it. I am not certain how to approach this problem from that perspective, however I would definitely like to find out how to do it.

댓글을 달려면 로그인하십시오.

추가 답변 (2개)

Did you try the Data Cleaner app on the Apps tab of the tool ribbon?
Can you upload a screenshot of your noisy original data, and of the denoised signal that you say is not denoised enough?
If you have any more questions, then attach your screenshots and code with the paperclip icon after you read this:

카테고리

질문:

2024년 4월 28일

댓글:

2024년 4월 28일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by