Автор Тема: Цифровая АРУ 0...1  (Прочитано 32181 раз)

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

Оффлайн Игорь 2

  • Administrator
  • *****
  • Сообщений: 19679
Re: Цифровая АРУ 0...1
« Ответ #150 : Ноябрь 15, 2020, 07:37:46 pm »
Это розовый шум!!

Какой же он розовый? Судя по спектру, это всё-таки, белый шум - спектр ровный.
Да и откуда там розовому взяться, только при косячном приёмнике - напомню, розовый шум имеет спектр -6 дБ/октава.  cr123
Ничего невозможного нет

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: Цифровая АРУ 0...1
« Ответ #151 : Ноябрь 15, 2020, 08:21:04 pm »
Так и есть. Поэтому я им и пользовался для тестов, у него, у шума, низов больше и сигнал более сложный получается чем белый (по структуре). На белом ставишь вроде нормально работает, переключаешь на розовый и упс, идут завалы.
Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: Цифровая АРУ 0...1
« Ответ #152 : Ноябрь 16, 2020, 05:31:19 pm »
Нашел утечку памяти и еще пару досадных ошибок (логических, это же анализ cr123)

Теперь так:
(там где дельта 0 то это стробирование около 1, алгоритм пытается держать 1 без диапазона гистерезиса по усилению, ну и там где дельта 0.3 - это как раз гистерезис)
Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: Цифровая АРУ 0...1
« Ответ #153 : Ноябрь 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

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

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: Цифровая АРУ 0...1
« Ответ #154 : Ноябрь 16, 2020, 05:37:58 pm »
дерьмо пришло к нам в семью сегодня ночью
грёбанный вирус , забирает близких  cry333
Да да, я знаю, у меня ничего не получится )))

Оффлайн Игорь 2

  • Administrator
  • *****
  • Сообщений: 19679
Re: Цифровая АРУ 0...1
« Ответ #155 : Ноябрь 16, 2020, 06:44:46 pm »
 dontt44 У сестры тоже все болеют... no88
Ничего невозможного нет

Оффлайн 6Ж2П

  • Hero Member
  • *****
  • Сообщений: 505
Re: Цифровая АРУ 0...1
« Ответ #156 : Ноябрь 16, 2020, 10:52:50 pm »
розовый шум имеет спектр -6 дБ/октава. 
Нет, спад 3дб/октава

Оффлайн Игорь 2

  • Administrator
  • *****
  • Сообщений: 19679
Re: Цифровая АРУ 0...1
« Ответ #157 : Ноябрь 16, 2020, 11:35:08 pm »
спад 3дб/октава

Согласен... dontt44
Ничего невозможного нет

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: Цифровая АРУ 0...1
« Ответ #158 : Ноябрь 28, 2020, 06:35:13 pm »
Замеры, замеры, замеры

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

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

PS несложно заметить, что мое ару спасает на 2-3 дб тульское ару, а если вообще без меня то стучит безбожно морзянка и всплески до 10дб ....это абзац.
Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: Цифровая АРУ 0...1
« Ответ #159 : Ноябрь 28, 2020, 06:38:42 pm »
...
Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: Цифровая АРУ 0...1
« Ответ #160 : Ноябрь 30, 2020, 09:51:14 pm »
А я тут опять сел за АРУ

Проблема в том , что нельзя просто применить коэффициент к полупериоду, и даже к полному периоду. И даже нельзя применить последовательное наращивание коэффициента. Все это приводит к изменению синуса (как на картинке).
На фото как раз работа ару по полупериоду. Такой подход стучит и это видно на анализаторе.
Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: Цифровая АРУ 0...1
« Ответ #161 : Ноябрь 30, 2020, 09:59:49 pm »
Что делать?  dontt44 Нужно восстанавливать синусоиду. Мне кажется от пика до пика следующей полуволны. И работать нужно по разному. Тот пик который мы занижаем (реакция на всплеск)  мы просто умножаем на 0.ХХ коэффициент и тем самым мы этот полупериод прижимаем ближе к 0. НО! с предыдущем пиком нельзя также делать, у него растет горб. Там нужен другой коэффициент, и причем пик этой полуволны трогать нельзя он должен остаться. Смежные скаты полуволн похожи на улитку. С каждым шагом увеличивается радиус улитки. 
Вот я и говорю, синусоиду нужно восстанавливать.
Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: Цифровая АРУ 0...1
« Ответ #162 : Декабрь 01, 2020, 02:28:05 pm »
Вот этот более наглядней
Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: Цифровая АРУ 0...1
« Ответ #163 : Декабрь 01, 2020, 02:30:34 pm »
Если идет от 0 изменение амплитуды , то вроде все ок, легкое расширение спектра и всё, но если точка изменение амплитуды отстоит от 0 то спектр разливается почти до конца. Не так конечно как при ступеньке, но все же его видно и слышно.
« Последнее редактирование: Декабрь 01, 2020, 02:37:52 pm от ra0ahc »
Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: Цифровая АРУ 0...1
« Ответ #164 : Декабрь 01, 2020, 02:32:46 pm »
Эксперименты продолжаются. Надо почти полностью алгоритм переделывать. Сейчас я меняю амплитуду скачкообразно внутри системы без АЦП
Да да, я знаю, у меня ничего не получится )))