Масштабирование вывода БПФ (MATLAB)

Я делаю некоторые преобразования Фурье аудио (.wav) данных с помощью команды FFT в MATLAB. Входные значения - числа от -1,0 до 1,0.

Насколько я понимаю, после получения абсолютного значения (модуля) выходного сигнала БПФ я должен получить значения, которые имеют единицы амплитуды, но фактические значения порядка тысяч. Это не имеет смысла, поскольку теоретически я должен суммировать компоненты Фурье, чтобы вернуть исходный сигнал. Я чувствую, что результат также должен быть между 0 и 1, так что здесь? Я предполагаю, что алгоритм БПФ раздувает его, но я не уверен, какое значение использовать для его уменьшения.


person Marc Langer    schedule 09.09.2015    source источник


Ответы (2)


БПФ - это алгоритм вычисления дискретного преобразования Фурье (ДПФ). обратный ДПФ (IDFT) имеет 1 / N коэффициент масштабирования в его определении. Возможно, именно это вас смущает. Из Википедии:

  • ДПФ (от конечной последовательности x до коэффициентов Фурье X):

    введите описание изображения здесь

  • IDFT (от X до x):

    введите описание изображения здесь

Итак, просто примените ifft к результату fft, и вы получите исходный результат. Например:

>> x = linspace(-1,1,5)
x =
   -1.0000   -0.5000         0    0.5000    1.0000

>> y = fft(x)
y =
        0            -1.2500 + 1.7205i  -1.2500 + 0.4061i  -1.2500 - 0.4061i  -1.2500 - 1.7205i

>> abs(y)
ans =
         0    2.1266    1.3143    1.3143    2.1266 %// note values greater than 1

>> ifft(y)
ans =
   -1.0000   -0.5000    0.0000    0.5000    1.0000

Фактически, IDFT можно выразить в терминах DFT, применяя комплексное сопряжение и приведенный коэффициент масштабирования. Обозначая ДПФ через F, IDFT как F -1 и комплексное сопряжение через *,

введите описание изображения здесь

В приведенном выше примере

>> 1/numel(y) * conj(fft(conj(y)))
ans =
   -1.0000   -0.5000    0.0000    0.5000    1.0000
person Luis Mendo    schedule 09.09.2015
comment
Конечно, альтернативное (и одинаково действительное) определение имеет sqrt(1/N) член как в DFT, так и в IDFT, что, вероятно, дает результаты, которых ожидает OP. - person Ben Voigt; 10.09.2015
comment
@BenVoigt Хорошее замечание. Но 1-масштабирование для DFT и 1 / N-масштабирование для IDFT - наиболее распространенное определение, по крайней мере, по моему опыту. - person Luis Mendo; 10.09.2015
comment
Думаю, я понимаю, что есть искажение шкалы из-за суммирования по n для каждого X_k, но есть ли способ восстановить правильное масштабирование? То есть, если бы вход был чем-то вроде прямоугольной волны, при аналитическом анализе выходы были бы нечетными гармониками с - person Marc Langer; 10.09.2015
comment
** Извините, что комментарий был опубликован до того, как он был закончен: - person Marc Langer; 10.09.2015
comment
я имел в виду следующее: я думаю, что понимаю, что есть искажение шкалы из-за суммирования по n для каждого X_k (поправьте меня, если это неверно), но есть ли способ восстановить значимое масштабирование? то есть пропорция, в которой каждый компонент Фурье вносит вклад в сигнал? Если F.T. были выполнены аналитически, и на входе была прямоугольная волна, на выходе - нечетные гармоники с коэффициентами (1 / n) (может быть, я тоже об этом жму?), и ни один из этих коэффициентов не превысит исходную амплитуду функции. Итак, как я могу восстановить это в ДПФ? - person Marc Langer; 10.09.2015
comment
Чтобы синтезировать сигнал из его гармоник, вы используете IDFT (функция ifft). Посмотрите на определение IDFT: оно содержит масштабный коэффициент 1 / N. Итак, если вы хотите получить синусоиды, которые при суммировании воспроизводят сигнал, вам необходимо масштабировать выходной сигнал fft на 1/numel(x). (Но тогда вы не можете просто применить ifft к этому; вам нужно будет либо умножить обратно на numel(x), либо вычислить сумму синусоид вручную без коэффициента масштабирования IDFT) - person Luis Mendo; 10.09.2015
comment
@Luis Вам просто нужно разделить результаты БПФ на количество входных отсчетов. - person Heinz M.; 11.09.2015
comment
@HeinzM. Это то, что я сказал в своем предыдущем комментарии (жирным шрифтом)! Масштабировать вывод fft на 1/numel(x) - person Luis Mendo; 11.09.2015
comment
Привет всем, похоже, это помогает. Я провел тест на синусоиде с амплитудой 1, и максимальное значение на выходе fft было 0,5. Есть ли причина, по которой правильный коэффициент масштабирования может быть 2 / numel (x) ?? - person Marc Langer; 11.09.2015
comment
Да, есть. Обратите внимание, что у вас есть два коэффициента со значением (приблизительно) 0,5 в fft. Это потому, что sin(t) = (exp(1j*t)-exp(-1j*t))/2j. Таким образом, sin - это сумма двух экспонент с положительной и отрицательной частотами, каждая с половинной амплитудой. То же самое происходит с cos(t) или вообще с sin(t+phi); изменяется только фаза экспонент. Конечно, в ДПФ отрицательные частоты появляются в верхней половине частотного интервала, потому что спектр периодический. - person Luis Mendo; 11.09.2015

В Matlab используйте следующий код для масштабирования от 1 до (примерно) 0.

dataDFT=abs(fft(data)); % Take the complex magnitude of the fft of your data
dataDFTScaled=dataDFT/max(dataDFT); % Divide by the maximum value

Вы не хотите, чтобы он масштабировался до нуля, потому что это сделало бы невозможным просмотр на графике журнала.

person Adjwilley    schedule 14.09.2015