rmaik
rmaik

Reputation: 1086

Is the spectrogram displaying correct values?

I want to know whether the spectrogram posted below is a true representation of the given non-stationary signal.

If it is a true representation, I have a number of questions regarding specific features in the plot...

For 0->.25 on the horizontal axis, why does it show signal components up to the highest frequencies? I assume that, given the first time duration t1, I should only see the frequency of signal x1. Furthermore, given the second time duration t2, I should only see the frequency of signal x2, and so on. But, that is not what i see in the below posted spectrogram.

Could you please explain why we see these features in the spectrogram?

Spectrogram With equations enter image description here

Code:

% Time specifications:
Fs = 8000;                       % samples per second
dt = 1/Fs;                       % seconds per sample
StopTime = 1;                    % seconds
t = (0:dt:StopTime-dt);             % seconds

t1 = (0:dt:.25);
t2 = (.25:dt:.50);
t3 = (.5:dt:.75);
t4 = (.75:dt:1);

 x1 = (10)*sin(2*pi*10*t1);
x2 = (10)*sin(2*pi*20*t2) + x1;
x3 = (10)*sin(2*pi*30*t3) + x2;
x4 = (10)*sin(2*pi*40*t4) + x3;


NFFT = 2 ^ nextpow2(length(t));     % Next power of 2 from length of y
Y    = fft(x4, NFFT);
f    = Fs / 2 * linspace(0, 1, NFFT/2 + 1);
%{
figure;
plot(f(1:200), 2 * abs( Y( 1:200) ) );
%}

 T = 0:.01:1;
 spectrogram(x4,10,9,NFFT);
 ylabel('Frequency');
 axis(get(gcf,'children'), [0, 1, 1, 50]);

Update_1: when i tried the suggested answer, i received the following.

??? Out of memory. Type HELP MEMORY for your options.
Error in ==> spectrogram at 168
y = y(1:length(f),:);
Error in ==> stft_1 at 36
spectrogram(x,10,9,NFFT);

The code used:

% Time specifications:
Fs = 8000;                       % samples per second
dt = 1/Fs;                       % seconds per sample
StopTime = 1;                    % seconds
t = (0:dt:StopTime-dt);             % seconds

%get a full-length example of each signal component
x1 = (10)*sin(2*pi*10*t);
x2 = (10)*sin(2*pi*20*t);
x3 = (10)*sin(2*pi*30*t);
x4 = (10)*sin(2*pi*40*t);

%construct a composite signal
x = zeros(size(t));
I = find((t >= t1(1)) & (t <= t1(end)));
x(I) = x1(I);
I = find((t >= t2(1)) & (t <= t2(end)));
x(I) = x2(I);
I = find((t >= t3(1)) & (t <= t3(end)));
x(I) = x3(I);
I = find((t >= t4(1)) & (t <= t4(end)));
x(I) = x4(I);

NFFT = 2 ^ nextpow2(length(t));     % Next power of 2 from length of y
Y    = fft(x, NFFT);
f    = Fs / 2 * linspace(0, 1, NFFT/2 + 1);
%{
figure;
plot(f(1:200), 2 * abs( Y( 1:200) ) );
 %}

T = 0:.01:1;
spectrogram(x,10,9,NFFT);
ylabel('Frequency');
  axis(get(gcf,'children'), [0, 1, 1, 50]);

Update_2

% Time specifications:
Fs = 8000;                       % samples per second
dt = 1/Fs;                       % seconds per sample
 StopTime = 1;                    % seconds
  t = (0:dt:StopTime-dt);             % seconds
  t1 = ( 0:dt:.25);
  t2 = (.25:dt:.50);
  t3 = (.5:dt:.75);
  t4 = (.75:dt:1);

  %get a  full-length example of each signal component
 x1 = (10)*sin(2*pi*100*t);
 x2 = (10)*sin(2*pi*200*t);
 x3 = (10)*sin(2*pi*300*t);
 x4 = (10)*sin(2*pi*400*t);

 %construct a composite signal
 x = zeros(size(t));
 I = find((t >= t1(1)) & (t <= t1(end)));
 x(I) = x1(I);
 I = find((t >= t2(1)) & (t <= t2(end)));
 x(I) = x2(I);
 I = find((t >= t3(1)) & (t <= t3(end)));
 x(I) = x3(I);
 I = find((t >= t4(1)) & (t <= t4(end)));
 x(I) = x4(I);

 NFFT = 2 ^ nextpow2(length(t));     % Next power of 2 from length of y
 Y    = fft(x, NFFT);
 f    = Fs / 2 * linspace(0, 1, NFFT/2 + 1);
 %{
 figure;
 plot(f(1:200), 2 * abs( Y( 1:200) ) );
 %}

 T = 0:.001:1;
 spectrogram(x,10,9);
 ylabel('Frequency');
 axis(get(gcf,'children'), [0, 1, 1, 100]);

Dpectrogram_2: enter image description here

Upvotes: -1

Views: 435

Answers (1)

chipaudette
chipaudette

Reputation: 1675

I don't think that you are plotting what you think that you are plotting. You should plot the signal in the time domain to ensure that it looks like what you expect...plot(x4). I think that you think that your signal is x1 followed by x2 followed by x3 followed by x4. Based on the Matlab code that you are showing, however, this is not the case.

Instead, your signal is the sum of x1+x2+x3+x4 all on top of each other. As a result, you should be seeing signal components at 10, 20, 30, 40 Hz, along with other components due to the transient start-up of the signals.

To get the signal that you want, you should do something like:

%get a full-length example of each signal component
t = (0:dt:StopTime-dt);
x1 = (10)*sin(2*pi*10*t);
x2 = (10)*sin(2*pi*20*t);
x3 = (10)*sin(2*pi*30*t);
x4 = (10)*sin(2*pi*40*t);

%construct a composite signal from the four signals above
x = zeros(size(t)); %allocate an empty vector of the correct size
I = find((t >= t1(1)) & (t <= t1(end)));
x(I) = x1(I);
I = find((t >= t2(1)) & (t <= t2(end)));
x(I) = x2(I);
I = find((t >= t3(1)) & (t <= t3(end)));
x(I) = x3(I);
I = find((t >= t4(1)) & (t <= t4(end)));
x(I) = x4(I);

Then you can plot your new signal x in the time domain (plot(x)) to ensure that it is what you want. Finally, you can perform your spectrogram.

Note that you will see artifacts in the spectrogram at the transition between each time period (between t1 and t2, between t2 and t3, and then between t3 and t4). The signal artifacts will be reflecting that the signal is complicated during the discontinuous transition between the different signal frequencies.

Upvotes: 1

Related Questions