| 
									
										
										
										
											2015-05-12 12:12:13 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * kissagc.h | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Created on: May 12, 2015 | 
					
						
							|  |  |  |  *      Author: f4exb | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef INCLUDE_GPL_DSP_AGC_H_
 | 
					
						
							|  |  |  | #define INCLUDE_GPL_DSP_AGC_H_
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "movingaverage.h"
 | 
					
						
							| 
									
										
										
										
											2018-02-03 17:06:16 +01:00
										 |  |  | #include "util/movingaverage.h"
 | 
					
						
							| 
									
										
										
										
											2018-03-20 13:49:21 +01:00
										 |  |  | #include "export.h"
 | 
					
						
							| 
									
										
										
										
											2015-05-12 12:12:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-03 20:23:38 +01:00
										 |  |  | class SDRBASE_API AGC | 
					
						
							| 
									
										
										
										
											2015-06-20 09:28:57 +02:00
										 |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2017-08-05 23:11:05 +02:00
										 |  |  | 	AGC(int historySize, double R); | 
					
						
							| 
									
										
										
										
											2015-09-07 23:31:34 +02:00
										 |  |  | 	virtual ~AGC(); | 
					
						
							| 
									
										
										
										
											2015-09-07 09:32:29 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-05 23:11:05 +02:00
										 |  |  | 	void resize(int historySize, double R); | 
					
						
							|  |  |  | 	void setOrder(double R) { m_R = R; } | 
					
						
							| 
									
										
										
										
											2015-09-07 23:31:34 +02:00
										 |  |  | 	Real getValue(); | 
					
						
							| 
									
										
										
										
											2015-09-12 16:34:57 +02:00
										 |  |  | 	Real getAverage(); | 
					
						
							| 
									
										
										
										
											2015-09-07 23:31:34 +02:00
										 |  |  | 	virtual void feed(Complex& ci) = 0; | 
					
						
							| 
									
										
										
										
											2015-09-07 09:32:29 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-07 23:31:34 +02:00
										 |  |  | protected: | 
					
						
							| 
									
										
										
										
											2017-08-05 19:08:33 +02:00
										 |  |  | 	double m_u0;                            //!< AGC factor
 | 
					
						
							| 
									
										
										
										
											2017-08-06 00:02:16 +02:00
										 |  |  | 	double m_R;                             //!< ordered magnitude
 | 
					
						
							| 
									
										
										
										
											2017-08-05 19:08:33 +02:00
										 |  |  | 	MovingAverage<double> m_moving_average; //!< Averaging engine. The stack length conditions the smoothness of AGC.
 | 
					
						
							|  |  |  | 	int m_historySize;                      //!< Averaging length (attack)
 | 
					
						
							|  |  |  | 	int m_count;                            //!< Samples counter
 | 
					
						
							| 
									
										
										
										
											2015-09-07 09:32:29 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-03 20:23:38 +01:00
										 |  |  | class SDRBASE_API MagAGC : public AGC | 
					
						
							| 
									
										
										
										
											2015-09-07 23:31:34 +02:00
										 |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2017-07-25 00:58:16 +02:00
										 |  |  | 	MagAGC(int historySize, double R, double threshold); | 
					
						
							| 
									
										
										
										
											2015-09-07 23:31:34 +02:00
										 |  |  | 	virtual ~MagAGC(); | 
					
						
							| 
									
										
										
										
											2017-07-27 10:50:41 +02:00
										 |  |  | 	void setSquared(bool squared) { m_squared = squared; } | 
					
						
							| 
									
										
										
										
											2018-05-06 02:39:39 +02:00
										 |  |  | 	void resize(int historySize, int stepLength, Real R); | 
					
						
							| 
									
										
										
										
											2017-08-05 23:11:05 +02:00
										 |  |  | 	void setOrder(double R); | 
					
						
							| 
									
										
										
										
											2015-09-07 23:31:34 +02:00
										 |  |  | 	virtual void feed(Complex& ci); | 
					
						
							| 
									
										
										
										
											2017-07-25 00:58:16 +02:00
										 |  |  |     double feedAndGetValue(const Complex& ci); | 
					
						
							| 
									
										
										
										
											2017-08-05 23:11:05 +02:00
										 |  |  |     double getMagSq() const { return m_magsq; } | 
					
						
							| 
									
										
										
										
											2017-07-25 21:21:48 +02:00
										 |  |  |     void setThreshold(double threshold) { m_threshold = threshold; } | 
					
						
							| 
									
										
										
										
											2017-07-27 10:50:41 +02:00
										 |  |  |     void setThresholdEnable(bool enable); | 
					
						
							| 
									
										
										
										
											2019-06-09 09:25:18 +02:00
										 |  |  |     void setGate(int gate) { m_gate = gate; m_gateCounter = 0; m_count = 0; } | 
					
						
							|  |  |  |     void setStepDownDelay(int stepDownDelay) { m_stepDownDelay = stepDownDelay; m_gateCounter = 0; m_count = 0; } | 
					
						
							| 
									
										
										
										
											2017-08-05 19:08:33 +02:00
										 |  |  |     void setClamping(bool clamping) { m_clamping = clamping; } | 
					
						
							|  |  |  |     void setClampMax(double clampMax) { m_clampMax = clampMax; } | 
					
						
							| 
									
										
										
										
											2018-04-22 09:37:34 +02:00
										 |  |  |     int getStepDownDelay() const { return m_stepDownDelay; } | 
					
						
							| 
									
										
										
										
											2018-05-06 02:39:39 +02:00
										 |  |  |     float getStepValue() const; | 
					
						
							| 
									
										
										
										
											2019-05-07 02:50:05 +02:00
										 |  |  |     void setHardLimiting(bool hardLimiting) { m_hardLimiting = hardLimiting; } | 
					
						
							| 
									
										
										
										
											2018-04-22 09:37:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-04 06:26:06 +02:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2017-07-27 10:50:41 +02:00
										 |  |  |     bool m_squared;        //!< use squared magnitude (power) to compute AGC value
 | 
					
						
							|  |  |  | 	double m_magsq;        //!< current squared magnitude (power)
 | 
					
						
							| 
									
										
										
										
											2017-07-26 08:39:20 +02:00
										 |  |  |     double m_threshold;    //!< squelch on magsq average
 | 
					
						
							| 
									
										
										
										
											2017-07-27 10:50:41 +02:00
										 |  |  |     bool m_thresholdEnable; //!< enable squelch on power threshold
 | 
					
						
							| 
									
										
										
										
											2017-07-26 08:39:20 +02:00
										 |  |  |     int m_gate;            //!< power threshold gate in number of samples
 | 
					
						
							|  |  |  |     int m_stepLength;      //!< transition step length in number of samples
 | 
					
						
							| 
									
										
										
										
											2017-07-26 16:23:34 +02:00
										 |  |  |     double m_stepDelta;    //!< transition step unit by sample
 | 
					
						
							| 
									
										
										
										
											2017-07-26 08:39:20 +02:00
										 |  |  |     int m_stepUpCounter;   //!< step up transition samples counter
 | 
					
						
							|  |  |  |     int m_stepDownCounter; //!< step down transition samples counter
 | 
					
						
							|  |  |  |     int m_gateCounter;     //!< threshold gate samples counter
 | 
					
						
							| 
									
										
										
										
											2017-08-05 19:08:33 +02:00
										 |  |  |     int m_stepDownDelay;   //!< delay in samples before cutoff (release)
 | 
					
						
							|  |  |  |     bool m_clamping;       //!< clamping active
 | 
					
						
							| 
									
										
										
										
											2017-08-06 00:02:16 +02:00
										 |  |  |     double m_R2;           //!< square of ordered magnitude
 | 
					
						
							|  |  |  |     double m_clampMax;     //!< maximum to clamp to as power value
 | 
					
						
							| 
									
										
										
										
											2019-05-07 02:50:05 +02:00
										 |  |  |     bool m_hardLimiting;   //!< hard limit multiplier so that resulting sample magnitude does not exceed 1.0
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     double hardLimiter(double multiplier, double magsq); | 
					
						
							| 
									
										
										
										
											2015-09-07 23:31:34 +02:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2015-06-20 09:28:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-03 17:06:16 +01:00
										 |  |  | template<uint32_t AvgSize> | 
					
						
							| 
									
										
										
										
											2015-09-07 23:31:34 +02:00
										 |  |  | class SimpleAGC | 
					
						
							| 
									
										
										
										
											2015-06-20 09:28:57 +02:00
										 |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2018-02-16 00:43:21 +01:00
										 |  |  | 	SimpleAGC(Real initial, Real cutoff=0, Real clip=0) : | 
					
						
							| 
									
										
										
										
											2018-02-03 17:06:16 +01:00
										 |  |  |         m_cutoff(cutoff), | 
					
						
							| 
									
										
										
										
											2018-02-16 00:43:21 +01:00
										 |  |  |         m_clip(clip), | 
					
						
							|  |  |  |         m_moving_average(AvgSize, initial) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-06-20 09:28:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-16 00:43:21 +01:00
										 |  |  | 	void resize(Real initial, Real cutoff=0, Real clip=0) | 
					
						
							| 
									
										
										
										
											2017-05-12 16:38:58 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-02-03 17:06:16 +01:00
										 |  |  |         m_cutoff = cutoff; | 
					
						
							|  |  |  |         m_clip = clip; | 
					
						
							| 
									
										
										
										
											2018-02-16 00:43:21 +01:00
										 |  |  |         m_moving_average.resize(AvgSize, initial); | 
					
						
							| 
									
										
										
										
											2017-05-12 16:38:58 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-13 22:30:50 +02:00
										 |  |  |     void resizeNew(uint32_t newSize, Real initial, Real cutoff=0, Real clip=0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_cutoff = cutoff; | 
					
						
							|  |  |  |         m_clip = clip; | 
					
						
							|  |  |  |         m_moving_average.resize(newSize, initial); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-16 00:43:21 +01:00
										 |  |  |     void fill(double value) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_moving_average.fill(value); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-20 09:28:57 +02:00
										 |  |  | 	Real getValue() | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-02-16 00:43:21 +01:00
										 |  |  |         if ((Real) m_moving_average.average() > m_clip) { | 
					
						
							|  |  |  |             return (Real) m_moving_average.average(); | 
					
						
							|  |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2018-02-03 17:06:16 +01:00
										 |  |  |             return m_clip; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-09-07 23:31:34 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void feed(Real value) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2018-02-16 00:43:21 +01:00
										 |  |  |         if (value > m_cutoff) { | 
					
						
							|  |  |  |             m_moving_average.feed(value); | 
					
						
							| 
									
										
										
										
											2018-02-03 17:06:16 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-09-07 23:31:34 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-20 09:28:57 +02:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2015-09-07 23:31:34 +02:00
										 |  |  |     Real m_cutoff;  // consider samples only above this level
 | 
					
						
							|  |  |  |     Real m_clip;    // never go below this level
 | 
					
						
							| 
									
										
										
										
											2018-02-16 00:43:21 +01:00
										 |  |  |     MovingAverage<double> m_moving_average; // Averaging engine. The stack length conditions the smoothness of AGC.
 | 
					
						
							|  |  |  |     //MovingAverageUtil<Real, double, AvgSize> m_moving_average;
 | 
					
						
							| 
									
										
										
										
											2015-05-12 12:12:13 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /* INCLUDE_GPL_DSP_AGC_H_ */
 |