kopia lustrzana https://github.com/f4exb/sdrangel
				
				
				
			SSB demod: better algorithm for AGC limitation. For #1918
							rodzic
							
								
									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> | <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> | <h4>13.4: Noise Reduction</h4> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -73,8 +73,6 @@ SSBDemodSink::SSBDemodSink() : | ||||||
| 	m_magsqSum = 0.0; | 	m_magsqSum = 0.0; | ||||||
| 	m_magsqPeak = 0.0; | 	m_magsqPeak = 0.0; | ||||||
| 	m_magsqCount = 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); | 	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); | 	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; |         float agcVal = m_agcActive ? m_agc.feedAndGetValue(sideband[i]) : 1.0; | ||||||
|         fftfilt::cmplx& delayedSample = m_squelchDelayLine.readBack(m_agc.getStepDownDelay()); |         fftfilt::cmplx& delayedSample = m_squelchDelayLine.readBack(m_agc.getStepDownDelay()); | ||||||
|         m_audioActive = delayedSample.real() != 0.0; |         m_audioActive = delayedSample.real() != 0.0; | ||||||
|         m_magsqCur = std::norm(sideband[i]*agcVal); |  | ||||||
| 
 | 
 | ||||||
|         // Prevent overload based on squared magnitude variation
 |         // Prevent overload based on squared magnitude variation
 | ||||||
|         // Only if AGC is active
 |         // 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
 |             qDebug("SSBDemodSink::processOneSample: %f", agcVal); | ||||||
|             m_agc.reset(target); |             m_agc.reset(m_agcTarget*m_agcTarget); | ||||||
|             m_squelchDelayLine.write(fftfilt::cmplx{target, 0.0}); |             m_squelchDelayLine.write(fftfilt::cmplx{0.0, 0.0}); | ||||||
|             m_magsqCur = target*target; |  | ||||||
|         } |         } | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
|             m_squelchDelayLine.write(sideband[i]*agcVal); |             m_squelchDelayLine.write(sideband[i]*agcVal); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         m_magsqPrev = m_magsqCur; |  | ||||||
| 
 |  | ||||||
|         if (m_audioMute) |         if (m_audioMute) | ||||||
|         { |         { | ||||||
|             m_audioBuffer[m_audioBufferFill].r = 0; |             m_audioBuffer[m_audioBufferFill].r = 0; | ||||||
|  | @ -200,7 +194,6 @@ void SSBDemodSink::processOneSample(Complex &ci) | ||||||
|         } |         } | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
|             // fftfilt::cmplx z = m_agcActive ? delayedSample * m_agc.getStepValue() : delayedSample;
 |  | ||||||
|             fftfilt::cmplx z = (m_agcActive && m_agcClamping) ? |             fftfilt::cmplx z = (m_agcActive && m_agcClamping) ? | ||||||
|                 fftfilt::cmplx{m_lowpassI.filter(delayedSample.real()), m_lowpassQ.filter(delayedSample.imag())} |                 fftfilt::cmplx{m_lowpassI.filter(delayedSample.real()), m_lowpassQ.filter(delayedSample.imag())} | ||||||
|                 : delayedSample; |                 : delayedSample; | ||||||
|  |  | ||||||
|  | @ -102,8 +102,6 @@ private: | ||||||
| 	double m_magsqSum; | 	double m_magsqSum; | ||||||
| 	double m_magsqPeak; | 	double m_magsqPeak; | ||||||
|     int  m_magsqCount; |     int  m_magsqCount; | ||||||
|     double m_magsqCur; |  | ||||||
|     double m_magsqPrev; |  | ||||||
|     MagSqLevelsStore m_magSqLevelStore; |     MagSqLevelsStore m_magSqLevelStore; | ||||||
|     MagAGC m_agc; |     MagAGC m_agc; | ||||||
|     bool m_agcActive; |     bool m_agcActive; | ||||||
|  |  | ||||||
		Ładowanie…
	
		Reference in New Issue
	
	 f4exb
						f4exb