Как масштабировать вывод FFT волнового файла?

Волновой файл: 44100 Гц, 16 бит, двухканальный.

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

Кто-нибудь может мне помочь?


person cobazet    schedule 12.07.2011    source источник
comment
Много дубликатов - см., например. Анализ спектра звука с использованием алгоритма FFT в Java   -  person Paul R    schedule 12.07.2011
comment
Метод масштабирования по ссылке выше преобразуется только в db. Потому что я не знаю максимальное значение сложного вывода после использования алгоритма БПФ. Я просто знаю только максимальное значение вывода одного экземпляра, но каждые N мс у меня есть другой вывод. Помоги мне, пожалуйста !   -  person cobazet    schedule 12.07.2011
comment
Я не могу рассчитать все выходные данные и найти их максимальное значение, это слишком сложно.   -  person cobazet    schedule 12.07.2011


Ответы (2)


Что ж; есть несколько способов сделать это...

например: если вам нужна шкала дБ, для каждой воображаемой выборки вычислите

ymag = (x.real^2 + x.imag^2)

вам нужно будет пройти только половину массива, потому что вам нужны положительные частоты; вторая половина будет просто повторением первой с реальными данными, подаваемыми на БПФ.

искать среди полученных значений минимальное и максимальное значения и сохранять их. если ваше минимальное значение равно нулю, выберите какое-то очень маленькое значение, которое будет вашим минимумом. (0,000001 или что-то в этом роде). затем установите минимальное значение дБ как mindB = 10 * log10 (минимум).

теперь первое возвращаемое значение (sample[0]) будет вашим постоянным смещением, которое вы, вероятно, захотите установить равным нулю.

затем для каждого образца вычислите: ydB = 10 * log10 (ymag / максимум).

это должно дать вам массив, который представляет собой дБ вниз от максимума каждого бина выборки. вы можете масштабировать это до того, что вам нужно; если ваша область графика изменяется от y = 5 до y = 200, вы можете использовать что-то вроде:

yscaled = ((ydB / -mindB) * (200 - 5) + 200)

я также хотел бы убедиться, что масштабированное значение соответствует границам в случае ошибки округления FP.

масштаб y = мин (макс (масштаб y, 5), 200)

это было давно, так что я извиняюсь, если есть какие-либо математические ошибки. :)

person shelleybutterfly    schedule 12.07.2011
comment
@cobazet я видел ваши комментарии выше; Я думаю, это дает вам то, что вы хотите. Насколько я помню, он приближается к шкале от -inf дБ до 0 дБ ... если это не сработает для вас, дайте мне знать, и я изучу это дальше. - person shelleybutterfly; 12.07.2011
comment
да, это действительно то, что я хочу. Но у меня проблема: мои данные настолько велики, что мне не хватает памяти для их хранения, поэтому я не могу найти максимум или минимум для применения вышеуказанной формулы. Я думаю, что у него фиксированный минимум или максимум, тогда моя работа более проста. - person cobazet; 12.07.2011
comment
вам нужно найти только минимум и максимум всего, что вы только что БПФ, а не весь набор данных, в этом случае. (другими словами: если вы использовали БПФ с 32768 точками, вы найдете только максимум из 16384 точек, с которыми вы работаете...) - person shelleybutterfly; 12.07.2011
comment
хотя, да, если необходимо иметь опорное значение 0 дБ, которое представляет 0 дБ абсолютного максимума всех БПФ в реальном времени для всего фрагмента данных, тогда вам нужно знать эту точку заранее. если вам это нужно, вашим единственным выбором будет заранее выбрать значение для использования в качестве максимального, возможно, в результате экспериментов и поиска подходящего значения. вы также можете выбрать фактическое максимально возможное значение, которое будет связано с максимально возможным значением ваших входных данных, но, вероятно, это оставит много дополнительного места вверху... - person shelleybutterfly; 12.07.2011
comment
если min ~ 0 => db результат будет ‹ 0. Если я выберу min = 0,00001 или 0,0000001, mindb слишком отличается (-50 и -60). Должен ли я добавить к нему 1, затем db › 0 ? - person cobazet; 12.07.2011
comment
нет; результат должен быть ‹ 0; он вычисляет дБ вниз от самого высокого уровня мощности, поэтому все будет меньше или равно нулю; вот почему масштабирование использует -mindB... также я нашел несколько заметок о том, что я использовал, и мы, по-видимому, использовали 0,000000001. - person shelleybutterfly; 12.07.2011
comment
Итак, в примере, который я привел с вашей областью графика, имеющей значение от y = 5 до y = 200, вы должны получить 5 в масштабированном значении при нашей попытке приближения к отрицательной бесконечности дБ, и вы должны получить 200 для масштабированного значения, которое представляет 0 дБ . (я мог где-то масштабировать что-то неправильно, но это идея.) - person shelleybutterfly; 12.07.2011

Различные реализации БПФ имеют разные масштабные коэффициенты, которые могут отличаться на N, 1/N или 1/sqrt(N), где N — длина БПФ. По крайней мере, для одного вида целочисленного входного FFT со знаком максимальный масштаб составляет около sqrt (2) * N * 2 ^ (b - 1), где b - количество битов слева от десятичной точки (16 в вашем случае, может быть 17, если вы суммируете каналы в более крупный тип данных перед БПФ).

person hotpaw2    schedule 13.07.2011