VB FFT - застряло в понимании связи результатов с частотой

StackOverflow https://stackoverflow.com/questions/138558

Вопрос

Пытаюсь понять процедуру БПФ (быстрого преобразования Фурье), которую я использую (ворую) (перерабатываю)

Входные данные представляют собой массив из 512 точек данных, которые представляют собой образец сигнала.В этот массив генерируются тестовые данные.fft преобразует этот массив в частотную область.Пытаюсь понять взаимосвязь между частотой, периодом, частотой дискретизации и положением в массиве FFT.Проиллюстрирую примерами:

========================================

Частота дискретизации составляет 1000 выборок/с.Сгенерируйте набор выборок на уровне 10 Гц.

Входной массив имеет пиковые значения в arr(28), arr(128), arr(228)...период = 100 точек выборки

пиковое значение в массиве fft имеет индекс 6 (исключая огромное значение в 0)

========================================

Скорость дискретизации составляет 8000 образцов/с. Создание набора образцов при 440 Гц

Пиковые значения входного массива включают arr(7), arr(25), arr(43), arr(61)...период = 18 точек выборки

пиковое значение в массиве fft имеет индекс 29 (исключая огромное значение 0)

========================================

Как связать индекс пика в массиве БПФ с частотой?

Это было полезно?

Решение

Если вы проигнорируете мнимую часть, распределение частот будет линейным по интервалам:

Частота@i = (Частота выборки/2)*(i/Nbins).

Итак, для вашего первого примера, если у вас 256 ячеек, самый большой бин соответствует частоте 1000/2 * 6/256 = 11,7 Гц.Поскольку ваш ввод составлял 10 Гц, я предполагаю, что ячейка 5 (9,7 Гц) также имела большую составляющую.Чтобы добиться большей точности, вам нужно взять больше проб и получить меньшие интервалы.

Ваш второй пример дает 8000/2*29/256 = 453 Гц.Опять же близко, но нужно больше мусорных баков.Ваше разрешение здесь всего 4000/256 = 15,6Гц.

Другие советы

Было бы полезно, если бы вы предоставили образец набора данных.

Я предполагаю, что у вас есть так называемые артефакты выборки.Сильный сигнал на постоянном токе (частота 0) предполагает, что это так.

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

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

Суть в том, что выполнение анализа БПФ требует большей осторожности, чем простое использование найденной где-то процедуры БПФ.

Вот первые 100 точек выборки сигнала частотой 10 Гц, как описано в вопросе, обработанные во избежание артефактов выборки.

> sinx[1:100]
  [1]  0.000000e+00  6.279052e-02  1.253332e-01  1.873813e-01  2.486899e-01  3.090170e-01  3.681246e-01  4.257793e-01  4.817537e-01  5.358268e-01
 [11]  5.877853e-01  6.374240e-01  6.845471e-01  7.289686e-01  7.705132e-01  8.090170e-01  8.443279e-01  8.763067e-01  9.048271e-01  9.297765e-01
 [21]  9.510565e-01  9.685832e-01  9.822873e-01  9.921147e-01  9.980267e-01  1.000000e+00  9.980267e-01  9.921147e-01  9.822873e-01  9.685832e-01
 [31]  9.510565e-01  9.297765e-01  9.048271e-01  8.763067e-01  8.443279e-01  8.090170e-01  7.705132e-01  7.289686e-01  6.845471e-01  6.374240e-01
 [41]  5.877853e-01  5.358268e-01  4.817537e-01  4.257793e-01  3.681246e-01  3.090170e-01  2.486899e-01  1.873813e-01  1.253332e-01  6.279052e-02
 [51] -2.542075e-15 -6.279052e-02 -1.253332e-01 -1.873813e-01 -2.486899e-01 -3.090170e-01 -3.681246e-01 -4.257793e-01 -4.817537e-01 -5.358268e-01
 [61] -5.877853e-01 -6.374240e-01 -6.845471e-01 -7.289686e-01 -7.705132e-01 -8.090170e-01 -8.443279e-01 -8.763067e-01 -9.048271e-01 -9.297765e-01
 [71] -9.510565e-01 -9.685832e-01 -9.822873e-01 -9.921147e-01 -9.980267e-01 -1.000000e+00 -9.980267e-01 -9.921147e-01 -9.822873e-01 -9.685832e-01
 [81] -9.510565e-01 -9.297765e-01 -9.048271e-01 -8.763067e-01 -8.443279e-01 -8.090170e-01 -7.705132e-01 -7.289686e-01 -6.845471e-01 -6.374240e-01
 [91] -5.877853e-01 -5.358268e-01 -4.817537e-01 -4.257793e-01 -3.681246e-01 -3.090170e-01 -2.486899e-01 -1.873813e-01 -1.253332e-01 -6.279052e-02

А вот результирующие абсолютные значения частотной области БПФ

 [1] 7.160038e-13 1.008741e-01 2.080408e-01 3.291725e-01 4.753899e-01 6.653660e-01 9.352601e-01 1.368212e+00 2.211653e+00 4.691243e+00 5.001674e+02
[12] 5.293086e+00 2.742218e+00 1.891330e+00 1.462830e+00 1.203175e+00 1.028079e+00 9.014559e-01 8.052577e-01 7.294489e-01

Я тоже немного подзабыл о математике и обработке сигналов, но с дополнительной информацией я могу попробовать.

Если вы хотите узнать энергию сигнала на элемент, вам нужна величина комплексного выходного сигнала.Поэтому просто посмотреть на реальный результат недостаточно.Даже если на входе только действительные числа.Для каждого интервала выходная величина равна sqrt(real^2 + imag^2), как и у Пифагора :-)

ячейки от 0 до 449 — это положительные частоты от 0 до 500 Гц.элементы от 500 до 1000 представляют собой отрицательные частоты и должны совпадать с положительными для реального сигнала.Если вы обрабатываете один буфер каждую секунду, частоты и индексы массива хорошо совпадают.Таким образом, пик с индексом 6 соответствует частоте 6 Гц, что немного странно.Это может быть связано с тем, что вы смотрите только на реальные выходные данные, а реальные и мнимые данные объединяются, чтобы дать ожидаемый пик с индексом 10.Частоты должны линейно отображаться в ячейки.

Пики на уровне 0 указывают на смещение постоянного тока.

Прошло некоторое время с тех пор, как я занимался БПФ, но вот что я помню

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

Я не очень понимаю, что ты делаешь.В первом примере вы говорите, что обрабатываете буферы выборки с частотой 10 Гц для частоты дискретизации 1000 Гц?Таким образом, у вас должно быть 10 буферов в секунду по 100 выборок в каждом.Я не понимаю, как ваш входной массив может иметь длину не менее 228 образцов.

Обычно первая половина выходного буфера представляет собой элементы разрешения по частоте от 0 частоты (= смещение постоянного тока) до 1/2 частоты дискретизации.а вторая половина – отрицательные частоты.если ваш вход представляет собой только реальные данные с 0 для мнимого сигнала, положительные и отрицательные частоты одинаковы.Отношение реального/мнимого сигнала на выходе содержит информацию о фазе входного сигнала.

Частота для элемента i равна i * (частота выборки / n), где n — количество выборок во входном окне БПФ.

Если вы обрабатываете звук, поскольку высота тона пропорциональна логарифму частоты, разрешение высоты тона увеличивается вместе с частотой - трудно точно разрешить низкочастотные сигналы.Для этого вам необходимо использовать большие окна БПФ, что снижает временное разрешение.Для данной частоты дискретизации существует компромисс между частотой и временным разрешением.

Вы упоминаете бин с большим значением в 0 - это бин с частотой 0, т.е.компонент постоянного тока.Если это большое значение, то, вероятно, ваши значения в целом положительны.Элемент n/2 (в вашем случае 256) — это частота Найквиста, половина частоты дискретизации, которая является самой высокой частотой, которую можно разрешить в дискретизированном сигнале с этой частотой.

Если сигнал действительный, то элементы разрешения от n/2+1 до n-1 будут содержать комплексно-сопряженные элементы элементов от n/2-1 до 1 соответственно.Значение постоянного тока появляется только один раз.

Выборки, как говорили другие, равномерно распределены в частотной области (не логарифмически).

Например 1, вы должны получить это:

альтернативный текст http://home.comcast.net/~kootsoop/images/SINE1.jpg

Для другого примера вы должны получить

альтернативный текст http://home.comcast.net/~kootsoop/images/SINE2.jpg

Таким образом, оба ваших ответа кажутся правильными относительно местоположения пика.

Чего я не получаю, так это большого компонента постоянного тока.Вы уверены, что генерируете синусоидальную волну в качестве входного сигнала?Вход становится отрицательным?Для синусоидальной волны постоянный ток должен быть близок к нулю, если у вас достаточно циклов.

Еще один путь — создать Алгоритм Герцеля центральной частоты каждой ноты, которую вы ищете.

Как только вы получите работающую реализацию алгоритма, вы можете сделать ее такой, чтобы для установки центральной частоты требовались параметры.При этом вы можете легко запустить 88 из них или что-нибудь еще в коллекции и отсканировать пиковое значение.

Алгоритм Герцеля по сути представляет собой БПФ с одним интервалом.Используя этот метод, вы можете размещать ячейки логарифмически в соответствии с естественным расположением музыкальных нот.

Немного псевдокода из Википедии:

s_prev = 0
s_prev2 = 0
coeff = 2*cos(2*PI*normalized_frequency);
for each sample, x[n],
  s = x[n] + coeff*s_prev - s_prev2;
  s_prev2 = s_prev;
  s_prev = s;
end
power = s_prev2*s_prev2 + s_prev*s_prev - coeff*s_prev2*s_prev;

Две переменные, представляющие две предыдущие выборки, сохраняются для следующей итерации.Затем это можно использовать в потоковом приложении.Я думаю, что, возможно, расчет мощности также должен быть внутри цикла.(Однако в статье Wiki это не изображено как таковое.)

В случае обнаружения тона будет 88 различных коэффициентов, 88 пар предыдущих выборок, что приведет к 88 выборкам выходной мощности, указывающим относительный уровень в этом частотном элементе.

ВэйвиДэйви говорит, что он записывает звук с микрофона через аудиоаппаратуру своего компьютера, НО его результаты не имеют нулевого центра.Это похоже на проблему с оборудованием.Он ДОЛЖЕН БЫТЬ с нулевым центром.

Когда в комнате тихо, поток значений, поступающий от звукового API, должен иметь амплитуду, очень близкую к 0, с небольшими вариациями +- для окружающего шума.Если в комнате присутствует вибрирующий звук (например,фортепиано, флейта, голос) поток данных должен представлять собой синусоидальную волну, которая имеет как положительные, так и отрицательные значения и имеет среднее значение, близкое к нулю.Если это не так, значит, в системе что-то не так!

-Рик

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top