Автор Тема: Реверсивная цифровая АРУ с антипитченгом.  (Прочитано 14400 раз)

0 Пользователей и 2 Гостей просматривают эту тему.

Оффлайн VA7KL

  • Administrator
  • *****
  • Сообщений: 142
  • ex-VA7FFT
Re: Реверсивная цифровая АРУ с антипитченгом.
« Ответ #15 : Январь 01, 2022, 11:21:56 pm »
Спасибо Сергей за отличный новогодний подарок всем ! (главное вовремя напроситься  8) )

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

А насколько далеко в миллисекундах надо идти в прошлое от точки реверса, чтобы заранее ослабить сигнал ?
« Последнее редактирование: Январь 01, 2022, 11:50:43 pm от VA7KL »

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: Реверсивная цифровая АРУ с антипитченгом.
« Ответ #16 : Январь 02, 2022, 03:48:08 pm »
Последняя версия АРУ

void AGC_do_digi(void) {
    //main circle
    for (int i = 0; i < FRAME_SIZE; i += 8) {
        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 - 8) - 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--; //уменьшим счетчик задержки если он не пустой

}

Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: Реверсивная цифровая АРУ с антипитченгом.
« Ответ #17 : Январь 02, 2022, 03:49:34 pm »
ини

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;
            }

}

Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: Реверсивная цифровая АРУ с антипитченгом.
« Ответ #18 : Январь 02, 2022, 04:56:02 pm »
Ворота в АРУ

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

Оффлайн VA7KL

  • Administrator
  • *****
  • Сообщений: 142
  • ex-VA7FFT
Re: Реверсивная цифровая АРУ с антипитченгом.
« Ответ #19 : Январь 05, 2022, 04:19:00 am »
a = fabsf(saiRxBank[saiRxBankNowNumber]); // модуль замера

это сигнал прямо с АЦП, или уже както обработанный? На последней картинке это тот же сигнал, или его огибающая?

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: Реверсивная цифровая АРУ с антипитченгом.
« Ответ #20 : Январь 05, 2022, 08:39:39 am »
Хороший вопрос.
В процессоре с ацп идут только положительные значения. В ацп серьёзных с плис  уже сделана средняя точка  и значения уже от -1 до 1 (средняя точка это пол питания ) . В плис системах там сразу вводят среднюю точку и берут ее за 0 и значения летят от -1 до 1 (условно) . Теперь ещё один момент это тип данных, нужен float32_t . Все мат процессоры работают с float типом данных.
В строчке я беру модуль замеров и работаю только с положительными значениями. Название массива говорит само за себя - это один из двух блоков заполненных значениями , которые прилетели с шины i2s (не важно от куда).
Я ответил на вопрос ?
Да да, я знаю, у меня ничего не получится )))

Оффлайн VA7KL

  • Administrator
  • *****
  • Сообщений: 142
  • ex-VA7FFT
Re: Реверсивная цифровая АРУ с антипитченгом.
« Ответ #21 : Январь 06, 2022, 07:50:15 am »
почти... Хотелось бы уточнить: по i2s прилетают положительные и отрицательные значения. Вы берете их абсолютные значения, то есть все отсчеты становятся положительными, и только на них и работает АРУ ?

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

Я подумал вдруг у вас там вычисляется огибающая аудио сигнала, (например через преобразование Гильберта) и по ней работает АРУ. Для АРУ такие сложности наверное излишни. Я огибающую находил в процессе определения фазы речевого сигнала, но это совсем другая история.
« Последнее редактирование: Январь 06, 2022, 08:58:49 am от VA7KL »

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: Реверсивная цифровая АРУ с антипитченгом.
« Ответ #22 : Январь 06, 2022, 09:57:06 am »
Да, это другая история.
Да все просто )) модули значений мне нужны для расчёта коэффициента (множителя) ару. Там же все время все значения умножаются на какой-то коэффициент, который мы рассчитываем. В этом есть программный смысл ару - просто умножить на коэффициент каждый замер. А так как я ищу всегда максимум сигнала то мне надо смотреть как положительные полуволны так и отрицательные (всплеск может в любой части полуволны) и чтобы не путаться со знаком потом и не проверять каждый раз на знак, то лучше сразу взять модуль и не парится да и его надо взять один раз. По i2s с плис летят -1 по 1 float32 замеры. Огибающую не надо вычислять (я пробовал залазить в сигнал - это был капец) ее ацп стробирует. По фильтрам и гильбертам … я отдал в е адау1467 - это серьезный звуковой процессор с очень простым программированием. И фильтра и формирование ssb сигнала всё в ней. Я серьезно разгрузил процессор отдав всю фильтрацию в адау . За счёт такого тандема мне удалось сделать очень качественный звук с минимальной задержкой. 96к 24 бита довёл до наушников! Это реально круто.
Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: Реверсивная цифровая АРУ с антипитченгом.
« Ответ #23 : Январь 06, 2022, 10:07:27 am »
Если есть желание то я могу выложить проект по адау с комментами и программным кодом внешней загрузки коэффициентов в фильтра. Единственное , я так и не научился расчитывать коэффициенты на лету под фильтра, и пришлось дампы коэффициентов сохранять с шагом 100 гц ))
Да да, я знаю, у меня ничего не получится )))

Оффлайн r1tx

  • Hero Member
  • *****
  • Сообщений: 502
Re: Реверсивная цифровая АРУ с антипитченгом.
« Ответ #24 : Январь 07, 2022, 01:32:36 am »
Я уже год жду когда...  lol22

Оффлайн VA7KL

  • Administrator
  • *****
  • Сообщений: 142
  • ex-VA7FFT
Re: Реверсивная цифровая АРУ с антипитченгом.
« Ответ #25 : Январь 07, 2022, 02:56:45 am »
всегда интересуюсь что вы делаете с Адау, хотя сам вряд ли за нее возьмусь - глубоко влез в свой проект   8)