Мне нужно найти частоту выборки, хранящуюся (в vb) в виде массива байтов. Образец представляет собой синусоиду, известная частота, поэтому я могу проверить), но числа немного странные, а мои математические способности слабы. Полный диапазон значений 0-255. 99% чисел находятся в диапазоне от 235 до 245, но есть некоторые выбросы до 0 и 1 и до 255 в оставшемся 1%. Как мне нормализовать это, чтобы удалить выбросы (вычисление интервала 235-245, поскольку он может меняться для разных выборок), и как мне затем вычислить пересечение нуля, чтобы получить частоту? Извините, если это описание является мусором!
Математический анализ звукового образца (в виде массива чисел)
Ответы (7)
7
БПФ, вероятно, лучший ответ, но если вы действительно хотите сделать это своим методом, попробуйте следующее:
Чтобы нормализовать, сначала сделайте гистограмму, чтобы подсчитать, сколько вхождений каждого значения от 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.
Теперь вы можете считать нулевые пересечения. Чтобы убедиться, что вас не обманывает шум, вы можете отслеживать наклон в нескольких последних точках и подсчитывать пересечения только тогда, когда средний уклон идет в правильном направлении.
5
Стандартный метод решения этой проблемы состоит в том, чтобы рассмотреть один блок данных, желательно, по крайней мере, в два раза превышающий фактическую частоту (брать больше данных неплохо, так что лучше немного переоценить), а затем взять БПФ и предположить, что частота соответствует наибольшему числу в результирующем спектре БПФ.
Кстати, очень похожие проблемы уже задавались здесь раньше - вы можете поискать и эти ответы.
3
Используйте преобразование Фурье, оно гораздо менее чувствительно к шуму, чем подсчет пересечений нуля.
Изменить: @WaveyDavey
Я нашел библиотеку F# для выполнения БПФ: отсюда
Как оказалось, лучшей бесплатной реализацией, которую я нашел для пользователей F#, по-прежнему является фантастическая библиотека FFTW. На их сайте есть предварительно скомпилированная Windows DLL. Я написал минимальные привязки, которые обеспечивают потокобезопасный доступ к FFTW из F# как с гуру, так и с простыми интерфейсами. Производительность отличная, 32-битная Windows XP Pro всего на 35% медленнее, чем 64-битная Linux.
Теперь я уверен, что вы можете вызвать библиотеку F# из VB.net, C# и т. д., которая должна быть в их документах.
2
Если я правильно понял из вашего описания, то у вас есть сигнал, представляющий собой комбинацию синуса плюс константа плюс некоторые случайные глюки. Скажи, как
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]), отсортируйте их, и ваш результат будет средним.
Теперь, когда шумовой сигнал отсутствует, избавьтесь от постоянного сигнала. Я понимаю, что буфер имеет ограниченную и известную длину, поэтому вы можете просто вычислить среднее значение всего буфера. Вычтите это.
Теперь у вас есть единственный синусовый сигнал. Теперь вы можете вычислить основную частоту, подсчитав пересечение нуля. Подсчитайте количество выборок выше 0, в которых предыдущая выборка была ниже 0. Период - это общее количество выборок вашего буфера, деленное на это, а частота - это противоположность (1/x) периода.
1
Хотя я бы согласился с большинством и сказал, что кажется, что вам нужно решение fft (алгоритм fft довольно быстр), если fft не является ответом по какой-либо причине, вы можете попытаться подогнать синусоиду к данным, используя программа подгонки и считывание подобранной частоты.
Используя Fityk, вы можете загрузить данные и подогнать их к a*sin(b*x-c), где 2*pi/b даст вам Частота после установки.
Fityk можно использовать из графического интерфейса, из командной строки для сценариев и имеет C++ API, поэтому его можно напрямую включать в ваши программы.
0
Я погуглил «базовый ффт». Visual Basic FFT Ваш вопрос кричит о БПФ, но будьте осторожны, используя БПФ, не понимая даже немного о DSP может привести к результатам, которые вы не понимаете или не знаете, откуда они берутся.
0
загрузите анализатор частоты по адресу http://www.relisoft.com/Freeware/index.htm и запустите его и посмотрите на код.