Модифицированный алгоритм Герцеля
Модифицированный алгоритм Герцеля
Здравствуйте. Есть несколько вопросов по данной теме. Если точнее, то по реализации с вещественными умножениями.
Начиная с формулы 12 у меня появились вопросы.
В статье пишется:
"Пусть комплексный входной сигнал s(n) равен:
Первый вопрос: входные отсчеты не комплексные, так откуда взять q(n) ? Приравнять их нулю?
Второй вопрос: Допустим, у меня есть массив семплов, размерностью 100. Частота дискретизации 9000гц. Сигнал состоит из двух частот: 600 и 1000 гц. Тогда исходя из формулы 17, N должно быть больше 23. Правильно ли я понял?
Далее, формуле 16 имеем (n-N).
Второй вопрос: правильно ли я понимаю, что , если с АЦП я считал , допустим, всешл 6 семплов, то i(n-N) = 0, как и q(n-N). И правильно ли я понимаю, что q(n-N) всегда равны нулю, ибо входные семплы действительные?
Третий вопрос: Выходит, что нужно иметь один большой массив семплов, разбить его на участки размерностью N? Для первых N семплов i(n-N) принять равными нулю?
Четвертый вопрос: Модуль. Модуль - это корень из суммы квадратов I и Q ?
Начиная с формулы 12 у меня появились вопросы.
В статье пишется:
"Пусть комплексный входной сигнал s(n) равен:
Первый вопрос: входные отсчеты не комплексные, так откуда взять q(n) ? Приравнять их нулю?
Второй вопрос: Допустим, у меня есть массив семплов, размерностью 100. Частота дискретизации 9000гц. Сигнал состоит из двух частот: 600 и 1000 гц. Тогда исходя из формулы 17, N должно быть больше 23. Правильно ли я понял?
Далее, формуле 16 имеем (n-N).
Второй вопрос: правильно ли я понимаю, что , если с АЦП я считал , допустим, всешл 6 семплов, то i(n-N) = 0, как и q(n-N). И правильно ли я понимаю, что q(n-N) всегда равны нулю, ибо входные семплы действительные?
Третий вопрос: Выходит, что нужно иметь один большой массив семплов, разбить его на участки размерностью N? Для первых N семплов i(n-N) принять равными нулю?
Четвертый вопрос: Модуль. Модуль - это корень из суммы квадратов I и Q ?
- Бахурин Сергей
- Администратор
- Сообщения: 1116
- Зарегистрирован: 05 окт 2010, 19:55
- Контактная информация:
Re: Модифицированный алгоритм Герцеля
Да просто считать равными нулю.Heavy писал(а): Здравствуйте. Есть несколько вопросов по данной теме. Если точнее, то по реализации с вещественными умножениями.
Начиная с формулы 12 у меня появились вопросы.
В статье пишется:
"Пусть комплексный входной сигнал s(n) равен:
Первый вопрос: входные отсчеты не комплексные, так откуда взять q(n) ? Приравнять их нулю?
Правильно, но это не означает что надо использовать 23. Можно использовать значение большее чем 23 для того чтобы спектральные отсчеты отстояли друг от друга на бОльшую величину отсчетов.Heavy писал(а): Второй вопрос: Допустим, у меня есть массив семплов, размерностью 100. Частота дискретизации 9000гц. Сигнал состоит из двух частот: 600 и 1000 гц. Тогда исходя из формулы 17, N должно быть больше 23. Правильно ли я понял?
Да отсчеты с отрицательными индексами можно принять равными нулю.Heavy писал(а): Далее, формуле 16 имеем (n-N).
Второй вопрос: правильно ли я понимаю, что , если с АЦП я считал , допустим, всешл 6 семплов, то i(n-N) = 0, как и q(n-N). И правильно ли я понимаю, что q(n-N) всегда равны нулю, ибо входные семплы действительные?
Не надо ничего разбивать. Это просто фильтр, который обрабатывает ваш массив по одному сэмплу. При этом когда буфер задержек заполнится и все индексы станут положительными, то каждый сэмпл вы будете иметь обновленное значение спектрального отсчета.Heavy писал(а): Третий вопрос: Выходит, что нужно иметь один большой массив семплов, разбить его на участки размерностью N? Для первых N семплов i(n-N) принять равными нулю?
Да все верно.Heavy писал(а): Четвертый вопрос: Модуль. Модуль - это корень из суммы квадратов I и Q ?
Re: Модифицированный алгоритм Герцеля
Бахурин Сергей писал(а): Правильно, но это не означает что надо использовать 23. Можно использовать значение большее чем 23 для того чтобы спектральные отсчеты отстояли друг от друга на бОльшую величину отсчетов.
Может быть на меньшую величину отсчетов? Чем больше N,тем больше разрешение по частоте вроде как, то есть тем меньше расстояние по частоте между бинами.
- Бахурин Сергей
- Администратор
- Сообщения: 1116
- Зарегистрирован: 05 окт 2010, 19:55
- Контактная информация:
Re: Модифицированный алгоритм Герцеля
Да расстояние между бинами будет меньше и как результат между двумя гармониками 100 и 600 Гц будет больше спектральных бинов. Это хорошо потому что гармоники отстоят друг от друга на большее количество бинов и легче различимы
Re: Модифицированный алгоритм Герцеля
Написал код на Си:
https://pp.vk.me/c630722/v630722756/104 ... rv6xSg.jpg
Модули выдает всегда разные:
https://pp.vk.me/c630722/v630722756/104 ... rRTaOI.jpg
Как это понимать? По идее модуль должен быть всегда одинаков, раз частота присутствует постоянно.
https://pp.vk.me/c630722/v630722756/104 ... rv6xSg.jpg
Модули выдает всегда разные:
https://pp.vk.me/c630722/v630722756/104 ... rRTaOI.jpg
Как это понимать? По идее модуль должен быть всегда одинаков, раз частота присутствует постоянно.
- Бахурин Сергей
- Администратор
- Сообщения: 1116
- Зарегистрирован: 05 окт 2010, 19:55
- Контактная информация:
Re: Модифицированный алгоритм Герцеля
Мой компилятор не поддерживает исходники в виде png картинок. Пожалуйста приведите код в виде текста используя тег code
Re: Модифицированный алгоритм Герцеля
Код: Выделить всё
#define Fd 9000 //частота дискретизации
#define f1 600 //частота тона
#define f_search 600 //искомая алгоритмом частота
#define N 70 //размер массива
int main()
{
unsigned char ADC[350]; //Массив, эмулирующий поток из АЦП
unsigned char buff[N]; //Буфер, в который пишутся данные из АЦП
float I[2];
float Q[2];
float a;
float b;
float c = 2* M_PI *f1/Fd; //Заранее рассчитаем то, что не будет меняться
float module; //здесь будет лежать модуль комплексного числа
I[0]=0; I[1]=0; //инициализируем массивы
Q[0]=0; Q[1]=0;
for (int i =0; i<350; i++)
{
ADC[i] = (unsigned char) 100*sin(c*i)+100; //заполняем "поток" АЦП синусом с амплитудой от 0 до 100
}
a=cos(2*M_PI*f_search/N); //рассчитываем к-ты
b=sin(2*M_PI*f_search/N);
for (int n=0; n<70; n++) //начальное заполнение буфера
{
I[0]=I[1]; //Готовим предыдущее I
Q[0]=Q[1];
buff[n]=ADC[n]; // Просто заполняем буфер данными из АЦП
I[1]=a*(I[0]+buff[n])-b*Q[0]; //Все по формуле 16 из статьи
Q[1]=a*Q[0]+b*(I[0]+buff[n]);
}
for (int n=70; n<350; n++) //Когда буфер заполнился, то запускаем цикл с выталкиванием
{
I[0]=I[1];
Q[0]=Q[1];
I[1]=a*(I[0]+ADC[n]-buff[0])-b*Q[0]; //В качестве i(n) выступает ADC(n), где n=70. Следовательно buff(n-N)=buff(0)
Q[1]=a*Q[0]+b*(I[0]+ADC[n]-buff[0]);
for (int nn=0; nn<69; nn++) //перемещаем элементы массива на 1 влево
{
buff[nn]=buff[nn+1];
}
buff[69]=ADC[n]; //Заносим полученное значение АЦП на данном цикле работы алгоритма в последний эллемент буфера
module = sqrt(I[1]*I[1]+Q[1]*Q[1]); //вычисляем модуль комплексного числа
}
//конец работы алгоритма
}
Re: Модифицированный алгоритм Герцеля
Забыл перевести градусы в радианы. Перевел, все равно модуль пляшет
- Бахурин Сергей
- Администратор
- Сообщения: 1116
- Зарегистрирован: 05 окт 2010, 19:55
- Контактная информация:
Re: Модифицированный алгоритм Герцеля
несколько ошибок:
1) Fd =9000 f1=600 и N=70 не дают целого номера спектрального отсчета. Я бы взял N = 90
2) Не учтен параметр k0
3) Ошибка в реализации цикла.
Правильный код:
1) Fd =9000 f1=600 и N=70 не дают целого номера спектрального отсчета. Я бы взял N = 90
2) Не учтен параметр k0
3) Ошибка в реализации цикла.
Правильный код:
Код: Выделить всё
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define Fd 9000
#define f1 600
#define f_search 600
#define N 90
#define K 350
int main()
{
unsigned char ADC[K];
float I[2];
float Q[2];
float a;
float b;
float c = 2* M_PI *f1/Fd;
float module;
float k0;
float u;
int n;
I[0]=0; I[1]=0;
Q[0]=0; Q[1]=0;
for (n =0; n<K; n++)
ADC[n] = (unsigned char) 100*sin(c*n)+100;
k0 = (float)f_search / ((float)Fd/(float)N);
a=cos(2*M_PI*k0/N);
b=sin(2*M_PI*k0/N);
for (n=0; n<K; n++)
{
I[0]=I[1];
Q[0]=Q[1];
u = I[0] + ADC[n] - ((n>=N) ? ADC[n-N] : 0.0);
I[1]= u*a - b*Q[0];
Q[1]= u*b + a*Q[0];
module = sqrt(I[1]*I[1] + Q[1]*Q[1]);
printf("%.4f\n", module);
}
return 0;
}
Re: Модифицированный алгоритм Герцеля
Теперь понял. k0 - это номер спектрального отсчета, а не искомая частота. Перепутал понятия. В ЦОС новичок совсем. Спасибо. Попробую осмыслить и протестировать