Автокорреляция возвращает случайные результаты с микрофонным входом (используя фильтр верхних частот) - PullRequest
1 голос
/ 30 августа 2009

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

Я пытаюсь определить тональность пения пользователей. Проблема в том, что он возвращает случайные результаты. У меня есть код из http://code.google.com/p/yaalp/, который я преобразовал в C ++ и изменил (ниже). Моя частота дискретизации 2048, а размер данных 1024. Я определяю высоту как синусоидальной волны, так и микрофонного входа. Частота синусоидальной волны равна 726,0, и она обнаруживает 722,950820 (что вполне нормально), но она определяет тональность микрофона как случайное число от 100 до 1050.

Сейчас я использую фильтр верхних частот для удаления смещения постоянного тока, но он не работает. Я делаю это правильно, и если да, что еще я могу сделать, чтобы это исправить? Любая помощь будет принята с благодарностью!

(фиксированный)

Спасибо

Найл.

Редактировать: Изменен код для реализации фильтра верхних частот с частотой среза 30 Гц (из Что такое фильтры верхних и нижних частот? , кто-нибудь может подсказать, как преобразовать фильтр нижних частот? фильтровать, используя свертку к высокочастотному?), но он все еще возвращает случайные результаты. Подключить его к хосту VST и использовать плагины VST для сравнения спектров, к сожалению, для меня не вариант.

Редактировать: Исправлено, спасибо за помощь всем, но я так и не заработал, теперь использую новый код.

Ответы [ 4 ]

2 голосов
/ 30 августа 2009

Я не эксперт по звуку, но если вы используете сэмплирование с 44100 (я думаю, сэмплов в секунду) и используете 1024 точки данных. Вы работаете с данными на 1/40 секунды. Меня не удивляет, что текущая высота звука сильно варьируется в зависимости от того, какую часть вы выберете Если вы хотите определить среднюю или основную высоту голоса, я ожидаю, что вам потребуется около 1 секунды данных.

1 голос
/ 30 августа 2009

При частоте дискретизации 44,1 кГц, 1024 выборки - это данные с чуть более 23 мсек. Разве не возможно, что этих данных просто недостаточно, чтобы вычислить высоту человеческого певца?

Я имею в виду, что звук, который я могу издавать и который длится 23 мс, вероятно, не является чем-то, над чем у меня много контроля высоты тона; Я ожидаю, что этот вид измерения будет выполняться в течение чуть более длительных периодов времени.

1 голос
/ 30 августа 2009

Проблема в вашей функции findBestCandidates ():

Внутри этой функции вы получаете доступ к массиву входов от 0 до длины - 1. Когда вы вызываете эту функцию внутри функции receivePitchCalculation (), «входы» - это «результаты», а «длина» - это «nHiPeriodInSamples». Но «результаты» только распределяются и заполняются до «nHiPeriodInSamples - nLowPeriodInSamples - 1». Поэтому, если nLowPeriodInSamples больше 0, вы получаете доступ к нераспределенной и случайной памяти внутри функции findBestCandidates ()!

EDIT:

Другая ошибка заключается в том, что вы заполняете каждую запись 'nResolution' массива 'results' в функции detePitchCalculation (), но получаете доступ к каждой записи в функции findBestCandidates () (через аргумент 'input'). Но, так как вы вызываете detectPitchCalculation () с 'nResolution = 1', это не объясняет вашу конкретную проблему ... поэтому я посмотрю немного больше. Но это определенно будет проблемой, если вы называете это с более высоким разрешением.

0 голосов
/ 30 августа 2009

Я не вижу проблемы в вашем коде, но я не очень хорош в C. Но я бы попробовал следующее, чтобы найти проблему:

  • запустить с данными, где результат известен, например с грехом (х) в качестве ввода
  • запустить его с небольшим размером данных (например, 2)

Сравните результаты с известными правильными. Вы должны быть в состоянии найти их в Интернете или сделать это вручную.

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

...