I am trying to remove noise from a wav file. But I keep getting the following error after run the script.
The wav file I use is https://drive.google.com/file/d/0BzIyOj_KUKufTTNWMFlRMW9fT2c/view?usp=sharing
I use the code from Remove noise from wav file, MATLAB.
>> run sample3
Index exceeds matrix dimensions.
Error in sample3 (line 17)
stem(1:N, f(:,2));
Error in run (line 96)
evalin('caller', [script ';']);
Here is the code:
%% Read in the file
clearvars;
close all;
[f,fs] = audioread('noise.wav');
%% Play original file
pOrig = audioplayer(f,fs);
pOrig.play;
%% 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');
%% 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));
[B,A] = butter(n, [beginFreq, endFreq], 'bandpass');
%% 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');
%% Filter the signal
fOut = filter(b, a, f);
%% Construct audioplayer object and play
p = audioplayer(fOut, fs);
p.play;
The code assumes that the signal is stereo (a.k.a. two channels). Your sound file most likely is mono (judging from the way it sounds... a.k.a. one channel), so any references in the code that uses the right channel should be removed.
Simply put, the only part of the code that is affected is displaying the right channel in time-domain. The rest of the code should work as it accesses the left channel in stereo, which is coincidentally the first column of the sound file and the only column in a mono file.
Replace this code:
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');
with:
N = size(f,1); % Determine total number of samples in audio file
figure;
stem(1:N, f(:,1));
title('Mono Channel');
In the future, try and read the MATLAB errors more carefully. They're very verbose and descriptive on what the problem in your code is. In this case, it's complaining that you are trying to access a column in the sound file f that doesn't exist.
Note: I am the original author of the answer you have linked.
Related
I have a mp3 file in the link below, where there is a man human voice and some humming noise in the background. I want the humming noise removed. Is there anyone who can tell me how to do it in MATLAB?
https://www.dropbox.com/s/h95y1oelbzvcgkc/allthatbass.mp3?dl=0
%% Read in the file
clearvars;
close all;
[f,fs] = audioread('allthatbass.mp3');
%% Play original file
pOrig = audioplayer(f,fs);
N = size(f,1);
%% 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));
%% 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');
%% Filter the signal
fOut = filter(b, a, f);
%% Construct audioplayer object and play
p = audioplayer(fOut, fs);
p.play;
I expect the humming noise removed, but the output sound like the original sound.
enter link description here
I have downloaded the original file you linked in your question and added the following line at the end:
audiowrite('filtered.wav', fOut, fs);
The resulting file 'filtered.wav' sounds very different to my ears (I used a headset to listen). If you open 'filtered.wav' for example in Audacity and take a look at the spectrum then it looks indeed different from the original (as expected, the frequencies below 700 Hz and above 12 kHz are removed).
Let's try to verify this in matlab. The following script reads both files and plots the dB value of both ffts. The lower plot represents the filtered signal and it is clearly visible that the bass frequencies are removed. The cut above 12 kHz is visible as well but it seems that these frequencies have already been attenuated in the original signal and the bandpass filter reinforces that.
%% Read in both files
clearvars;
close all;
[f,fs] = audioread('allthatbass.mp3');
[fflt, fsflt] = audioread('filtered.wav');
N = size(f,1);
%% Compute the ffts
df = fs / N;
n = N / 2; % plot only the second half of the spectrum
w = (0:(n)-1)*df;
y = fft(f(:,1), N) / N;
y2 = fftshift(y);
yflt = fft(fflt(:,1), N) / N;
y2flt = fftshift(yflt);
%% Plot the spectrum of both files (use the dB value, i.e. 10 * log(abs(x)) )
figure;
ax1 = subplot(2,1,1);
plot(w,10*log(abs(y2(n:end-1,1))));
ax2 = subplot(2,1,2);
plot(w, 10*log(abs(y2flt(n:end-1,1))));
linkaxes([ax1, ax2], 'y'); % link the axes (this makes it easier to visually compare the plots)
Try using a low pass filter in MATLAB. They're relatively easy to implement. You can find the documentation, along with examples, here.
guys below are my code. I want to remove noise from audio signal which I added up by myself using random function.The following code removes somehow noise but it is still too noisy that I can't hear the sound. I also want to add the audio file for this code but i didn't find any option while posting my question so you can add any two channel .wav sound file . Any comment or hint will be helpful thanks.
close all
clear
clc
[x,fs] = audioread('cello.wav');
whos x;
pOrig = audioplayer(x,fs); %Signal Play
pOrig.play;
N = size(x,1);
figure;
subplot(2,1,1);
stem(1:N, x(:,1));
title('Left Channel of Origional signal');
subplot(2,1,2);
stem(1:N, x(:,2));
title('Right Channel of origional signal');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
df = fs/N;
w = (-(N/2):(N/2)-1)*df;
y1= fft(x(:,1),N)/N;
y2 = fftshift(y1);
figure;
plot(w,abs(y2));
title('Fast Fourier Transform of Origional Signal')
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
pause
y=x;
y = y + randn(size(y));
pOrig = audioplayer(y,fs);
pOrig.play;
figure;
subplot(2,1,1);
stem(1:N, y(:,1));
title('Left Channel with Noise');
subplot(2,1,2);
stem(1:N, y(:,2));
title('Right Channel with Noise');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
df = fs/N;
w = (-(N/2):(N/2)-1)*df;
y1= fft(y(:,1),N)/N;
y2 = fftshift(y1);
figure;
plot(w,abs(y2));
title('Fast Fourier Transform of Noisy Signal')
pause
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% filter design
n = 10;
beginFreq = 100 / (fs/2);
endFreq = 2000 / (fs/2);
%[b,a] = butter(n, endFreq, 'low');
%fout = filter(b,a,y); % input y(noisy signal)
[b,a] = butter(n, endFreq, 'low');
fout = filter(b,a,y); % input y(noisy signal)
figure;
subplot(2,1,1);
stem(1:N, fout(:,1));
title('Left channel after filtering');
subplot(2,1,2);
stem(1:N, fout(:,2));
title(' Right channel after filtering');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%plot(fout);
df = fs/N;
w = (-(N/2):(N/2)-1)*df;
y1= fft(fout(:,1),N)/N;
y2 = fftshift(y1);
figure;
plot(w,abs(y2));
title('Fast Fourier Transform after filtering');
pOrig = audioplayer(fout,fs);
pOrig.play;
You are adding noise using randn() function, which generatares Gaussian noise, i.e. white noise. The white noise has constant power over the spectrum, that means you are adding noise from 0 to 20kHz (only considering the audio spectrum).
Your filter is a bandpass filter between 0.1-2 kHz, so according to what I pointed out above, you still have noise components in these frequency bands. Theoritecally, it is impossible to filter all of the noise components, however you may want to check out Wiener filters to get better results. Actually, it is the optimal filter if you know about the Gaussian noise parameters, which is only the variance of the noise in your case.
If you want to see an example that removes all the noise, you can add out-of-band noise on to your original signal. That is possible by generating a random sequence by rand() and using a filter to make it bandlimited. For example, filter the generated noise sequence with a 3-10kHz bandpass filter then add to the original audio sequence. Finally, apply the same butter filter in your script to see all the noise is removed.
I need to check the quality of the EEG signal, to see if there is any noise in the signal (e.g. the 50 Hz line noise).
For what I have read so far, a good way to check would be to conduct Single-sided amplitude spectrum analyses both for all electrodes and for single electrodes (e.g. Cz).
I have run the following code:
%Open the file
FileName = 'Data.dat';
fid = fopen(FileName);
if fid < 0, error('Cannot open file'); end
signal = fread(fid, Inf, 'float32');
fclose(fid);
%Set the parameters of the recording
Fs = 1000; % Sampling frequency
T = 1/Fs; % Sample time
L = length(signal); % Length of signal
%Amplitude spectrum analysis
NFFT = 2^(nextpow2(L)-1);
x=zeros(NFFT,1);
x(1:NFFT,1) = signal(1:NFFT,1);
YY = fft(x,NFFT)/L;
ff = Fs/2*linspace(0,1,NFFT/2+1);
%is taking the positive half of the spectrum (NFFT/2 +1 gives this, including 0 and nyquist, hence the +1) and mapping it onto your real frequencies from 'normalised frequency'.
% Plot single-sided amplitude spectrum.
figure; plot(ff,2*abs(YY(1:NFFT/2+1))), title('Single-Sided Amplitude Spectrum of tp'), xlabel('Frequency (Hz)'), ylabel('|Y(f)|');
I am not sure how to plot only one channel (e.g. Cz being channel 28).
(I have 64 channels, with 10-20 IS).
Any suggestion would be very much appreciated.
My project Noise reduction.
1.Here my code input from microphone and save to .wav
Read in the file
clear all;
close all;
mic1= dsp.AudioRecorder;
hmfw = dsp.AudioFileWriter('myspeech.wav','FileFormat','WAV');
disp('Speak into microphone now');
time_end = 10;
tic;
while toc <= time_end
step(hmfw, step(mic1));
end
release(mic1);
release(hmfw);`
disp('Recording complete');
[f,fs] = audioread('C:\Users\Admin\Documents\MATLAB\myspeech.wav');`
before recorded how can i plot a spectrogram graph
time = 10
frequency = 0 - 8000
2.how to plot a spectrogram graphs after of noise reduction between frequency 500 - 2000 Hz
Like this graphs spectrogram and spectrum
Here Link
https://www.google.co.th/search?q=spectrogram+matlab&newwindow=1&rlz=1C1JPGB_enTH637TH637&espv=2&source=lnms&tbm=isch&sa=X&ei=PZliVf3GMcuIuATCroIg&ved=0CAcQ_AUoAQ&biw=1920&bih=979#imgrc=s05zemtY2IFy7M%253A%3BBgWyAcO6UJomJM%3Bhttp%253A%252F%252Fwww.aquaphoenix.com%252Flecture%252Fmatlab10%252Fimages-large%252Fmatlab_audio_funky_plot_spectrogram.jpg%3Bhttp%253A%252F%252Fwww.aquaphoenix.com%252Flecture%252Fmatlab10%252Fpage4.html%3B960%3B768
Here my filter code.
n = 7;
beginFreq = 500 / (fs/2);
endFreq = 2000 / (fs/2);
[b,a] = butter(n, [beginFreq, endFreq], 'bandpass');
thank you.
Try this:
**** The previous part of your code goes here ***
disp('Recording complete');
[y,fs] = audioread('myspeech.wav');
y = y(:,1); % Take only one channel from the recording
n = 7;
beginFreq = 500 / (fs/2);
endFreq = 2000 / (fs/2);
[b,a] = butter(n, [beginFreq, endFreq], 'bandpass');
%
dt = 1/fs;
L = size(y,1); % Length of signal
t = (0:L-1)'*dt; % Time vector
figure(1)
plot(t,y(:,1))
title('Recording')
xlabel('time (milliseconds)')
NFFT = 2^nextpow2(L); % Next power of 2 from length of y
Y = fft(y(:,1),NFFT)/L;
f = fs/2*linspace(0,1,NFFT/2+1);
% Plot spectrum of channel 1 from the original signal
figure()
plot(f,2*abs(Y(1:NFFT/2+1))); hold on
title('Single-Sided Amplitude Spectrum of y(t)')
xlabel('Frequency (Hz)')
ylabel('|Y(f)|')
% Filter the two channels
filt_y = filter(b,a,y);
filt_Y = fft(filt_y,NFFT)/L;
% Plot the filtered spectrum of channel 1 from the original signal
plot(f,2*abs(filt_Y(1:NFFT/2+1)))
title('Single-Sided Amplitude Spectrum of y(t)')
xlabel('Frequency (Hz)')
ylabel('|Y(f)|')
Hi I'm trying to calculate mfcc for which i'm windowing. I have seen this one post I'm getting error in fftOneSide.
my code is
waveFile='test_preEmphasis.wav';
[y, fs]=wavread(waveFile);
n=512;
t=(1:n)'/fs;
startIndex=30418;
endIndex=startIndex+n-1;
original=y(startIndex:endIndex);
windowed=original.*hamming(n);
[mag1, phase1, freq1]=fftOneSide(original, fs);
[mag2, phase2, freq2]=fftOneSide(windowed, fs);
subplot(3,2,1); plot(original); grid on; axis([-inf inf -1 1]);
title('Original signal');
subplot(3,2,2); plot(windowed); grid on; axis([-inf inf -1 1]);
title('Windowedsignal');
subplot(3,2,3); plot(freq1, mag1); grid on;
title('Energy spectrum (linear scale)');
subplot(3,2,4); plot(freq2, mag2); grid on;
title('Energy spectrum (linear scale)');
subplot(3,2,5); plot(freq1, 20*log(mag1)); grid on;
axis([-inf inf -80 120]); title('Energy spectrum (db)');
subplot(3,2,6); plot(freq2, 20*log(mag2)); grid on; axis([-inf inf -80 120]);
title('Energy spectrum (db)');
the error i'm getting is
??? Undefined function or method 'fftOneSide' for input arguments of type 'double'.
any help is appreciated
thanks
This is a really old post, it'd be neat if someone still cared. I just provided what I believe to be the answer in the recent post below, which I arrived at after a fair bit of frustration: Undefined function 'fftOneSide' for input arguments of type 'double'.
It should be noted here there's a call to a file, which I'm not sure if the author had originally or not. I suspect all the problems are related to a similarly named file in the sourcecode.
If you look at my discussion in the other post, within the function definition there is a call to a method demo with a file - which isn't present if you just have the function definition, not the original file. Calling [mag1, phase1, freq1]=fftOneSide(original, fs,1), after you comment out the first line if nargin <1... and the demo routine worked fine on my machine with the code which I'll show below. Having the third argument equal to 1 guarantees that the code will run the print routines, which is important.
In case the other thread is closed, I just want to show the output, when the input is manually defined, and I call [mag1, phase1, freq1]=fftOneSide(original, fs,1) on the properly edited method, with the inputs as in the original post shown below (notice the call is to original in fftOneSide..in the other post it was like this as well.. I believe the call was was meant to be instead for windowed, but I don't have the signals toolbox with hamming anyways):
fs=8000;
t=(1:512)'/fs; %'// <-- prevents string markdown
f=306.396;
original=sin(2*pi*f*t)+0.2*randn(length(t),1);
% windowed=original.*hamming(length(t)); % defined in other post
[mag1,phase1,freq1]=fftOneSide(original,fs); % I call fftOneSide(original,fs,1);
The output is as follows (source code below!)
Anyways, here's the source code in case anyone wants to use this function
function [magSpec, phaseSpec, freq, powerSpecInDb]=fftOneSide(signal, fs, plotOpt)
% fftOneSide: One-sided FFT for real signals
% Usage: [magSpec, phaseSpec, freq, powerSpecInDb]=fftOneSide(signal, fs)
%
% For example:
% [y, fs]=wavread('welcome.wav');
% frameSize=512;
% startIndex=2047;
% signal=y(startIndex:startIndex+frameSize+1);
% signal=signal.*hamming(length(signal));
% plotOpt=1;
% [magSpec, phaseSpec, freq, powerSpecInDb]=fftOneSide(signal, fs, plotOpt);
% Roger Jang, 20060411, 20070506
if nargin<1, selfdemo; return; end %=== (MathBio: Comment this out!)
if nargin<2, fs=1; end
if nargin<3, plotOpt=0; end
N = length(signal); % Signal length
freqStep = fs/N; % Frequency resolution
time = (0:N-1)/fs; % Time vector
z = fft(signal); % Spectrum
freq = freqStep*(0:N/2); % Frequency vector
z = z(1:length(freq)); % One side
z(2:end-1)=2*z(2:end-1); % Assuming N is even, symmetric data is multiplied by 2
magSpec=abs(z); % Magnitude spectrum
phaseSpec=unwrap(angle(z)); % Phase spectrum
powerSpecInDb=20*log(magSpec+realmin); % Power in db
if plotOpt
% ====== Plot time-domain signals
subplot(3,1,1);
plot(time, signal, '.-');
title(sprintf('Input signals (fs=%d)', fs));
xlabel('Time (seconds)'); ylabel('Amplitude'); axis tight
% ====== Plot spectral power
subplot(3,1,2);
plot(freq, powerSpecInDb, '.-'); grid on
title('Power spectrum');
xlabel('Frequency (Hz)'); ylabel('Power (db)'); axis tight
% ====== Plot phase
subplot(3,1,3);
plot(freq, phaseSpec, '.-'); grid on
title('Phase');
xlabel('Frequency (Hz)'); ylabel('Phase (Radian)'); axis tight
end
% ====== Self demo (MathBio: Comment all of this out! )
function selfdemo
[y, fs]=wavread('welcome.wav');
frameSize=512;
startIndex=2047;
signal=y(startIndex:startIndex+frameSize+1);
signal=signal.*hamming(length(signal));
[magSpec, phaseSpec, freq, powerSpecInDb]=feval(mfilename, signal, fs, 1);