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

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

  •  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 и запустите его и посмотрите код.

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