Нормализуйте величину FFT для подражания WMP

Так, я работал над небольшим visualizer для звуковых файлов, только для забавы. Я в основном хотел подражать "Объему" и "Океанскому Туману" visualizers в Windows Media Player. Объем был достаточно легок, но у меня есть проблемы с Океанским Туманом. Я вполне уверен, что это - некоторый спектр частот, но когда я делаю FFT на своих данных формы сигнала, я не получаю данные, которые соответствуют тому, что отображает Океанский Туман. Спектр на самом деле выглядит корректным, таким образом, я знал, что не было ничего неправильно с FFT. Я предполагаю, что visualizer выполняет спектр через некоторый фильтр, но я понятия не имею, каково это могло бы быть. Какие-либо идеи?

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

Править: Вот изображения. Первым является мой visualizer, и вторым является Океанский Туман.

my visualizer

ocean mist

6
задан Glorfindel 3 July 2019 в 14:24
поделиться

4 ответа

Вот некоторый код 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. Возможно, он также сглаживает соседние частотные бины в наборах или что-то в этом роде.
6
ответ дан 9 December 2019 в 22:32
поделиться

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

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

3
ответ дан 9 December 2019 в 22:32
поделиться

Определенно похоже, что ось Y океанского тумана логарифмический.

1
ответ дан 9 December 2019 в 22:32
поделиться

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

1
ответ дан 9 December 2019 в 22:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: