error in using fftoneside - matlab

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);

Related

Applying bandpass in the Fourier for my signal in matlab

I'm trying to apply a bandpass around freq 0 without luck. I'd be happy to receive some help please
x=scan11(1,:)*1e-3/3e8; y=scan11(2,:);
plot(x,y) % my function
[XX,ff]=trans_fourier(y,mean(diff(x)));
plot(ff,abs(XX)) % gives the Fourier transform
I want to choose the freq around 0. let's suppose -1e13 till 1e13 and than to make ifft and to plot the signal after this filer.
How should I start doing this? the command
YY=bandpass(y,[-1e13 1e13],1/mean(diff(x)))
didn't help here unfortunately.
Since, i can't upload here files, here is also my question on matlab forum with all the files
matlab link
I am not sure what the contents of the trans_fourier function exactly are, but in 'plain matlab functions', you could attempt something along the lines of the following.
Nt = 1024; % Number of samples
Fs = 10; % Sampling frequency (samples / second)
t = (0:Nt-1)/Fs; % Time array
x = sin(t/10); % Low-frequency signal
x = x + 0.25*randn(1,Nt); % add some noise
X = fftshift(fft(x)); % FFT of signal with 0 Hz centered
fr = (-Nt/2 : Nt/2-1)/(Nt/Fs); % Frequency axis
% Filter: squared cosine (edit as desired)
fsl = 10; % Length of filter slope, in samples
filt = zeros(size(X));
filt(Nt/2+1+(-fsl:fsl)) = cos( linspace(-pi/2,pi/2,2*fsl+1) ).^2;
x_filt = real(ifft(ifftshift( filt.*X ))); % Filtered x
figure();
subplot(2,2,1); plot(t,x); ax=axis; title('original signal');
subplot(2,2,4); plot(t,x_filt); axis(ax); title('Low-pass filtered signal');
subplot(2,2,2); plot(fr,abs(X)); ax=axis; title('original amplitude spectrum');
subplot(2,2,3); plot(fr,abs(X).*filt); axis(ax); title('Filtered amplitude spectrum');
I am not sure what exactly you meant when you said
let's suppose -1e13 till 1e13
, but keep in mind that extracting a single fourier component (essentially setting all values of the spectrum to zero, except the one you are interested in) acts as a brick-wall filter, and you will get considerable artefacts if you take the inverse transform. Refer to this topic or this page if you're interested.

Do I need to call fftshift before calling fft or ifft?

In the book "Computational Fourier Optics, A Matlab Tutorial" by David Voelz, it is written that a call to fftshift is needed before a call to fft or ifft, but in the MATLAB documentation of fftshift it's only written that this command
rearranges the outputs of fft, fft2, and fftn by moving the zero-frequency component to the center of the array.
There is no mention in documentation that this command should be called before the call to fft, and I saw some examples that call fft without a call to fftshift beforehand.
My question is: Whether or not fftshift needed to be called before a call to fft or ifft?
If fftshift doesn't need to be called before a call to fft, and only after a call to fft, then when should we use (if at all) the command ifftshift with relation to a calculation of the fft of a data set?
The matlab fft only computes half of the frequency spectrum (positive frequencies and the zero frequency if your number of samples is odd) in order to save computation time.
Then, the second half of the frequency spectrum (which is the complex conjugate of the first half) is just added at the end of this vector.
So what you get after a fft is the following vector:
0 1 2 3 ... Fs/2 -Fs/2 ... -3 -2 -1
<----------------> <------------------>
positive freq negative freq
where Fs is the frequency sample.
Now, what fftshift does is just shifting the negative frequency bins (2nd part of the frequency spectrum) at the beginning of your vector so that you can display a nice frequency spectrum starting at -Fs/2 and ending at +Fs/2.
The shifted vector becomes:
-Fs/2 ... -3 -2 -1 0 1 2 3 ... Fs/2
<------------------> <---------------->
negative freq positive freq
So, to answer your question, no you don't need to use fftshift after or before a call to fft or ifft. But if you used a fftshift on your vector, you should undo it by applying an ifftshift or fftshift. (I think both calls are equivalent.)
If you read onwards in the documentation on fftshift:
"It is useful for visualizing a Fourier transform with the zero-frequency component in the middle of the spectrum."
The shift is not necessary to perform the fft, but it is handy to visualise the Fourier transform. Whether to use fftshift or not is thus dependent upon whether you want to visualise your transform or not.
Note that ifftshift is different than fftshift because it shifts the negative back to the positive. Assume a simple 3 bin unit impulse in frequency domain before fftshift
[0, exp(-jw1), exp(-(jw1-pi)=exp(-jw1+pi)];
fftshift gives
[exp(-jw1+pi)], 0, exp(-jw1)];
you can see the discontinuity in phase. If you perform ifftshift, negative freq is shifted back to positive:
[0, exp(-jw1), exp(-jw1+pi)];
whereas, fftshift again gives:
[exp(-jw1), exp(-jw1+pi), 0];
one can see the phase monotonicity is not the same, (aka, fftshift-ifftshift case gives [decrease, increase] and fftshift-fftshift case gives [increase, decrease] in phase).
Given the title of the book you are studying, I assume you are working with images. Then the proper way is to call both fftshift and ifftshift before and after you call [i]fft.
Your code should look like
spectrum = fftshift(fft2(ifftshift(myimage))
It is quite the same when applying the inverse Fourier transform
myimage = fftshift(ifft2(ifftshift(spectrum))
The simple answer is call to fftshift not needed before a call to fft. fftshift does not influence the calculation of Fast fourier transform. fftshift rearranges values inside a matrix. For eg:
cameraman = imread('cameraman.tif');
fftshifted_cameraman = fftshift(cameraman);
subplot(1,2,1); imshow(cameraman); title('Cameraman');
subplot(1,2,2); imshow(fftshifted_cameraman); title('FFTShifted Cameraman');
It depends on what you are going to do with the transformed data. If you don't perform an fftshift before transforming, the fft result will have every other value multiplied by -1. This doesn't matter if you plan to view the magnitude or magnitude squared of the result. However, if you plan to compare adjacent spectral values and phase is important, you'll need to apply fftshift before transforming to avoid the alternating sign.
Here is a MATLAB script I use to test basic sound analysis functions of MATLAB including fftshift() in displaying the output of fft().
if ~exist('inputFile', 'var')
inputFile = 'vibe.wav';
end
[inputBuffer, Fs] = audioread(inputFile);
fileSize = length(inputBuffer);
numSamples = 2.^(ceil(log2(fileSize))); % round up to nearest power of 2
x = zeros(numSamples, 1); % zero pad if necessary
x(1:fileSize) = inputBuffer(:,1); % if multi-channel, use left channel only
clear inputBuffer; % free this memory
clear fileSize;
t = linspace(0, (numSamples-1)/Fs, numSamples)';
f = linspace(-Fs/2, Fs/2 - Fs/numSamples, numSamples)';
X = fft(x);
plot(t, x);
xlabel('time (seconds)');
ylabel('amplitude');
title(['time-domain plot of ' inputFile]);
sound(x, Fs); % play the sound
pause;
% display both positive and negative frequency spectrum
plot(f, real(fftshift(X)));
xlabel('frequency (Hz)');
ylabel('real part');
title(['real part frequency-domain plot of ' inputFile]);
pause;
plot(f, imag(fftshift(X)));
xlabel('frequency (Hz)');
ylabel('imag part');
title(['imag part frequency-domain plot of ' inputFile]);
pause;
plot(f, abs(fftshift(X))); % linear amplitude by linear freq plot
xlabel('frequency (Hz)');
ylabel('amplitude');
title(['abs frequency-domain plot of ' inputFile]);
pause;
plot(f, 20*log10(abs(fftshift(X))+1.0e-10)); % dB by linear freq plot
xlabel('frequency (Hz)');
ylabel('amplitude (dB)');
title(['dB frequency-domain plot of ' inputFile]);
pause;
% display only positive frequency spectrum for log frequency scale
semilogx(f(numSamples/2+2:numSamples), 20*log10(abs(X(2:numSamples/2)))); % dB by log freq plot
xlabel('frequency (Hz), log scale');
ylabel('amplitude (dB)');
title(['dB vs. log freq, frequency-domain plot of ' inputFile]);
pause;
semilogx(f(numSamples/2+2:numSamples), (180/pi)*angle(X(2:numSamples/2))); % phase by log freq plot
xlabel('frequency (Hz), log scale');
ylabel('phase (degrees)');
title(['phase vs. log freq, frequency-domain plot of ' inputFile]);
pause;
%
% this is an alternate method of unwrapping phase
%
% phase = cumsum([angle(X(1)); angle( X(2:numSamples/2) ./ X(1:numSamples/2-1) ) ]);
% semilogx(f(numSamples/2+2:numSamples), phase(2:numSamples/2)); % unwrapped phase by log freq plot
%
semilogx(f(numSamples/2+2:numSamples), unwrap(angle(X(2:numSamples/2)))); % unwrapped phase by log freq plot
xlabel('frequency (Hz), log scale');
ylabel('unwrapped phase (radians)');
title(['unwrapped phase vs. log freq, frequency-domain plot of ' inputFile]);
If you were windowing segments of audio and passing them to the FFT, then you should use fftshift() on the input to the FFT to define the center of the windowed segment as the t=0 point.
[x_input, Fs] = audioread('vibe.wav'); % load time-domain input
N = 2*floor(length(x_input)/2); % make sure N is even
x = x_input(1:N);
t = linspace(-N/2, N/2-1, N); % values of time in units of samples
omega = linspace(-pi, pi*(1-2/N), N); % values of (normalized) angular frequency
X = fftshift( fft( fftshift( x.*hamming(length(x)) ) ) );
[X_max k_max] = max( abs(X) );
figure(1);
plot(t, x, 'g');
figure(2);
plot(omega, abs(X), 'b');
hold on;
plot(omega(k_max), X_max, 'or');
hold off;

maximum peak of an FFT signal

I have a code for a band pass filter process:
clc;
f=2075; % Input frequency
Fs=4*f; % Sampling Frequency
t=0:(1:100)/Fs:0.01;
s=sin(2*pi*f*t);
subplot(2,3,1)
plot(t,s)
grid on;
xlabel('time')
ylabel('magnitude')
fp1=2070; % Low Cut
fp2=2080; % High Cut
w1=(fp1)/(Fs); % normalization
w2=(fp2)/(Fs); % normalization
%Bandpass Filter Function
[b,a] = butter(8, w1, 'low'); % lowpass filter
y1 = filtfilt(b, a, s);
[b,a] = butter(8, w2, 'high'); % highpass filter
y2 = filtfilt(b, a, y1);
subplot (2,3,2);
plot(y2);
grid on;
xlabel('time')
ylabel('magnitude')
% Input Frequency Spectrum
S1=fft(s,512);
w=(0:255)/256*(Fs/2);
subplot(2,3,4)
plot(w,abs(S1(1:256)))
grid on;
xlabel('frequency')
ylabel('magnitude')
% Out of Band pass filter spectrum
S2=fft(y2,512);
w=(0:255)/256*(Fs/2);
subplot(2,3,5)
plot(w,abs(S2(1:256)))
grid on;
xlabel('frequency')
ylabel('magnitude') `
Here are my questions:
Is the code of the program that I created is correct
What command line should I add to look for the maximum frequency of the bandpass filter spectrum results
I thank you for your help!
Best Regards

create subplot with loop

i have following question and please help me to solve following task:
i want to create subplot in matlab which depend on loop variable,for example as i know to crate plot menu 2X2,we are doing like this
subplot(2,2,1)
subplot(2,2,2)
subplot(2,2,3)
subplot(2,2,4)
but can i do linear form?like 1:100?or something like this ,more generally like this
n=100;
for i=1:n
subplot(1,n,i)
?
thanks very much
EDITED CODE
function [order]=find_order(y,fs);
order=0;
n=length(y);
n1=nextpow2(n);
ndft=2^n1;
for i=1:floor(n/2)
[Pxx,f]=pburg(y,i,ndft,fs);
subplot(ndft,ndft,i);
plot(f,Pxx);
title(['order',num2str(i),'i']);
order=i;
end
end
picture :
i can't understand what happens
1-D Demo
Code
%%// Data
t = 0:0.01:15*pi;
y1 = sin(t);
%%// Plot
figure,
for k=1:4
subplot(4,1,k)
plot(t((k-1)*1000+1:k*1000),y1((k-1)*1000+1:k*1000))
xlim([0 40])
end
Output
2-D Demo
Code
%%// Data
t = 0:0.01:15*pi;
y1 = sin(t);
%%// Plot
colors=['r' 'g' ; 'y' 'k'];
figure,
for k1=1:2
for k2=1:2
subplot(2,2,(k1-1)*2+k2)
plot(t,y1,colors(k1,k2));
end
end
Output
Hopefully these demos would guide to you something meaningful for your case.
Yes, it is:
n=5;
for i=1:n
subplot(1,n,i)
end
gives
for pat=1: N % main loop
% Define the sublot grid
s1=3; % subplot rows
s2=3; % subplot columns
% find the figure number
fig_num=floor(pat/(s1*s2))+1 % Figure number
% Find the subplot number
sub_fig=mod(pat,s1*s2) % subplot number
% correct for corners
if(sub_fig==0)
sub_fig=s1*s2;
fig_num=fig_num-1;
end
% plot something
figure(fig_num);
subplot(s1,s2,sub_fig) ;
plot(1,1) % plot something
end % of main loop

Reconstructing time series from FFT in MATLAB

I am trying to reconstruct the sunspots signal from the FFT, the time series and periodogram are in the following site http://www.mathworks.com/help/matlab/examples/using-fft.html . I wrote the following code but the result were not similar to original wave:
YY=Y(1:floor(n/2))
% magnitude
mag_fft = 2*abs(YY)/length(Y);
% phase angle
ang_fft = angle(YY);
[new_mag,new_i]=sort(mag_fft,'descend');
new_ang=ang_fft(new_i);
new_freq=freq(new_i)
wave=zeros(1,length(YY));
wave=new_mag(1);
t=1:length(YY)
for(i=1:70)
wave=wave+new_mag(i).*sin(2*pi*new_freq(i)*t+new_ang(i));
end
wave=wave-mag_fft(1)
figure;plot(year(t),wave,'-b')
hold on;plot(year(t),relNums(t),'-r')
any ideas?
%http://www.mathworks.com/help/matlab/examples/using-fft.html
% sunspots
% sunspots have period of 10 years
%%
clc;clear all;close all;
load sunspot.dat
year=sunspot(:,1);
relNums=sunspot(:,2);
figure;plot(year,relNums)
title('Sunspot Data')
plot(year(1:50),relNums(1:50),'b.-');
yfft = fft(relNums);%figure;plot(ifft(yfft)-data1d,'r')
%yfft = fft(data1d); iyfft=ifft(yfft);
[sum(relNums) yfft(1)]
yfft(1)=[]; % we grid rid of the first value as it corresponeding to zero frequency.
N=length(yfft)+1;
yfft=yfft.*2./N;
%%
power_fft = abs(yfft);power1_fft = sqrt(yfft.*conj(yfft));
figure;plot(power_fft,'-b');hold on;plot(power_fft,'rO')
ang_fft = angle(yfft);real_fft= real(yfft);imag_fft= imag(yfft);
figure;plot(real_fft);hold on;plot(imag_fft,'-r')
figure;plot(angle(yfft))
ph = (180/pi)*unwrap(ang_fft); % phase in degrees
% Now the total length of the per and all other powers should be N-1 because there is no
% more corresponding poweres and phases, and the number of frequencies before the nequiest is
Nneq=length(N./(1:N/2));
Nm1=N-1; per=N./(1:Nm1); freq=1./per;
[per'/12 power_fft(1:Nm1)/100 ] % so as to display the period in years
%% ytyt
ndat=length(relNums);
x=0:ndat-1;
sumharmony1(1:Nneq,1:ndat)=0;
sumharmony2(1:Nneq,1:ndat)=0;
for i=1:Nneq
% those two forms are equal, the last one is called the cos form.
% sumharmony1(i,:)=sumharmony1(i,:)+real_fft(i)*cos(2*pi*x/(per(i)))- imag_fft(i)*sin(2*pi*x/(per(i)));
sumharmony1(i,:)=sumharmony1(i,:)+power_fft(i)*cos(2*pi*x./(per(i))+ang_fft(i));
end
y1 =sum(relNums)/N+ sum(sumharmony1);
%y2 =sum(tmp)/N+ sum(sumharmony2);
figure;plot(relNums);hold on; plot( y1, 'r');
figure;plot((relNums-y1')) % However, the excellent results, we couldnot yet reach to the that of the built in function ifft.
figure;plot(relNums(1:100),'-ob');hold on; plot( y1(1:100), 'r');
% note that we multiply by 2 because of using the window hanning.enter code here