Нормализовать величину БПФ для имитации WMP - PullRequest
6 голосов
/ 18 марта 2010

Итак, я работаю над небольшим визуализатором для звуковых файлов, просто для удовольствия. В основном я хотел подражать визуализаторам «Scope» и «Ocean Mist» в Windows Media Player. Сфера была достаточно простой, но у меня проблемы с Ocean Mist. Я почти уверен, что это какой-то частотный спектр, но когда я делаю БПФ на своих данных формы волны, я не получаю данные, которые соответствуют тому, что отображает Ocean Mist. Спектр на самом деле выглядит правильно, поэтому я знал, что с FFT все в порядке. Я предполагаю, что визуализатор пропускает спектр через какой-то фильтр, но я понятия не имею, что это может быть. Есть идеи?

EDIT2: Я разместил отредактированную версию своего кода здесь (примечание редактора: ссылка больше не работает). Под редактированием я имею в виду, что я удалил все экспериментальные комментарии везде и оставил только активный код. Я также добавил несколько описательных комментариев. Визуализатор теперь выглядит как this .

EDIT: Вот изображения. Первый - мой визуализатор, второй - Ocean Mist.

my visualizer

ocean mist

Ответы [ 4 ]

6 голосов
/ 18 марта 2010

Вот некоторый код Octave, который показывает, что, по моему мнению, должно произойти.Я надеюсь, что синтаксис не требует пояснений:

%# 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

, что приводит к следующему графику: вверху: обычный спектральный график, внизу: логлогический спектральный график (синий цвет без окон) http://img710.imageshack.us/img710/3994/spectralplots.png

Я позволяю Octave обрабатывать масштабирование от линейных до логических осей x и y.У вас есть что-то похожее для простой формы волны, такой как синусоида?

СТАРЫЙ ОТВЕТ

Я не знаком с упомянутым вами визуализатором, но в целом:

  • Спектры часто отображаются с использованием логарифмической оси y (или цветовой карты для спектрограмм).
  • Возможно, ваше БПФ возвращает двусторонний спектр, но вы, вероятно, хотите использовать толькопервая половина (похоже, что вы уже делаете).
  • Применение оконной функции к вашим данным времени сужает спектральные пики за счет уменьшения утечки (похоже, вы тоже это делаете).
  • Возможно, вам придется разделитьпо размеру блока преобразования, если вас интересуют абсолютные величины (я думаю, это не важно в вашем случае).
  • Похоже, визуализатор Ocean Mist также использует ось журнала X.Это также может быть сглаживание смежных частотных бинов в наборах или что-то в этом роде.
3 голосов
/ 18 марта 2010

Обычно для такого рода вещей вы хотите преобразовать свой выход FFT в спектр мощности, обычно с логарифмической (дБ) шкалой амплитуды, например для заданного выходного лотка:

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

1 голос
/ 18 марта 2010

Кажется, что не только ось y, но и ось x также является логарифмической. Расстояние между пиками, кажется, уменьшается на более высоких частотах.

1 голос
/ 18 марта 2010

Похоже, что ось Y тумана океана является логарифмической.

...