mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-31 13:00:26 -04:00 
			
		
		
		
	SSB demod: better algorithm for AGC limitation. For #1918
This commit is contained in:
		
							parent
							
								
									f98800702c
								
							
						
					
					
						commit
						68601d6947
					
				| @ -143,7 +143,7 @@ This AGC is based on the calculated magnitude (square root of power of the filte | ||||
| 
 | ||||
| <h4>13.3: AGC clamping</h4> | ||||
| 
 | ||||
| When on this clamps signal at the maximum amplitude. Normally this is not needed for most signals as the AGC amplitude order is quite conservative at 10% of the maximum. You may switch it on if you notice a loud click when a transmission starts. | ||||
| This limits AGC gain when signal rises up sharply avoiding peak audio overload. You may switch it on if you notice a loud click on strong signals after silences. | ||||
| 
 | ||||
| <h4>13.4: Noise Reduction</h4> | ||||
| 
 | ||||
|  | ||||
| @ -73,8 +73,6 @@ SSBDemodSink::SSBDemodSink() : | ||||
| 	m_magsqSum = 0.0; | ||||
| 	m_magsqPeak = 0.0; | ||||
| 	m_magsqCount = 0; | ||||
|     m_magsqCur = 0.0; | ||||
|     m_magsqPrev = 0.0; | ||||
| 
 | ||||
| 	SSBFilter = new fftfilt(m_LowCutoff / m_audioSampleRate, m_Bandwidth / m_audioSampleRate, m_ssbFftLen); | ||||
| 	DSBFilter = new fftfilt((2.0f * m_Bandwidth) / m_audioSampleRate, 2 * m_ssbFftLen); | ||||
| @ -175,24 +173,20 @@ void SSBDemodSink::processOneSample(Complex &ci) | ||||
|         float agcVal = m_agcActive ? m_agc.feedAndGetValue(sideband[i]) : 1.0; | ||||
|         fftfilt::cmplx& delayedSample = m_squelchDelayLine.readBack(m_agc.getStepDownDelay()); | ||||
|         m_audioActive = delayedSample.real() != 0.0; | ||||
|         m_magsqCur = std::norm(sideband[i]*agcVal); | ||||
| 
 | ||||
|         // Prevent overload based on squared magnitude variation
 | ||||
|         // Only if AGC is active
 | ||||
|         if (m_agcActive && m_agcClamping && (std::abs(m_magsqCur - m_magsqPrev) > m_agcTarget*m_agcTarget*5.0) & (agcVal > 100.0)) | ||||
|         if (m_agcActive && m_agcClamping && agcVal > 100.0) | ||||
|         { | ||||
|             float target = m_agcTarget*sqrt(agcVal); // Quench AGC depending on previous value
 | ||||
|             m_agc.reset(target); | ||||
|             m_squelchDelayLine.write(fftfilt::cmplx{target, 0.0}); | ||||
|             m_magsqCur = target*target; | ||||
|             qDebug("SSBDemodSink::processOneSample: %f", agcVal); | ||||
|             m_agc.reset(m_agcTarget*m_agcTarget); | ||||
|             m_squelchDelayLine.write(fftfilt::cmplx{0.0, 0.0}); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             m_squelchDelayLine.write(sideband[i]*agcVal); | ||||
|         } | ||||
| 
 | ||||
|         m_magsqPrev = m_magsqCur; | ||||
| 
 | ||||
|         if (m_audioMute) | ||||
|         { | ||||
|             m_audioBuffer[m_audioBufferFill].r = 0; | ||||
| @ -200,7 +194,6 @@ void SSBDemodSink::processOneSample(Complex &ci) | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             // fftfilt::cmplx z = m_agcActive ? delayedSample * m_agc.getStepValue() : delayedSample;
 | ||||
|             fftfilt::cmplx z = (m_agcActive && m_agcClamping) ? | ||||
|                 fftfilt::cmplx{m_lowpassI.filter(delayedSample.real()), m_lowpassQ.filter(delayedSample.imag())} | ||||
|                 : delayedSample; | ||||
|  | ||||
| @ -102,8 +102,6 @@ private: | ||||
| 	double m_magsqSum; | ||||
| 	double m_magsqPeak; | ||||
|     int  m_magsqCount; | ||||
|     double m_magsqCur; | ||||
|     double m_magsqPrev; | ||||
|     MagSqLevelsStore m_magSqLevelStore; | ||||
|     MagAGC m_agc; | ||||
|     bool m_agcActive; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user