This morning i was experimenting with GNU Octave. I created several signals(Sine, Saw tooth, square wave and noise). After this i used the periodogram. in the periodogram the square wave weren't showed.
I tried a test file from where the square wave is broken.

enter image description here

A = 1;
f = 2;
T = 2;
fs = 512;

if isOctave = exist('OCTAVE_VERSION', 'builtin') ~= 0;
    pkg load signal
    clear isOctave;

t = 0:1/fs:T-1/fs ;
sine = A * sin(2*pi*f*t);
sq =  A * square(2*pi*f*t);
F = 0:(fs/(T*fs)):fs/2;
SINE = fft(sine);SINE = abs(SINE(1,1:(T*fs)/2+1));
SQ = fft(sq); SQ = abs(SQ(1,1:(T*fs)/2+1));

subplot(2,1,1); plot(t,sine, t,sq); 
legend('Sine', 'Square','Location','northoutside','Orientation','horizontal')
subplot(2,1,2); plot( F, 20*log10(1/(length(SINE))*SINE), F,20*log10(1/(length(SQ))* SQ));

periodogram(sine,[],length(sine),fs,'power'); hold all

What i found out is that till the fft everything works as suspected.
But when i take the log of the square wave. the result disappears.

My question is why does this happening?

  1. what cause this problem.
  2. Happens this also in Matlab or python.
  3. What solution fix this problem?

Your array SQ has many zero-valued elements:

SQ =
 Columns 1 through 6:
     0.00000     0.00000     0.00000     0.00000   651.91501     0.00000
 Columns 7 through 12:
     0.00000     0.00000     0.00000     0.00000     0.00000     0.00000

Taking the logarithm gives a minus infinity for the zeros:

octave> 20*log10(1/(length(SQ))*SQ)
ans =
 Columns 1 through 8:
      -Inf      -Inf      -Inf      -Inf    2.0815      -Inf      -Inf      -Inf
 Columns 9 through 16:
      -Inf      -Inf      -Inf      -Inf   -7.4592      -Inf      -Inf      -Inf

You can clamp those values to some more reasonable limit using max, which does the right thing handling minus infinities (unlike plot):

octave> max(20*log10(1/(length(SQ))*SQ), -120)
ans =
 Columns 1 through 7:
  -120.0000  -120.0000  -120.0000  -120.0000     2.0815  -120.0000  -120.0000
 Columns 8 through 14:
  -120.0000  -120.0000  -120.0000  -120.0000  -120.0000    -7.4592  -120.0000


plot( F, 20*log10(1/(length(SINE))*SINE), F, max(20*log10(1/(length(SQ))*SQ), -120));

Spectrum of sine and square wave

You can do the same thing with the sine wave, which by luck had a spectral floor of numerical error. With audio, you rarely care about things more quiet than -120 dB.

| improve this answer | |

The library function log of zero results in a NaN (not a real number, -inf). So the log of a square with a base of zero can't be plotted.

| improve this answer | |

I don't know what you mean by "disappears". Your only 'log' command has been commented out, so no 'log' operation is executed.

I tried to run your code in Matlab. Everything was fine until the 'periodogram()' commands. Matlab did not recognize those commands as you have typed them. Taking a wild guess here, I wonder if your Octave 'periodogram()' command merely computes a frequency-domain sequence of numbers, but it does not perform any plotting. Your:

subplot(2,1,2); plot( F, 20*log10(1/(length(SINE))*SINE), F,20*log10(1/(length(SQ))* SQ),F,1/(length(SQ))* SQ);

command is strange. You seem to be plotting two logarithmic curves and one linear curve in the same window. Is that what you want? Try the following log plotting (it worked for me in Matlab):

subplot(2,1,2); plot(F,20*log10(1/(length(SQ))* SQ), '-bo');
| improve this answer | |
  • $\begingroup$ I see when plotting only one curve in both in subplot(2,1,2) and in the periodogram(). I added the question: I added a picture with what showed on my screen and i deleted some test code (I was playing around with what works and what was broken...) $\endgroup$ – Jan-Bert Dec 30 '15 at 14:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.