2

To convert power spectrum to a log-scaled one, how to define log10(X(k)) if X(k)=0 for some k?

For sake of illustration, I brief my process as follows which is a convention one:

  1. Calculate the magnitude spectrum X(k) of the time-domain signal x(n) by X(k) = abs(fft(x(n))).

  2. Convert the magnitude spectrum or power spectrum to db by 20*log10(X(k)) or 10*log10(X(k)**2), respectively.

My problem arises when there is X(k)=0 when computing log10(X(k)) which is either not defined or -inf. How to deal with this?

Fred
  • 31
  • 2
  • What simulation software you use? – Oliver Aug 03 '15 at 07:18
  • It is the function spectrum from the library called Essentia that I used to calculate the magnitude spectrum. – Fred Aug 03 '15 at 07:22
  • If you want to avoid -inf in your answer, please add a very small value, say 1*e-20, to the zero coefficients. – Oliver Aug 03 '15 at 07:25
  • 1
    Thanks, it seems like a doable solution. But does the literature solve the problem this way? Because taking log of X(k) is essential in the field of signal processing, e.g, MFCC. – Fred Aug 03 '15 at 07:29
  • The literature does not solve the problem this way. BTW, it is not a problem I guess, you just display the log power spectrum with - infinity. May I know for what reason you want to avoid -infinity? – Oliver Aug 03 '15 at 08:00
  • I want to get rid of spectrums with small energy in the spectrogram, usually are the last few frames. To this end, I tend to sum up 10*log10(X(k)) for each frame (spectrum) in the spectrogram and obtain a curve of energy or loudness E(n), where n is the frame index. From which I calculate the standard deviation and set the threshold as 2*std away from mean. That is, frames with loudness E(n_i) = sum(10*log10(X(k))) lower than mean(E(n))-2*std(E(n)) will be removed. So -inf will result in unreasonable threshold value. – Fred Aug 03 '15 at 08:36

1 Answers1

2

Typically, one's data has some sort of noise floor (-96 dB, etc.). So one common way to deal with the FFT bins that are zero (or tiny) is to replace anything below the noise floor with the noise floor level, since any value below that value is most likely not useful data. Doing this before taking the log() function may provide some computational efficiency.

hotpaw2
  • 35,346
  • 9
  • 47
  • 90
  • Thank you. So simply adding 1e-12 to the bins, i.e., log10(X(k)+1e-12) as suggested by @Oliver, is what you meant? – Fred Aug 04 '15 at 05:02
  • Depends. Is 1e-12 around the noise floor of you data? If not, perhaps a much larger value might do. Around -96 dB is closer to 1e-5 ; but it depends on the scaling of your data and FFT as well as the S/N. – hotpaw2 Aug 04 '15 at 05:57
  • rather than replace, i would simply add a small number like $10^{\frac{-120}{10}}$ to the square magnitude or power spectrum. add it to all bins before the $\log()$. – robert bristow-johnson Sep 02 '15 at 20:04