Математический анализ образца звука (в виде массива чисел) - PullRequest
11 голосов
/ 18 сентября 2008

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

Ответы [ 7 ]

7 голосов
/ 18 сентября 2008

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

Чтобы нормализовать, сначала создайте гистограмму, чтобы подсчитать, сколько вхождений каждого значения от 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 голосов
/ 18 сентября 2008

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

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

3 голосов
/ 18 сентября 2008

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

Редактировать: @ WaveyDavey

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

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

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

2 голосов
/ 18 сентября 2008

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

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 голос
/ 18 сентября 2008

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

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

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

0 голосов
/ 18 сентября 2008

получите анализатор частоты на http://www.relisoft.com/Freeware/index.htm, запустите его и посмотрите на код.

0 голосов
/ 18 сентября 2008

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

...