Форум Радиолюбителей

Реверсивная цифровая АРУ с антипитченгом.

47769 просмотров, 26 ответов — стр. 2 из 2

VA7KLVA7KL
Сообщений: 158
1 января 2022 г. в 11:21#16
Спасибо Сергей за отличный новогодний подарок всем ! (главное вовремя напроситься )

Хоть каждый и собирает свое, все равно необходимо знать общие Правильные подходы к элементам АРУ. У меня сейчас работает STM32H747 c квадратурным полумонстром Игоря, без АРУ, с децибельником - ужас! Я пока фокусировался на формировании SSB, уже сделал, теперь АРУ...

А насколько далеко в миллисекундах надо идти в прошлое от точки реверса, чтобы заранее ослабить сигнал ?
ra0ahcra0ahc
Сообщений: 4868
2 января 2022 г. в 03:48#17
Последняя версия АРУ

Код: [Выделить]void AGC_do_digi(void) {
//main circle
for (int i = 0; i < FRAME_SIZE; i += {
float32_t a = fabsf(saiRxBank[saiRxBankNowNumber][i]); // модуль замера
//сильный
if (a * agcd.val > agcd.max) {//сюда если сигнал превысил максималку

agcd.delayNow = 0;
agcd.delay = 5; //мин задержка отката сразу
agcd.val = agcd.max / a; //расчет нового множителя

//переменный степ от 250...100 шагов назад
uint16_t steps = 100;
steps = (uint16_t) ((float32_t) steps * agcd.oldVal / agcd.val);
if (steps > 250)steps = 250;

float32_t step = (agcd.oldVal - agcd.val) / (float32_t) (steps);//шаг изменения амплитуды

uint8_t nn = saiTxBankNowNumber ? 0 : 1;//выбор банки которая уже отдана дма
uint16_t vv = 0;
for (int loc = 1; loc < steps; loc++) {
int32_t ii = i - loc * 8;
if (ii >= 0) {//если еще не вышли за текущий блок приема
saiRxBank[saiRxBankNowNumber][ii] /= agcd.oldVal;//сперва вернем старое значение
saiRxBank[saiRxBankNowNumber][ii] *= (agcd.val + step * (float32_t) loc);//а теперь умножим на новый множитель
} else {//сюда зашли если уже вышли с текущего блока и зашли в старый блок
uint16_t x = (FRAME_SIZE - - vv * 8;//адрес в слотах
float32_t tx = (float32_t) saiTxBank[nn][x] / 0x1p24f;//специфика адау 1647
vv++;
tx /= agcd.oldVal;////сперва вернем старое значение
tx *= (agcd.val + step * (float32_t) loc);//а теперь умножим на новый множитель
saiTxBank[nn][x] = (int32_t) (tx * 0x1p24f);//особенность адау
SCB_CleanDCache_by_Addr((uint32_t *) &saiTxBank[nn][x], 4); //сброс кэша в память
}
}

} else {//сюда если сигнал меньше чем максималка (начало алгоритма отката)
//антипитченг
//если задержка не достигла максимального
if (agcd.delay < agcd.delayMax) agcd.delay += agcd.speedPitchingRise;// добавим приращение к задержки

if (!agcd.delayNow) { //если счетчик задержки закончился и нужно возвращать усиление
if (a * agcd.val * agcd.speed <= agcd.max) //если можем еще поднять усиление
agcd.val *= agcd.speed; //то подымаем
else agcd.val = agcd.max / a;//если не можем понять то берем максимально возможное усиление
}
}

saiRxBank[saiRxBankNowNumber][i] *= agcd.val;// фиксируем усиление в каждой ячейки блока

//ворота
//если сигнал не падает то отодвигаем задержку
if (saiRxBank[saiRxBankNowNumber][i] >= agcd.max / agcd.gate) {//продолжаем задержку
agcd.delayNow = agcd.delay>2.0f?(uint16_t) agcd.delay:2;
}
agcd.oldVal = agcd.val; //сохраним старый коэфф

}
if (agcd.delayNow)agcd.delayNow--; //уменьшим счетчик задержки если он не пустой

}

ra0ahcra0ahc
Сообщений: 4868
2 января 2022 г. в 03:49#18
ини

Код: [Выделить]void AGC_ini(void) {
HAL_DAC_Start(&hdac1, DAC_CHANNEL_1);//для аналогового ару
HAL_ADC_Start(&hadc1);//для аналогового ару
HAL_TIM_Base_Start_IT(&htim6);//для аналогового ару
tmp = (uint32_t) hdac1.Instance + DAC_DHR12R1_ALIGNMENT(0); // DAC address


// rx agc digi ini
agcd.val = 0.5f;
agcd.max = 0.3f;

agcd.delay = 5;
agcd.delayNow = 0;
agcd.delayMax = 100;
agcd.delayMax_max = 150;
agcd.delayMax_min = 10;

agcd.speed = 1.0003f;
agcd.speed_max = 1.0006f;
agcd.speed_min = 1.00002f;

agcd.gate = 3.0f;
agcd.gate_max = 4.0f;
agcd.gate_min = 1.1f;

agcd.speedPitchingRise = 0.001f;
agcd.speedPitchingRise_max = 0.1f;
agcd.speedPitchingRise_min = 0.0001f;
agcd.oldVal = 0.0000001f;
agcd.needToChange = YES;
agcd.windowYN = NO;
agcd.needToDrawWindow = NO;

//analog
agcd.dacMax = 3000.0f;
agcd.dacMin = 200.0f;
agcd.dacAnalog = (uint16_t) agcd.dacMax;
*(__IO uint32_t *) tmp =1700;// DAC

}

void AGC_load_default_setting(void) {

for (uint8_t rx = 0; rx < 2; rx++)
for (uint8_t mode = 0; mode < 3; mode++)
for (uint8_t variant = 0; variant < 3; variant++) {
agcd.e.loadedVariantNN[rx][mode] = 0;
agcd.e.var[rx][mode][variant].gate = 3.0f;
agcd.e.var[rx][mode][variant].delayMax = 100.0f;
agcd.e.var[rx][mode][variant].speed = 1.0003f;
agcd.e.var[rx][mode][variant].speedPitch = 0.001f;
}

}

ra0ahcra0ahc
Сообщений: 4868
2 января 2022 г. в 04:56#19
Ворота в АРУ

Важный параметр! Этот параметр отвечает за продление задержки отката усиления. Станция говорит и делает паузы между слов и если пауза не вышла за рамки максимальной задержки отката ару и следующая слово или фраза стали меньше по уровню, но не вышли за ворота (в дб), то задержка отодвинется на максималку - обновится без коррекции усиления. А вот если сигнал ушел в qsb и вышел за рамки ворот (уменьшился на критичные дБ) то АРУ откорректирует усиление и примет эту "фразу" как новый нормальный уровень и выставит опять задержку отката.


VA7KLVA7KL
Сообщений: 158
5 января 2022 г. в 04:19#20
a = fabsf(saiRxBank[saiRxBankNowNumber]); // модуль замера

это сигнал прямо с АЦП, или уже както обработанный? На последней картинке это тот же сигнал, или его огибающая?
ra0ahcra0ahc
Сообщений: 4868
5 января 2022 г. в 08:39#21
Хороший вопрос.
В процессоре с ацп идут только положительные значения. В ацп серьёзных с плис уже сделана средняя точка и значения уже от -1 до 1 (средняя точка это пол питания ) . В плис системах там сразу вводят среднюю точку и берут ее за 0 и значения летят от -1 до 1 (условно) . Теперь ещё один момент это тип данных, нужен float32_t . Все мат процессоры работают с float типом данных.
В строчке я беру модуль замеров и работаю только с положительными значениями. Название массива говорит само за себя - это один из двух блоков заполненных значениями , которые прилетели с шины i2s (не важно от куда).
Я ответил на вопрос ?
VA7KLVA7KL
Сообщений: 158
6 января 2022 г. в 07:50#22
почти... Хотелось бы уточнить: по i2s прилетают положительные и отрицательные значения. Вы берете их абсолютные значения, то есть все отсчеты становятся положительными, и только на них и работает АРУ ?

На последней картинке с воротами вот те горбы с пичками и есть положительные отсчеты?

Я подумал вдруг у вас там вычисляется огибающая аудио сигнала, (например через преобразование Гильберта) и по ней работает АРУ. Для АРУ такие сложности наверное излишни. Я огибающую находил в процессе определения фазы речевого сигнала, но это совсем другая история.
ra0ahcra0ahc
Сообщений: 4868
6 января 2022 г. в 09:57#23
Да, это другая история.
Да все просто )) модули значений мне нужны для расчёта коэффициента (множителя) ару. Там же все время все значения умножаются на какой-то коэффициент, который мы рассчитываем. В этом есть программный смысл ару - просто умножить на коэффициент каждый замер. А так как я ищу всегда максимум сигнала то мне надо смотреть как положительные полуволны так и отрицательные (всплеск может в любой части полуволны) и чтобы не путаться со знаком потом и не проверять каждый раз на знак, то лучше сразу взять модуль и не парится да и его надо взять один раз. По i2s с плис летят -1 по 1 float32 замеры. Огибающую не надо вычислять (я пробовал залазить в сигнал - это был капец) ее ацп стробирует. По фильтрам и гильбертам … я отдал в е адау1467 - это серьезный звуковой процессор с очень простым программированием. И фильтра и формирование ssb сигнала всё в ней. Я серьезно разгрузил процессор отдав всю фильтрацию в адау . За счёт такого тандема мне удалось сделать очень качественный звук с минимальной задержкой. 96к 24 бита довёл до наушников! Это реально круто.
ra0ahcra0ahc
Сообщений: 4868
6 января 2022 г. в 10:07#24
Если есть желание то я могу выложить проект по адау с комментами и программным кодом внешней загрузки коэффициентов в фильтра. Единственное , я так и не научился расчитывать коэффициенты на лету под фильтра, и пришлось дампы коэффициентов сохранять с шагом 100 гц ))
r1tx
Сообщений: 503
7 января 2022 г. в 01:32#25
Я уже год жду когда...
VA7KLVA7KL
Сообщений: 158
7 января 2022 г. в 02:56#26
всегда интересуюсь что вы делаете с Адау, хотя сам вряд ли за нее возьмусь - глубоко влез в свой проект