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

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

243432 просмотров, 284 ответов — стр. 3 из 19

ra0ahcra0ahc
Сообщений: 4868
11 октября 2020 г. в 02:52#31
Цитата: GenaSPB
А что за выброс на графике Снимок экрана 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;
}
ra0ahcra0ahc
Сообщений: 4868
11 октября 2020 г. в 03:04#32
Выбросы есть длительностью 0.7мСек и ампл 2.5дб
Да и то, мне кажется это артефакты звуковой платы.
ra0ahcra0ahc
Сообщений: 4868
11 октября 2020 г. в 04:35#33
Разместил на цкьюхаме тему эту
один ответ про то , что всё очень не понятно.
ra0ahcra0ahc
Сообщений: 4868
11 октября 2020 г. в 04:39#34
Ладно, что ржать то, тема очень узкая и тяжелая, что я хотел ? 10 человек в принципе понимает о чем речь и лишь немногие хотят хоть что-то обсудить.
Relayer
Сообщений: 1006
11 октября 2020 г. в 04:46#35
При такой реализации у вас АРУ будет цепляться за любые "пички"
ra0ahcra0ahc
Сообщений: 4868
11 октября 2020 г. в 04:47#36
Цитата: Relayer
При такой реализации у вас АРУ будет цепляться за любые "пички"


Я знаю.
ra0ahcra0ahc
Сообщений: 4868
11 октября 2020 г. в 04:51#37
Цепляться надо, но вот с отпусканием можно поработать. Там всё ару работает к 1. Это выглядит как интеллектуальное ару, с переменным фронтом отпускания и переменной задержкой
Relayer
Сообщений: 1006
11 октября 2020 г. в 04:53#38
Вот ару которая у меня в сдр трудилась. Алгоритм сдерт со статей Gerald Youngblood, K5SDR в 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;
ra0ahcra0ahc
Сообщений: 4868
11 октября 2020 г. в 05:06#39
Да тот же алгоритм самый. Мусора многовато. Может для Паскаля это нормально, но С не простит по скорости такое расточительство по циклам.
Про пиччи я ничего не увидел. Да их надо убирать через среднее значение АРУ за период, а это совсем другая история.
Vlad
Сообщений: 2245
11 октября 2020 г. в 05:36#40
Разместил на цкьюхаме тему эту
Если бы там хоть слышали об этой теме - давно бы забросали г... м да еще с ветиляторами. Здесь (на форуме) очень много посетителей оттель, боящихся задать простой вопрос Мэтрам из боязни быть высмеянными. (Посмотрите мой вопрос по ДПФ для поддверждения месным аматорам прописных истин). Там куча просмотров "молчаливым большинством".
ra0ahcra0ahc
Сообщений: 4868
11 октября 2020 г. в 05:42#41
Ага


Relayer
Сообщений: 1006
11 октября 2020 г. в 05:50#42
Да тот же алгоритм самый
Тот да не тот Посмотрите внимательно как усиление выбирается и для чего буфер длиной равной времени отпускания сделан
Relayer
Сообщений: 1006
11 октября 2020 г. в 06:02#43
Ага
Да, ретротема. 8 лет назад когда я еще писал что-то на сикухаме я рассказывал народу в этой теме о QER-фильтрах, доку выкладывал, рассчеты. Наткнулся на глухую стену непонимания и нежелания понимать. Это сейчас все такие умные на кверы перешли, а тогда моя "Стрекоза" была наверное первой конструкцией в рунете с таким фильтром на QER
ra0ahcra0ahc
Сообщений: 4868
11 октября 2020 г. в 06:37#44
Немного запутанно , но в принципе понятно.
Ещё из темы анализа это автонотч и приём телеграфа, но лучше фт8
Relayer
Сообщений: 1006
11 октября 2020 г. в 07:01#45
Автонотч делается элементарно как LMS невысокого порядка с вычитанием