Related
I am developing a 1v peak-to-peak sine wave with a 60hz frequency. I am doing this in order to ground truth certain methods of measuring sound. I am running into trouble in using and plotting various methods for developing a PSD. I have code below. Running this plots a fine sine wave and the RMS value of the data is .71 (good!). I expect to see a PSD plot with 1v energy at 60hz and no energy outside that band. I'm not getting that and am not sure why. For reference, I am a biologist - this is all Greek to me but I'm trying my best. Code:
Fs = 32000; % samples per second
dt = 1/Fs; % seconds per sample
StopTime = .5; % seconds
t = (0:dt:StopTime-dt)'; % seconds
%%Sine wave:
Fc = 60; % hertz
x = cos(2*pi*Fc*t);
% Plot the signal versus time:
figure;
plot(t,x);
xlabel('time (in seconds)');
title('Signal versus Time');
NFFT = 8192; %
NOVERLAP = round(0.75*NFFT);
w = hanning(NFFT);
[sensor_spectrum, freq] = pwelch(x,w,NOVERLAP,NFFT,fs);
figure;
plot (freq, sensor_spectrum );
I have a matlab code to Frequency modulation and demodulation a signal. My code is work well for modulation part. My message signal is m and modulated signal is u, code plot the message signal and its integral in one graph for plotting 1.
Then signal modulated with carrier and program plots the modulated signal in time domain for plotting 2.
After that, by the help of some code blocks program find the frequency spectrum of modulated signal and message signal to plot graph of them for plotting 3.
In demodulation part program make some fundamental calculation for FM detection, then to obtain message signal it uses filter.
Last part program plots the graph of recovered signal with message signal to compare them.
I summarized all code because ı do not know whre is the problem.
My problem about plotting 3 when I make zoom graph 3 I see some phase foldings or like it.Graph is not symmetric according to y-axis.
I did not solve this problem, I research about them and I decided to use unwrap(). Although I tried a lot, I could not be successful. How can I get rid of this phase folding with unwrap() function. Thank you.
My matlab code is ;
ts = 0.0001;% Sampling interval
t0 = 0.15; % Duration
t = 0:ts:t0;% define time vector
%% OTHER PARAMETERS
fc = 200; % Carrier signal frequency
kf =50; % Frequency deviation constant
fs = 1/ts; % Sampling frequency
%% MESSAGE SIGNAL SIMPLY
m = 1*(t<t0/3)-2*(t<2*t0/3).*(t>=t0/3);
%% Integration of m
int_m(1) = 0;
for k =1:length(m)-1
int_m(k+1) = int_m(k) + m(k)*ts;
end
%% PLOTTING 1
figure; subplot(211); % Message signal
plot(t,m);grid on;xlabel('time');ylabel('Amplitude');
title('m(t)');ylim([-3 2]);
subplot(212);plot(t,int_m);% Integral of message signal
grid on; xlabel('time');ylabel('Amplitude');title('integral of m(t)');
ylim([-0.07 0.07]);
%% FM MODULATED SIGNAL
u = cos(2*pi*fc*t + 2*pi*kf*int_m);
%% PLOTTING 2
figure; plot(t,u); % Modulated signal in time domain
grid on;xlabel('time');
ylabel('Amplitude');title('FM :u(t)');
ylim([-1.2 1.2]);
%% FINDING FREQUENCY SPECTRUM AND PLOTTING 3
% Frequency spectrum of m(t)
f=linspace(-1/(2*ts),1/(2*ts),length(t));
M=fftshift(fft(m))./length(t); % Taking fourier transform for m(t)
U=fftshift(fft(u))./length(t); % Taking fourier transform for u(t)
figure;subplot(211); % Frequence spectrum of m(t)
plot(f,abs(M)); grid;
xlabel('Frequency in Hz');xlim([-500 500]);
ylabel('Amplitude');title('Double sided Magnitude spectrum of m(t)');
subplot(212);plot(f,abs(U)); % Frequency spectrum of u(t)
grid;xlabel('Frequency in Hz');xlim([-500 500]);
ylabel('Amplitude');title('Double sided Magnitude spectrum of u(t)');
%% DEMODULATION (Using Differentiator)
dem = diff(u);
dem = [0,dem];
rect_dem = abs(dem);
%% Filtering out High Frequencies
N = 80; % Order of Filter
Wn = 1.e-2; % Pass Band Edge Frequency.
a = fir1(N,Wn);% Return Numerator of Low Pass FIR filter
b = 1; % Denominator of Low Pass FIR Filter
rec = filter(a,b,rect_dem);
%% Finding frequency Response of Signals
fl = length(t);
fl = 2^ceil(log2(fl));
f = (-fl/2:fl/2-1)/(fl*1.e-4);
mF = fftshift(fft(m,fl)); % Frequency Response of Message Signal
fmF = fftshift(fft(u,fl)); % Frequency Response of FM Signal
rect_demF = fftshift(fft(rect_dem,fl));% Frequency Response of Rectified FM Signal
recF = fftshift(fft(rec,fl)); % Frequency Response of Recovered Message Signal
%% PLOTTING 4
figure;subplot(211);plot(t,m);grid on;
xlabel('time');ylabel('Amplitude');
title('m(t)');ylim([-3 2]);
subplot(212);plot(t,rec);
title('Recovered Signal');xlabel('{\it t} (sec)');
ylabel('m(t)');grid;
My problem is in this third graph to show well I put big picture
k = -(length(X)-1)/2:1:length(X)/2;
Your k is not symmetric.
If you work with symmetric k is it working fine?
Hello I want to calculate realtime FFT plot of my input. With the following code i create a record and calculation. The point is that the calculation is takes to much time to get i nice plot update.
Fs = 44100; % sampling frequency in Hz
T = 1/5; % length of one interval signal in sec
t = 0:1/Fs:T-1/Fs; % time vector
nfft = 2^nextpow2(Fs); % n-point DFT
f = (0:nfft/2)'*Fs/nfft; % Frequency vector
%# prepare plots
figure
hrec(1) = subplot(211);
tplot(1) = plot(t, nan(size(t)), 'Color','b', 'Parent',hrec(1));
xlabel('Time [s]'), ylabel('Amplitude')
hrec(2) = subplot(212);
spec(2) = semilogx(f,nan(size(f)),'Color','b', 'Parent',hrec(2));
xlabel('Frequency [Hz]'), ylabel('Magnitude [dB]'), %XScale('log');
set(hrec, 'Box','on', 'XGrid','on', 'YGrid','on');set(hrec(2), 'XScale','log', 'Xlim',[20 20000]);
% specgram(sig, nfft, Fs);
% prepare audio recording
recObj = audiorecorder(Fs,16,1,0);
% Record
disp('Start Recording...')
for i=1:20
recordblocking(recObj, T);
%# get data and compute FFT
sig = getaudiodata(recObj);
fftMag = 20*log10( abs(fft(sig,nfft)) ); fftMag = fftMag(1:ceil((nfft+1)/2));
% update plots
set(tplot(1),'YData',sig);
set(spec(2), 'YData', fftMag);
title(hrec(1), num2str(i,'Interval = %d'))
drawnow % force MATLAB to flush any queued displays
end
disp('Done.')
So I create a parallel computed calculation:
% Record for 10 intervals of 1sec each
disp('Start speaking...')
for i =1:20
parfor ii=1:2
if ii == 1
recordblocking(recObj, T);
elseif ii == 2
%# get data and compute FFT
sig = getaudiodata(recObj);
fftMag = 20*log10( abs(fft(sig,nfft)) ); fftMag = fftMag(1:ceil((nfft+1)/2));recordblocking(recObj, T);
% update plots
set(tplot(1),'YData',sig);
set(spec(2), 'YData', fftMag);
title(hrec(1), num2str(i,'Interval = %d'))
drawnow %# force MATLAB to flush any queued displays
end
end
end
disp('Done.')
i get now Errors:
Error using audiorecorder/getaudiodata (line 742) Recorder is empty.
Error in parallel_function (line 466)
F(base, limit);
Error in par_plotupdate (line 25) parfor ii=1:2
How do I fix this, because i don't get this error when i don't use the parallel for loop. The last error comes i think from lack of information the first iteration. So i get an a-synchronized loop? or do i make it to difficult…
Thanks
Here is a implementation using asynchron recording. This way recording the audio data runs in the background and the execution of the code is only paused when no data is available. With nearly 100% of the cpu time available to process the data, it came out that processing was possible faster than real-time. This is why I did not use the parallel computing toolbox to further speed-up the process.
Fs = 44100; % sampling frequency in Hz
T = 1/5; % length of one interval signal in sec
t = 0:1/Fs:T-1/Fs; % time vector
nfft = 2^nextpow2(Fs); % n-point DFT
f = (0:nfft/2)'*Fs/nfft; % Frequency vector
%# prepare plots
figure
hrec(1) = subplot(211);
tplot(1) = plot(t, nan(size(t)), 'Color','b', 'Parent',hrec(1));
xlabel('Time [s]'), ylabel('Amplitude')
hrec(2) = subplot(212);
spec(2) = semilogx(f,nan(size(f)),'Color','b', 'Parent',hrec(2));
xlabel('Frequency [Hz]'), ylabel('Magnitude [dB]'), %XScale('log');
set(hrec, 'Box','on', 'XGrid','on', 'YGrid','on');set(hrec(2), 'XScale','log', 'Xlim',[20 20000]);
% specgram(sig, nfft, Fs);
% prepare audio recording
recObj = audiorecorder(Fs,16,1,0);
N=20;
% Record
disp('Start Recording...')
%set up one continuous recording for all N loops. Each loop processes T seconds of data
recObj.record(N*T);
%avoid empty recorder;
pause(.1);
for idx=1:N
%we are continuously recording and this iteration of the loop should process the data from startindex to endindex
startindex=1+(idx-1)*Fs*T;
endindex=(idx)*Fs*T;
audioData=recObj.getaudiodata();
%if not enough data is available, wait.
while size(audioData,1)<endindex
%amount of missing data can be caluclated, wait that time
pause((endindex-size(audioData,1))/Fs);
audioData=recObj.getaudiodata();
end
fprintf('processing index %d to %d\n',startindex,endindex);
%# get data and compute FFT
sig =audioData(startindex:endindex,:);
%If you want to use parallel computing, submit the next line to a worker (http://www.mathworks.com/help/distcomp/createtask.html). Keep in mind that workers can not update your UI, you have to get the results back from the workers.
fftMag = 20*log10( abs(fft(sig,nfft)) ); fftMag = fftMag(1:ceil((nfft+1)/2));
% update plots
set(tplot(1),'YData',sig);
set(spec(2), 'YData', fftMag);
title(hrec(1), num2str(idx,'Interval = %d'))
drawnow % force MATLAB to flush any queued displays
end
disp('Done.')
I'm using the pwelch method in matlab to compute the power spectra for some wind speed measurements. So, far I have written the following code as an example:
t = 10800; % number of seconds in 3 hours
t = 1:t; % generate time vector
fs = 1; % sampling frequency (seconds)
A = 2; % amplitude
P = 1000; % period (seconds), the time it takes for the signal to repeat itself
f1 = 1/P; % number of cycles per second (i.e. how often the signal repeats itself every second).
y = A*sin(2*pi*f1*t); % signal
fh = figure(1);
set(fh,'color','white','Units', 'Inches', 'Position', [0,0,6,6],...
'PaperUnits', 'Inches', 'PaperSize', [6,6]);
[pxx, f] = pwelch(y,[],[],[],fs);
loglog(f,10*(pxx),'k','linewidth',1.2);
xlabel('log10(cycles per s)');
ylabel('Spectral Density (dB Hz^{-1})');
I cannot include the plot as I do not have enough reputation points
Does this make sense? I'm struggling with the idea of having noise at the right side of the plot. The signal which was decomposed was a sine wave with no noise, where does this noise come from? Does the fact that the values on the yaxis are negative suggest that those frequencies are negligible? Also, what would be the best way to write the units on the y axis if the wind speed is measured in m/s, can this be converted to something more meaningful for environmental scientists?
Your results are fine. dB can be confusing.
A linear plot will get a good view,
Fs = 1000; % Sampling frequency
T = 1/Fs; % Sample time
L = 1000; % Length of signal
t = (0:L-1)*T; % Time vector
y = sin(2 * pi * 50 * t); % 50Hz signal
An fft approach,
NFFT = 2^nextpow2(L); % Next power of 2 from length of y
Y = fft(y,NFFT)/L;
f = Fs/2*linspace(0,1,NFFT/2+1);
subplot(1,2,1);
plot(f,2*abs(Y(1:NFFT/2+1)))
xlabel('Frequency (Hz)')
ylabel('|Y(f)|')
pwelch approach,
subplot(1,2,2);
[pxx, freq] = pwelch(y,[],[],[],Fs);
plot(freq,10*(pxx),'k','linewidth',1.2);
xlabel('Frequency (Hz)');
ylabel('Spectral Density (Hz^{-1})');
As you can see they both have peak at 50Hz.
Using loglog for both,
So "noise" is of 1e-6 and exists in fft as well, and can be ignored.
For your second question, I don't think the axis will change it will be frequency again. For Fs you should use the sampling frequency of wind speed, like if you have 10 samples of speed in one second your Fs is 10. Higher frequencies in your graph means more changes in wind speed and lower frequencies represent less changes for the speed.
I have an audio file , which represent the sound of a motor running at 2500rpm my aim is to get the period of this signal, so I can automaticlly tell what is the motor speed is. To do that I take a part of the signal and run get it autocorrelation , hopping that this willl tell the period of the singal! but I just don't get it :
here is a part of my code :
clear;
clc;
[x0,Fs] = audioread('_2500.wav');
x= x0(1:2000,1);
xc = xcorr(x);
clf;
subplot(3,1,1);
plot(x);
subplot(3,1,2);
plot(xc);
[peaks,locs] = findpeaks(xc);
hold on
subplot(3,1,3)
plot(xc(locs),'ro');
and here are the plot :
and how should I consider the sampling frequency, which is : 44100 ?
You can use the autocorrelation or FFT of the signal to find where is the maximum:
% Parameters
Fc = 1e1;
Fs = 1e3;
% Signal
t = 0:1/Fs:1;
x = sin(2*pi*Fc*t);
% FFT
Y = abs(fft(x));
[~,I] = max(Y(1:floor(end/2)));
% Frequency and period
F = I-1;
T = 1/F;
% Plot
figure;
subplot(2,1,1); plot(t,x);
subplot(2,1,2); plot(Y);
disp(['The frequency is ',mat2str(F),'Hz, and the period is ',mat2str(T),'sec.']);
This and this post are related.
To go from your auto-correlation function xc to an estimate of the fundamental frequency, do:
fs = 44100; % Unit: Hz
xc = xc((length(xc) - 1) / 2 + 1: end); % Get the half on the positive time axis.
[~, pidx] = findpeaks(xc);
period = (pidx(1) - 1) / fs;
F0 = 1 / period; % Estimated fundamental frequency.
Note that there are other potentially more robust fundamental frequency / pitch estimation algorithms. Doing a google scholar search on "fundamental frequency estimation" or "pitch estimation" will lead you to some good reviews.
you find all peaks using "findpeaks" funciton, now compute the difference between each peak
P=diff(locs)
your period can be :
max(P)
The peiod of 250hz sine at 22050 sample rate, is about 88, the Frequency of your signal is equivalent at the Period if you do (Fs/Period) == Frequency
If you Know the frequency of your signal you can find the period just do Fs/Frequency