реклама на сайте
подробности

 
 
> Грамотный AGC для вокодера, Теория, а главное практика :)
sigmaN
сообщение Sep 6 2009, 23:48
Сообщение #1


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



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

Собственно, после недолгих раздумий, действовал так:
Определил верхний порог: AGC_MINTHRESHOLD
нижний порог: AGC_MAXTHRESHOLD

На асме зарулил функцию, быстро считающую сумму квадратов переданного ей буфера из 320 отсчётов сигнала
И сам AGC
Код
unsigned long do_agc(int *input, int len){
    //считаем энергию сигнала
    agc_currEnergy=my_sqrsum(input,len);

    if(agc_currEnergy==0)
        return agc_currEnergy; //AGC не требуется - на выход
    if(agc_currEnergy>=AGC_MINTHRESHOLD && agc_currEnergy<=AGC_MAXTHRESHOLD)
        return agc_currEnergy; //AGC не требуется
    else
    if(agc_currEnergy<AGC_MINTHRESHOLD){ //надо бы усилить
        agc_multiplier=sqrt((double)AGC_MINTHRESHOLD/(double)agc_currEnergy);
    }
    else
    if(agc_currEnergy>AGC_MAXTHRESHOLD){//придётся сделать немного потише :)
        agc_multiplier=sqrt((double)AGC_MAXTHRESHOLD/(double)agc_currEnergy);
    }
    
//а теперь подправим сигнал
    while(len--)
        *input++=(int)((double)*input * agc_multiplier);
    
    return agc_currEnergy;
}


От нижнего порога в итоге пришлось отказаться, т.к. регулировка чувствительности микрофона "железными" средствами аудиокодека вроде позволяет добиться неплохой чувствительности.
Верхний тоже вроде режет лишку и с диким теском, от того, что ты подул в микрофон вроде покончено.

Но в целом мне не нравится работа АРУ. Оно то и понятно, ведь то, что я сделал - достаточно тривиально.
Погуглить пробовал, но не так усердно, как мог бы.

Вот прошу пару подсказок.
Также, подозреваю, что и вокодер работал бы эффективнее и качественнее, при наличии грамотно спроектированного и настроенного AGC.

Традиционно, с громоздким и прожорливым Speex препроцессором связываться не хотелось-бы.
Беглого взгляда на функцию, реализующую AGC в speex хватило, чтобы понять, что там наворочено много всего и половина из этого мне не нужна.

Да и заодно практика будет.

В общем покритикуйте мою реализацию плиз. И дайте совет как бы завернуть так, чтобы и голос был loud and clear и в момент громких всплесков было всё хорошо. Ну а я пока параллельно буду гуглить и напрягать CPU:)


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
DRUID3
сообщение Sep 7 2009, 11:15
Сообщение #2


山伏
*****

Группа: Свой
Сообщений: 1 827
Регистрация: 3-08-06
Из: Kyyiv
Пользователь №: 19 294



Цитата(sigmaN @ Sep 7 2009, 02:48) *
Код
unsigned long do_agc(int *input, int len){
    //считаем энергию сигнала
    agc_currEnergy=my_sqrsum(input,len);

Считать нужно скользящим средним, а не для буфера. Иначе это будет не АРУ а "бла-бла-бла" по звучанию...

Цитата(sigmaN @ Sep 7 2009, 02:48) *
Код
    if(agc_currEnergy==0)
        return agc_currEnergy; //AGC не требуется - на выход

Бесполезнйший участок кода отбирающий ресурсы, и компилятор никогда не догадается, что условие заведомо не выполнимое.

Цитата(sigmaN @ Sep 7 2009, 02:48) *
Код
    if(agc_currEnergy>=AGC_MINTHRESHOLD && agc_currEnergy<=AGC_MAXTHRESHOLD)
        return agc_currEnergy; //AGC не требуется

Жжоте! А я думал у АРУ постоянно действующая петля...

Цитата(sigmaN @ Sep 7 2009, 02:48) *
Код
    else
    if(agc_currEnergy<AGC_MINTHRESHOLD){ //надо бы усилить
        agc_multiplier=sqrt((double)AGC_MINTHRESHOLD/(double)agc_currEnergy);
    }

Жесть!

Цитата(sigmaN @ Sep 7 2009, 02:48) *
Код
    else
    if(agc_currEnergy>AGC_MAXTHRESHOLD){//придётся сделать немного потише :)
        agc_multiplier=sqrt((double)AGC_MAXTHRESHOLD/(double)agc_currEnergy);
    }

...и получается у нас ограничитель, и ни разу не АРУ smile.gif . Где сокрыта постоянная времени?

На CQHAM я приводил код АРУ в моем ее понимании smile.gif . Вобщем она мало чем отличается от аналогового прототипа по сути и от рекомендаций Лайонса так же.
Рабочий код остался у меня на работе которую я покинул 3 года назад, но кое что я "тянул домой", подождите немного я гляну есть ли код.

Работает обычная АРУ так - скользящий измеритель мощности на периоде(в аналоговой технике обычный АМ-детектор) через время задерживающую цепочку (а иначе прощайте слабые звуки, в "аналоге" это RC-цепочка в простейшем случае) управляет через линейный элемент ("аналог" - полевой транзистор без питания - т.е. как управляемое сопротивление - включенный как аттенюатор по схеме обычного делителя напряжения или в цепь ОС) управляет масштабом напряжения сигнала("веса" сэмплов для ЦОС).

Чего у Вас нет - времени срабатывания/отпускания. А это принципиально отличие АРУ от банального ограничителя. Вот с таким кодом как у Вас звук будет похож на работу жесткого (причем нелинейного biggrin.gif ) клипера для армейской SSB станции, можно продать код в студию спецэффектов wink.gif .

Далее - очень важна сама форма функции срабатывания/нарастания - Лайонс рекомендует простейший случай - экспоненту(переходной процесс в "аналоговом" RC-звене) - но в серьезной аппаратуре(как аудио, так и связной - от армейской до кол-центров) она обычно сложнее, и лучше всего если ее может задавать пользователь...

Цитата(litv @ Sep 7 2009, 08:45) *
АРУ - вычисляем мощность, ставим ФНЧ на нее с полосой 50 Гц , корректируем сигнал по мощности раз ,применяем примерно раз 0.1 секунды.

Не совсем понял, но если имеется ввиду коррекция применительно к буферам, то это не верно. АРУ работает непрерывно, обновляясь с частотой дискретизации. ФНЧ тоже не совсем то, фильтр низких частот имеет отклик по природе близкий интегратору, но ФНЧ - не интегратор. Попытка сделать хороший ФНЧ отдалит нас еще больше от искомой цели - получим много ненужных пульсаций в переходном процессе.

Цитата(des00 @ Sep 7 2009, 06:01) *
думаю что скажу чушь, т.к. именно со звуком не работал. Но при приеме радиосигналов я делаю ару по средней мощности с учетом запаса на пик-фактор сигнала и использую ПИ-звено регулирования. Использования П звена для быстро изменяющихся сигналов ИМХО не верно.

ПИ - это пропорционально интегрирующее?
А просто П - это пропорциональное?

Тогда Вы конечно же правы! Все верно!

P.S.: Еще добавлю, что если перемудрить с функцией обратной связи и на ней появится участок на котором прирост реакции обратен по знаку приросту воздействия - получится неплохой релаксационный генератор biggrin.gif , как на тунельном диоде...


--------------------
Нас помнят пока мы мешаем другим...
//--------------------------------------------------------
Хороший блатной - мертвый...
//--------------------------------------------------------
Нет старик, это те дроиды которых я ищу...
Go to the top of the page
 
+Quote Post
dch
сообщение Sep 8 2009, 02:46
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 1 179
Регистрация: 15-09-04
Из: 141070 г. Королев МО, улица Горького 39-121
Пользователь №: 661



Цитата(DRUID3 @ Sep 7 2009, 15:15) *
Жжоте! А я думал у АРУ постоянно действующая петля...

тут наверное идет речь не о ару , а какой то нормализации входного сигнала , как этот термин в цифровой обработке называется?
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 20:57
Рейтинг@Mail.ru


Страница сгенерированна за 0.01415 секунд с 7
ELECTRONIX ©2004-2016