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

Цифровая АРУ 0...1

243433 просмотров, 284 ответов — стр. 7 из 19

ra0ahcra0ahc
Сообщений: 4868
6 ноября 2020 г. в 04:28#91
Терпение
Есть еще варианты при который алгоритм "улетает"

Игорь 2
Сообщений: 21288
6 ноября 2020 г. в 04:39#92
Да, сложная задача...
Положим, хотите АРУ с временем срабатывания 20 мс, отпускания - 2 с.
Берёте интеграл модуля по времени от того, что загнано в буфер (он у Вас, по-моему, как раз-то 20 мс.), если величина превышает заданный порог (величина порога зависит от выставленного в данный момент усиления в ЦАП), пропорционально скидываете усиление в ЦАП, и всё в порядке - перегруз по среднему уровню исключён, выброса не будет, в отличие от аналогового аналога.
Отпускание - по 2-секундной экспоненте, повторю - вместе с ростом усиления ЦАП, пропорционально снижается порог срабатывания интегратора (чтобы средний уровень на выходе ЦАП держать), у меня эта фигня ещё в конце 80-х работала, как АРУ без выбросов, правда, на весьма примитивной элементной базе - по-моему, вообще 8-битки были с процом размером с коробок спичек lllol, и никаких проблем.
..
Игорь 2
Сообщений: 21288
6 ноября 2020 г. в 05:02#93
Причём, ЧТО ВАЖНО - у меня не было никаких кусочных разбиваний - 256 выборок грузились в сдвиговый регистр, и обновлялись с каждой новой выборкой.
Работа по кускам, когда Вы грузите 20 мс, потом их скидываете, и загоняете новые, обрабатывая их ПО ОТДЕЛЬНОСТИ, по самой своей природе НЕ СМОЖЕТ адекватно работать АРУ.
Простой пример - на конце последней выборки всплеск, и на начале следующей - тоже, тот же самый. Интегрирование по выборкам не даст превышение порога, а интегрирование по последней половине первой, и началу последующей - даст.
Т. е., есть временнАя неопределённость алгоритма - всплеск на границе фреймов не отработается, а в середине - да.
Только непрерывно, тогда и будет Вам счастье. Кусками даже голову не морочьте, ибо там ацтой по определению...
ra0ahcra0ahc
Сообщений: 4868
6 ноября 2020 г. в 06:32#94
Я еще на пути Джедая , пока не сдаемся. Есть моменты, которые у меня в голове не укладываются. Наверное надо паузу сделать.
ra0ahcra0ahc
Сообщений: 4868
6 ноября 2020 г. в 07:15#95
Ну как-то так

переход -45дб -5дб на разных частотах.

Игорь 2
Сообщений: 21288
6 ноября 2020 г. в 08:39#96
Да не, то фигня какая-то. Должна быть одна вполне явная синусоида, потом, не менее явная другая...
ra0ahcra0ahc
Сообщений: 4868
7 ноября 2020 г. в 12:47#97
Пока воюю с вот таким всплеском.
Пока даже физику не могу понять , что раскачивает . Сейчас ару по скату работает.

ra0ahcra0ahc
Сообщений: 4868
7 ноября 2020 г. в 03:10#98
Лайт версия
Работает
плавное от -5 до -45
и резкое от -45 до -5дб

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

Косяк: ару должно работать 0...1 , а сейчас работает 0...0.8, ставишь даже предел 0.9 сразу на всплесках проскакивает инверсный float . Уже целый день борюсь с этим перегрузом (инверсия float) . У меня уже программа больше из защит и проверок состоит, нежели сам алгоритм.

ra0ahcra0ahc
Сообщений: 4868
7 ноября 2020 г. в 03:22#99
УФ

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

Код: [Выделить]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
}
ra0ahcra0ahc
Сообщений: 4868
7 ноября 2020 г. в 03:44#100
На фото и проблема и решение ее
Я целяком в реверсе опускаю скат и ступеньки не получается


ra0ahcra0ahc
Сообщений: 4868
8 ноября 2020 г. в 04:57#101
Нашёл ошибки , будут уточнения по алгоритму .
Например , откат ару вещь тоже сложная. Ее можно только на пиках откатывать с контролем на два шага вперёд.
ra0ahcra0ahc
Сообщений: 4868
8 ноября 2020 г. в 09:30#102
Игорь, есть вопрос.
Я правильно подключаю ацп ?


ra0ahcra0ahc
Сообщений: 4868
8 ноября 2020 г. в 09:34#103
А то по ходу я с ветряными мельницами воюю. Может я неправильно подключил цап или ацп к звуковой?

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

Может просадка напряжения ...??


Игорь 2
Сообщений: 21288
8 ноября 2020 г. в 09:49#104
Я повально подключаю ацп ?

Правильно.
А по поводу переходного процесса - Вы откуда сигнал берёте?
ra0ahcra0ahc
Сообщений: 4868
8 ноября 2020 г. в 10:07#105
Выход на наушники