Normalize FFT magnitude to imitate WMP

孤街浪徒 提交于 2019-11-29 09:41:42

问题


So, I've been working on a little visualizer for sound files, just for fun. I basically wanted to imitate the "Scope" and "Ocean Mist" visualizers in Windows Media Player. Scope was easy enough, but I'm having problems with Ocean Mist. I'm pretty sure that it is some kind of frequency spectrum, but when I do an FFT on my waveform data, I'm not getting the data that corresponds to what Ocean Mist displays. The spectrum actually looks correct, so I knew there was nothing wrong with the FFT. I'm assuming that the visualizer runs the spectrum through some kind of filter, but I have no idea what it might be. Any ideas?

EDIT2: I posted an edited version of my code here (editor's note: link doesn't work anymore). By edited, I mean that I removed all the experimental comments everywhere, and left only the active code. I also added some descriptive comments. The visualizer now looks like this.

EDIT: Here are images. The first is my visualizer, and the second is Ocean Mist.


回答1:


Here's some Octave code that shows what I think should happen. I hope the syntax is self-explanatory:

%# First generate some test data
%# make a time domain waveform of sin + low level noise
N = 1024;
x = sin(2*pi*200.5*((0:1:(N-1))')/N) + 0.01*randn(N,1);

%# Now do the processing the way the visualizer should
%# first apply Hann window = 0.5*(1+cos)
xw = x.*hann(N, 'periodic');
%# Calculate FFT.  Octave returns double sided spectrum
Sw = fft(xw);
%# Calculate the magnitude of the first half of the spectrum
Sw = abs(Sw(1:(1+N/2))); %# abs is sqrt(real^2 + imag^2)

%# For comparison, also calculate the unwindowed spectrum
Sx = fft(x)
Sx = abs(Sx(1:(1+N/2)));

subplot(2,1,1);
plot([Sx Sw]); %# linear axes, blue is unwindowed version
subplot(2,1,2);
loglog([Sx Sw]); %# both axes logarithmic

which results in the following graph: top: regular spectral plot, bottom: loglog spectral plot (blue is unwindowed) http://img710.imageshack.us/img710/3994/spectralplots.png

I'm letting Octave handle the scaling from linear to log x and y axes. Do you get something similar for a simple waveform like a sine wave?

OLD ANSWER

I'm not familiar with the visualizer you mention, but in general:

  • Spectra are often displayed using a log y-axis (or colormap for spectrograms).
  • Your FFT might be returning a double-sided spectrum, but you probably want to use only the first half (looks like you're doing already).
  • Applying a window function to your time data makes the spectral peaks narrower by reducing leakage (looks like you're doing this too).
  • You might need to divide by the transform blocksize if you're concerned with absolute magnitudes (I guess not important in your case).
  • It looks like the Ocean Mist visualizer is using a log x-axis too. It might also be smoothing adjacent frequency bins in sets or something.



回答2:


Normally for this kind of thing you want to convert your FFT output to a power spectrum, usually with a log (dB) amplitude scale, e.g. for a given output bin:

p = 10.0 * log10 (re * re + im * im);




回答3:


It definitely looks like the ocean mist Y-Axis is logarithmic.




回答4:


It seems to that not only the y axis, but the x axis also is logarithmic. The distance between peaks seems to lower at higher frequencies.



来源:https://stackoverflow.com/questions/2466196/normalize-fft-magnitude-to-imitate-wmp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!