Модифицированный алгоритм Герцеля

Heavy
Сообщения: 17
Зарегистрирован: 20 янв 2016, 16:12

Re: Модифицированный алгоритм Герцеля

Сообщение Heavy »

Такой вопрос:
Если необходимо детектировать 8 частот, которые приходят в случайном порядке ( DTMF передача данных), то при успешном детектировании одной из частот (когда модуль искомой частоты перевалит за порог), следует обнулять I и Q ? Верно ли я понимаю?

И еще: если на входе алгоритма присутствует шум, или просто звук, который не содержит искомой компоненты, то модуль растет со временем. Допустим, я ставлю порог равным 5000. Из-за шума модуль постепенно доползет до 5000 за несколько секунд, и произойдет ложное детектирование, хотя искомый сигнал так и не пришел. Что в этом случае необходимо делать? Есть мысль обнулять I и Q с определенной периодичностью, но тогда теряется смысл SDFT. Есть мысль резать шум, то есть принимать все семплы, которые ниже определенного уровня, равными нулю. Но это как-то слишком топорно.

Аватара пользователя
Бахурин Сергей
Администратор
Сообщения: 1114
Зарегистрирован: 05 окт 2010, 19:55
Контактная информация:

Re: Модифицированный алгоритм Герцеля

Сообщение Бахурин Сергей »

Вероятно, что у вас просто ошибка. Модуль не должен расти со временем.

Аватара пользователя
Santik
Сообщения: 609
Зарегистрирован: 28 дек 2010, 08:04
Откуда: Мирный (Якутия)
Контактная информация:

Re: Модифицированный алгоритм Герцеля

Сообщение Santik »

Heavy писал(а): ...И еще: если на входе алгоритма присутствует шум, или просто звук, который не содержит искомой компоненты, то модуль растет со временем.
Может на этот эффект Вам намекали здесь?
http://electronix.ru/forum/index.php?sh ... 33098&st=0

Heavy
Сообщения: 17
Зарегистрирован: 20 янв 2016, 16:12

Re: Модифицированный алгоритм Герцеля

Сообщение Heavy »

Бахурин Сергей писал(а): Вероятно, что у вас просто ошибка. Модуль не должен расти со временем.
Хм. Взял реализацию, предложенную вами несколько сообщений назад. В ней ошибки вроде нет.
Единственное что заменил, так это инициализацию массива ADC[]:

Код: Выделить всё

#define N 147		//размер окна
#define K 294		//кол-во семплов всего
for (int i =0; i<K; i++)
{
//вторая половина 294 семплов (от 147 до 293) равна постоянному уровню 100
    if ((i/147)%2)	
    {
        ADC[i]=100;
    }
    else
    {
 //первая половина (от 0 до 146) равна искомой частоте со сдвигом фазы.
       ADC[i] = (unsigned char) 100*sin((c*i + M_PI/5))+100; 
    }
}
От 0 семпла до 147 семпла идет рост модуля, и на 147 семпле я ловлю искомую частоту. Пусть на 17000гц есть растекание спектра (17000 на 300 не делится). Как мне кажется, это не важно.
После 147 семпла (номер 146) идут нули. Ровно 147 семплов, до 294 семпла (293 номер). Модуль растет все равно. Даже если обнулить I и Q, все равно растет из-за наличия искомой частоты на 147 семплов назад.
То есть рост модуля происходит за счет:

Код: Выделить всё

u = I[0] + ADC[n] - ((n>=N) ? ADC[n-N] : 0.0);
А именно за счет ADC[n-N] .
Получается, что надо еще 147 семплов не посылать в буфер искомую частоту. То есть , как я понял , получается примерно так:
[0..146] = sin(2pi*17000t) => рост модуля, на номере 146 модуль максимален
[147..293] = 100 => рост модуля продолжается за счет предыдущих 147 семплов. Можно словить ложное детектирование
[294..440] = роста нет, все предыдущие 147 семплов равны нулю.
Последний раз редактировалось Heavy 03 мар 2016, 18:36, всего редактировалось 1 раз.

Heavy
Сообщения: 17
Зарегистрирован: 20 янв 2016, 16:12

Re: Модифицированный алгоритм Герцеля

Сообщение Heavy »

Santik писал(а):
Heavy писал(а): ...И еще: если на входе алгоритма присутствует шум, или просто звук, который не содержит искомой компоненты, то модуль растет со временем.
Может на этот эффект Вам намекали здесь?
http://electronix.ru/forum/index.php?sh ... 33098&st=0
Нет, там на счет округления намекали. С этим можно бороться. У Лайонса написано как. Но это добавляет еще кучу вычислительных операций. Тестирую алгоритм на QT и на STM32F103VET. На QT буфер генерю программно, на STM буфер шлю через звуковую карту, звук генерю тоже через QT. С генерацией буфера и звука проблем нет. Пока что хотя бы на QT отладить.

Heavy
Сообщения: 17
Зарегистрирован: 20 янв 2016, 16:12

Re: Модифицированный алгоритм Герцеля

Сообщение Heavy »

Прихожу к выводу, что после детектирования частоты необходимо не только обнулить I и Q, но еще и предыдущие N семплов принять равными 0.

Heavy
Сообщения: 17
Зарегистрирован: 20 янв 2016, 16:12

Re: Модифицированный алгоритм Герцеля

Сообщение Heavy »

Записал видео с своей реализацией https://youtu.be/FhoelOKbjfk?t=964 . Сильно не пинайте за путаницу в терминологии, и за неуверенность в некоторой матчасти. Видео около часа длительностью. Примерно с 16 минуты запускаю алгоритм, и начинаю тестить и показывать что получается. В итоге прихожу в ступор.

serjik
Сообщения: 1
Зарегистрирован: 23 июн 2016, 23:32

Re: Модифицированный алгоритм Герцеля

Сообщение serjik »

Не знаю, нашел ли автор топика ответы на свои вопросы. Видео я смотреть не стал.
Поскольку мне была интересна эта тема, я решил попробовать реализовать приведенный алгоритм.
В исходном варианте у меня модуль не уменьшался. То есть, если фильтр сработал на какую-то частоту, то его значение не уменьшалось, даже если этой частоты уже нет в сигнале.
Однако вот такая модификация: умножение на коэффиент 0.9995 значений a и b
a = 0.9995 * Math.Cos(2.0 * Math.PI * k0 / filterConfig.FrameSamplesCount);
b = 0.9995 * Math.Sin(2.0 * Math.PI * k0 / filterConfig.FrameSamplesCount);
при каждом вычислении модуля, будет уменьшать его.
И еще, чтобы величина модуля оставалась постоянной от частоты, его можно вычислять так:
value = Math.Sqrt(i1 * i1 + q1 * q1) / k0;
k0 это "номер гармоники"

Вот что у меня получилось: https://github.com/jauseg/GoertzelOnTheFly

Как это прикрутить к ардуинке со светодиодной лентой я пока еще не придумал.

Ответить