| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | /*  wcpAGC.c
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This file is part of a program that implements a Software-Defined Radio. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Copyright (C) 2011 - 2017 Warren Pratt, NR0V | 
					
						
							|  |  |  | Copyright (C) 2024 Edouard Griffiths, F4EXB Adapted to SDRangel | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  | modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  | as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  | of the License, or (at your option) any later version. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  | GNU General Public License for more details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  | along with this program; if not, write to the Free Software | 
					
						
							|  |  |  | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The author can be reached by email at | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | warren@wpratt.com | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | or by paper mail at | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Warren Pratt | 
					
						
							|  |  |  | 11303 Empire Grade | 
					
						
							|  |  |  | Santa Cruz, CA  95060 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "comm.hpp"
 | 
					
						
							|  |  |  | #include "nbp.hpp"
 | 
					
						
							|  |  |  | #include "wcpAGC.hpp"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace WDSP { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  | void WCPAGC::calc() | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     //assign constants
 | 
					
						
							|  |  |  |     //do one-time initialization
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     out_index = -1; | 
					
						
							|  |  |  |     ring_max = 0.0; | 
					
						
							|  |  |  |     volts = 0.0; | 
					
						
							|  |  |  |     save_volts = 0.0; | 
					
						
							|  |  |  |     fast_backaverage = 0.0; | 
					
						
							|  |  |  |     hang_backaverage = 0.0; | 
					
						
							|  |  |  |     hang_counter = 0; | 
					
						
							|  |  |  |     decay_type = 0; | 
					
						
							|  |  |  |     state = 0; | 
					
						
							|  |  |  |     loadWcpAGC(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | WCPAGC::WCPAGC( | 
					
						
							|  |  |  |     int _run, | 
					
						
							|  |  |  |     int _mode, | 
					
						
							|  |  |  |     int _pmode, | 
					
						
							|  |  |  |     float* _in, | 
					
						
							|  |  |  |     float* _out, | 
					
						
							|  |  |  |     int _io_buffsize, | 
					
						
							|  |  |  |     int _sample_rate, | 
					
						
							|  |  |  |     double _tau_attack, | 
					
						
							|  |  |  |     double _tau_decay, | 
					
						
							|  |  |  |     int _n_tau, | 
					
						
							|  |  |  |     double _max_gain, | 
					
						
							|  |  |  |     double _var_gain, | 
					
						
							|  |  |  |     double _fixed_gain, | 
					
						
							|  |  |  |     double _max_input, | 
					
						
							|  |  |  |     double _out_targ, | 
					
						
							|  |  |  |     double _tau_fast_backaverage, | 
					
						
							|  |  |  |     double _tau_fast_decay, | 
					
						
							|  |  |  |     double _pop_ratio, | 
					
						
							|  |  |  |     int _hang_enable, | 
					
						
							|  |  |  |     double _tau_hang_backmult, | 
					
						
							|  |  |  |     double _hangtime, | 
					
						
							|  |  |  |     double _hang_thresh, | 
					
						
							|  |  |  |     double _tau_hang_decay | 
					
						
							|  |  |  | ) : | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     //initialize per call parameters
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     run(_run), | 
					
						
							|  |  |  |     mode(_mode), | 
					
						
							|  |  |  |     pmode(_pmode), | 
					
						
							|  |  |  |     in(_in), | 
					
						
							|  |  |  |     out(_out), | 
					
						
							|  |  |  |     io_buffsize(_io_buffsize), | 
					
						
							|  |  |  |     sample_rate((double) _sample_rate), | 
					
						
							|  |  |  |     tau_attack(_tau_attack), | 
					
						
							|  |  |  |     tau_decay(_tau_decay), | 
					
						
							|  |  |  |     n_tau(_n_tau), | 
					
						
							|  |  |  |     max_gain(_max_gain), | 
					
						
							|  |  |  |     var_gain(_var_gain), | 
					
						
							|  |  |  |     fixed_gain(_fixed_gain), | 
					
						
							|  |  |  |     max_input(_max_input), | 
					
						
							|  |  |  |     out_targ(_out_targ), | 
					
						
							|  |  |  |     tau_fast_backaverage(_tau_fast_backaverage), | 
					
						
							|  |  |  |     tau_fast_decay(_tau_fast_decay), | 
					
						
							|  |  |  |     pop_ratio(_pop_ratio), | 
					
						
							|  |  |  |     hang_enable(_hang_enable), | 
					
						
							|  |  |  |     tau_hang_backmult(_tau_hang_backmult), | 
					
						
							|  |  |  |     hangtime(_hangtime), | 
					
						
							|  |  |  |     hang_thresh(_hang_thresh), | 
					
						
							|  |  |  |     tau_hang_decay(_tau_hang_decay) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     calc(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void WCPAGC::loadWcpAGC() | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-18 02:08:05 +02:00
										 |  |  |     double tmp; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     //calculate internal parameters
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     attack_buffsize = (int)ceil(sample_rate * n_tau * tau_attack); | 
					
						
							|  |  |  |     in_index = attack_buffsize + out_index; | 
					
						
							|  |  |  |     attack_mult = 1.0 - exp(-1.0 / (sample_rate * tau_attack)); | 
					
						
							|  |  |  |     decay_mult = 1.0 - exp(-1.0 / (sample_rate * tau_decay)); | 
					
						
							|  |  |  |     fast_decay_mult = 1.0 - exp(-1.0 / (sample_rate * tau_fast_decay)); | 
					
						
							|  |  |  |     fast_backmult = 1.0 - exp(-1.0 / (sample_rate * tau_fast_backaverage)); | 
					
						
							|  |  |  |     onemfast_backmult = 1.0 - fast_backmult; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     out_target = out_targ * (1.0 - exp(-(double)n_tau)) * 0.9999; | 
					
						
							|  |  |  |     min_volts = out_target / (var_gain * max_gain); | 
					
						
							|  |  |  |     inv_out_target = 1.0 / out_target; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     tmp = log10(out_target / (max_input * var_gain * max_gain)); | 
					
						
							| 
									
										
										
										
											2024-07-18 02:08:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     if (tmp == 0.0) | 
					
						
							|  |  |  |         tmp = 1e-16; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     slope_constant = (out_target * (1.0 - 1.0 / var_gain)) / tmp; | 
					
						
							|  |  |  |     inv_max_input = 1.0 / max_input; | 
					
						
							|  |  |  |     tmp = pow (10.0, (hang_thresh - 1.0) / 0.125); | 
					
						
							|  |  |  |     hang_level = (max_input * tmp + (out_target / | 
					
						
							|  |  |  |         (var_gain * max_gain)) * (1.0 - tmp)) * 0.637; | 
					
						
							|  |  |  |     hang_backmult = 1.0 - exp(-1.0 / (sample_rate * tau_hang_backmult)); | 
					
						
							|  |  |  |     onemhang_backmult = 1.0 - hang_backmult; | 
					
						
							|  |  |  |     hang_decay_mult = 1.0 - exp(-1.0 / (sample_rate * tau_hang_decay)); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  | void WCPAGC::flush() | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     std::fill(ring.begin(), ring.end(), 0); | 
					
						
							|  |  |  |     std::fill(abs_ring.begin(), abs_ring.end(), 0); | 
					
						
							|  |  |  |     ring_max = 0.0; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  | void WCPAGC::execute() | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  |     int i; | 
					
						
							|  |  |  |     int k; | 
					
						
							| 
									
										
										
										
											2024-07-18 02:08:05 +02:00
										 |  |  |     double mult; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     if (run) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |         if (mode == 0) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |             for (i = 0; i < io_buffsize; i++) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  |                 out[2 * i + 0] = (float) (fixed_gain * in[2 * i + 0]); | 
					
						
							|  |  |  |                 out[2 * i + 1] = (float) (fixed_gain * in[2 * i + 1]); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2024-07-18 02:08:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |         for (i = 0; i < io_buffsize; i++) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |             if (++out_index >= ring_buffsize) | 
					
						
							|  |  |  |                 out_index -= ring_buffsize; | 
					
						
							| 
									
										
										
										
											2024-07-18 02:08:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |             if (++in_index >= ring_buffsize) | 
					
						
							|  |  |  |                 in_index -= ring_buffsize; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |             out_sample[0] = ring[2 * out_index + 0]; | 
					
						
							|  |  |  |             out_sample[1] = ring[2 * out_index + 1]; | 
					
						
							|  |  |  |             abs_out_sample = abs_ring[out_index]; | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  |             ring[2 * in_index + 0] = in[2 * i + 0]; | 
					
						
							|  |  |  |             ring[2 * in_index + 1] = in[2 * i + 1]; | 
					
						
							|  |  |  |             double xr = ring[2 * in_index + 0]; | 
					
						
							|  |  |  |             double xi = ring[2 * in_index + 1]; | 
					
						
							| 
									
										
										
										
											2024-07-18 02:08:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |             if (pmode == 0) | 
					
						
							|  |  |  |                 abs_ring[in_index] = std::max(fabs(xr), fabs(xi)); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |             else | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                 abs_ring[in_index] = sqrt(xr*xr + xi*xi); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |             fast_backaverage = fast_backmult * abs_out_sample + onemfast_backmult * fast_backaverage; | 
					
						
							|  |  |  |             hang_backaverage = hang_backmult * abs_out_sample + onemhang_backmult * hang_backaverage; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |             if ((abs_out_sample >= ring_max) && (abs_out_sample > 0.0)) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                 ring_max = 0.0; | 
					
						
							|  |  |  |                 k = out_index; | 
					
						
							| 
									
										
										
										
											2024-07-18 02:08:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  |                 for (int j = 0; j < attack_buffsize; j++) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                 { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                     if (++k == ring_buffsize) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                         k = 0; | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                     if (abs_ring[k] > ring_max) | 
					
						
							|  |  |  |                         ring_max = abs_ring[k]; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2024-07-18 02:08:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |             if (abs_ring[in_index] > ring_max) | 
					
						
							|  |  |  |                 ring_max = abs_ring[in_index]; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |             if (hang_counter > 0) | 
					
						
							|  |  |  |                 --hang_counter; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |             switch (state) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |             { | 
					
						
							|  |  |  |             case 0: | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                     if (ring_max >= volts) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                     { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                         volts += (ring_max - volts) * attack_mult; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                     } | 
					
						
							|  |  |  |                     else | 
					
						
							|  |  |  |                     { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                         if (volts > pop_ratio * fast_backaverage) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                         { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                             state = 1; | 
					
						
							|  |  |  |                             volts += (ring_max - volts) * fast_decay_mult; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                         } | 
					
						
							|  |  |  |                         else | 
					
						
							|  |  |  |                         { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                             if (hang_enable && (hang_backaverage > hang_level)) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                             { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                                 state = 2; | 
					
						
							|  |  |  |                                 hang_counter = (int)(hangtime * sample_rate); | 
					
						
							|  |  |  |                                 decay_type = 1; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                             } | 
					
						
							|  |  |  |                             else | 
					
						
							|  |  |  |                             { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                                 state = 3; | 
					
						
							|  |  |  |                                 volts += (ring_max - volts) * decay_mult; | 
					
						
							|  |  |  |                                 decay_type = 0; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                             } | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2024-07-18 02:08:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |             case 1: | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                     if (ring_max >= volts) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                     { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                         state = 0; | 
					
						
							|  |  |  |                         volts += (ring_max - volts) * attack_mult; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                     } | 
					
						
							|  |  |  |                     else | 
					
						
							|  |  |  |                     { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                         if (volts > save_volts) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                         { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                             volts += (ring_max - volts) * fast_decay_mult; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                         } | 
					
						
							|  |  |  |                         else | 
					
						
							|  |  |  |                         { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                             if (hang_counter > 0) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                             { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                                 state = 2; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                             } | 
					
						
							|  |  |  |                             else | 
					
						
							|  |  |  |                             { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                                 if (decay_type == 0) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                                 { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                                     state = 3; | 
					
						
							|  |  |  |                                     volts += (ring_max - volts) * decay_mult; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                                 } | 
					
						
							|  |  |  |                                 else | 
					
						
							|  |  |  |                                 { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                                     state = 4; | 
					
						
							|  |  |  |                                     volts += (ring_max - volts) * hang_decay_mult; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                                 } | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2024-07-18 02:08:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |             case 2: | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                     if (ring_max >= volts) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                     { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                         state = 0; | 
					
						
							|  |  |  |                         save_volts = volts; | 
					
						
							|  |  |  |                         volts += (ring_max - volts) * attack_mult; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                     } | 
					
						
							|  |  |  |                     else | 
					
						
							|  |  |  |                     { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                         if (hang_counter == 0) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                         { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                             state = 4; | 
					
						
							|  |  |  |                             volts += (ring_max - volts) * hang_decay_mult; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2024-07-18 02:08:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |             case 3: | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                     if (ring_max >= volts) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                     { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                         state = 0; | 
					
						
							|  |  |  |                         save_volts = volts; | 
					
						
							|  |  |  |                         volts += (ring_max - volts) * attack_mult; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                     } | 
					
						
							|  |  |  |                     else | 
					
						
							|  |  |  |                     { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                         volts += (ring_max - volts) * decay_mult; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                     } | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2024-07-18 02:08:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |             case 4: | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                     if (ring_max >= volts) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                     { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                         state = 0; | 
					
						
							|  |  |  |                         save_volts = volts; | 
					
						
							|  |  |  |                         volts += (ring_max - volts) * attack_mult; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                     } | 
					
						
							|  |  |  |                     else | 
					
						
							|  |  |  |                     { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |                         volts += (ring_max - volts) * hang_decay_mult; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |                     } | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  |             default: | 
					
						
							|  |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |             if (volts < min_volts) | 
					
						
							|  |  |  |                 volts = min_volts; | 
					
						
							| 
									
										
										
										
											2024-07-18 02:08:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |             gain = volts * inv_out_target; | 
					
						
							|  |  |  |             mult = (out_target - slope_constant * std::min (0.0, log10(inv_max_input * volts))) / volts; | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  |             out[2 * i + 0] = (float) (out_sample[0] * mult); | 
					
						
							|  |  |  |             out[2 * i + 1] = (float) (out_sample[1] * mult); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     else if (out != in) | 
					
						
							| 
									
										
										
										
											2024-07-18 02:08:05 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |         std::copy(in, in + io_buffsize * 2, out); | 
					
						
							| 
									
										
										
										
											2024-07-18 02:08:05 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  | void WCPAGC::setBuffers(float* _in, float* _out) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     in = _in; | 
					
						
							|  |  |  |     out = _out; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  | void WCPAGC::setSamplerate(int _rate) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     sample_rate = _rate; | 
					
						
							|  |  |  |     calc(); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  | void WCPAGC::setSize(int _size) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     io_buffsize = _size; | 
					
						
							|  |  |  |     calc(); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /********************************************************************************************************
 | 
					
						
							|  |  |  | *                                                                                                       * | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  | *                                        Public Properties                                              * | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | *                                                                                                       * | 
					
						
							|  |  |  | ********************************************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  | void WCPAGC::setMode(int _mode) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     switch (_mode) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         case 0: //agcOFF
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |             mode = 0; | 
					
						
							|  |  |  |             loadWcpAGC(); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |             break; | 
					
						
							|  |  |  |         case 1: //agcLONG
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |             mode = 1; | 
					
						
							|  |  |  |             hangtime = 2.000; | 
					
						
							|  |  |  |             tau_decay = 2.000; | 
					
						
							|  |  |  |             loadWcpAGC(); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |             break; | 
					
						
							|  |  |  |         case 2: //agcSLOW
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |             mode = 2; | 
					
						
							|  |  |  |             hangtime = 1.000; | 
					
						
							|  |  |  |             tau_decay = 0.500; | 
					
						
							|  |  |  |             loadWcpAGC(); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |             break; | 
					
						
							|  |  |  |         case 3: //agcMED
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |             mode = 3; | 
					
						
							|  |  |  |             hang_thresh = 1.0; | 
					
						
							|  |  |  |             hangtime = 0.000; | 
					
						
							|  |  |  |             tau_decay = 0.250; | 
					
						
							|  |  |  |             loadWcpAGC(); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |             break; | 
					
						
							|  |  |  |         case 4: //agcFAST
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |             mode = 4; | 
					
						
							|  |  |  |             hang_thresh = 1.0; | 
					
						
							|  |  |  |             hangtime = 0.000; | 
					
						
							|  |  |  |             tau_decay = 0.050; | 
					
						
							|  |  |  |             loadWcpAGC(); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |             break; | 
					
						
							|  |  |  |         default: | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |             mode = 5; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |             break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  | void WCPAGC::setFixed(double _fixed_agc) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  |     fixed_gain = pow (10.0, _fixed_agc / 20.0); | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     loadWcpAGC(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void WCPAGC::setAttack(int _attack) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     tau_attack = (double) _attack / 1000.0; | 
					
						
							|  |  |  |     loadWcpAGC(); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  | void WCPAGC::setDecay(int _decay) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     tau_decay = (double) _decay / 1000.0; | 
					
						
							|  |  |  |     loadWcpAGC(); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  | void WCPAGC::setHang(int _hang) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     hangtime = (double) _hang / 1000.0; | 
					
						
							|  |  |  |     loadWcpAGC(); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  | void WCPAGC::getHangLevel(double *hangLevel) const | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | //for line on bandscope
 | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     *hangLevel = 20.0 * log10(hang_level / 0.637); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  | void WCPAGC::setHangLevel(double _hangLevel) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | //for line on bandscope
 | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  |     double convert; | 
					
						
							|  |  |  |     double tmp; | 
					
						
							| 
									
										
										
										
											2024-07-13 23:59:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     if (max_input > min_volts) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |         convert = pow (10.0, _hangLevel / 20.0); | 
					
						
							|  |  |  |         tmp = std::max(1e-8, (convert - min_volts) / (max_input - min_volts)); | 
					
						
							|  |  |  |         hang_thresh = 1.0 + 0.125 * log10 (tmp); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |         hang_thresh = 1.0; | 
					
						
							| 
									
										
										
										
											2024-07-13 23:59:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     loadWcpAGC(); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  | void WCPAGC::getHangThreshold(int *hangthreshold) const | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | //for slider in setup
 | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     *hangthreshold = (int) (100.0 * hang_thresh); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  | void WCPAGC::setHangThreshold(int _hangthreshold) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | //For slider in setup
 | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     hang_thresh = (double) _hangthreshold / 100.0; | 
					
						
							|  |  |  |     loadWcpAGC(); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  | void WCPAGC::getTop(double *max_agc) const | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | //for AGC Max Gain in setup
 | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     *max_agc = 20 * log10 (max_gain); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  | void WCPAGC::setTop(double _max_agc) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | //for AGC Max Gain in setup
 | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  |     max_gain = pow (10.0, _max_agc / 20.0); | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     loadWcpAGC(); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  | void WCPAGC::setSlope(int _slope) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     var_gain = pow (10.0, (double) _slope / 20.0 / 10.0); | 
					
						
							|  |  |  |     loadWcpAGC(); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  | void WCPAGC::setMaxInputLevel(double _level) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-29 23:31:43 +02:00
										 |  |  |     max_input = _level; | 
					
						
							|  |  |  |     loadWcpAGC(); | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  | void WCPAGC::setRun(int _state) | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-08-03 11:05:12 +02:00
										 |  |  |     run = _state; | 
					
						
							| 
									
										
										
										
											2024-06-16 11:31:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // namespace WDSP
 |