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