Игорь 2

Трансиверы, передатчики, РПУ => Software Defined Radio (SDR) => Тема начата: ra0ahc от Октябрь 10, 2020, 04:11:30 pm

Название: Цифровая АРУ 0...1
Отправлено: ra0ahc от Октябрь 10, 2020, 04:11:30 pm
Начал поползновения с цифровой АРУ.
Пока столкнулся с некоторым не пониманием. Значения амплитуду логарифмическое и пока я ключик подобрать не могу, выскакивает за границы.
Название: Re: Цифровое АРУ 0...1
Отправлено: ra0ahc от Октябрь 10, 2020, 04:15:00 pm
Вот пока , что удалось. На входе то есть то нет синус с шумом.
Название: Re: Цифровое АРУ 0...1
Отправлено: ra0ahc от Октябрь 10, 2020, 04:18:52 pm
Вот этот провал это момент появления сигнала, при этом ару улетает в 0. Долго думал почему так. Амплитуда взлетает во всем спектре. Но у меня после ару стоит еще один фир фильтр на 3кгц поэтому скачок только в спектре 3 кгц.
Название: Re: Цифровое АРУ 0...1
Отправлено: ra0ahc от Октябрь 10, 2020, 04:21:04 pm
без шума вот так выглядит
Название: Re: Цифровое АРУ 0...1
Отправлено: ra0ahc от Октябрь 10, 2020, 04:59:30 pm
Немного изменил расчет дельты возврата.
Название: Re: Цифровое АРУ 0...1
Отправлено: Игорь 2 от Октябрь 10, 2020, 05:48:18 pm
Красный трек - это то, что Вы в сильносигналку пускаете?  cr123
Название: Re: Цифровое АРУ 0...1
Отправлено: ra0ahc от Октябрь 10, 2020, 05:54:09 pm
это с динамика нч
Название: Re: Цифровое АРУ 0...1
Отправлено: Игорь 2 от Октябрь 10, 2020, 06:10:27 pm
Поподробней, я ничего не понял... dontt44
Название: Re: Цифровое АРУ 0...1
Отправлено: ra0ahc от Октябрь 10, 2020, 06:17:51 pm
это симуляция работы ару.
синус генерится бесконечный, а дальше как бы попадает в дсп . я его подхватываю и обрабатываю, фир , ару и еще один фир.
дальше уже обработанный сигнал идет на цап где я его программой и смотрю и наушниками слушаю. 
ну и синус то есть то нет через 1 сек период.
вот я и разглядываю как ведет себя цифровое ару
Название: Re: Цифровое АРУ 0...1
Отправлено: Relayer от Октябрь 10, 2020, 06:27:59 pm
Возьмите готовую реализацию из того же поверсдр например или еще откуда-то. Нафига лисапед изобретать?
Название: Re: Цифровое АРУ 0...1
Отправлено: Игорь 2 от Октябрь 10, 2020, 06:37:59 pm
Так всё-таки, на красном-то что за картинка?  cr123
Название: Re: Цифровое АРУ 0...1
Отправлено: ra0ahc от Октябрь 10, 2020, 06:54:14 pm
Возьмите готовую реализацию из того же поверсдр например или еще откуда-то. Нафига лисапед изобретать?
Не интересно так.

Так всё-таки, на красном-то что за картинка?  cr123
Да это лог осцил. Реакция ару на подачу и на снятия.
Название: Re: Цифровое АРУ 0...1
Отправлено: Игорь 2 от Октябрь 10, 2020, 07:10:29 pm
А, вон оно что... lllol
Название: Re: Цифровое АРУ 0...1
Отправлено: ra0ahc от Октябрь 10, 2020, 07:54:53 pm
Ну пока тупик. Пропуск с 0 уровнем одного блока пролетает, при переходе 0->1 (слабый сигнала - сильный сигнал)
Название: Re: Цифровое АРУ 0...1
Отправлено: ra0ahc от Октябрь 10, 2020, 10:08:34 pm
Одну часть победил.
Теперь плавно без ступенек.
Название: Re: Цифровое АРУ 0...1
Отправлено: Игорь 2 от Октябрь 10, 2020, 10:53:17 pm
Теперь плавно без ступенек.

Перепад уровней на входе те же 40 дБ?  cr123
Кстати, не помню уже, как название поправлять, но АРУ всё-таки, цифровАя... dontt44
Название: Re: Цифровое АРУ 0...1
Отправлено: ra0ahc от Октябрь 10, 2020, 11:12:37 pm
Перепад уровней на входе те же 40 дБ? 
Често, не знаю. Амплитуды от балды поставил.
Название: Re: Цифровое АРУ 0...1
Отправлено: Игорь 2 от Октябрь 10, 2020, 11:13:51 pm
 1yep
Название: Re: Цифровое АРУ 0...1
Отправлено: ra0ahc от Октябрь 10, 2020, 11:14:54 pm
но АРУ всё-таки, цифровАя.
вот вот , настоящая женщина!

(завтра поправлю)
Название: Re: Цифровое АРУ 0...1
Отправлено: ra0ahc от Октябрь 10, 2020, 11:41:22 pm
Пока застрял. Походу надо математику пересчитывать.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Октябрь 11, 2020, 10:26:52 am
Проблема получается в том, что в одном фрейме может быть сигнал как низкого уровня так и большого уровня. Изменение амплитуды происходит скачкообразно. И если сильный сигнал приходится к концы фрейма, то расчет общей амплитуды приводит к тому, что часть с низким уровнем сигнала провалится и образует провал и сильный стук в наушниках . И все это будет внизу пока не дойдет очередь до сильного сигнала в этом фрейме. Вот и получается, что надо ару считать внутри фрэйма. И это усложняет все расчеты.
Вот пока так я научился обрабатывать  этот скачок внутри фрэйма. Длина фрэйма 22мСек
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Октябрь 11, 2020, 11:30:33 am
Линейное снижение амплитуды не катит no88. Нужно что-то другое. Именно линейное снижение амплитуды дает такой эффект, сперва провал потом скачок. Нужен другой закон например экспонента.
Название: Re: Цифровая АРУ 0...1
Отправлено: GenaSPB от Октябрь 11, 2020, 12:59:37 pm
А забыть про фреймы и каждую квадратуру обсчитывать исходя из состояния заряда воображаемых конденсаторв?
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Октябрь 11, 2020, 01:26:30 pm
А забыть про фреймы и каждую квадратуру обсчитывать исходя из состояния заряда воображаемых конденсаторв?
"кондеры" тоже надо заряжать и разрежать и если обнаружена квадратура с высоким сигналом то нужно как то плавно к ней готовится и как-то плавно зарядить кондер. Иначе будет стук-стук. Я понимаю, что в природе нет моментальных сигналов и они как-то нарастают и как-то плавно спадают , и все же надо чтобы было плавно. Вообщем то можно и забить, но есть возможность с импульсной помехой побороться. 
Название: Re: Цифровая АРУ 0...1
Отправлено: GenaSPB от Октябрь 11, 2020, 02:05:45 pm
Да... со стук стук я поборолся доп фильтром за детектором
Название: Re: Цифровая АРУ 0...1
Отправлено: GenaSPB от Октябрь 11, 2020, 02:06:25 pm
https://youtu.be/hNtaXETcAjQ

Кстати вот запись работы...
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Октябрь 11, 2020, 02:12:12 pm
Я тоже сделал фильтр за детектором.

Ну вот так если каждый замер обслуживать, а не фрейм
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Октябрь 11, 2020, 02:20:01 pm
https://youtu.be/hNtaXETcAjQ

Кстати вот запись работы...

Я так понял - это новый на 157?
Название: Re: Цифровая АРУ 0...1
Отправлено: GenaSPB от Октябрь 11, 2020, 02:40:33 pm
Да. Это он. Но тут вроде ничего из особенностей не используется кроме fft 1024. А что за выброс на графике  Снимок экрана 2020-10-11 в 14.13.12.png?
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Октябрь 11, 2020, 02:47:50 pm
Вот на суд, что получилось
Здесь переменная амплитуда и переменное время смены амплитуды

https://drive.google.com/file/d/16t-HwrUr-_jusRCDANxMCG1j21P4E_Hn/view?usp=sharing
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Октябрь 11, 2020, 02:52:46 pm
А что за выброс на графике  Снимок экрана 2020-10-11 в 14.13.12.png?
Да там что угодно может быть. Синус рисуется идеальный и после ару фазы не совпали (на много не совпали) и получатся ступенька. А ее собаку уже ничем не убрать.
Фильтр после ару на 3 кгц - работает.


ару вот




float32_t a;
        if (tim > 0)tim--;
        for (int i = 0; i < FRAME_SIZE; i++) {
            a = (pFirOutTemp[i ] < 0) ? -1.0f * (pFirOutTemp[i ]) : pFirOutTemp[i ];
            nowAgc = 1 / a;
            if (nowAgc < agcLevel) {
                agcLevel = nowAgc;
                tim = 6; //задержка отпускания
            } else {
                if (tim == 0) {
                    agcLevel += 0.02f; //нарастание 
                }
            }

            pFirOutTemp[i ] *= agcLevel;
        }
 
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Октябрь 11, 2020, 03:04:05 pm
Выбросы есть длительностью 0.7мСек и ампл 2.5дб
Да и то, мне кажется это артефакты звуковой платы.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Октябрь 11, 2020, 04:35:46 pm
Разместил на цкьюхаме  тему эту  lllol lllol lllol
один ответ  lllol lllol про то , что всё очень не понятно.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Октябрь 11, 2020, 04:39:20 pm
Ладно, что ржать то, тема очень узкая и тяжелая, что я хотел ?  cr123 10 человек в принципе понимает о чем речь и лишь немногие хотят хоть что-то обсудить.  lol22
Название: Re: Цифровая АРУ 0...1
Отправлено: Relayer от Октябрь 11, 2020, 04:46:07 pm
При такой реализации у вас АРУ будет цепляться за любые "пички"
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Октябрь 11, 2020, 04:47:05 pm
При такой реализации у вас АРУ будет цепляться за любые "пички"

Я знаю.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Октябрь 11, 2020, 04:51:42 pm
Цепляться надо, но вот с отпусканием можно поработать. Там всё ару работает к 1. Это выглядит как  интеллектуальное ару, с переменным фронтом отпускания и переменной задержкой
Название: Re: Цифровая АРУ 0...1
Отправлено: Relayer от Октябрь 11, 2020, 04:53:14 pm
Вот ару которая у меня в сдр трудилась. Алгоритм сдерт со статей Gerald Youngblood, K5SDR (http://) в QEX.

procedure TDSPAGCYB.DataEvent;
var px: PFloat32;
    pf: PFloatArray absolute px;
    j: Integer;
    bf: TBuffer;
    Vpk, Gain, GainStep, val: TFloat32;
    AGCHang,ms1: integer;
begin
  bf:=InputPin.Get;
  if bf <> nil then begin
    if Enabled and (HangTime > 0) then begin
      AGCHang:=Round((1000*bf.Size)/(1.0*HangTime*bf.SampleRate));
      ms1:=(bf.SampleRate+500) div 1000; // samples per 1 msec
      if ms1 > bf.Size then ms1:=bf.Size;
      if ms1 = 0 then ms1:=1;     
      px:=bf_Data(bf);
      if AGCHang < 1 then AGCHang:=1
      else if AGCHang >= MAX_Hang then AGCHang:=MAX_Hang;
      Inc(AGCLoop);
      if AGCLoop >= AGCHang then AGCLoop:=0;
      // Get peak magnitude
      Vpk:=0;
      for j:=bf.Size-1 downto 0 do begin
        val:=Abs(px^);
        if val > Vpk then Vpk:=val;
        Inc(px);
      end;
      if Vpk > 0 then begin
        bf_Write(bf);
        // AGC gain factor with 6 dB headroom
        Gb[AGCLoop]:=NormalLevel/Vpk;
        // Find peak gain reduction (Min)
        Gain:=1e+6;
        for j:=AGCHang-1 downto 0 do begin
          if Gb[j] < Gain then Gain:=Gb[j];
        end;
        // Limit Gain to MaxGain
        if Gain > MaxGain then Gain:=MaxGain;
        // agc
        pf:=bf_Data(bf);
        if Gain < PrevGain then begin
          // AGC Gain is decreasing
          GainStep := (PrevGain - Gain) / ms1;       // 44 Sample ramp = 1 ms attack time
          for j:=0 to ms1-1 do                         // Ramp Gain down over 1 ms period
            pf[j]:=pf[j]*(PrevGain - ((j + 1) * GainStep));
          //for j:=ms1 to bf.Size-1 do                 // Multiply remaining Envelope by Gain
          //  pf[j]:=pf[j] * Gain;
          MulConst_Buff(@pf[ms1],bf.Size-ms1,Gain);
        end else if Gain > PrevGain then begin
          // AGC Gain is increasing
          GainStep := (Gain - PrevGain) / ms1;       // 44 Sample ramp = 1 ms attack time
          for j:=0 to ms1-1 do                         // Ramp Gain down over 1 ms period
            pf[j]:=pf[j]*(PrevGain + ((j + 1) * GainStep));
          //for j:=ms1 to bf.Size-1 do                 // Multiply remaining Envelope by Gain
          //  pf[j]:=pf[j] * Gain;
          MulConst_Buff(@pf[ms1],bf.Size-ms1,Gain);
        end else
          MulConst_Buff(px,bf.Size,Gain);           // Multiply Envelope by AGC gain
        PrevGain:=Gain;                             // Save Gain for next loop
        PropertyChanged(idCurrentGain);
      end;
    end else if MaxGain > 0 then begin
      bf_Write(bf);
      MulConst_Buff(bf_Data(bf),bf.Size,MaxGain);
    end;
    OutputPin.Put(bf);
  end;
end;
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Октябрь 11, 2020, 05:06:42 pm
Да тот же алгоритм самый. Мусора многовато. Может для Паскаля это нормально, но С не простит по скорости такое расточительство по циклам. 
Про пиччи я ничего не увидел. Да их надо убирать через среднее значение АРУ за период, а это совсем другая история.
Название: Re: Цифровая АРУ 0...1
Отправлено: Vlad от Октябрь 11, 2020, 05:36:12 pm
Разместил на цкьюхаме  тему эту
Если бы там хоть слышали об этой теме - давно бы забросали г... м да еще с ветиляторами. Здесь (на форуме) очень много посетителей оттель, боящихся задать простой вопрос Мэтрам из боязни быть высмеянными. (Посмотрите мой вопрос по ДПФ для поддверждения месным аматорам прописных истин). Там куча просмотров "молчаливым большинством".
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Октябрь 11, 2020, 05:42:42 pm
Ага  lllol
Название: Re: Цифровая АРУ 0...1
Отправлено: Relayer от Октябрь 11, 2020, 05:50:16 pm
Да тот же алгоритм самый
Тот да не тот :) Посмотрите внимательно как усиление выбирается и для чего буфер длиной равной времени отпускания сделан
Название: Re: Цифровая АРУ 0...1
Отправлено: Relayer от Октябрь 11, 2020, 06:02:08 pm
Ага  lllol
Да, ретротема. 8 лет назад когда я еще писал что-то на сикухаме я рассказывал народу в этой теме о QER-фильтрах, доку выкладывал, рассчеты. Наткнулся на глухую стену непонимания и нежелания понимать. Это сейчас все такие умные на кверы перешли, а тогда моя "Стрекоза" была наверное первой конструкцией в рунете с таким фильтром на QER
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Октябрь 11, 2020, 06:37:50 pm
Немного запутанно , но в принципе понятно.
Ещё из темы анализа это автонотч и приём телеграфа, но лучше фт8
Название: Re: Цифровая АРУ 0...1
Отправлено: Relayer от Октябрь 11, 2020, 07:01:14 pm
Автонотч делается элементарно как LMS невысокого порядка с вычитанием
Название: Re: Цифровая АРУ 0...1
Отправлено: GenaSPB от Октябрь 11, 2020, 07:48:06 pm
Кто знает... автонотч lms. Через минут пятнадцать работы начинает превращать звук в какафонию.
На cmsis dsp. Куда бежать?
Название: Re: Цифровая АРУ 0...1
Отправлено: Relayer от Октябрь 11, 2020, 08:14:25 pm
C cmsis не работал. У LMS есть коэффициенты отвечающие за скорость адаптации. Может там подкрутить чего?
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Октябрь 11, 2020, 08:43:06 pm
Кто знает... автонотч lms. Через минут пятнадцать работы начинает превращать звук в какафонию.
На cmsis dsp. Куда бежать?
https://www.keil.com/pack/doc/CMSIS/DSP/html/group__LMS.html
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Октябрь 11, 2020, 09:00:56 pm
А можно немного подробней о коэффициентах, которы прописаны в LMS фильтре

void arm_lms_init_f32   (   arm_lms_instance_f32 *    S,
uint16_t    numTaps,
float32_t *    pCoeffs,
float32_t *    pState,
float32_t    mu,
uint32_t    blockSize
)      
Parameters
[in]   S   points to an instance of the floating-point LMS filter structure
[in]   numTaps   number of filter coefficients
[in]   pCoeffs   points to coefficient buffer
[in]   pState   points to state buffer
[in]   mu   step size that controls filter coefficient updates
[in]   blockSize   number of samples to process
Returns
none
Details
pCoeffs points to the array of filter coefficients stored in time reversed order:
   {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
The initial filter coefficients serve as a starting point for the adaptive filter. pState points to an array of length numTaps+blockSize-1 samples, where blockSize is the number of input samples processed by each call to arm_lms_f32().
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Октябрь 11, 2020, 09:01:52 pm
Они как-то похожи на то, что я рассчитал для ФИР фильтра?
Название: Re: Цифровая АРУ 0...1
Отправлено: Relayer от Октябрь 11, 2020, 09:15:02 pm
LMS это обычный FIR по структуре. Но его коэффициенты постоянно пересчитываются (адаптируются)
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Октябрь 11, 2020, 09:16:08 pm
А что в качестве референса использовать? Шум белый?
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Октябрь 11, 2020, 09:22:57 pm
void arm_lms_norm_f32   (   arm_lms_norm_instance_f32 *    S ,
const float32_t *    pSrc ,
float32_t *    pRef ,
float32_t *    pOut ,
float32_t *    pErr ,
uint32_t    размер блока
)      
Параметры
[в]   S   указывает на экземпляр структуры нормализованного фильтра LMS с плавающей запятой
[в]   pSrc   указывает на блок входных данных
[в]   pRef   указывает на блок справочных данных
[вне]   pOut   указывает на блок выходных данных
[вне]   pErr   указывает на блок данных об ошибке
[в]   размер блока   количество образцов для обработки
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 02, 2020, 09:24:04 pm
Решил вернуться к АРУ
Разобрал по косточкам алгоритм Андрея. Не нашел я обработку питчей. Простое плавное изменение множителя в оба направления. При этом ищется пик из всех значений .
                                       
    // Find peak gain reduction (Min)   
    Gain:=1e+6;                         
    for j:=AGCHang-1 downto 0 do begin 
      if Gb[j] < Gain then Gain:=Gb[j];
    end;                               
                                         
то есть алгоритм реагирует на всплески амплитуды и после срабатывает полная задержка. 

Название: Re: Цифровая АРУ 0...1
Отправлено: Relayer от Ноябрь 03, 2020, 12:30:21 am
Алгоритм изначально не мой а Янглблуда - я давал ссыль на статьи в QEX. Там на васике но еще проще - возможно имеет смысл оригинал почитать. Сейчас я бы так уже не делал. Мне больше понравилась реализация с удержанием ДД принимаемых сигналов на заданном уровне (http://dspview.com/viewtopic.php?f=8&t=261). В цифре это совсем не сложно получается - делал на ADAU1761 (http://dspview.com/viewtopic.php?f=9&t=263), на обычном проце еще проще. Суть в том что АРУ цепляется не за максимальный уровень а за минимальный, тоесть за шум эфира. При этом постоянная времени АРУ достаточно большая - единицы секунд. А после АРУ стоит компрессор который имеет порог +20..+30дб выше чем уровень шума. Итого имеем прозрачный эфир, слабые и громкие станции хорошо различаются. Хлопков нет т.к. АРУ за пички и прочее не цепляется. Постоянная времени срабатывания компрессора берется достаточно маленькая. Дополнительно за компрессором можно поставить жесткий лимитер на всякий пожарный
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 03, 2020, 08:19:26 am
Интересно , надо покурить. Игорь того же мнения относительно шума и сигнала. Честнее конечно мерить сигнал - шум .
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Ноябрь 03, 2020, 10:57:45 am
Игорь того же мнения относительно шума и сигнала.

Я бы так не сказал - написанное Андреем вообще не укладывается в моей голове - что там за что цепляется - не пойму. Нужна хотя бы блок-схема с подробным описанием.  1yep Зато, явно указано то, что АРУ у него медленная, несколько секунд, а это явно говорит о том, что пока она включится в работу при появлении мощной станции, в работе будут компрессор и лимитер, что само по себе явный ацтой - длительная компрессия на приёме - это же не наши методы и явное искажение динамики.
В последней моей АРУ, напомню, так же можно назвать скоростную ветку компрессором, но она работает при номинальных установках АРУ во временном диапазоне 5...30 мс после всплеска, дальше в работу вступает обычная АРУ, это никак не секунды, поэтому, и субъективно воспринимается нормально - компрессия незаметна, ну, и понятно, что без лимитера подобные устройства вообще делать нельзя, т. к., до момента срабатывания скоростной ветки (те же примерно 5 мс), сигнал на НЧ выходе будет существенно превышать номинальный уровень, а как это скажется на последующем тракте, не всегда можно с точностью предсказать.
Существенным плюсом цифры перед аналогом в этом случае, является возможность работы с предсказанием, т. е., без первого выброса при резком всплеске, неизбежного в моём варианте - ставить нулевое время срабатывания у скоростной АРУ нельзя - при работе в помехах лажа получается.
Но, опять же, этот неизбежный выброс ушами, фактически, не слышен, так что, к цифровизации своей АРУ пока что не стремлюсь... lol22
Название: Re: Цифровая АРУ 0...1
Отправлено: Relayer от Ноябрь 03, 2020, 12:09:20 pm
АРУ у него медленная, несколько секунд, а это явно говорит о том, что пока она включится в работу при появлении мощной станции
Вы ничего не поняли. И даже не пытались. АРУ у меня не цепляется за громкие станции - я об этом писал раз надцать уже. Она отслеживает шумовую дорожку и корректирует усиление тракта так, чтобы шум эфира был на заданное количество дб ниже порога срабаывания компрессора/лимитера

надо покурить
На адау получилось достаточно много блоков т.к. там потокое программирование. На сях да еще если ффт есть будет проще. Ищем минимальную амплитуду бина, усредняем по времени, рассчитываем усиление чтобы привести амплитуду шума к заданному уровню. Дальше я использовал PeakRMS компрессор с минимальным временем срабатывания, а сам сигнал подавал на него с задержкой
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Ноябрь 03, 2020, 02:07:01 pm
И даже не пытались.

Ну почему, я попытался, но не понял.  dontt44
И сейчас тоже пытаюсь, но, опять не понимаю.  1yep dontt44
К примеру, вот, типа, Вы отслеживаете какую-то шумовую дорожку, а, положим, на частоте идёт постоянный радиообмен, ну, и за что там Ваша АРУ будет цепляться, где она эту самую шумовую дорожку возьмёт?  44443
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 03, 2020, 02:09:33 pm
если ффт есть будет проще
Это есть. Идея пока понятна. В отсутствии станции не поднимать амплитуду до "1" . Я тут подумал, получается 2 ару расчета: первый приводим к  нужному уровню "0.5" шумовую дорожку, второй расчет получается, все что выше шумового уровня идет в прогрессивную компрессию до "1"
Никогда компрессор не использовал на приеме )))
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 03, 2020, 02:11:14 pm
и за что там Ваша АРУ
Игорь, там используется ффт панорамы для определения уровня шума на широком диапазоне частот. Кстати это же значения используется для определения старта панорамы снизу. Ару для панорамы
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Ноябрь 03, 2020, 02:52:59 pm
Игорь, там используется ффт панорамы для определения уровня шума на широком диапазоне частот.

Так, один фиг, неувязочка выходит - шумы на широком диапазоне смотрим, а слушаем 3 кГц. Это же разные вещи.  cr123
Впрочем, ни на чём не настаиваю, каждый сам творец своей АРУ... dontt44 lol22
Название: Re: Цифровая АРУ 0...1
Отправлено: Relayer от Ноябрь 03, 2020, 02:54:20 pm
К примеру, вот, типа, Вы отслеживаете какую-то шумовую дорожку, а, положим, на частоте идёт постоянный радиообмен, ну, и за что там Ваша АРУ будет цепляться, где она эту самую шумовую дорожку возьмёт?
За минимальный уровень в паузах. Причем не возьмет (в будущем когда-то) а уже вполне уверенно берет при обработке во временной области. У меня тоже были опасения что при длительном бла-бла-бла на частоте привязка шумовой дорожки будет "уплывать". Но на практике оказалось что все нормально - речь это вам не музыка. Но постоянная времени достаточно большая - единицы/десятки секунд.
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Ноябрь 03, 2020, 03:09:33 pm
За минимальный уровень в паузах.

Так паузы бывают разные. Бывают между словами, когда шум при мощной станции определяется ни столько шумом эфира, сколько шумом комнаты, из которой ведётся передача, бывает между серией передач, где реально только шум эфира.
Бывают в речи шипящие звуки, которые тоже вряд ли от шума отличить, и, их может быть очень много, если у человека проблемы с дикцией.  dontt44 1yep
Кроме того, как уже писал ранее, сама идея длительной работы компрессора на приём (более 30 мс на мои уши) вряд ли оправдана - убивать в явном виде динамику корреспондента - не самая хорошая идея.
На мой взгляд, идея убитая ещё при рождении, тем не менее, отговаривать не собираюсь... cr123
Название: Re: Цифровая АРУ 0...1
Отправлено: Relayer от Ноябрь 03, 2020, 03:19:35 pm
Ппц. Я вам рассказываю что сделано и работает, а вы мне рассказываете что пепелацы не летают потому что не соответствуют вашим представлениям о кошерности летательных аппаратов.
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Ноябрь 03, 2020, 03:32:27 pm
Я вам рассказываю что сделано и работает,

А я Вам рассказываю не про то, что это не работает, а про то, что даже на первый беглый взгляд, там глюков может быть выше крыши.
Дайте хотя бы 10-минутную запись работы этого чуда в загруженном диапазоне с шумами.  cr123
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 03, 2020, 04:24:43 pm
Вам не понравится. Это вообще странная технология, хотя может что то не понимаю. 20-30 дБ между Макс и шумом , это значит, что громкие станции будут компрессированными  dontt44 и шум будет слышно всегда
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Ноябрь 03, 2020, 04:28:19 pm
Вам не понравится.

А я это знаю.  44443
Мне моя нравится, работает именно так, как мне и нужно было.  1999
Это, как раз, тот случай, когда аналоговое решение не прогадывает любому цифровому.  cr123 pl33 lol22
А слушать слабые станции на 30 дБ слабее сильных, это для меня вообще что-то запредельное.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 03, 2020, 04:34:12 pm
А кто же спорит ? Речь о чем-то новеньком.
Название: Re: Цифровая АРУ 0...1
Отправлено: Relayer от Ноябрь 03, 2020, 05:12:14 pm
20-30 дБ между Макс и шумом , это значит, что громкие станции будут компрессированными  dontt44 и шум будет слышно всегда
Динамический диапазон сигналов на выходе такой АРУ можно выставить любым по своему усмотрению. Начиная от совсем плоского эфира и одинаковой громкости всех станций (но и сильным уровнем шума в паузах), так и 40-50дб когда вы шума эфира вообще не услышите в паузах
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Ноябрь 03, 2020, 05:52:31 pm
Тем не менее, опять же хотелось услышать реальную работу в зашумленном эфире.
Лично мне до сих пор непонятно, откуда там возьмётся какая-то прозрачность, про которую Вы писали - АРУ, типа, вообще, можно сказать, не при делах - она, по Вашим же словам, отрабатывает чуть не десятки секунд, а вся быстрая обработка предоставлена компрессору и лимитеру, успешно превращающим сигнал в кашу, и доводящим, к примеру, двухтоновый сигнал в сплошной частокол, за примерами ходить далеко не нужно - см., к примеру, мой ВЧ компрессор, это же реально крутая компрессия с нулевым временем срабатывания, и малым отпускания, там все картинки налицо, но то ж, пардон, устройство, СПЕЦИАЛЬНО искажающее сигнал для пробойности, и ни о какой "прозрачности" подобного сигнала даже речи быть не может... pl33
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 03, 2020, 06:05:43 pm
Кстати, Андрей, пытался сейчас кое что повторить из вашего алгоритма и нашел серьезный косяк. Там ару срабатывает на фрейм целиком, с нарастанием в 1мсек. Если в этот участок попадет скачок то будет стук стук, или всплеск или перегруз даже. Такой подход на обработку громких сигналов ставить нельзя. Так, что пока остается подход Геннадия: изменение ару на протяжении всего фрейма в зависимости от уровня. У вас,  если там будет (условно) три скачка (в начале, в середине и в конце с нарастанием) то ваш алгоритм сразу начнет ару загрублять (1мс) и туда попадет первый всплеск (который даст стук стук) потом провал будет пока не придет самый громкий всплеск где уже будет ару актуально.

С новым алгоритмом пока не дал ладу...думаю над ним пока.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 03, 2020, 06:10:15 pm
Я думаю в новом алгоритме есть резон. Ну смотрите, мы делаем компрессоры , которые ломают сигнал лишь бы энергетики туда дать. А какая разница с приемом? Если человек работает без компрессора, то мы ему "включим" компрессор как бы.  lllol и по идеи если слабая станция работает без компрессора, то вероятность улучшения приема имеет место быть.   
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Ноябрь 03, 2020, 06:24:00 pm
Если человек работает без компрессора, то мы ему "включим" компрессор как бы.

Компрессия повышает пробойность только в том случае, когда исходник чистый, в этом случае, по крайней мере, перемножения полезного сигнала на мусор не происходит, а при приёме, именно этот нежелательный момент и произойдёт.
По моим наблюдениям, и статистике от сторонних людей, эфир карёжить компрессией нельзя категорически - появляющиеся лишние компоненты существенно снижают прозрачность...  lllol
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 03, 2020, 09:29:26 pm
Попробовал компрессор по приему  cr123 cr123
Сделал из хорошего приемника - плохой )))
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Ноябрь 03, 2020, 09:44:39 pm
 44443
Название: Re: Цифровая АРУ 0...1
Отправлено: Relayer от Ноябрь 04, 2020, 12:24:21 am
Попробовал компрессор по приему
Так компрессор компрессору рознь. Поиграйтесь параметрами. В адау например там их есть несколько
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 04, 2020, 05:51:55 pm
Потратил целый день на всякие алгоритмы, но не нашел лучше варианта Андрея. Кстати беру свои слова назад, алгоритм Андрея работает мягко. Да, есть провалы перед всплеском, но это не слышно, только видно. Напомню, алгоритм Андрея делает ару на фрейм, причем, первую 1 мсек нарастание идет плавно (это основная фишка алгоритма). И можно было бы бросить дальше  что -то придумывать , но башка рукам покоя не дает.

Вот мой алгоритм  (потом фишки расскажу)
uint16_t countBack = 10;

void agcDo(float32_t *buffer) {

    float32_t agcMetrTemp = 0;

    if (tim > 0)tim--; //уменьшение задержки


    for (uint16_t i = 0; i < FRAME_SIZE; i++) {
        float32_t a;
        a = (buffer[i] < 0.0f) ? -buffer[i] : buffer[i];// adc V

        nowAgc = 1.0f / a; //coeff --> 1, nowAgc=чем меньше - тем сильнее загибаем pOutLms, 1 макс усиление.
        if (a > agcMetrTemp) agcMetrTemp = a; //s-meter макс V

        if (nowAgc < agcLevel) {
            tim = 40;//задержка отпускания
            agcLevel = nowAgc;
        } else {

            if (nowAgc > agcLevel) {
                float32_t s = (1.0f / agcLevel);//скорость нарастания
                if (tim == 0) {//активное нарастание
                    agcLevel += s;/// 0.01f;//скорость нарастания
                } else {
                    if (!countBack) {//спокойное нарастание через шаг
                        agcLevel += 0.001f;
                        countBack = 5;// шаг , делаем плавное нарастание через 5 замеров
                        //если делать каждый шаг - растет имд
                    } else countBack--;
                }
            }
        }
        buffer[i] *= agcLevel;
    }
    agcMetr = agcMetrTemp; //s-meter

}
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 04, 2020, 05:59:50 pm
Вот так это выглядит.
Сперва плавный подъем потом основной. Зачем это надо? При долгом прослушивании музыки и эфира через всю системы (музыка в 3 кГц  cr123)  обнаружил, что иногда в тихих местах начинает срабатывать основной возврат (откат ару) и это прям сильно все портит. Тоже самое в эфире, когда человек говорит и иногда ару приспичевает сработать и это дает "ПШИК" . Я вспонил, что боролся с этим в Монстре и вспомнил как  rrr7777 мелкий дрифт ару туда-сюда, без задействования основной задержки. Просто постепенно +1 уе или -1 уе даю пока не придет что то серьезное - тогда полный запуск   

PS на снимке во время возврата есть всплеск и опять назад - это так комп чудит совместно с видоуз. В нормальной жизни его нет.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 04, 2020, 06:03:24 pm
Причем в генераторных условиях все достаточно обыденно, но в реалях это работает и дает мягкую подтяжку ,  стробирование  сигнала в то время как основная задержка еще держит. Так же это все не плохо работает на шумовой дорожке - нет "ПШШШ" неожиданных.
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Ноябрь 04, 2020, 06:13:43 pm
А где же работа компрессора, который должен был сразу резко поднять усиление, и АРУ, которая цепляется за шум, и имеет время отрабатывания несколько секунд?
Или это что-то другое?  cr123
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 04, 2020, 06:22:04 pm
Вот запись 80м
Ару мое, фильтра мои.
СДР в Туле.

https://drive.google.com/file/d/1CJ-NMpZv79WvvCWnEGPIBw1HtxoT6Qc-/view?usp=sharing
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 04, 2020, 06:23:52 pm
А где же работа компрессора, который должен был сразу резко поднять усиление, и АРУ, которая цепляется за шум, и имеет время отрабатывания несколько секунд?
Или это что-то другое?  cr123

Шутите  lllol

Я понял , что имел ввиду Андрей. Громкие станции должны звучать громче. Мы страниц 10 исписали когда я Монстра на прием запустил.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 06, 2020, 08:17:47 am
После вчерашнего разговора с Игорем , нашёл серьёзный косяк в работе ару. Раньше я  только догадывался , что где то косяк , а после разговора как лампочка зажглась  id99
Когда в рамках одного фрейма идёт коррекция, то это выглядит вот "так" ! Нужен другой подход. Этот алгоритм обязательно будет стучать. И чем ниже частота тем сильнее это будет появляться. Зато теперь понятно почему когда я музыку слушал и там били низы зачастую проскакивал стук.
На фото оригинал и обработанный алгоритмом ару.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 06, 2020, 08:26:03 am
Буду пробовать так (абсолютные значения замеров):
Нужно обрабатывать СКАТ , а не искать только пики.

Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Ноябрь 06, 2020, 01:02:27 pm
После вчерашнего разговора с Игорем , нашёл серьёзный косяк в работе ару.

Честно говоря, вообще не понимаю, в чём там могут быть проблемы.  dontt44
Ставим АЦП, приведённый на вход максимальный сигнал должен быть -10 дБ от его перегрузки, т. е., её перегруз исключён по определению, разве что, на то время, пока сильносигнальная АРУ не отработает, а это единицы миллисекунд.
По умолчанию, выходной сигнал ЦАП вычисляется как 3162*вход АЦП (+70 дБ). Как только входной сигнал на АЦП превышает -80 дБ от максимума (как раз, сумма 70 и 10), коэффициент усиления пропорционально роняем, удерживая уровень на выходе ЦАП на пиках равным, на этом этапе можно и интегрирование сделать, допустив перегрузку ЦАП на коротких импульсах, он же, кстати, будет и лимитером работать по нулевому уровню.
Никто не запрещает работать в номинале на уровне -6 дБ от максимума ЦАП, получится лимитер +6 дБ, или те же 3 дБ, как у меня в последних версиях монстра.
Можно две петли сделать, как у меня - быструю и медленную - с одной все хотелки получить проблематично.  1yep
Естественно, после лимитера должен быть ФНЧ, в противном случае, расширение спектра на пиках будет слушаться ацтойно.
И никаких проблем нет, от слова вообще - полное повторение моего аналогового алгоритма АРУ, в котором никаких глюков нет и в помине, и адекватной реальной замены которому с полной объективной выкладкой получившихся результатов, а не только фантазиями, которых я и сам мастер нагнать 500 вариантов, пока что никто не придумал... pl33 lllol lol22

Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 06, 2020, 01:49:21 pm
Нарвался на пульсации блока питания компьютера  cr123
ару стремится даже их отработать.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 06, 2020, 02:42:11 pm
Еще просидел. Теперь я знаю как компрессор делается, но к ару это мало отношение имеет. Бился, бился - все равно компрессор выходит и всё  dontt44

ОПЯТЬ ВСЕ УДАЛИЛ .

Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 06, 2020, 04:16:58 pm
По выше нарисованному чертежу новой ару сделал алгоритм.
Как то работате.

На рисунке стыковка шума (максимальное усиление) и два тона (с максимальной амплитудой мин усиление)
 
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Ноябрь 06, 2020, 04:26:45 pm
Да Вы ступеньки покажите с однотоновым перепадом 60 дБ, т. е., идёт 10 мкВ, потом 10 мВ, потом - назад, переходная характеристика интересна... cr123
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 06, 2020, 04:28:54 pm
Терпение  rrr7777
Есть еще варианты при который алгоритм "улетает"
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Ноябрь 06, 2020, 04:39:40 pm
Да, сложная задача... 44443
Положим, хотите АРУ с временем срабатывания 20 мс, отпускания - 2 с.
Берёте интеграл модуля по времени от того, что загнано в буфер (он у Вас, по-моему, как раз-то 20 мс.), если величина превышает заданный порог (величина порога зависит от выставленного в данный момент усиления в ЦАП), пропорционально скидываете усиление в ЦАП, и всё в порядке - перегруз по среднему уровню исключён, выброса не будет, в отличие от аналогового аналога.
Отпускание - по 2-секундной экспоненте, повторю - вместе с ростом усиления ЦАП, пропорционально снижается порог срабатывания интегратора (чтобы средний уровень на выходе ЦАП держать), у меня эта фигня ещё в конце 80-х работала, как АРУ без выбросов, правда, на весьма примитивной элементной базе - по-моему, вообще 8-битки были с процом размером с коробок спичек  lllol, и никаких проблем.
.. lol22
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Ноябрь 06, 2020, 05:02:23 pm
Причём, ЧТО ВАЖНО - у меня не было никаких кусочных разбиваний - 256 выборок грузились в сдвиговый регистр, и обновлялись с каждой новой выборкой.
Работа по кускам, когда Вы грузите 20 мс, потом их скидываете, и загоняете новые, обрабатывая их ПО ОТДЕЛЬНОСТИ, по самой своей природе НЕ СМОЖЕТ адекватно работать АРУ.
Простой пример - на конце последней выборки всплеск, и на начале следующей - тоже, тот же самый. Интегрирование по выборкам не даст превышение порога, а интегрирование по последней половине первой, и началу последующей - даст.
Т. е., есть временнАя неопределённость алгоритма - всплеск на границе фреймов не отработается, а в середине - да.
Только непрерывно, тогда и будет Вам счастье. Кусками даже голову не морочьте, ибо там ацтой по определению... lllol
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 06, 2020, 06:32:38 pm
Я еще на пути Джедая  8) , пока не сдаемся. Есть моменты, которые у меня в голове не укладываются. Наверное надо паузу сделать. 
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 06, 2020, 07:15:43 pm
Ну как-то так

переход -45дб  -5дб на разных частотах.
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Ноябрь 06, 2020, 08:39:41 pm
Да не, то фигня какая-то. Должна быть одна вполне явная синусоида, потом, не менее явная другая... lllol
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 07, 2020, 12:47:12 pm
Пока воюю с вот таким всплеском.
Пока даже физику не могу понять , что раскачивает . Сейчас ару по скату работает.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 07, 2020, 03:10:05 pm
Лайт версия
Работает
плавное от -5 до -45
и резкое от -45 до -5дб

Совмещение частот вроде норм.

Косяк: ару должно работать 0...1 , а сейчас работает  0...0.8, ставишь даже предел 0.9 сразу на всплесках проскакивает инверсный float . Уже целый день борюсь с этим перегрузом (инверсия float) . У меня уже программа больше из защит и проверок состоит, нежели сам алгоритм.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 07, 2020, 03:22:18 pm
УФ

Новое АРУ по скату.

float32_t adcMin = 1;
float32_t nextAdc;
float32_t ampMax = 0;

uint8_t isMin = 0;
float32_t max = 0.8f;

void agcDo(float32_t *buffer) {

    float32_t agcMetrTemp = 0;
    uint16_t countBack = 10;
    uint16_t idx = 0;
    uint16_t idxMin = 0;

    if (tim > 0)tim--; //уменьшение задержки


    for (uint16_t i = 0; i < FRAME_SIZE; i++) {
        float32_t a;
        //a = (buffer[i] < 0.0f) ? -1.0f * buffer[i] : buffer[i];// adc V
        a = fabsf(buffer[i]);



        if (a > 0)nowAgc = max / a; //coeff --> 1, nowAgc=чем меньше - тем сильнее загибаем pOutLms, 1 макс усиление.
        else nowAgc = max / 0.0001f;


        if (nowAgc < agcLevel) { // всплеск V
            tim = 10;//задежка отпускания
            uint16_t downIdx = i;
            uint16_t upIdx = i;
            uint16_t exit = 1;
            int direction = 0;//напрвление вниз (отрицательная синусоида)

            if (buffer[i] > 0) direction = 1;//напрвление вверх (положительная синусоида)

            while (exit) {
                exit = 0;//выходим
                if (direction) {//++
                    //going up

                    if (buffer[upIdx] <= buffer[upIdx + 1] && upIdx + 1 < FRAME_SIZE) {
                        upIdx++;
                        exit = 1;//не выходим
                    }
                    //go down
                    if (buffer[downIdx] >= buffer[downIdx - 1] && downIdx - 1 >= 0) {//&& buffer[downIdx - 1] >= 0
                        downIdx--;
                        exit = 1;//не выходим
                    }

                } else { //--
                    //going up
                    if (buffer[upIdx] >= buffer[upIdx + 1] && upIdx + 1 < FRAME_SIZE) {
                        upIdx++;
                        exit = 1;//не выходим
                    }
                    //go down
                    if (buffer[downIdx] <= buffer[downIdx - 1] && downIdx - 1 >= 0) {// && buffer[downIdx - 1] <= 0
                        downIdx--;
                        exit = 1;//не выходим
                    }
                }
            }//while

            if ((upIdx > downIdx) && i > 0 && i < FRAME_SIZE - 1) {
                if (buffer[upIdx] != 0)
                    nowAgc = max / fabsf(buffer[upIdx]);//максимальное значение
                else nowAgc = max / 0.0002f;

                for (uint16_t z = downIdx; z <= upIdx; z++) {

                    double_t f = fabsf(buffer[z]) * nowAgc;

                    if (f > max) {//out
                        if (buffer[z] > 0) buffer[z] = max;
                        else buffer[z] = -max;
                    } else if (f > 0)//norm
                        buffer[z] *= nowAgc;
                    else {//out
                        if (buffer[z] >= 0) buffer[z] = 0.0002f;
                        else buffer[z] = -0.0002f;
                    }
                }

                i = upIdx;
            } else {

                double_t f = a * nowAgc;

                if (f > max) {//out
                    if (buffer[i] > 0) buffer[i] = max;
                    else buffer[i] = -max;
                } else if (f > 0)//norm
                    buffer[i] *= nowAgc;
                else {//out
                    if (buffer[i] >= 0) buffer[i] = 0.0002f;
                    else buffer[i] = -0.0002f;
                }


//                //защита от прегруза
//                if (buffer[i] < -max)buffer[i] = -(max-0.5f);
//                if (buffer[i] > max) buffer[i] = max-0.5f;
//
            }
            agcLevel = nowAgc;


        } else {//если спад V
            double_t f;
            float32_t cc = agcLevel + 0.005f;

            if (tim == 0)f = a * cc;
            else f = a * agcLevel;

            if (f > max) {//out
                if (buffer[i] > 0) buffer[i] = max;
                else buffer[i] = -max;
            } else if (f > 0) {//norm
                if (tim == 0) {
                    agcLevel = cc;
                    buffer[i] *= cc;
                } else buffer[i] *= agcLevel;
            } else {//out
                if (buffer[i] >= 0) buffer[i] = 0.0002f;
                else buffer[i] = -0.0002f;
            }
//            //guard
//                if (buffer[i] < -max)buffer[i] = -(max-0.5f);
//                if (buffer[i] > max) buffer[i] = max-0.5f;


        }
        if (a > agcMetrTemp) agcMetrTemp = a; //s-meter макс V
    }
    // защита от перегруза
//    for (uint16_t i = 0; i < FRAME_SIZE; i++) {
//        if (buffer[i] < -max) buffer[i] = -max+0.2f;
//        if (buffer[i] > max) buffer[i] = max-0.2f;
//
//    }
    agcMetr = agcMetrTemp; //s-meter
}
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 07, 2020, 03:44:53 pm
На фото и проблема и решение ее
Я целяком в реверсе опускаю скат и ступеньки не получается
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 08, 2020, 04:57:23 pm
Нашёл ошибки , будут уточнения по алгоритму .
Например , откат ару вещь тоже сложная. Ее можно только на пиках откатывать с контролем на два шага вперёд.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 08, 2020, 09:30:56 pm
Игорь, есть вопрос.
Я правильно подключаю ацп ?
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 08, 2020, 09:34:59 pm
А то по ходу я с ветряными мельницами воюю. Может я неправильно подключил цап или ацп к звуковой?

фото : это без работы ару . И там появляется переходный процесс. А если со звуковой на звуковую (разные) то все ок , синусоида перетекает ровно без переходноо процесса.

Может просадка напряжения ...??
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Ноябрь 08, 2020, 09:49:39 pm
Я повально подключаю ацп ?

Правильно.  1yep
А по поводу переходного процесса - Вы откуда сигнал берёте?
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 08, 2020, 10:07:18 pm
Выход на наушники
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Ноябрь 08, 2020, 10:11:42 pm
Я не про то. Кто формирует сигнал со ступенчатым перепадом? И зачем брать такие низкие частоты?  dontt44
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 09, 2020, 11:31:36 am
По низким в основном и происходят искажения. Это связано с там , что больше точек при оцифровки. Ну или еще по каким причинам хз .

Игорь, какие будут (схемные решения) рекомендации по выходу ЦАП?
У меня сейчас просто последовательно емкость 10.0
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Ноябрь 09, 2020, 03:52:50 pm
Игорь, какие будут (схемные решения) рекомендации по выходу ЦАП?

Поставьте 10 мкФ, после него - 1 кОм на землю. Если Ваш ЦАП такие нагрузки выдерживает.
Частота среза - 16 Гц, Вам хватит за глаза.... lol22
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 10, 2020, 05:46:44 pm
Ну в общем провел еще несколько тестов.
Однозначно это глючит АЦП. При серьезном скачке идет провал. Этот провал полностью отсутствует когда со звуковой на звуковую напрямик подаешь. Смоделировал синус внутри системы - этого провала тоже нет.
Вывод можно сделать один: референсное питание ацп и мои полпитания на входе ацп  - отличаются.
Нужно и реф питание ацп и полпитание на входе ацп питать от одного источника, а моем случаи между ними есть дроссель и за дросселем емкости.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 11, 2020, 11:08:32 am
Оставлю я пока проблему ацп. Да и нет так сильно она влияет. Есть другая проблема, питчки. Они дергаю ару и как следствие систему отката и выглядит это так:

(подан белый шум макс амплитуды)
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 11, 2020, 11:10:16 am
Соответственно на каждый взлет срабатывает система ару, а потом опять откат, и так в бесконечном цикле. Туда - сюда колбасит.
Нужно окно, гистерезис
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 11, 2020, 11:16:16 am
Пока действует этот вариант, он значительно лучше Лайт варианта. Полностью переработана система отката ару (через поиск пика сигнала).

float32_t max = 0.5f;

void agcDo(float32_t *buffer) {

    float32_t agcMetrTemp = 0;

    if (tim > 0)tim--; //уменьшение задержки


    for (uint16_t i = 0; i < FRAME_SIZE; i++) {
        float32_t a;
        //a = (buffer[i] < 0.0f) ? -1.0f * buffer[i] : buffer[i];// adc V
        a = fabsf(buffer[i]);


        // seach min

        if (a > 0)nowAgc = max / a; //coeff --> 1, nowAgc=чем меньше - тем сильнее загибаем pOutLms, 1 макс усиление.
        else nowAgc = max / 0.00005f;


        if (nowAgc < agcLevel) { // всплеск V
            tim = 10;//задежка отпускания
            uint16_t downIdx = i;
            uint16_t upIdx = i;
            uint16_t exit = 1;
            int direction = 0;//напрвление вниз (отрицательная синусоида)

            if (buffer[i] > 0) direction = 1;//напрвление вверх (положительная синусоида)

            while (exit) {
                exit = 0;//выходим
                if (direction) {//++
                    //going up

                    if (buffer[upIdx] <= buffer[upIdx + 1] && upIdx + 1 < FRAME_SIZE) {
                        upIdx++;
                        exit = 1;//не выходим
                    }
                    //go down

//                    if (((buffer[downIdx] >= buffer[downIdx - 1] && buffer[downIdx] > 0) || buffer[downIdx - 1] < 0) && downIdx - 1 >= 0) {//&& buffer[downIdx - 1] >= 0
                   if (buffer[downIdx - 1] >= 0 && downIdx - 1 >= 0) {//&& buffer[downIdx - 1] >= 0
                        downIdx--;
                        exit = 1;//не выходим
                    }

                } else { //--
                    //going up
                    if (buffer[upIdx] >= buffer[upIdx + 1] && upIdx + 1 < FRAME_SIZE) {
                        upIdx++;
                        exit = 1;//не выходим
                    }
                    //go down
//                    if (((buffer[downIdx] <= buffer[downIdx - 1] && buffer[downIdx] < 0) || buffer[downIdx - 1] > 0) &&  downIdx - 1 >= 0) {// && buffer[downIdx - 1] <= 0
                   if (buffer[downIdx - 1] <= 0 && downIdx - 1 >= 0) {// && buffer[downIdx - 1] <= 0
                        downIdx--;
                        exit = 1;//не выходим
                    }
                }
            }//while

            if ((upIdx > downIdx) && i > 0 && i < FRAME_SIZE - 1) {
                if (buffer[upIdx] != 0) {
                    nowAgc = max / fabsf(buffer[upIdx]);//максимальное значение
                } else nowAgc = max / max;


                for (uint16_t z = downIdx; z <= upIdx; z++) {
                    if (z < i) buffer[z] *= nowAgc / agcLevel; //там уже применен коэфф
                    else buffer[z] *= nowAgc;//применить новый коэфф
                }

                i = upIdx;
            } else {

                float32_t f = a * nowAgc;

                if (f > max) {//out
                    if (buffer[i] >= 0) buffer[i] = max;//max
                    else buffer[i] = -max;//max
                    nowAgc = 1;
                }else  buffer[i] *= nowAgc;

            }
            agcLevel = nowAgc;


        } else {//если спад V
            float32_t f = fabsf(buffer[i + 1]);


            if(tim == 0 && a < f && f >= fabsf(buffer[i + 2]) && i < FRAME_SIZE - 2 ) {
                float32_t cc = agcLevel + 0.005f;
                if ( f * cc < max ) {
                    agcLevel = cc;
                } else {
                    cc = agcLevel + 0.0005f;
                    if ( f * cc < max ) {
                        agcLevel = cc;
                    }
                }
            }
            if( a < f && f >= fabsf(buffer[i + 2]) && i < FRAME_SIZE - 2 )
                agcLevel += 0.00001f;

            if (a * agcLevel <= max)
                buffer[i] *= agcLevel;
            else {
                if (buffer[i] >= 0) buffer[i] = max;//max
                else buffer[i] = -max;//max
                agcLevel = max;
            }


        }
        if (a > agcMetrTemp) agcMetrTemp = a; //s-meter макс V
    }
    agcMetr = agcMetrTemp; //s-meter
}
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 12, 2020, 09:04:10 am
Всё удалил. Делаю новый алгоритм.  cr123
Название: Re: Цифровая АРУ 0...1
Отправлено: r1tx от Ноябрь 12, 2020, 10:10:13 am
Соответственно на каждый взлет срабатывает система ару, а потом опять откат, и так в бесконечном цикле. Туда - сюда колбасит.
Нужно окно, гистерезис
А скорость атаки и скорость отпускания регулируется?
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 12, 2020, 10:16:38 am
Скорость атаки понятие отсутствует, а отпускание и угол отпускания само сабой.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 12, 2020, 10:17:12 am
Сейчас воюю над этим (белый шум макс уровня на входе)
фото
 с ару
и без ару
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 12, 2020, 10:28:11 am
Думаю над питчиками  cr123

Название: Re: Цифровая АРУ 0...1
Отправлено: r1tx от Ноябрь 12, 2020, 09:15:44 pm
Скорость атаки в моем понимании скорость реакции на входной импульс. В компрессорах ее так называют.
И еще вы фазу сигнала рвете при регулировании? птички от разрыва фазы могут быть.
ФЧХ посмотрите Во время регулирования.
Спектр при zerospan у анализатора передний фронт при атаке на выходе АРУ какой? ...если можно конечно посмотреть на нем так...
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 12, 2020, 10:09:48 pm
В цифре такого нет . В цифре сперва обрабатывается данные и только потом они воспроизводятся. Поэтому всегда задержка есть. И понятие атаки нет, либо ее можно сделать так как захочешь. Пока есть над чем подумать и сделать.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 12, 2020, 10:11:28 pm
И еще вы фазу сигнала рвете при регулировании?
так об этом и речь, что я работаю со скатом целиком, а сейчас вообще с полупериодом  как раз чтобы сигнал не портить.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 12, 2020, 10:32:20 pm
Я понял, что это за всплески  lol22
Это как раз те участки в которых нет питчей и ару их поднимает. И длина у них почти с фрейм (1024 замера ацп)
Название: Re: Цифровая АРУ 0...1
Отправлено: Relayer от Ноябрь 12, 2020, 11:28:53 pm
rms-детектор спасет отца русской демократии. Не надо за пички цеплятся. Их надо просто срезать лимитером после ару
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 13, 2020, 01:18:33 pm
ну хорошо, rms, а дальше что с ним делать. Занижать битность ?

Есть у меня мысль ... питч чаще всего приходит в одной полярности и очень большой амплитуды. Так вот, а что если мне смотреть следующий за питчем пик и сделать вывод был это сигнал или просто вылет. Если второй пик тоже мощный то с большой долей вероятности это сигнал и нужно включать задержку с занижением амплитуды, а если следующий питчек мал и не является выбросом - то первый был питчек и мы не включаем задержку, а просто просаживаем питчек по амплитуде. Своеобразный шумодав получается. 
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 13, 2020, 01:52:19 pm
я же говорил шумодав получится  lol22
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 13, 2020, 05:41:05 pm
Пока получается полная фигня
Название: Re: Цифровая АРУ 0...1
Отправлено: Relayer от Ноябрь 13, 2020, 06:52:27 pm
google("feedforward agc");
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 14, 2020, 10:35:06 am
google("feedforward agc");
спасибо я посмотрю обязательно.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 14, 2020, 10:42:11 am
Война с питчиками оказалась весьма интересная.  lol22 lol22 веселья аж на 3 дня и три ночи. Цепануло так цепануло.  44443 44443

Вроде победил, но с одной оговоркой. Нужно вводить дельту на откат ару к максимальным усилениям. Что это значит: если постоянно держать сигнал около 1, без дельты, то происходит "стробирование" сигнала и постоянная качка то усиливаем то ослабляем. В наушниках как море  и прибой со случайными времменными задержками. Кстати, самый честный сигнал для испытания ару - это розовый шум  cr123 он сразу все косяки вытаскивает.
Вот пример когда ару пытается держать 1 без дельты:

На водопаде хорошо видно стробирование сигнала по амплитуде. (я еще работаю над этим)

PS Контроль питчиков идет в 1мсек. Идет замер 2 пиков по 1мсек с контролем перехода через 0, то есть, там не ровно 1 мсек - плавает в зависимости от сигнала. Так вот, если второй пик не содержит больших амплитуд, то мы оставляем уровень ару до появления питчика. Ну конечно же сам питчик прижимается к нормальному уровню без перегруза.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 14, 2020, 10:53:16 am
Новый вариант с контролем питчиков

float32_t max = 0.49975586f;
uint16_t count = 100;
float32_t pit1 = 0;
float32_t pit2 = 0;

void agcDo(float32_t *buffer) {

    float32_t agcMetrTemp = 0;

    if (tim > 0)tim--; //уменьшение задержки


    for (uint16_t i = 0; i < FRAME_SIZE; i++) {
        float32_t a;
        //a = (buffer[i] < 0.0f) ? -1.0f * buffer[i] : buffer[i];// adc V
        a = fabsf(buffer[i]);


        // seach min

        if (a > 0)nowAgc = max / a; //coeff --> 1, nowAgc=чем меньше - тем сильнее загибаем pOutLms, 1 макс усиление.
        else nowAgc = max / 0.00005f;

        uint16_t upIdx = i;
        float32_t pikBuf = 0;
        uint16_t exit = 1;
        int direction = 0;//напрвление вниз (отрицательная синусоида)

        if (buffer[i] >= 0) direction = 1;//напрвление вверх (положительная синусоида)

        while (exit) {
            exit = 0;//выходим
            uint16_t idx1 = (uint16_t) (upIdx + 1);
            float32_t p1 = fabsf(buffer[idx1]);
            if (idx1 < FRAME_SIZE) {
                if (direction) {//+++++++++++++++++++++++++++++
                    if ((buffer[upIdx] < 0 && buffer[idx1] >= 0) || (upIdx - i < 48)) {
                        upIdx++;
                        if (p1 > pikBuf) {
                            pikBuf = p1;
                        }
                        exit = 1;//не выходим
                    }
                } else { //------------------------
                    //going up
                    if ((buffer[upIdx] > 0 && buffer[idx1] <= 0) || (upIdx - i < 48)) {
                        upIdx++;
                        if (p1 > pikBuf) {
                            pikBuf = p1;
                        }
                        exit = 1;//не выходим
                    }
                }
            }
        }//while

        if (upIdx > i) upIdx--;

        if (upIdx > i) {
            float32_t locNowAgc;

            if (!pit1) {
                pit1 = pikBuf;
                pit2 = 0;
            } else {
                pit2 = pikBuf;
            }
            //проверка на 0
            if (pikBuf != 0) {
                locNowAgc = max / pikBuf;//максимальное значение
            } else locNowAgc = max / 0.00005f;

            //agcLevel == текущий уровень ару
            if (locNowAgc < agcLevel) { // всплеск или питч V, идем вниз
                //заполним полупериод
                if (i) {
                    for (uint16_t z = i; z <= upIdx; z++) {
                        buffer[z] *= locNowAgc;//применить новый коэфф
                    }
                } else {//механизм сочленения с пред фреймом ...ждем первого нуля
                    if (buffer[0] >= 0) direction = 1;//напрвление вверх (положительная синусоида)
                    exit = 1;
                    uint16_t idx0=0;
                    while (exit) {
                        exit = 0;//выходим
                        if (direction) {//+++++++++++++++++++++++++++++
                            if (buffer[idx0] >= 0) {
                                idx0++;
                                exit = 1;//не выходим
                            }
                        } else { //------------------------
                            //going up
                            if (buffer[idx0] <= 0 ) {
                                idx0++;
                                exit = 1;//не выходим
                            }
                        }
                    }//while
                    for (uint16_t z = 0; z <= upIdx; z++) {
                       if(z<=idx0)buffer[z] *= agcLevel;//применить старый коэфф
                       else buffer[z] *= locNowAgc;//применить новый коэфф
                    }

                }


                if (pit1 && pit2) { //если есть оба пика (модуль амплитуды)

                    if (pit1 > pit2) {
                        agcLevel = (max / pit2); // ставим текущий уровень ару по пику2
                        tim = 10;//задежка отпускания

                    }
                    //если сигнал продолжает наращивать амплитуду то будем ждать пока не перестанет
                    //обнуляем содержимое пик1 и пишим туда текущее пик2 (пик2 всегда текущие)
                    if (pit2 >= pit1) {//смотрим следующий питч если
                        pit1 = pit2;
                        pit2 = 0;

                    } else {
                        pit1 = pit2 = 0;//запускаем заново поиск пиков питчей
                    }
                }

            } else {//идем вверх
                if (tim == 0) {//подождали и начинаем

                    float32_t bb = pikBuf;
                    //расчет сколько будем откатывать .....сложно всё надо еще думать
                    float32_t cc = agcLevel + (sqrtf(agcLevel) / 200) * (upIdx - i);

                    if (bb * cc < max-0.0f) {
                        agcLevel = cc;
                    }
                }
                //заполним полупериод
                for (uint16_t z = i; z <= upIdx; z++) {
                    buffer[z] *= agcLevel;//применить новый коэфф
                }
            }
            i = upIdx; // след цикл будет стратовать от upIdx

        } else { //это сидуация редкая но тоже надо . сделано по класике одного замера

            if (nowAgc < agcLevel) { // всплеск V
                agcLevel = nowAgc;
                tim = 10;//задежка отпускания
            }

            float32_t f = a * agcLevel;

            //контроль вылета в out
            if (f > max) {//out
                if (buffer[i] >= 0) buffer[i] = max;//max
                else buffer[i] = -max;//max
                // agcLevel = 1;
            } else
                buffer[i] *= agcLevel;

        }

        if (a > agcMetrTemp) agcMetrTemp = a; //s-meter макс V
    }//for
    agcMetr = agcMetrTemp; //s-meter
}
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 14, 2020, 10:59:24 am
А вот так уже с дельтой по откату
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 14, 2020, 11:02:17 am
При этом на нормальном сигнале эта дельта не сказывается. Наверное будет заметна только в динамике.
Название: Re: Цифровая АРУ 0...1
Отправлено: Relayer от Ноябрь 14, 2020, 04:34:47 pm
Сложный алгоритм работы ару приведет к тому что она будет жить своей жизнью и "дышать" вам в уши.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 14, 2020, 04:50:52 pm
Я ещё не закончил , но уже надоедает. Посмотрел алгоритм feed forward - это мы уже пошли. Шум сложнее всего обрабатывать. Все не предсказуемо. Длина фрейма всего 20 мсек сильно не наанализируешь. Но вообще я начал с левого ската , потом полупериод, потом период и сейчас уже несколько периодов длиной в 1 мсек анализирую. Я даже меж фреймовое сопряжение сделал. Выглядит страшно, но там просто много условий, а они выполняются в один такт. Пока я столкнулся с тем , что я не знаю до куда откатывать ару - это всегда сюрприз. Попадаешь в тихий участок без питчеков ару откатывает ещё (даёт усиление) и тут питчик прилетает и система сразу реагирует сильным снижением усиления. Причём может несколько секунд быть все ок , а потом прилетает. Но я ещё думаю. Далеко продвинулся. Но толи где-то ошибка либо просто не все учёл.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 14, 2020, 07:41:05 pm
Интересный эффект обнаружил  cr123 cr123 cr123
Борьба с питчиками привела к компрессии
Вот фото отката (после снятия сильного сигнала) ару начинает усиление и в правом верхнем углу хорошо видно как алгоритм начинает борьбу с питчиками и глатает их и при этом происходит компрессия сигнала. Естественно потом ару "просыпается" и скидывает вниз  усиление. 
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 14, 2020, 11:30:09 pm
И я снова удалил практически всё. Нужен был новый подход.
Наверное Андрей прав (опять) и нужно сигнал на лимиттер садить иногда.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 15, 2020, 09:09:16 am
Ну вот пока , что удалось на розовом шуме сделать. С компрессией. Все питчи автоматом съедает.
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Ноябрь 15, 2020, 11:00:17 am
нужно сигнал на лимиттер садить иногда.

У меня, напомню, совсем короткие пички (типа, до 2 мс, точное время уже не помню) именно на лимитер и садятся, отрабатывать их АРУ смысла не вижу никакого..  dontt44 pl33
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 15, 2020, 02:06:45 pm
Я вообщем то все понимаю, но только не могу до конца понять от куда этот хвост появляется ?  no88 Собственно с ним и борюсь уже три дня.

Ну вот какой участок осциллограммы дает этот хвост?
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Ноябрь 15, 2020, 02:38:33 pm
Любое амплитудное вмешательство в исходник расширяет его спектр, и тем сильнее, чем с большей частотой (большей крутизной) Вы осуществляете регулирование, от этого уйти нельзя, это по определению.
Если стоит лимитер, или скоростная АРУ, рубящая пички, НЧ фильтр за ней очень полезен, гляньте, к примеру, на модуль 0913... 123123 pl33
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 15, 2020, 03:06:16 pm
У меня стоит фильтр 300-ого порядка после ару
Название: Re: Цифровая АРУ 0...1
Отправлено: Relayer от Ноябрь 15, 2020, 03:08:31 pm
стоит фильтр 300-ого порядка после ару
Зачем так много? Уменьшите порядок до разумного :)
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 15, 2020, 03:08:55 pm
Основной 800-ого порядка
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 15, 2020, 03:29:39 pm
Любое амплитудное вмешательство в исходник расширяет его спектр
Даже если от 0 до 0 я это делаю?
Я определяю начало периода и конец (через 1мс) тоже 0 или около того, и только потом умножаю на коэффициент.
Причем когда я это делаю на увеличение амплитуды то все ок хвоста нет, а на уменьшение почти всегда. Либо где-то не увидел не стыковку амплитуд либо еще что.
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Ноябрь 15, 2020, 03:40:52 pm
Я определяю начало периода и конец (через 1мс) тоже 0 или около того, и только потом умножаю на коэффициент.

А какая разница? Это же, фактически, АМ со всеми вытекающими.  cr123
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 15, 2020, 03:54:21 pm
Вот пример в котором алгоритм цепляется за питчики и запускает задержку и второй - это с поглощением питчиков. 

Смотрим на водопад  123123

Ну вот как раз "лимиттер" дает на водопаде лес.
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Ноябрь 15, 2020, 05:01:35 pm
Это обычный шум?  cr123
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 15, 2020, 06:52:42 pm
Это розовый шум!! и на него ару ох сильно реагирует.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 15, 2020, 06:55:39 pm
Сделал !!!
Новая версия. Работает даже если стробировать сигнал около 1 !!! Без дельты. С дельтой вооще огонь  cr123

float32_t max = 0.49975586f; //максималка от -0.5 до +0.5 примерно для 12 бит
uint16_t count = 100;
float32_t pit1 = -1;
float32_t pit2 = 0;
uint8_t stopGoingUp = 0;
float32_t rmsPik = 0;
float32_t rmsFrame = 0;

void agcDo(float32_t *buffer) {

    float32_t agcMetrTemp = 0;

    if (tim > 0)tim--; //уменьшение задержки
    stopGoingUp = 0;

    for (uint16_t i = 0; i < FRAME_SIZE; i++) {
        float32_t a;
        //a = (buffer[i] < 0.0f) ? -1.0f * buffer[i] : buffer[i];// adc V
        a = fabsf(buffer[i]);
        // seach min
        if (a > 0)nowAgc = max / a;
        else nowAgc = max / 0.000005f;


        uint16_t upIdx = i;
        float32_t pikBuf = -1;
        uint8_t exit = 1;
        uint8_t exitYN = 0;
        uint16_t wait = 48;// 1msec
        int direction = 0;//напрвление вниз (отрицательная синусоида)

        if (buffer[i] > 0) direction = 1;//напрвление вверх (положительная синусоида)
        if (buffer[i] == 0) exit = 0; //пропустим поиск пика в блоке

        while (exit) { //поиск пика в блоке от 0 до 0
            exit = 0;//выходим
            float32_t p1 = fabsf(buffer[upIdx]);//feature
            if (upIdx < FRAME_SIZE) {
                if (direction) {//+++++++++++++++++++++++++++++
                    //если условие остановило в ++ то добиваем его до 0
                    if ((buffer[upIdx] >= 0 && !exitYN) || (upIdx - i < wait)) {
                        upIdx++;
                        if (p1 > pikBuf) {
                            pikBuf = p1;
                        }
                        exit = 1;//не выходим
                    }
                    //если условие остановило в -- то добиваем его до 0 и выходим
                    if (((buffer[upIdx] < 0)) && (upIdx - i >= wait)) {
                        upIdx++;
                        exitYN = 1; //не дадим пред условию сработать
                        if (p1 > pikBuf) {
                            pikBuf = p1;
                        }
                        exit = 1;//не выходим
                    }

                } else { //------------------------
                    //going up
                    //если условие остановило в -- то добиваем его до 0 и выходим
                    if ((buffer[upIdx] <= 0 && !exitYN) || (upIdx - i < wait)) {
                        upIdx++;
                        if (p1 > pikBuf) {
                            pikBuf = p1;
                        }
                        exit = 1;//не выходим
                    }
                    //если условие остановило в ++ то добиваем его до 0
                    if (((buffer[upIdx] > 0)) && (upIdx - i >= wait)) {
                        upIdx++;
                        exitYN = 1; //не дадим пред условию сработать
                        if (p1 > pikBuf) {
                            pikBuf = p1;
                        }
                        exit = 1;//не выходим
                    }

                }
                //добавим блок если в нем есть глобальный пик (выброс)
                if (upIdx - i >= wait && max / pikBuf < agcLevel) {
                    if (256 + upIdx < FRAME_SIZE) wait = 256;
                }
            }
        }//while

        if (upIdx > i) { //если блок не пустой то...
            float32_t locNowAgc;
            //проверка на 0
            if (pikBuf != 0) {
                locNowAgc = max / pikBuf;//максимальное значение
            } else locNowAgc = max / 0.00005f;
//типа среднее значение . исползуется для отката .
            rmsPik = (rmsPik + pikBuf) / 2.0f;

            //agcLevel == текущий уровень ару
            if (locNowAgc < agcLevel) { // всплеск или питч V, идем вниз ..........................
                 stopGoingUp=0;
                //заполним блок
                if (i) {
                    for (uint16_t z = i; z <= upIdx; z++) {
                        buffer[z] *= locNowAgc;//применить новый коэфф
                    }
                } else {//механизм сочленения с пред фреймом ...ждем первого нуля
                    if (buffer[0] > 0) direction = 1;//напрвление вверх (положительная синусоида)
                    exit = 1;
                    uint16_t idx0 = 0;
                    while (exit) {
                        exit = 0;//выходим
                        if (direction) {//+++++++++++++++++++++++++++++
                            if (buffer[idx0] > 0) {
                                idx0++;
                                exit = 1;//не выходим
                            }
                        } else { //------------------------
                            //going up
                            if (buffer[idx0] < 0) {
                                idx0++;
                                exit = 1;//не выходим
                            }
                        }
                    }//while
                    for (uint16_t z = 0; z <= upIdx; z++) {
                        if (z <= idx0)buffer[z] *= agcLevel;//применить старый коэфф
                        else buffer[z] *= locNowAgc;//применить новый коэфф
                    }
                }


                if ((pit2< pit1 &&  pit1 > pikBuf ) ) {//смотрим следующий питч если
                    agcLevel -= (agcLevel - locNowAgc) / 5;
                } else {
                   // agcLevel = locNowAgc;
                    agcLevel -= (agcLevel - locNowAgc) / 2;
                }
                if ((pit2< pit1 &&  pit1 < pikBuf )) {//смотрим следующий питч если
                   // agcLevel = locNowAgc;
                    agcLevel -= (agcLevel - locNowAgc) / 1;
                }
                pit2 = pit1;
                pit1 = pikBuf;

                tim = 30;//задежка отпускания



//                }

            } else {//идем вверх/////////////////////////////////////////////////////////////////////

                float32_t cc ;

                if (tim == 0) {//подождали и начинаем
                    cc = agcLevel + (locNowAgc - agcLevel) / 600;
                    //проверим можем нет еще откатить
                    if (rmsFrame * cc < max - 0.0f && !stopGoingUp) {//дельта отката 0.4
                        agcLevel = cc;
                    } else stopGoingUp=1; //остановить откат
                }
                //заполним полупериод
                for (uint16_t z = i; z <= upIdx; z++) {
                    buffer[z] *= agcLevel;//применить новый коэфф
                }
            }
            i = upIdx; // след цикл будет стратовать от upIdx

        } else { //это ситуация редкая но тоже надо . сделано по классике одного замера

            if (nowAgc < agcLevel) { // всплеск V
                agcLevel -= (agcLevel - nowAgc) / 2;
               // tim = 10;//задежка отпускания
            }
            float32_t f = a * agcLevel;
            //контроль вылета в out
            if (f > max) {//out
                if (buffer[i] >= 0) buffer[i] = max;//max
                else buffer[i] = -max;//max
                // agcLevel = 1;
            } else
                buffer[i] *= agcLevel;

        }

        if (a > agcMetrTemp) agcMetrTemp = a; //s-meter макс V
    }//for
    rmsFrame=(rmsFrame+rmsPik)/2.0f; // глобальный меж фреймовый средничок  нужен для отката до какого-то уровня.
    agcMetr = agcMetrTemp; //s-meter
}
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 15, 2020, 06:58:31 pm
вот алгоритм убирания питчиков


                if ((pit2< pit1 &&  pit1 > pikBuf ) ) {//смотрим следующий питч если
                    agcLevel -= (agcLevel - locNowAgc) / 5;
                } else {
                    agcLevel -= (agcLevel - locNowAgc) / 2;
                }
                if ((pit2< pit1 &&  pit1 < pikBuf )) {//смотрим следующий питч если
                    agcLevel -= (agcLevel - locNowAgc) / 1;
                }
                pit2 = pit1;
                pit1 = pikBuf;

pit1 pit2 - это глобальные амплитуды всплесков, которые требуют занижать амплитуду
agcLevel - самая главная переменная в ару !
pikBuf - текущий пик
locNowAgc - значение лимиттера по которому был опущен пик
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 15, 2020, 07:08:59 pm
Очень много контроля и самое главное был косяк: пропуск применения главного множителя, отсюда и сигнал ломался. Сейчас тоже проскакиваю нестыковки. Скорей всего межфреймомые дела. И достаточно редко. И ару ОЧЕНЬ не любит низкие частоты 150Гц и ниже. Запустил музыку и ару посчитало, что низы - это ступенька.  cr123
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Ноябрь 15, 2020, 07:37:46 pm
Это розовый шум!!

Какой же он розовый? Судя по спектру, это всё-таки, белый шум - спектр ровный.
Да и откуда там розовому взяться, только при косячном приёмнике - напомню, розовый шум имеет спектр -6 дБ/октава.  cr123
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 15, 2020, 08:21:04 pm
Так и есть. Поэтому я им и пользовался для тестов, у него, у шума, низов больше и сигнал более сложный получается чем белый (по структуре). На белом ставишь вроде нормально работает, переключаешь на розовый и упс, идут завалы.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 16, 2020, 05:31:19 pm
Нашел утечку памяти и еще пару досадных ошибок (логических, это же анализ cr123)

Теперь так:
(там где дельта 0 то это стробирование около 1, алгоритм пытается держать 1 без диапазона гистерезиса по усилению, ну и там где дельта 0.3 - это как раз гистерезис)
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 16, 2020, 05:32:38 pm
Вот так сейчас
float32_t max = 0.49975586f; //максималка от -0.5 до +0.5 примерно для 12 бит
uint16_t count = 100;
uint8_t stopGoingUp = 0;
float32_t rmsPik = 0;
float32_t rmsFrame = 0;

void agcDo(float32_t *buffer) {

    float32_t agcMetrTemp = 0;
    float32_t pit1 = -1;
    float32_t pit2 = 0;

    if (tim > 0)tim--; //уменьшение задержки
    stopGoingUp = 0;

    for (uint16_t i = 0; i < FRAME_SIZE; i++) {
        float32_t a;
        //a = (buffer[i] < 0.0f) ? -1.0f * buffer[i] : buffer[i];// adc V
        a = fabsf(buffer[i]);
        // seach min
        if (a > 0)nowAgc = max / a;
        else nowAgc = max / 0.000005f;


        uint16_t upIdx = i;
        uint16_t upIdxNow ;

        float32_t pikBuf = -1;
        uint8_t exit = 1;
        uint8_t exitYN = 0;
        uint16_t wait = 48;// 1msec
        int direction = 0;//напрвление вниз (отрицательная синусоида)

        if (buffer[i] > 0) direction = 1;//напрвление вверх (положительная синусоида)
        if (buffer[i] == 0) exit = 0; //пропустим поиск пика в блоке

        while (exit) { //поиск пика в блоке от 0 до 0
            exit = 0;//выходим
            float32_t p1 = fabsf(buffer[upIdx]);//feature
            upIdxNow = upIdx;
            if (direction) {//+++++++++++++++++++++++++++++
                //если условие остановило в ++ то добиваем его до 0
                if ((buffer[upIdx] >= 0 && !exitYN) || (upIdx - i < wait)) {
                    if (p1 > pikBuf) {
                        pikBuf = p1;
                    }
                    if (upIdx + 1 < FRAME_SIZE) {
                        upIdx++;
                        exit = 1;//не выходим
                    }
                }
                //если условие остановило в -- то добиваем его до 0 и выходим
                if ((buffer[upIdxNow] < 0) && (upIdxNow - i >= wait)) {
                    exitYN = 1; //не дадим пред условию сработать
                    if (p1 > pikBuf) {
                        pikBuf = p1;
                    }
                    if (upIdxNow + 1 < FRAME_SIZE) {
                        upIdx++;
                        exit = 1;//не выходим
                    }
                }

            } else { //------------------------
                //going up
                //если условие остановило в -- то добиваем его до 0 и выходим
                if ((buffer[upIdx] <= 0 && !exitYN) || (upIdx - i < wait)) {
                    if (p1 > pikBuf) {
                        pikBuf = p1;
                    }
                    if (upIdx + 1 < FRAME_SIZE) {
                        upIdx++;
                        exit = 1;//не выходим
                    }
                }
                //если условие остановило в ++ то добиваем его до 0
                if ((buffer[upIdxNow] > 0) && (upIdxNow - i >= wait)) {
                    exitYN = 1; //не дадим пред условию сработать
                    if (p1 > pikBuf) {
                        pikBuf = p1;
                    }
                    if (upIdxNow + 1 < FRAME_SIZE) {
                        upIdx++;
                        exit = 1;//не выходим
                    }
                }
            }
            //добавим блок если в нем есть глобальный пик (выброс)
            if (upIdx - i >= wait && max / pikBuf > agcLevel) {
                if (256 + upIdx < FRAME_SIZE) wait = 256;
            }

        }//while

        if (upIdx > i) { //если блок не пустой то...
            //upIdx--;
            float32_t locNowAgc;
            //проверка на 0
            if (pikBuf != 0) {
                locNowAgc = max / pikBuf;//максимальное значение
            } else locNowAgc = max / 0.00005f;
//типа среднее значение . исползуется для отката .
            rmsPik = (rmsPik + pikBuf) / 2.0f;

            //agcLevel == текущий уровень ару
            if (locNowAgc < agcLevel) { // всплеск или питч V, идем вниз ..........................
                stopGoingUp = 0;
                //заполним блок
                if (i > 0) {
                    for (uint16_t z = i; z <= upIdx; z++) {
                        buffer[z] *= locNowAgc;//применить новый коэфф
                    }
                } else {//механизм сочленения с пред фреймом ...ждем первого нуля
                    if (buffer[0] > 0) direction = 1;//напрвление вверх (положительная синусоида)
                    exit = 1;
                    uint16_t idx0 = 0;
                    while (exit) {
                        exit = 0;//выходим
                        if (direction) {//+++++++++++++++++++++++++++++
                            if (buffer[idx0] > 0) {
                                idx0++;
                                exit = 1;//не выходим
                            }
                        } else { //------------------------
                            //going up
                            if (buffer[idx0] < 0) {
                                idx0++;
                                exit = 1;//не выходим
                            }
                        }
                    }//while
                    for (uint16_t z = 0; z <= upIdx; z++) {
                        if (z <= idx0)buffer[z] *= agcLevel;//применить старый коэфф
                        else buffer[z] *= locNowAgc;//применить новый коэфф
                    }
                }


                tim = 10;//задежка отпускания
                if ((pit2 < pit1 && pit1 < pikBuf)) {//смотрим следующий питч если
                     agcLevel = locNowAgc;
                   // agcLevel -= (agcLevel - locNowAgc) / 1;
                    tim = 30;//задежка отпускания
                } else if ((pit2 < pit1 && pit1 > pikBuf)) {//смотрим следующий питч если
                    agcLevel -= (agcLevel - locNowAgc) / 5;
                } else {
                    agcLevel -= (agcLevel - locNowAgc) / 2;
                }


                pit2 = pit1;
                pit1 = pikBuf;

            } else {//идем вверх/////////////////////////////////////////////////////////////////////

                float32_t cc;

                if (tim == 0) {//подождали и начинаем
                    cc = agcLevel + (locNowAgc - agcLevel) / 600;
                    //проверим можем нет еще откатить
                    if (rmsFrame * cc < max - 0.3f && !stopGoingUp) {//дельта отката 0.4
                        agcLevel = cc;
                    } else stopGoingUp = 1; //остановить откат
                }
                //заполним полупериод
                for (uint16_t z = i; z <= upIdx; z++) {
                    buffer[z] *= agcLevel;//применить новый коэфф
                }
            }
            i = upIdx; // след цикл будет стратовать от upIdx

        } else { //это сидуация редкая но тоже надо . сделано по класике одного замера

            if (nowAgc < agcLevel) { // всплеск V
                agcLevel -= (agcLevel - nowAgc) / 2;
                // tim = 10;//задежка отпускания
            }
            float32_t f = a * agcLevel;
            //контроль вылета в out
            if (f > max) {//out
                if (buffer[i] >= 0) buffer[i] = max;//max
                else buffer[i] = -max;//max
                // agcLevel = 1;
            } else
                buffer[i] *= agcLevel;

        }

        if (a > agcMetrTemp) agcMetrTemp = a; //s-meter макс V
    }//for
    rmsFrame = (rmsFrame + rmsPik) / 2.0f;
    agcMetr = agcMetrTemp; //s-meter

Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 16, 2020, 05:37:58 pm
дерьмо пришло к нам в семью сегодня ночью
грёбанный вирус , забирает близких  cry333
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Ноябрь 16, 2020, 06:44:46 pm
 dontt44 У сестры тоже все болеют... no88
Название: Re: Цифровая АРУ 0...1
Отправлено: 6Ж2П от Ноябрь 16, 2020, 10:52:50 pm
розовый шум имеет спектр -6 дБ/октава. 
Нет, спад 3дб/октава
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Ноябрь 16, 2020, 11:35:08 pm
спад 3дб/октава

Согласен... dontt44
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 28, 2020, 06:35:13 pm
Замеры, замеры, замеры

Идет CW WW
Запись с WEB SDR Тульского.

3 варианта записи
1. Тульский АРУ выключен, работает только моя платка и мое АРУ
2. Работает Тульское АРУ и мое АРУ
3. Только Тульский WEB SDR, моя платка отключена физически.

PS несложно заметить, что мое ару спасает на 2-3 дб тульское ару, а если вообще без меня то стучит безбожно морзянка и всплески до 10дб ....это абзац.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 28, 2020, 06:38:42 pm
...
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 30, 2020, 09:51:14 pm
А я тут опять сел за АРУ

Проблема в том , что нельзя просто применить коэффициент к полупериоду, и даже к полному периоду. И даже нельзя применить последовательное наращивание коэффициента. Все это приводит к изменению синуса (как на картинке).
На фото как раз работа ару по полупериоду. Такой подход стучит и это видно на анализаторе.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Ноябрь 30, 2020, 09:59:49 pm
Что делать?  dontt44 Нужно восстанавливать синусоиду. Мне кажется от пика до пика следующей полуволны. И работать нужно по разному. Тот пик который мы занижаем (реакция на всплеск)  мы просто умножаем на 0.ХХ коэффициент и тем самым мы этот полупериод прижимаем ближе к 0. НО! с предыдущем пиком нельзя также делать, у него растет горб. Там нужен другой коэффициент, и причем пик этой полуволны трогать нельзя он должен остаться. Смежные скаты полуволн похожи на улитку. С каждым шагом увеличивается радиус улитки. 
Вот я и говорю, синусоиду нужно восстанавливать.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 01, 2020, 02:28:05 pm
Вот этот более наглядней
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 01, 2020, 02:30:34 pm
Если идет от 0 изменение амплитуды , то вроде все ок, легкое расширение спектра и всё, но если точка изменение амплитуды отстоит от 0 то спектр разливается почти до конца. Не так конечно как при ступеньке, но все же его видно и слышно.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 01, 2020, 02:32:46 pm
Эксперименты продолжаются. Надо почти полностью алгоритм переделывать. Сейчас я меняю амплитуду скачкообразно внутри системы без АЦП
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Декабрь 01, 2020, 02:33:22 pm
А любое изменение формы даёт расширение спектра, как правило, если будут какие-то острые углы, то расширение с более длинным хвостом, если плавное - с более коротким.  dontt44
Кстати, в искажении спектра нескольких периодов трагедии-то нет никакой, я уже выпал из темы - Вы по какой-то ПЧ типа 15...20 кГц работаете, или же, прямо на НЧ пытаетесь работать?  cr123
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 01, 2020, 02:34:52 pm
Прямо по НЧ ару делаю, полностью цифровую
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 01, 2020, 02:36:41 pm
как правило, если будут какие-то острые углы, то расширение с более длинным хвостом, если плавное - с более коротким
Вот и я про то же, нифига нельзя проходить одним множителем по положительной и отрицательной полуволне, даже не так.... по скату правому+ и смежному ему  левому-
Там расчет надо другой.
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Декабрь 01, 2020, 02:41:19 pm
А всё-таки, напомните - Вы на НЧ АРУ делаете, или же на низкой ПЧ?  cr123
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 01, 2020, 02:44:58 pm
Прям 0-3кГц
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Декабрь 01, 2020, 02:46:01 pm
Прям 0-3кГц

Тогда примите мои соболезнования - это путь в никуда... dontt44 pl33 lol22
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 01, 2020, 02:48:04 pm
Спортивный зуд покоя не дает  cr123
Уже лучше чем в web сдр получилось. Хочу полностью от этого стука уйти.

Да и алгоритм одинаковый, что для вч что для нч. Это же цифра.
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Декабрь 01, 2020, 02:51:02 pm
Спортивный зуд покоя не дает

Да направьте его в конструктивное русло - насколько помню, у Вас же была какая-то ПЧ, типа 10...30 кГц, именно по ней и нужно работать, альтернативы просто нет иной, не может быть физически универсального алгоритма для частот, отличающихся на порядок - там же хотя бы тайминги должны быть разными.
В точности та же фигня, что и с компрессированием... lol22
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 01, 2020, 03:05:01 pm
Да неее, Игорь, здесь тема DDC  там по другому ни как. Там же только цифра и нет ПЧ вообще. Битность на входе потом перенос на низкие частоты и всё, 32 бита чистого  оцифрованного звука. Вот по нему и надо АРУ пройтись.
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Декабрь 01, 2020, 03:11:35 pm
А, понял.  1yep dontt44 pl33
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 01, 2020, 10:28:35 pm
Пока не поддается  lllol
Нужно больше математики.
Алгоритм написал и переделал.

(на фото какой-то из вариантов, причем не самый лучший)
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 01, 2020, 10:46:51 pm
Такое ощущение, что вписался еще какой-то переходный процесс по входу звуковой. Почему кривая синусоида ?
Скорость нарастания скатов левого и правого разная?

(на фото стандартные константы для + и для - полуволн)
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Декабрь 02, 2020, 12:09:42 am
Этот кривой синус только на переходном процессе, или всё время?  cr123
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 02, 2020, 08:26:22 am
Только на переходном процессе.
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Декабрь 02, 2020, 10:33:05 am
У Вас же, как помню, с буфером работа, сделайте отработку АРУ за пару миллисекунд до появления сигнала... cr123
Название: Re: Цифровая АРУ 0...1
Отправлено: VA7KL от Декабрь 02, 2020, 11:14:35 am
по скату правому+ и смежному ему  левому
я строил правильную синусоиду между отрицательным и положительным экстремумами, пренебрегая где там уровень нуля. Получалось очень гладко, потому что сшивалось там где производная ноль - в плагине Адоба Аудишена. Сейчас надо бы в СТМ32 попробовать...
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Декабрь 02, 2020, 11:30:30 am
сшивалось там где производная ноль

Кстати, правильный ход - минимум мусора на сшивке. А при переходе через ноль производная максимальна... 1yep 1999 lol22
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 02, 2020, 12:06:44 pm
Очень интересно. Простым нарастанием коэффициента не получилось  всё равно ломается синус.
Там блин скаты по нарастание у полупериода не симметричны. А идея просто заново нарисовать скат осень хорошая. Математику Не подкинете  ?  cr123
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 02, 2020, 01:54:15 pm
t= 2*(pikIdxPlus-pikIdxMinus)
    -------------------------------
                  24000

f=1/t ;// частота синуса , который надо нарисовать


амплитуды не симметричные.

А=|pikVPlus| + |pikVMinus| ; //amplituda sin

//смещение  амплитуды относительно 0 вверх вниз, потом просто добавить к результату
Smeschenie= (|pikVPlus| - |pikVMinus|)/2 ;


рисовать синус надо будет от PI/2 до 3PI/4 те от -1 до 1 фаза

Шаг
delta = (float32_t) ((2 * 3.14159265359 *f) / 24000);

float32_t phase=PI/2;
  for (int i = pikIdxPlus; i <= pikIdxMinus; i += 1) {
            saiTxBank[saiTxBankNowNumber][ i ] =A *  arm_sin_f32(phase)+Smeschenie;
             phase += delta;
  }
       
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 02, 2020, 03:19:02 pm
Пока так ....
Один скат выровнял, но еще что то есть ..
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 02, 2020, 05:02:40 pm
О! восстановил

На фотках то один фронт восстанавливается, то другой. (все в центре)
Та просто 4 вариант прихода полуволн:
#define mP 1 //minus PLUS
#define pM 2 //plus MINUS
#define Mp 3 //MINUS plus
#define Pm 4 //PLUS minus

Два я сделал остались еще 2 самых сложных


..один из вариантов
                   if (variant == mP) {
                        if (z < uPikIxxMinus) {
                            buffer[z] *= locPik;
                        }
                        if (z >= uPikIxxMinus && z<=uPikIxxPlus ) {
                            float32_t rate = 24000.0f;
                            float32_t t = 2.0f * (uPikIxxPlus - uPikIxxMinus -0.0f) / rate;
                            float32_t freqS = 1.0f / t;
                            float32_t Am = (uPikVPlus*locNowAgc + uPikVMinus*locPik)/2.0f;
                            float32_t Sm = (uPikVPlus*locNowAgc - uPikVMinus*locPik) / 2.0f;
                            float32_t deltaFreq = (2.0f * PI * freqS) / rate;
                            float32_t phase = PI / 2.0f;
                            uint16_t ii;
                            for ( ii = uPikIxxMinus; ii <= uPikIxxPlus; ii += 1) {
                                buffer[ii] = -Am * arm_sin_f32(phase) - Sm;
                                phase += deltaFreq;
                            }
                            z=ii;
                        }
                        if (z>uPikIxxPlus) {//пиковая полуволна
                            buffer[z] *= locNowAgc;
                        }
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 02, 2020, 05:16:47 pm
Вот так музыка.... уже диких всплесков нету  lol22
маленький успех.
Название: Re: Цифровая АРУ 0...1
Отправлено: VA7KL от Декабрь 02, 2020, 09:36:15 pm
Математику Не подкинете
на самом деле если подвигать точку пересечения нуля вправо/влево, там обязательно существует точка где обе синусоиды (разного периода!) сшиваются гладко - с равными односторонними производными. Поскриплю мозгами вспомню. А пока более простой вариант: как провести косинусоиду если известны оба соседних экстремума и время между ними. Когда оба экстремума одинаковы а = в то вырождается в обычный косинус.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 02, 2020, 09:47:56 pm
Спасибо, вы тоже самое написали что и я до чего допер.  lol22
Сшивается идеально!
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 02, 2020, 09:51:41 pm
Сейчас сижу думаю....у меня один скат восстанавливает синус, а потом всё... а надо бы еще следующий тоже причесать, но не могу условие подобрать по которому будет запускаться алгоритм именно "этого" ската, ведь АРУ уже отработало и следующий пик не является новым максимумом.
Короче надо поспать с этой мыслью...хотя направление я уже понял куда топать.
Название: Re: Цифровая АРУ 0...1
Отправлено: VA7KL от Декабрь 02, 2020, 09:52:13 pm
по моему опыту, ловить точку пересечения нуля бесполезно - там шум всегда вырубает любой навороченный алгоритм. А экстремумы почти  всегда торчат из шума и легко определяются. Их достаточно чтобы восстановить любую кривую между ними. Даже не синусоиду а степенные функции проводил - на слух (мой) почти без разницы.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 02, 2020, 09:57:34 pm
Да так и есть. Так и сделано.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 02, 2020, 09:58:49 pm
Вот восстановленный скат
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 02, 2020, 10:12:00 pm
Если завтра время будет переделаю весь алгоритм в очередной раз.
Направление однозначно правильное.
Я сейчас прыгаю по полному периоду, а завтра попробую скакать только от пика до пика.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 02, 2020, 10:27:56 pm
О! я ваааще огонь алгоритм придумал! Там вообще без разницы шум не шум.

...берем два полупериода (включая шум внутри, который не пересекает 0). Ищем Максимум. И если надо занижать - занижаем полностью полупериод и бросаем его. Смотрим следующий полупериод...если он опять требует занижения - занижаем и восстанавливаем левый скат. Потом опять берем полупериод и его не надо уже занижать, то просто восстанавливаем опять левый скат. И так далее
Особенность этого подхода в том что нужно искать два ближайших к краю пика, и пофиг что между ними.

Вот так работать будет !
Название: Re: Цифровая АРУ 0...1
Отправлено: 6Ж2П от Декабрь 02, 2020, 11:12:08 pm
Если я правильно понял, то Вы собираетесь сделать почти искусственный (синтезированный) сигнал из исходного.

ПС Не знаю, к чему приведут поиски решения, но я бы обратил внимание на замечание Игоря про ПЧ, пусть и очень низкую. О том, что здесь нет ПЧ я помню, напоминать не требуется. Поясню, почему поддерживаю Игоря. Здесь мыслится принципиальное математическое ограничение на корректность обработки непосредственно на НЧ при полосе 0,3 - 3,0 кГц. Это широкополосный сигнал и ориентироваться на набор неких пиковых данных о сигнале, для последующего его воссоздания (синтезирования) по этим отсчётам, в принципе невозможно (информация в каком-то объёме обязательно будет теряться), ибо нарушение теоремы отсчётов/Котельникова. А вот применение ПЧ, даже очень низкой, например 19 кГц, кардинально меняет картину.
Название: Re: Цифровая АРУ 0...1
Отправлено: VA7KL от Декабрь 03, 2020, 12:57:24 am
искусственный (синтезированный) сигнал из исходного
это сводится к философскому вопросу что есть голос и чем он отличается от последовательности "неких пиковых данных", соединенных гладкими синусоидами. Я пробовал сделать это, программируя плагин Адоба Аудишена - голос пропадал в грохоте, который то и шумом назвать нельзя. Скорее всего надо учитывать и экстремумы второго порядка, которые с одной стороны нуля.. но это усложнение теряет смысл казалось бы простого алгоритма синтеза.
Название: Re: Цифровая АРУ 0...1
Отправлено: 6Ж2П от Декабрь 03, 2020, 01:53:31 am
в широкополосном сигнале принципиально невозможен подход с заменой реального сигнала на последовательность "неких пиковых данных" и последующей аппроксимацией отрезками синусоид между точками. Это легко понять и без высшей математики, если рассмотреть период времени, когда преобладает амплитуда самой низкой частоты, на которую наложено много меньшее напряжение максимальной частоты. Реальный сигнал будет виден на осциллографе, как постоянный сдвиг нулевого отсчёта для уровня ВЧ компоненты по закону изменения НЧ компоненты, пиковые же данные оставят информацию только об НЧ компоненте. Получится некий суррогат фильтра НЧ с плавающей  частотой среза, а при компонентах близкого уровня, должна быть "каша".
Название: Re: Цифровая АРУ 0...1
Отправлено: Relayer от Декабрь 03, 2020, 02:00:35 am
Сколько времени потрачено а конца и края пока не видно. АРУ должна быть простая и безмозглая как валенок. И работать она должна не по максимуму сигнала а по минимуму, приводя ДД сигнала к комфортному
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 03, 2020, 09:51:02 am
Все получится. У монстров сдр-строения же получается и у нас получится.
Я вот много уже картинок показывал , и там у полупериода оба ската с щербинками , даже если один скат наладить сигнал на слух становится чище и щелчки превращаются в глухие удары.
Да, я ломаю сигнал если в одном полупериода больше одного пика ... будет один ))) это своеобразный фильтр получается . По сути это и есть фильтр очень качественный и жесткий, но иначе спектр разливается.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 03, 2020, 10:01:13 am
С нч частотами очень все плохо, я уже говорил об этом. Чисто математически если мы хотим уменьшить задержку сигнала при прохождении через ару и тд, то надо снижать размер буфера и это приведёт к тому , что мы не сможем обработать период  нч частоты. Придётся просто прижимать его к 0 множителем и стук будет обязательно. Конечно установка фнч 1000 порядка перед и 500 порядка после АРУ помогает, но не сильно. Всплески (у меня сейчас) не дотягивают 30-40 дБ до пика сигнала при такой расстановке фнч. Но лучший результат если сперва 500 потом 1000 порядка поставить ))) но это самообман. Фнч и так проц грузит ого как.
Название: Re: Цифровая АРУ 0...1
Отправлено: 6Ж2П от Декабрь 03, 2020, 11:21:20 am
Можете уточнить, зачем уменьшать задержку на столько?
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 03, 2020, 12:09:42 pm
например adau1701 практически нет задержки.
У меня при 24000 частоте и 1024 замеров в блоке-  задержка около 50мс  потом полетело в цап еще столько на ацп итого 100мс задержка только в моей системе.

В аналоге эта цифра в районе нескольких мс (зависит от КФ или ЭМФ)
Название: Re: Цифровая АРУ 0...1
Отправлено: Relayer от Декабрь 03, 2020, 12:16:29 pm
итого 100мс задержка только в моей системе
Сергей, чем больше мозгов вы пытаетесь впихнуть в АРУ тем больше будет эта задержка. Как человек с высшим тматьматическим я могу сказать вам что при устремлении ее (задержки) к бесконечности АРУ станет ну просто идеальной. Но совершенно бесполезной :)

ЗЫ а за 100мс задержки телеграфисты вас могут и ... тапками закидать   rrr7777
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 03, 2020, 12:28:06 pm
Здесь сейчас не важно какая будет задержка, она уменьшится в 2 раза при переходе на 48000 и будет 50мс, потом можно уменьшить буфер до 512 замеров и будет 25мс , но уже проблемы будут с процессором. Геннадий, когда-нибудь запустит стм157 на 800МГц - вот на нем можно будет эксперименты делать и с 25мс.  и даже с 96кГц сэмплированием - вот тогда это будет практически аналоговый звук.
АРУ вов всех вариантах будет ...либо работать либо стучать.


Да, лист программы очень серьезный...для не  профессионала. Там же сплошные условия. Если не все учесть результат один - будет стучать )))
Название: Re: Цифровая АРУ 0...1
Отправлено: Relayer от Декабрь 03, 2020, 02:43:23 pm
Не поможет вам увеличение семплирования, поверьте. Только проц нагрузите
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 03, 2020, 03:34:37 pm
Так, ну я синус восстановил , разлива спектра нет, но я все равно слышу момент появления тональника в виде легко «ух»
Приеду посмотрю , что там получилось с музыкой, маленько времени не хватило.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 03, 2020, 03:38:15 pm
Причём , я поставил самые кабальные режимы работы ару. Минимальная задержка 100 мс и очень агрессивное восстановление уровня после снятия сильного сигнала.
Кстати, восстановление тоже малёк разливает спектр. По идеи , восстановление после снятия сигнала тоже надо синус восстанавливать
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 03, 2020, 04:09:19 pm
Не помогло   nea33
На фото видно где восстановление прошло
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 03, 2020, 04:14:46 pm
Как и ожидалось, алгоритм сметает часть информации под синус.
Название: Re: Цифровая АРУ 0...1
Отправлено: 6Ж2П от Декабрь 03, 2020, 04:20:39 pm
Широкополосный сигнал.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 03, 2020, 04:32:56 pm
Да, зато как с тональником все красиво
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 03, 2020, 05:19:37 pm
Начинаем все с начала. 123123
Есть идея. Не рисовать синус.
Название: Re: Цифровая АРУ 0...1
Отправлено: Relayer от Декабрь 03, 2020, 05:29:02 pm
Вашу бы энергию да в мирное русло. То направление куда вы пытаетесь идти - тупиковое. Если бы там все было хорошо - были бы реализации в том числе и в исходных кодах. Но их нет
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 03, 2020, 05:58:39 pm
Фигня, я это часто слышу.

Вот теперь "так" будем думать....

600Гц + 2900Гц
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 03, 2020, 06:03:37 pm
Текущая работа ару (ожидаемо съедала все вторичные пики) как здесь на фото, отсюда полный швах в наушниках.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 04, 2020, 03:17:14 pm
Отпала тема восстановления скатов полностью. Был проделан вариант при котором просто скат  сжимается в соответствии с sin от 0 до 1  это значит , что пик который не надо сжимать localAGCmax (множитель) умножается на 0 и пик остается на месте, а тот пик который надо занизить по итогу (по закону sin) localAGCmax умножается на 1 и пик слетает вниз в соответствии с расчетом.

Короче была сделана попытка реализовать алгоритм резинки которая растягивается в середине и применить его к скату.
Результат тот же - где-то все ломается хотя глазом на осциллограмме не видно. И иногда алгоритм уходил в конкретный блуд, который я не смог найти.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 04, 2020, 03:21:03 pm
Новая тема ! cr123

Надо собирать данные за несколько фрэймов и не поднимать усиление выше "чем..."
тем самы сделать ворота, про которые я сам много раз писал и делал.
Вот пример ворот (sweep амплитуды ) он не дает падать меньше чем на 4дБ
отсюда и будем плисать
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 04, 2020, 10:51:33 pm
А я сделал , что хотел.
 lol22
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Декабрь 04, 2020, 11:05:06 pm
Да ладно... cr123
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 04, 2020, 11:25:22 pm
Оказалось морзянка самым лучшим тестером.
Лучший вариант получил при воротах 7-8дб  с учетом анипитч. Завтра покажу все, сейчас уже глаза не видят.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 04, 2020, 11:29:12 pm
Кстати, Игорь, я сделал по итогу как вы говорили... плавный спад усиления к пику за 5-10мс
А так же полностью переделал системы возврата усиления ...там еще та песТня.
Название: Re: Цифровая АРУ 0...1
Отправлено: Relayer от Декабрь 04, 2020, 11:29:16 pm
Вот пример ворот (sweep амплитуды ) он не дает падать меньше чем на 4дБ
отсюда и будем плисать
А теперь переверните график алгоритм вверх ногами :) Есть шумовая дорожка. Не дадим сигналы превысить ее более чем на N дб :)
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 04, 2020, 11:34:09 pm
Вот интересный тест свипом амплитуды 0..-50дб
(смотреть на водопад)
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 04, 2020, 11:35:52 pm
А теперь переверните график алгоритм вверх ногами  Есть шумовая дорожка. Не дадим сигналы превысить ее более чем на N дб
то есть сигнал-шум всего навсего N дб будет. В чем прикол?
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 04, 2020, 11:43:07 pm
А вот тот же тест, но ворота 0. Алгоритм пытается сделать плоский эфир
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 04, 2020, 11:46:52 pm
Вот 80 с web sdr
Ну что-то сильно хорошо получилось.
(ворота 0дб)
Название: Re: Цифровая АРУ 0...1
Отправлено: 6Ж2П от Декабрь 05, 2020, 08:50:29 am
Я не очень пойму, что хорошего, когда верхняя граница ровная как стол?
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 05, 2020, 08:54:11 am
Я не очень пойму, что хорошего, когда верхняя граница ровная как стол?
Это значит, что вылетов за пределы нету. Само ару работает ниже. Сегодня записи сделаю.
Кстати там есть задержка отпускания и плавный подъем усиления - все как и планировалось и все регулируется.
Понятие «Ворота» это как раз и есть промежуток в дБ который убирает плоскость эфира . Громкие будут слегка громче тихих.
Название: Re: Цифровая АРУ 0...1
Отправлено: 6Ж2П от Декабрь 05, 2020, 09:14:13 am
Так что в итоге получиться должно, по задумкам? А то уже кажется, что это будет ровно та же аналоговая АРУ, только данные для управления извлекаются из цифрового потока, цифрой же и обрабатываются.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 05, 2020, 09:57:01 am
 Новая АРУ
(вариант 4)
 lol22

float32_t max = 0.49905586f; //максималка 0.49975586fот -0.5 до +0.5 примерно для 12 бит
uint16_t count = 100;
uint8_t stopGoingUp = 0;

float32_t rmsFrame = 0;
uint16_t uOldPikIdx;
float32_t uOldPikV;
uint16_t wait = 20;
float32_t rate = 24000.0f;

///@brief АРУ
///@param buffer
void agcDo(float32_t *buffer) {
    float32_t rmsPik = 0;
    float32_t agcMetrTemp = 0;
    float32_t pit1 = -1;
    float32_t pit2 = 0;
    uint8_t wasVariant = 0;
    uint16_t pikCount = 0;
    if (tim > 0)tim--; //уменьшение задержки
    stopGoingUp = 0;

    for (uint16_t i = 0; i < FRAME_SIZE; i++) {
        float32_t a;
        //a = (buffer[i] < 0.0f) ? -1.0f * buffer[i] : buffer[i];// adc V
        a = fabsf(buffer[i]);
        // seach min
        if (a > 0)nowAgc = max / a;
        else nowAgc = max / 0.000005f;


        uint16_t upIdx = i;
        uint16_t upIdxNow;

        float32_t pikBuf;
        uint8_t exit = 1;
        uint8_t exitYN = 0;
        uint16_t wait = 2;// 1msec

        uint16_t uPikIxxPlus = 0;
        uint16_t uPikIxxMinus = 0;
        float32_t uPikVPlus = 0; //V + pik
        float32_t uPikVMinus = 0;//V - pik
        //direction
        int direction = 1;//напрвление вниз (отрицательная синусоида)
        if (i + 1 < FRAME_SIZE) {
            if (buffer[i] <= 0 || buffer[i + 1] < 0) direction = 0;//напрвление вверх (положительная синусоида)
        } else {
            if (buffer[i] <= 0 || buffer[i - 1] > 0) direction = 0;//напрвление вверх (положительная синусоида)
        }
        while (exit) { //поиск пика в блоке от 0 до 0
            exit = 0;//выходим
            float32_t p1 = fabsf(buffer[upIdx]);//feature
            if (direction) {//+++++++++++++++++++++++++++++
                //если условие остановило в ++ то добиваем его до 0
                if ((buffer[upIdx] > 0 && !exitYN)) {
                    if (p1 > uPikVPlus) {
                        uPikVPlus = p1;
                        uPikIxxPlus = upIdx;
                    }
                    if (upIdx + 1 < FRAME_SIZE) {
                        upIdx++;
                        exit = 1;//не выходим
                    }
                }
                //если условие остановило в -- то добиваем его до 0 и выходим
                if ((buffer[upIdx] < 0)) {
                    exitYN = 1; //не дадим пред условию сработать
                    if (p1 >= uPikVMinus) {
                        uPikVMinus = p1;
                        uPikIxxMinus = upIdx;

                    }
                    if (upIdx + 1 < FRAME_SIZE) {
                        upIdx++;//
                        exit = 1;//не выходим
                    }
                }

            } else { //------------------------
                //going up
                //если условие остановило в -- то добиваем его до 0 и выходим
                if ((buffer[upIdx] <= 0 && !exitYN)) {
                    if (p1 > uPikVMinus) {
                        uPikVMinus = p1;
                        uPikIxxMinus = upIdx;
                    }
                    if (upIdx + 1 < FRAME_SIZE) {
                        upIdx++;
                        exit = 1;//не выходим
                    }
                }
                //если условие остановило в ++ то добиваем его до 0
                if ((buffer[upIdx] > 0)) {//
                    exitYN = 1; //не дадим пред условию сработать
                    if (p1 > uPikVPlus) {
                        uPikVPlus = p1;
                        uPikIxxPlus = upIdx;
                    }
                    if (upIdx + 1 < FRAME_SIZE) {
                        upIdx++;//
                        exit = 1;//не выходим
                    }
                }
            }

        }//while

        if (upIdx > i + 1) { //если блок не пустой то...

            upIdx -= 1;
            float32_t locNowAgc;


            if (uPikVPlus > uPikVMinus) {
                locNowAgc = max / (uPikVPlus);
                pikBuf = uPikVPlus;
            } else {
                locNowAgc = max / (uPikVMinus + 0.000001f);
                pikBuf = uPikVMinus;
            }

            //типа среднее значение этого блока. исползуется для отката .
            rmsPik += (uPikVPlus + uPikVMinus) / 2.0f;
            pikCount++;//количество синусоид, нужен для расчета среднего пика по блоку
            //agcLevel == текущий уровень ару
            if (locNowAgc <= agcLevel) { // всплеск или питч V, идем вниз || wasVariant..........................
                stopGoingUp = 0;
                //заполним блок
                //               if (i > 0) {

                for (uint16_t z = i; z <= upIdx; z++) {
                    buffer[z] *= locNowAgc;
                }


//                } else {//механизм сочленения с пред фреймом ...ждем первого нуля
//                    exit = 1;
//                    uint16_t idx0 = 0;
//                    while (exit) {
//                        exit = 0;//выходим
//                        if (direction) {//+++++++++++++++++++++++++++++
//                            if (buffer[idx0] > 0 && idx0 < upIdx) {
//                                idx0++;
//                                exit = 1;//не выходим
//                            }
//                        } else { //------------------------
//                            //going up
//                            if (buffer[idx0] <= 0 && idx0 < upIdx) {
//                                idx0++;
//                                exit = 1;//не выходим
//                            }
//                        }
//                    }//while
//                    for (uint16_t z = 0; z <= upIdx; z++) {
//                        //if (z <= idx0)
////                            buffer[z] *= agcLevel +
////                                         (locNowAgc - agcLevel) / (idx0 - z + 1);//применить старый коэфф
//                            if (z < idx0)
//                                buffer[z] *= agcLevel;//применить старый коэфф agcLevel
//                            else
//                                buffer[z] *= locNowAgc;//применить новый коэфф
//                    }
//                }

                //откат усиления назад по блоку
                //убират стук
                uint16_t d = 0;
                uint16_t dmax = (i - 500 >= 0 ? 500 : i);
                while (d < dmax && i - d > 0) {
                    float32_t dx = locNowAgc / agcLevel;
                    d++;
                    buffer[i - d] *= dx + d * (1 - dx) / dmax;
                }

                //питч детектор
                stopGoingUp = 0;
                //tim = wait;//задежка отпускания
                if ((pit2 < pit1 && pit1 < pikBuf)) {//не питч
                    agcLevel = locNowAgc;
                } else if ((pit2 < pit1 && pit1 > pikBuf)) {//питч
                    agcLevel -= (agcLevel - locNowAgc) / 4;
                } else {
                    agcLevel -= (agcLevel - locNowAgc) / 2;
                }
                tim = wait;
                //  agcLevel = locNowAgc;
                pit2 = pit1;
                pit1 = pikBuf;

            } else {//идем вверх/////////////////////////////////////////////////////////////////////
                float32_t cc;
                float32_t sred = agcLevel / locNowAgc;
                float32_t rmsNow = (rmsFrame + rmsPik / pikCount) / 2.0f;

                if (tim == 0) {//подождали и начинаем
                    cc = agcLevel + (sred / rmsNow) / 1000;
                    //проверим можем нет еще откатить
                    if (pikBuf * cc < max - 0.0f
                        && !stopGoingUp
                            ) {//дельта отката 0.4
                        agcLevel = cc;
                    } else {
                        stopGoingUp = 1; //остановить откат
                    }
                }
                //заполним период
                for (uint16_t z = i; z <= upIdx; z++) {
                    buffer[z] *= agcLevel;//применить новый коэфф
                }
            }
            i = upIdx; // след цикл будет стратовать от upIdx

        } else { //это сетуация редкая но тоже надо . сделано по класике одного замера
            stopGoingUp = 0;
            if (nowAgc < agcLevel) { // всплеск V
                agcLevel = nowAgc;
                tim = wait;//задежка отпускания
            }
//            float32_t f = a * agcLevel;
            //контроль вылета в out
//            if (f > max) {//out
//                if (buffer[i] >= 0) buffer[i] = max;//max
//                else buffer[i] = -max;//max
//                // agcLevel = 1;
//            } else
            buffer[i] *= agcLevel;

        }

        if (a > agcMetrTemp) agcMetrTemp = a; //s-meter макс V
    }//for

    //средний V за этот блок и прошлые (отсчет по пикам)
    //нужен для ограничения усиления при снятия сигнала
    float32_t mm = rmsPik / pikCount;

    if (mm > rmsFrame)rmsFrame = mm;
    else rmsFrame = (rmsFrame + mm) / 2.0f;

    agcMetr = agcMetrTemp; //s-meter
}
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 05, 2020, 10:00:11 am
Так что в итоге получиться должно, по задумкам? А то уже кажется, что это будет ровно та же аналоговая АРУ, только данные для управления извлекаются из цифрового потока, цифрой же и обрабатываются.

В идеале не должны хвосты разлива спектра быть. Вот сейчас их видно но не слышно.
(на спектре 3кГц и выше голубые полоски. Это как раз и есть разлив спектра)

И кстати, аналоговое ару никогда не будет такой ровной. Всегда будет присутствовать первый выброс в несколько дб (чем меньше вылет - тем лучше). А в цифре можно сделать абсолютно ровное все. Пример: при аналоге морзянка будет подстукивать при первом включении.

http://analogtrx.com/SMF/index.php?topic=100.msg5857#msg5857

это приме моего ару в аналоге. Тест примерно похож на то , что показал с свип амплитудой
Название: Re: Цифровая АРУ 0...1
Отправлено: 6Ж2П от Декабрь 05, 2020, 05:43:44 pm
В идеале не должны хвосты разлива спектра быть
В аналоговом режиме расширение спектра можно посчитать сразу по Фурье, перемножив две временные функции - сигнала и Ку(t) тракта под действием АРУ, затем посчитав интеграл Фурье для полученной функции. Рассматривая в частотной области, произведение двух функций во временной области есть свёртка в частотной. Из второго очевидно, что спектр расширится на величину, равную  максимальной частоте в спектре функции сигнала Ку(t). Понятно, что при оценке ширины спектра мы должны задавать некую нижнюю границу для амплитуды плотности спектральных составляющих, ниже которой считаем, что составляющих нет. При работе аналоговой АРУ максимальные компоненты в спектре Ку(t) появляются при резком её изменении, что происходит при появлении мощного сигнала. Учитывая, что всегда есть определённая задержка между сигналом и управлением, получаем, что пик спектральных составляющих функции Ку(t) попадает как раз на время, когда сигнал тоже практически максимального уровня, ограниченного только линейностью тракта или принудительно лимитером. Вот тут и возникает всплеск расширения спектра. Если сигнал управления действовал бы ещё до появления мощного сигнала, то он промодулировал бы сигнал обычного уровня или ещё меньшего, в случае прослушивания шума (мы же не выводим шум на уровень нормальной громкости).

ПС Хвосты есть и будут всегда, вопрос в их уровне.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 05, 2020, 06:07:49 pm
вот "эта" щербинка разливает спектр и ее слышно
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 05, 2020, 06:09:25 pm
Понятно, что при оценке ширины спектра мы должны задавать некую нижнюю границу для амплитуды плотности спектральных составляющих, ниже которой считаем, что составляющих нет.
Мы ее слышать не должны. Это всего лишь недоработки алгоритма. Надо копать.
Название: Re: Цифровая АРУ 0...1
Отправлено: 6Ж2П от Декабрь 05, 2020, 07:16:45 pm
А объективно, в цифрах, сколько это?
Вы сейчас проверяете на реальном сигнале? Это окончательная проверка должна быть. Входной сигнал ведь можно сгенерировать программно, обработать, просмотреть спектр, временную характеристику. Для всего этого вообще ничего не надо, кроме компьютера.

У Вас там три точки, где уширение спектра, две очень существенные. На осциллограмме видно только одно место, где первая производная испытывает разрыв. Спектр в большем интервале времени показан?
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 05, 2020, 07:26:55 pm
Я беру сигнал без ару с тульского сдр. Он полностью оцифрован и там разливов нет.

Походу как я не бегал от стыковки фрэймов никуда от нее не деться. Вот на фото не с того появляется козявка. По алгоритму: он вообще не должен в этом месте что-то править, однако правит. Вариант один...это 2 периода с обеих сторон фрейма (с начала и с конца). 
Название: Re: Цифровая АРУ 0...1
Отправлено: 6Ж2П от Декабрь 05, 2020, 07:32:52 pm
по виду, там сшивка прямым отрезком.
Цитировать
Стандарт натуральной цифровой записи звука обозначается, как РСМ (Pulse Code Modulation) Wave. В процессе записи через определенные промежутки времени регистрируется текущая амплитуда звуковой волны, в результате чего получаются как бы моментальные снимки (фреймы) звуковой волны. Из последовательности этих фреймов и состоит звукозапись, носящая название waveform.
Здесь фрейм, это просто амплитуда в моменты дискретизации, у Вас фрейм, это что?
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 05, 2020, 07:37:15 pm
Сшивок больше нет. Прохожусь плавным коэффициентом  Х....1 назад . Я последний (первый по очереди) вообще на 1 умножаю.

Фрэйм 1024 ацп замеров
Название: Re: Цифровая АРУ 0...1
Отправлено: 6Ж2П от Декабрь 05, 2020, 08:12:24 pm
Я так и подумал, что у Вас фрейм это набор отсчётов.
Я про сшивку не в алгоритме, а смотря на кривую сигнала. Там очевидная вставка прямого отрезка.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 05, 2020, 08:23:42 pm
Это не вставка, это так выглядит переходный процесс  если точки не в синусе. Это так цепи ЦАПа и входные цепи звуковой платы изображают. Вообщем переходный процесс.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 05, 2020, 08:25:32 pm
Будем залазить в предыдущий фрейм, который уже ушел под управления ДМА для выброса этого буфера  в ЦАП. Фрэйм 1024 точек, мне надо залезти с конца точек на 50 или около того. Надеюсь ДМА еще не успеет дойти до этих мест, а то буде коллизия, когда и ДМА и ПРОЦ будут обращаться к одной и тойже ячейке памяти. Неприятная ситуация будет.
Название: Re: Цифровая АРУ 0...1
Отправлено: 6Ж2П от Декабрь 06, 2020, 01:14:14 am
Новая АРУ
(вариант 4)
Это язык Си для STM32, насколько понимаю.
А это корректный код Вы вставили для обозрения?

 if (a > 0)nowAgc = max / a;
        else  nowAgc = max / 0.000005f;

нет пробела после условия и далее нет двух пар фигурных скобок

float32_t   почему так записывается тип float ? Зачем там 32_t ?


 
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 06, 2020, 09:02:25 am
Если один оператор после if или else то {} можно не ставить. float32_t это float  , но такая запись в листинге программы очень хорошо выхватывается на фоне всего.
Код корректный ....это вы так шутите ))) ?
Название: Re: Цифровая АРУ 0...1
Отправлено: Relayer от Декабрь 06, 2020, 10:18:09 am
еще короче :)
nowAgc = max / (a > 0? a : 0.000005f);
Название: Re: Цифровая АРУ 0...1
Отправлено: 6Ж2П от Декабрь 06, 2020, 10:20:27 am
А пробел тоже можно не ставить?
То есть, допустимы оба варианта записи типа с плавающей запятой, один просто float, второй с явным указанием разрядности числа? А float16_t тоже можно применять, как и для целочисленных переменных?
Шуток никаких нет, я спросил у Вас, вместо того, чтобы лезть в среду Си и проверять, это мне надо было комбайн целый запускать, не двумя кликами реализуется.
Название: Re: Цифровая АРУ 0...1
Отправлено: 6Ж2П от Декабрь 06, 2020, 10:24:24 am
еще короче
ага, для постоянно работающих с Си нормально наверное, а для обучающегося лучше не спешить с сокращениями. Один написал в теле цикла вместо индекса a[i+1]  a[i++], а потом долго искал ошибку.

ПС ra0ahc, давно подумываю тоже попрограммировать STM, но никак не соберусь. Подскажете, если что, для начала в технической части, по отладочным платам, или как они там называются? Один кристалл же никуда не приткнёшь, надо на плате распаянный иметь
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 06, 2020, 10:56:41 am
Nucleo H7 - есть ваше всё
Среда разработки от ST у них сейчас неплохая среда.
float16_t не бывает, только float64_t  cr123
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 06, 2020, 11:04:29 am
if (a)nowAgc = max / a;
else  nowAgc = max / 0.000005f;
и
nowAgc = max /(a?a: 0.000005f);

мне кажется первый будет работать быстрее(на сколько я помню ассемблер там один такт на это условие)...хотя фиг знает
в нашем случаи
nowAgc = max /(a+0.000005f); тоже будет работать и не на что не повлияет. Всеравно потом приводит к 12 битам.
Название: Re: Цифровая АРУ 0...1
Отправлено: Relayer от Декабрь 06, 2020, 12:07:51 pm
Одинаково они будут работать. Оптимизаторы в компиляторах давно уже заоптимизированы :)
Название: Re: Цифровая АРУ 0...1
Отправлено: VA7KL от Декабрь 06, 2020, 12:14:41 pm
от ST у них сейчас неплохая среда
Как называется среда что на картинке? А то я запускаю Geany c Ubuntu и компилирую руками.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 06, 2020, 03:00:05 pm
CLion от JetBrains
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 06, 2020, 09:02:13 pm
Просидел еще пару дней ...
Сделал "залаз" в соседний фрейм - однозначно помогло, прям сильно.
Остались "вот такие" фантомы ....убился искать какое событие из вызывает.

Ну в а целом (смотрим на панораму) без этих аномалий уже можно сказать, что это "ОНО"
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 07, 2020, 05:11:46 pm
НАШЕЛ ГДЕ КОСЯК
 
Вот записи в разных режимах.

Залетов и вылетов в аут не заметил.

https://drive.google.com/drive/folders/1Qnh064SKTlaO3RvhifW4HqcNGI8yzb9P?usp=sharing
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 07, 2020, 05:18:02 pm
SSB CW
Скорость АРУ - нормальная. Ворота 4дб. Задержка на отпускания 100мс
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 07, 2020, 05:34:35 pm
float32_t max = 0.49905586f; //максималка 0.49975586fот -0.5 до +0.5 примерно для 12 бит
uint16_t count = 100;
uint8_t stopGoingUp = 0;

float32_t rmsFrame = 0;
uint16_t uOldPStartIdx;
float32_t uOldPikV;
uint16_t wait = 5;
float32_t rate = 24000.0f;

///@brief АРУ
///@param buffer
void agcDo(float32_t *buffer) {
    float32_t rmsPik = 0;
    float32_t agcMetrTemp = 0;
    float32_t pit1 = -1;
    float32_t pit2 = 0;
    uint16_t pikCount = 0;
    if (tim > 0)tim--; //уменьшение задержки
    stopGoingUp = 0;
    uint16_t uLastNullIdx = 0;


    for (uint16_t i = 0; i < FRAME_SIZE; i++) {
        float32_t a;
        //a = (buffer[i] < 0.0f) ? -1.0f * buffer[i] : buffer[i];// adc V
        a = fabsf(buffer[i]);
        // seach min
        if (a > 0)nowAgc = max / a;
        else nowAgc = max / 0.000005f;


        uint16_t upIdx = i;

        float32_t pikBuf;
        uint8_t exit = 1;
        uint8_t exitYN = 0;
        uint16_t wait = 0;// 1msec

        uint16_t uPikIxxPlus = 0;
        uint16_t uPikIxxMinus = 0;
        float32_t uPikVPlus = 0; //V + pik
        float32_t uPikVMinus = 0;//V - pik
        //direction
        int direction = 1;//напрвление вниз (отрицательная синусоида)
        if (i + 1 < FRAME_SIZE) {
            if (buffer[i] <= 0 || buffer[i + 1] < 0) direction = 0;//напрвление вверх (положительная синусоида)
        } else {
            if (buffer[i] <= 0 || buffer[i - 1] > 0) direction = 0;//напрвление вверх (положительная синусоида)
        }

        while (exit) { //поиск пика в блоке от 0 до 0
            exit = 0;//выходим
            float32_t p1 = fabsf(buffer[upIdx]);//feature
            if (direction) {//+++++++++++++++++++++++++++++
                //если условие остановило в ++ то добиваем его до 0
                if ((buffer[upIdx] > 0 && !exitYN)) {
                    if (p1 > uPikVPlus) uPikVPlus = p1;
                    exit = 1;
                }
                //центральная точка
                if ((buffer[upIdx] > 0 && buffer[upIdx + 1] <= 0) && upIdx + 1 < FRAME_SIZE && !exitYN) {
                    uLastNullIdx = upIdx;
                }
                //если условие остановило в -- то добиваем его до 0 и выходим
                if ((buffer[upIdx] <= 0)) {
                    exitYN = 1; //не дадим пред условию сработать
                    if (p1 > uPikVMinus) uPikVMinus = p1;
                    exit = 1;
                }

            } else { //------------------------
                //going up
                //если условие остановило в -- то добиваем его до 0 и выходим
                if ((buffer[upIdx] <= 0 && !exitYN)) {
                    if (p1 > uPikVMinus) uPikVMinus = p1;
                    exit = 1;
                }
                //центральная точка
                if ((buffer[upIdx] <= 0 && buffer[upIdx + 1] > 0) && upIdx + 1 < FRAME_SIZE && !exitYN) {
                    uLastNullIdx = upIdx;
                }
                //если условие остановило в ++ то добиваем его до 0
                if ((buffer[upIdx] > 0)) {//
                    exitYN = 1; //не дадим пред условию сработать
                    if (p1 > uPikVPlus) uPikVPlus = p1;
                    exit = 1;
                }
            }
            if (upIdx + 1 < FRAME_SIZE && exit) upIdx++;
            else exit = 0;//выходим

        }//while
        if (upIdx + 1 == FRAME_SIZE) {} else upIdx -= 1;
        if (upIdx > i) { //если блок не пустой то...

            //upIdx -= 1;
            float32_t locNowAgc;


            if (uPikVPlus > uPikVMinus) {
                locNowAgc = max / (uPikVPlus ? uPikVPlus : 0.000001f);
                pikBuf = (uPikVPlus ? uPikVPlus : 0.000001f);
            } else {
                locNowAgc = max / (uPikVMinus ? uPikVMinus : 0.000001f);
                pikBuf = (uPikVMinus ? uPikVMinus : 0.000001f);
            }

            //типа среднее значение этого блока. исползуется для отката .
            rmsPik += (uPikVPlus + uPikVMinus) / 2.0f;
            pikCount++;//количество синусоид, нужен для расчета среднего пика по блоку
            //agcLevel == текущий уровень ару
            if (locNowAgc <= agcLevel) { // всплеск или питч V, идем вниз || wasVariant..........................
                stopGoingUp = 0;
                //заполним блок

                for (uint16_t z = i; z <= upIdx; z++) {//(upIdx+1==FRAME_SIZE?uLastNullIdx:upIdx)
                    buffer[z] *= locNowAgc;
                }


                //откат усиления назад по блоку
                //убират стук
                if (locNowAgc != agcLevel) {
                    uint16_t d = 0;
                    float32_t dx = locNowAgc / agcLevel;
                    if (i == 0) {

                        uint16_t dmax =(( (uint16_t) (FRAME_SIZE - uOldPStartIdx))) ;
                        uint16_t index = 1;
                        uint16_t srI=FRAME_SIZE/2;
                        if(dmax<50)dmax=200;
                        while (d < dmax-1) {
                            uint8_t o = (uint8_t) (dacTxBankNawNumber ? 0 : 1);
                            d++;

                            int buf0 = (int) (pOutDac[o][srI - index] >>16) - 2047;
                            int buf1 = (int) (pOutDac[o][srI - index] & 0x0000ffff) - 2047;

//                            if (d < FRAME_SIZE - uLastNullIdx && uLastNullIdx > 0)
//                                pOutDac[o][FRAME_SIZE - index] = ((uint32_t) (buf0 * dx + 2047)) << 16;
//                            else
                                pOutDac[o][srI - index] = ((uint32_t) (buf0 * (dx + d * (1 - dx) / dmax) + 2047))<< 16;

                            d++;
//                            if (d < FRAME_SIZE - uLastNullIdx && uLastNullIdx > 0)
//                                pOutDac[o][FRAME_SIZE - index] |= ((uint32_t) (buf1 * dx + 2047)) ;
//                            else
                                pOutDac[o][srI - index] |=
                                        ((uint32_t) (buf1 * (dx + d * (1 - dx) / dmax) + 2047)) ;

                            index++;
//                            pOutDac[o][srI - index]=0xffffffff;
                        }
                        // buffer[i]=0;
                    } else {
                        float32_t dmax = (i - uOldPStartIdx);
                        if (dmax <= 0 || uOldPStartIdx == 0) dmax = i;

                        while (d < dmax) {
                            d++;
                            buffer[i - d] *= dx + d * (1 - dx) / dmax;
                        }

                    }
                }
                //питч детектор
                stopGoingUp = 0;
                //tim = wait;//задежка отпускания
                if ((pit2 < pit1 && pit1 < pikBuf)) {//не питч
                    tim = wait;
                }
                agcLevel = locNowAgc;
                pit2 = pit1;
                pit1 = pikBuf;

            } else {//идем вверх/////////////////////////////////////////////////////////////////////
                float32_t cc;
                float32_t sred = agcLevel / locNowAgc;
                float32_t rmsNow = (rmsFrame + rmsPik / pikCount) / 2.0f;
                float32_t oldAgcLevel = agcLevel;

                if (tim == 0 && upIdx + 10 < FRAME_SIZE && i > 100) {//подождали и начинаем x
                    cc = agcLevel + (sred / rmsNow) / 50.5f;
                    //проверим можем нет еще откатить
                    if (pikBuf * cc < max - 0.2f && !stopGoingUp) {//дельта отката 0.4
                        agcLevel = cc;
                    } else {
                        stopGoingUp = 1; //остановить откат
                    }
                }
                float32_t kof = agcLevel / oldAgcLevel;
                uint16_t dmax = (upIdx - i);

                //заполним период
                for (uint16_t z = i; z <= upIdx; z++) {
                    buffer[z] *= oldAgcLevel * (kof + (upIdx - z) * (1 - kof) / dmax);//применить новый коэфф

                }
            }
            uOldPStartIdx = i;
            i = upIdx; // след цикл будет стратовать от upIdx
        } else { //это сетуация редкая но тоже надо . сделано по класике одного замера
            stopGoingUp = 0;
            if (nowAgc < agcLevel) { // всплеск V
                // tim = wait;//задежка отпускания
                buffer[i] *= nowAgc;
            } else {
                buffer[i] *= agcLevel;
            }
            uOldPStartIdx = i;

        }
        uLastNullIdx = 0; //на случай если больше не будет центра


        if (a > agcMetrTemp) agcMetrTemp = a; //s-meter макс V
    }//for
    // buffer[0] = 0;
    //средний V за этот блок и прошлые (отсчет по пикам)
    //нужен для ограничения усиления при снятия сигнала
    float32_t mm = rmsPik / pikCount;

    if (mm > rmsFrame)rmsFrame = mm;
    else rmsFrame = (rmsFrame + mm) / 2.0f;

    agcMetr = agcMetrTemp; //s-meter
}
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 07, 2020, 08:01:48 pm
Убрал все лишнее и написал коменты

loat32_t max = 0.49905586f; //максималка 0.49975586fот -0.5 до +0.5 примерно для 12 бит
uint16_t count = 100;
uint8_t stopGoingUp = 0;

float32_t rmsFrame = 0;
uint16_t uOldPStartIdx;
uint16_t wait = 20;//задержка возврата ару, в блоках 40мс каждый блок

///@brief АРУ
///@param buffer
void agcDo(float32_t *buffer) {
    float32_t rmsPik = 0;
    float32_t agcMetrTemp = 0;
    float32_t pit1 = -1;
    float32_t pit2 = 0;
    uint16_t pikCount = 0;
    if (tim > 0)tim--; //уменьшение задержки
    stopGoingUp = 0;


    for (uint16_t i = 0; i < FRAME_SIZE; i++) {
        float32_t a;
        a = fabsf(buffer[i]);
        if (a > 0)nowAgc = max / a;
        else nowAgc = max / (a?a:0.000005f);

        uint16_t upIdx = i;
        float32_t pikBuf = 0;
        uint8_t exit = 1;
        uint8_t exitYN = 0;
        //direction
         int direction = 1;// напрвление вверх (положительная синусоида)
        if (i + 1 < FRAME_SIZE) {
            if (buffer[i] <= 0 || buffer[i + 1] < 0) direction = 0;//напрвление вниз (отрицательная синусоида)
        } else {
            if (buffer[i] <= 0 || buffer[i - 1] > 0) direction = 0;//напрвление вниз (отрицательная синусоида)
        }

        while (exit) { //поиск пика в блоке от 0 до 0
            exit = 0;//выходим
            float32_t p1 = fabsf(buffer[upIdx]);//feature
            if (direction) {//+++++++++++++++++++++++++++++
                if ((buffer[upIdx] > 0 && !exitYN)) {
                    if (p1 > pikBuf) pikBuf = p1;
                    exit = 1;
                }
                if (buffer[upIdx] <=0 ) {// добиваем его до 0 и выходим
                    exitYN = 1; //не дадим пред условию сработать
                    if (p1 > pikBuf) pikBuf = p1;
                    exit = 1;
                }

            } else { //------------------------
                //going up
                if ((buffer[upIdx] <= 0 && !exitYN)) {
                    if (p1 > pikBuf) pikBuf = p1;
                    exit = 1;
                }
                if (buffer[upIdx] >0 ) {// добиваем его до 0
                    exitYN = 1; //не дадим пред условию сработать
                    if (p1 > pikBuf) pikBuf = p1;
                    exit = 1;
                }
            }
            if (upIdx + 1 < FRAME_SIZE && exit) upIdx++;
            else exit = 0;//выходим

        }//while
        if (upIdx + 1 == FRAME_SIZE) {} else upIdx -= 1;
        if (upIdx > i) { //если блок не пустой то...

            //upIdx -= 1;
            float32_t locNowAgc;
            locNowAgc = max / (pikBuf ? pikBuf : 0.000001f);

            //типа среднее значение этого блока. используется для отката .
            rmsPik += pikBuf;
            pikCount++;//количество синусоид, нужен для расчета среднего пика по блоку
            //agcLevel == текущий уровень ару
            if (locNowAgc <= agcLevel) { // всплеск или питч V, идем вниз ..........................
                stopGoingUp = 0;
                //заполним блок
                for (uint16_t z = i; z <= upIdx; z++) {
                    buffer[z] *= locNowAgc;
                }

                //откат усиления назад по блоку
                //убирает стук
                if (locNowAgc != agcLevel) {
                    uint16_t d = 0;
                    float32_t dx = locNowAgc / agcLevel;
                    //если начало фрэйма
                    if (i == 0) {//лезим в старый буфер который уже летит в цап
                        uint16_t dmax = (uint16_t) (FRAME_SIZE - uOldPStartIdx);
                        uint16_t index = 1;
                        uint16_t srI = FRAME_SIZE / 2;//в цап летят 16 битные данные
                        if (dmax < 50)dmax = 200;//нагло , можно уменьшить
                        while (d < dmax - 1) {
                            uint8_t o = (uint8_t) (dacTxBankNawNumber ? 0 : 1);
                            d++;
                            //плавное уменьшение  назад по старомы фрейму от dx до 1
                            int buf0 = (int) (pOutDac[o][srI - index] >> 16) - 2047;
                            int buf1 = (int) (pOutDac[o][srI - index] & 0x0000ffff) - 2047;
                            //первые 16 бит
                            pOutDac[o][srI - index] = ((uint32_t) (buf0 * (dx + d * (1 - dx) / dmax) + 2047)) << 16;

                            d++;
                            //вторые 16 бит
                            pOutDac[o][srI - index] |=
                                    ((uint32_t) (buf1 * (dx + d * (1 - dx) / dmax) + 2047));
                            index++;
                        }
                    } else {//просто откат на один период с уменьшением.
                        float32_t dmax = (i - uOldPStartIdx);
                        if (dmax <= 0 || uOldPStartIdx == 0) dmax = i;
                        //плавное уменьшение  назад по фрейму от dx до 1
                        while (d < dmax) {
                            d++;
                            buffer[i - d] *= dx + d * (1 - dx) / dmax;
                        }
                    }
                }
                stopGoingUp = 0;
                //питч детектор
                //нужно добавить еще уменьшение скорости отката и потом его возрат
                //для полной обработки питчиков
                if ((pit2 < pit1 && pit1 < pikBuf)) {//не питч
                    tim = wait;
                }
                agcLevel = locNowAgc;
                pit2 = pit1;
                pit1 = pikBuf;

            } else {//идем вверх/////////////////////////////////////////////////////////////////////
                float32_t cc;
                float32_t sred = agcLevel / locNowAgc;
                float32_t rmsNow = (rmsFrame + rmsPik / pikCount) / 2.0f;
                float32_t oldAgcLevel = agcLevel;
                //первый период и последний не поднимаем
                if (tim == 0 && upIdx + 10 < FRAME_SIZE && i > 100) {//подождали и начинаем x
                    cc = agcLevel + (sred / rmsNow) / 50.5f; // скорость отката 200...0.5
                    //проверим можем нет еще откатить
                    if (pikBuf * cc < max - 0.2f && !stopGoingUp) {//дельта ВОРОТА  0.3=8дб
                        agcLevel = cc;
                    } else {
                        stopGoingUp = 1; //остановить откат
                    }
                }
                float32_t kof = agcLevel / oldAgcLevel;
                uint16_t dmax = (upIdx - i);

                //заполним период , плавно!!!
                for (uint16_t z = i; z <= upIdx; z++) {
                    buffer[z] *= oldAgcLevel * (kof + (upIdx - z) * (1 - kof) / dmax);//применить новый коэфф
                }
            }
            uOldPStartIdx = i;
            i = upIdx; // след цикл будет стратовать от upIdx
        } else { //это ситуация редкая, но тоже надо . сделано по класике одного замера
            stopGoingUp = 0;
            if (nowAgc < agcLevel) buffer[i] *= nowAgc;
            else buffer[i] *= agcLevel;
            uOldPStartIdx = i;
        }
        if (a > agcMetrTemp) agcMetrTemp = a; //s-meter макс V
    }//for
    //средний V за этот блок и прошлые (отсчет по пикам)
    //нужен для ограничения усиления при снятия сигнала
    float32_t mm = rmsPik / pikCount;

    if (mm > rmsFrame)rmsFrame = mm;
    else rmsFrame = (rmsFrame + mm) / 2.0f;

    agcMetr = agcMetrTemp; //s-meter
}
Название: Re: Цифровая АРУ 0...1
Отправлено: 6Ж2П от Декабрь 07, 2020, 09:19:53 pm
Скорость АРУ - нормальная. Ворота 4дб. Задержка на отпускания 100мс
Вы обрезаете ось времени на спектрограмме? Не видно интервалы времени.
Что за сигнал подаёте?
По спектрограмме видно, что АРУ в постоянной работе у Вас, спектр постоянно разлетается на всю высоту (ширину полосы 7 кГц)
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 07, 2020, 10:16:25 pm
Он и будет разливаться вы же сами говорили. Просто раньше прям ступеньки проскакивали и их капец как слышно , а сегодня я победил их. Вверху чёрный водопад и на нем видно разлив на сколько.
Там фишка в чем с этим разливом: если нужно резко убрать усиление то мы умножаем на понижающий коэффициент часть фрейма у меня это один период от 0 до 0. Так появляются изломы ко лове спектр разливаю жестко и далеко и его слышно хоть и нет перегрузки по напряжению , просто цок в наушниках и все. Так вот, мне нужно сгладить этот перелом . Я беру и начинаю идти обратно плавно изменяя этот коэффициент. Эта обратная дороги моде в один период выйти , а может и в пару мс. И чем плавнее мы идём тем меньше разлив. Пока все просто . Теперь возьмём крайние варианты, а точнее переход между фреймами, там самое веселое было прогнать плавным коэффициентом. Прогнал - заработало. Теперь нам надо сделать тоже само с тем когда сил ней сигнал уходит и нам надо усилить сигнал тоже перемножив его на коэффициент. И там тоже происходит разлив спектра , поэтому я и там сделал плавный коэффициент и всё получилось.
Название: Re: Цифровая АРУ 0...1
Отправлено: 6Ж2П от Декабрь 08, 2020, 05:43:52 am
Не смотрел, как у Вас в коде написано, потому мог не так понять со слов, но показалось, что делаете подобное тому, как я графики обрабатываю. Прохожу по всем значениям весовой функцией а-ля кривая Гаусса, только количество точек маленькое - 5, 7.
Вы не откомментировали, почему АРУ постоянно в работе, что за сигнал?
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 08, 2020, 09:22:18 am
Интересные у вас задачки , я про ваши графики. Вроде что то подобное для фильтрация импульс использовать надо. Рисуем ачх потом как раз проходим импульсом по нему и типа фильтр готов.

Про ару

Я специально загнал ару в самый жесткий режим : почти мгновенный откат, 0дб ворота- типа плоский эфир, 0 время задержки (вообще не ждём и сразу после снятия сигнала начинаем поднимать усиление) . По этому кажется что ару постоянно работает ... хотя так и есть.  Сигнал реального эфира с вэб сдр Тульского сайта, там я отключаю ихнее ару и на вход своей платы завожу сигнал без ару , и уже ару работает в моей платке. Понятно , что я не смогу получить такую же чуйку из-за 12 битного ацп у меня, ну да не суть , я же ару делал с не приставку к компу. Этот алгоритм может быть будет работать в ddc трансивере на базе Аиста с новым процессором.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 08, 2020, 12:04:40 pm
Немного теории.
Название: Re: Цифровая АРУ 0...1
Отправлено: veso74 от Декабрь 08, 2020, 12:22:23 pm
скорее так (см. ниже):

"АРУ с задержкой" звучит лучше, где "угол преломления" около RS: 56-58.
Так не теряем усиление при слабых сигналах, а эфир чист, "прозрачен" на низких уровнях, и уровень немного повышается на сильных (напр. не нужно смотреть на S-метр, кто сильнее), а и усиление в ограничение никогда не доходит, даже при самых сильных входных сигналах.

диаграмма взята из:
Исследование систем автоматической регулировки усиления (ару) и автоматической подстройки частоты (апч) (https://gigabaza.ru/doc/45247.html)
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 08, 2020, 12:29:50 pm
Нет, Веселин, это другое. Нам же нужно тихий сигнал поднимать до уровня идеальной ару прямо с самого 0. Нам надо слышать "шум эфира" . Нет там на выходе спада выходного сигнала на наушники до 0, мы всегда слышим шум достаточной громкости.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 08, 2020, 12:32:25 pm
"АРУ с задержкой" звучит лучше,
Даже спорить не буду. Просто задержку во времени сложно изобразить. Она (задержка) будет задерживать откат усиления после снятия сильного сигнала. Хотя это всего лишь переменная настройки АРУ - можно делать и "с" и "без" задержки
Название: Re: Цифровая АРУ 0...1
Отправлено: veso74 от Декабрь 08, 2020, 12:36:16 pm
Да, "АРУ с задержкой" точно так, см. начало х-ки.

А "задержка" в имени (и в действии), ето задержка по уровень (реакции по уровень), а не по время (откат усиления после снятия сильного сигнала).

(А все действия условно без задержки по время реакции. Если необходимо - то интегратор: аналоговой или у вас - с цифровой метод: повторяем или постепенно уменьшаем уровень с нач. уровнем предыдущего накопления)). Пфу, нет у меня русс. слова, вероятно говорим для тех же вещей, но теряется при переводе BG-RU, RU-BG, sorry).


Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 08, 2020, 12:41:23 pm
График не правильный. Увы, но в нем ошибка. Либо мы в терминологии запутались.
Я имею ввиду, что если вытащить антенну , то мы услышим шум точно такой же , что и с антенной (понятно другого оттенка) по уровню. А на этом графике, если вытащить антенну то в наушниках будет 0. Понятно, что это можно регулировать "воротами", что собственно и сделано. Из экспериментов я пришел к выводу, что 7-9дб ворот -это в самый раз. 
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 08, 2020, 12:42:47 pm
А "задержка" в имени (и в действии)
А зачем она? Это пережитки аналогового радио, там всегда будет всплеск работы ару из-за задержак работы цепей обратной связи (скаты кф и эмф)
Кстати, он всегда "бьет по ушам"
Название: Re: Цифровая АРУ 0...1
Отправлено: veso74 от Декабрь 08, 2020, 12:47:45 pm
Цитировать
там всегда будет всплеск работы ару
Ето всплеск только при АРУ при НЧ детекция сигнала для АРУ.
При детекция по ПЧ нет такой. Почему запутались не знаю, там реакция мгновенная (начальная).

Послушайте, померите какое нибудь старое радио. Там у почти всех АРУ с детекция с помощью ПЧ сигнала.
Всплеск началной нет. Мгновенно.

Точно "удар по ушам" мне не нравится в АРУ по НЧ, и он только при НЧ-АРУ, где сигнал для рег. цепь взят через детекция НЧ.

(при детектор по ПЧ: "есть много полу-синусоид за эти напр. 0,1 микросекунды".
при детектор по НЧ (300-3000 Hz) полу-синусоид для детекции примерно 1000...3000 раза меньше)
А если предположить, что энергия больше в басах, отношение становится довольно грубо.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 08, 2020, 12:52:11 pm
Немного истории  lllol
Всё-таки 5 вариантов было. Учитывая полное отсутствие практики в математики , пришлось на «пальцах» саму себе помогать  lllol
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 08, 2020, 12:55:31 pm
Ето всплеск только при АРУ при НЧ детекция сигнала для АРУ.
Нет, он всегда будет, вопрос сколько по времени. У ЭМФ и КФ есть задержка, вот она всему виной. Сигнал вылетит пока не сработает АРУ.
Делал сам, тестил сам. Есть целая ветка, как я боролся с всплеском когда делал Монстро-DSP.
Название: Re: Цифровая АРУ 0...1
Отправлено: veso74 от Декабрь 08, 2020, 01:00:47 pm
Все сложно, и я говорю конечно "на первое приближение" мгновенно. Вы понимаете меня.
t детекция 200 Hz >> много раз t детекция 9000200 Hz начало фронта.

Не понимаю как не работает так. Даже при RS-53 на 59+60 фронт очень прямоугольный с детекция по ПЧ. Сплеск нет. Что детекторовали для АРУ в Монстро-DSP? сигнал ПЧ? или сигнал НЧ?
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 08, 2020, 01:05:52 pm
Все сложно, и я говорил конечно "на первое приближение" мгновенно. Вы понимаете меня.
t детекция 200 Hz >> много раз t детекция 9000200 Hz начало фронта.

Не понимаю как не работает так, даже при RS-53 на 59+60 фронт очень прямоугольный.
Что детекторовали? сигнал ПЧ?

Для аналогового радио - это работает. Точнее не работает, НЧ детекция - плохо. Но для цифрового радио -это нормально. Там всегда будет задержка (особенности технологии) и в это время можно успеть сделать нормальный сигнал без выбросов по амплитуде.
Название: Re: Цифровая АРУ 0...1
Отправлено: veso74 от Декабрь 08, 2020, 01:08:17 pm
Да, понял. Нет ПЧ в тип цифрового радио (обработка НЧ), как выбрали. Идем на метод с дорогой АЦП :). С все ц. обработки - после антенны.
Название: Re: Цифровая АРУ 0...1
Отправлено: 6Ж2П от Декабрь 08, 2020, 02:24:33 pm
График не правильный.
График правильный, там нарисован идеальный усилитель и его принцип регулировки усиления, усилитель который не шумит, а на его вход подаётся сигнал. Шум ли это эфира, полезный ли сигнал или даже свой собственный шум, приведённый ко входу, значения не имеет.
Название: Re: Цифровая АРУ 0...1
Отправлено: 6Ж2П от Декабрь 08, 2020, 02:29:21 pm
У ЭМФ и КФ есть задержка, вот она всему виной. Сигнал вылетит пока не сработает АРУ.
Но эти ФОС ведь не обязательно находятся в петле обратной связи, какая разница тогда сколько они задержки вносят?
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 08, 2020, 02:37:44 pm
У ЭМФ и КФ есть задержка, вот она всему виной. Сигнал вылетит пока не сработает АРУ.
Но эти ФОС ведь не обязательно находятся в петле обратной связи, какая разница тогда сколько они задержки вносят?
Еще как находятся. Они фильтруют потом этот сигнал уже попадает в петлю АРУ а потом опять фильтруют, ПЧ то 2. Да вообще то песня старая.
А график как усилитель - наверное да правильный, но как ару нет нет и еще раз нет.
Название: Re: Цифровая АРУ 0...1
Отправлено: 6Ж2П от Декабрь 08, 2020, 02:41:49 pm
Все сложно, и я говорю конечно "на первое приближение" мгновенно. Вы понимаете меня.
t детекция 200 Hz >> много раз t детекция 9000200 Hz начало фронта.
ВЧ сигнал имеют огибающую и эти много ВЧ импульсов, при АРУ по ПЧ, будут заряжать конденсатор фильтра АРУ лишь до текущего уровня огибающей, а для работы АРУ нужен некий средний уровень именно огибающей. В этом плане как раз отличий сразу и не видно, могу предположить, что огибающая по ВЧ имеет немного меньший диапазон чем НЧ сигнал, пики сигнала прижаты.
Название: Re: Цифровая АРУ 0...1
Отправлено: 6Ж2П от Декабрь 08, 2020, 02:46:44 pm
Они фильтруют потом этот сигнал уже попадает в петлю АРУ а потом опять фильтруют, ПЧ то 2
Это я немного не в курсе конкретно этого изделия, в таком случае в аналоговом АРУ надо две петли, по каждой ПЧ.
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 08, 2020, 02:53:08 pm
У Игоря в Монстре так и есть, 2 петли АРУ. Это жесть. Я задолбался их уравновешивать. Они последовательно идут. В цифре этого ничего нет. Есть только сигнал в 16 бит - "и делай с ним что хош" 
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Декабрь 08, 2020, 03:50:18 pm
Я задолбался их уравновешивать.

А я, сколько делал, пока что не морозился на эту тему ни разу... cr123 pl33
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Декабрь 08, 2020, 04:49:20 pm
Так у вас цап и ацп не было ))))
Название: Re: Цифровая АРУ 0...1
Отправлено: Игорь 2 от Декабрь 08, 2020, 06:47:09 pm
 cr123
Название: Re: Цифровая АРУ 0...1
Отправлено: ra0ahc от Январь 07, 2022, 07:45:05 pm
Продолжение тут

http://analogtrx.com/SMF/index.php?topic=667.0