Математический анализ звуковой выборки (как массив чисел)

Мне нужно найти частоту образца, сохраненную (в vb) как массив байтов. Образец - синусоидальная волна, известная частота, поэтому я могу проверить), но цифры немного странные, а моя математика-foo слаба. Полный диапазон значений 0-255. 99% номеров находятся в диапазоне от 235 до 245, но есть некоторые выбросы до 0 и 1 и до 255 в оставшихся 1%. Как нормализовать это, чтобы удалить выбросы, (вычисляя интервал 235-245, поскольку это может измениться с разными выборками), и как я тогда вычисляю нулевые пересечения, чтобы получить частоту? Извините, если это описание мусор!

Ответ 1

БПФ, вероятно, лучший ответ, но если вы действительно хотите сделать это с помощью своего метода, попробуйте следующее:

Чтобы нормализовать, сначала сделайте гистограмму, чтобы подсчитать, сколько разностей каждого значения от 0 до 255. Затем выкиньте X процентов значений из каждого конца с чем-то вроде:

for (i=lower=0;i< N*(X/100); lower++)
  i+=count[lower];
//repeat in other direction for upper

Теперь нормализуем с помощью

A[i] = 255*(A[i]-lower)/(upper-lower)-128

Выбросьте результаты вне диапазона -128..127.

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

Ответ 2

Стандартный метод для атаки на эту проблему состоит в том, чтобы рассмотреть один блок данных, мы надеемся, по крайней мере, в два раза больше фактической частоты (получение большего количества данных не так уж и плохо, поэтому полезно немного переоценить), затем возьмите FFT и предположим, что частота соответствует наибольшему числу в результирующем спектре FFT.

Кстати, здесь очень часто задавались очень похожие проблемы - вы могли бы также искать ответы.

Ответ 3

Используйте преобразование Фурье, оно намного больше, нечувствительное к шуму, чем подсчет пересечений нуля

Изменить: @WaveyDavey

Я нашел библиотеку F # для выполнения FFT: Отсюда

Как оказалось, лучший бесплатный реализация, которую я нашел для F # пользователи до сих пор остаются фантастическими Библиотека FFTW. На их сайте есть предварительно скомпилированная Windows DLL. Я написал минимальные привязки, которые позволяют потокобезопасный доступ к FFTW от F #, как с гуру, так и с простыми интерфейсами. Производительность отличная, 32-битная Windows XP Pro составляет до 35% медленнее, чем 64-разрядный Linux.

Теперь я уверен, что вы можете вызывать F # lib из VB.net, С# и т.д., которые должны быть в своих документах

Ответ 4

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

x[n] = A*sin(f*n + phi) + B + N[n]

где N [n] - это "глючный" шум, от которого вы хотите избавиться.

Если глюки имеют длину в один образец, вы можете удалить их с помощью медианного фильтра, который должен быть больше, чем длина глюка. По обе стороны от глюка. Глюки длины 1, означают, что у вас будет достаточно медиана из 3 образцов длины.

y[n] = median3(x[n])

Медиана вычисляется так: возьмем образцы x, которые вы хотите фильтровать (x [n-1], x [n], x [n + 1]), сортируйте их, а ваш результат является средним.

Теперь, когда шумовой сигнал отключен, избавьтесь от постоянного сигнала. Я понимаю, что буфер имеет ограниченную и известную длину, поэтому вы можете просто вычислить среднее значение всего буфера. Substract it.

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

Ответ 5

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

Используя Fityk, вы можете загрузить данные и поместиться в a*sin(b*x-c), где 2*pi/b даст вам частоту после фитинг.

Fityk может использоваться из gui, из командной строки для сценариев и имеет С++ API, поэтому может быть включен в ваши программы напрямую.

Ответ 6

Я googled для "основного fft". Visual Basic FFT Ваш вопрос кричит FFT, но будьте осторожны, используя FFT, даже не понимая, что DSP может привести к результатам, которые вы не делаете понять или не знать, откуда они пришли.