mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-26 02:20:26 -04:00 
			
		
		
		
	Channel Analyzer: fixed rational downsampler
This commit is contained in:
		
							parent
							
								
									cb3be14515
								
							
						
					
					
						commit
						bb35db0703
					
				| @ -137,7 +137,7 @@ bool ChannelAnalyzerBaseband::handleMessage(const Message& cmd) | |||||||
|         qDebug() << "ChannelAnalyzerBaseband::handleMessage: DSPSignalNotification: basebandSampleRate: " << notif.getSampleRate(); |         qDebug() << "ChannelAnalyzerBaseband::handleMessage: DSPSignalNotification: basebandSampleRate: " << notif.getSampleRate(); | ||||||
|         m_sampleFifo.setSize(SampleSinkFifo::getSizePolicy(notif.getSampleRate())); |         m_sampleFifo.setSize(SampleSinkFifo::getSizePolicy(notif.getSampleRate())); | ||||||
|         m_channelizer->setBasebandSampleRate(notif.getSampleRate()); |         m_channelizer->setBasebandSampleRate(notif.getSampleRate()); | ||||||
|         int desiredSampleRate = getSinkSampleRate(m_settings); |         int desiredSampleRate = m_channelizer->getBasebandSampleRate() / (1<<m_settings.m_log2Decim); | ||||||
|         m_channelizer->setChannelization(desiredSampleRate, m_settings.m_inputFrequencyOffset); |         m_channelizer->setChannelization(desiredSampleRate, m_settings.m_inputFrequencyOffset); | ||||||
|         m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), desiredSampleRate, m_channelizer->getChannelFrequencyOffset()); |         m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), desiredSampleRate, m_channelizer->getChannelFrequencyOffset()); | ||||||
| 
 | 
 | ||||||
| @ -156,7 +156,7 @@ void ChannelAnalyzerBaseband::applySettings(const ChannelAnalyzerSettings& setti | |||||||
|      || (settings.m_rationalDownSamplerRate != m_settings.m_rationalDownSamplerRate) |      || (settings.m_rationalDownSamplerRate != m_settings.m_rationalDownSamplerRate) | ||||||
|      || (settings.m_rationalDownSample != m_settings.m_rationalDownSample) || force) |      || (settings.m_rationalDownSample != m_settings.m_rationalDownSample) || force) | ||||||
|     { |     { | ||||||
|         int desiredSampleRate = getSinkSampleRate(settings); |         int desiredSampleRate = m_channelizer->getBasebandSampleRate() / (1<<settings.m_log2Decim); | ||||||
|         m_channelizer->setChannelization(desiredSampleRate, settings.m_inputFrequencyOffset); |         m_channelizer->setChannelization(desiredSampleRate, settings.m_inputFrequencyOffset); | ||||||
|         m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), desiredSampleRate, m_channelizer->getChannelFrequencyOffset()); |         m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), desiredSampleRate, m_channelizer->getChannelFrequencyOffset()); | ||||||
|     } |     } | ||||||
| @ -165,12 +165,6 @@ void ChannelAnalyzerBaseband::applySettings(const ChannelAnalyzerSettings& setti | |||||||
|     m_settings = settings; |     m_settings = settings; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int ChannelAnalyzerBaseband::getSinkSampleRate(ChannelAnalyzerSettings settings) |  | ||||||
| { |  | ||||||
|     int normalSinkSampleRate = m_channelizer->getBasebandSampleRate() / (1<<settings.m_log2Decim); |  | ||||||
|     return settings.m_rationalDownSample ? settings.m_rationalDownSamplerRate : normalSinkSampleRate; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| int ChannelAnalyzerBaseband::getChannelSampleRate() const | int ChannelAnalyzerBaseband::getChannelSampleRate() const | ||||||
| { | { | ||||||
|     return m_channelizer->getChannelSampleRate(); |     return m_channelizer->getChannelSampleRate(); | ||||||
|  | |||||||
| @ -84,7 +84,6 @@ private: | |||||||
| 
 | 
 | ||||||
|     bool handleMessage(const Message& cmd); |     bool handleMessage(const Message& cmd); | ||||||
|     void applySettings(const ChannelAnalyzerSettings& settings, bool force = false); |     void applySettings(const ChannelAnalyzerSettings& settings, bool force = false); | ||||||
|     int getSinkSampleRate(ChannelAnalyzerSettings settngs); |  | ||||||
| 
 | 
 | ||||||
| private slots: | private slots: | ||||||
|     void handleInputMessages(); |     void handleInputMessages(); | ||||||
|  | |||||||
| @ -274,13 +274,6 @@ void ChannelAnalyzerGUI::on_useRationalDownsampler_toggled(bool checked) | |||||||
|     applySettings(); |     applySettings(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int ChannelAnalyzerGUI::getSinkSampleRate() |  | ||||||
| { |  | ||||||
|     return m_settings.m_rationalDownSample ? |  | ||||||
|         m_settings.m_rationalDownSamplerRate |  | ||||||
|         : m_basebandSampleRate / (1<<m_settings.m_log2Decim); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void ChannelAnalyzerGUI::on_signalSelect_currentIndexChanged(int index) | void ChannelAnalyzerGUI::on_signalSelect_currentIndexChanged(int index) | ||||||
| { | { | ||||||
|     m_settings.m_inputType = (ChannelAnalyzerSettings::InputType) index; |     m_settings.m_inputType = (ChannelAnalyzerSettings::InputType) index; | ||||||
| @ -461,6 +454,13 @@ ChannelAnalyzerGUI::~ChannelAnalyzerGUI() | |||||||
| 	delete ui; | 	delete ui; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | int ChannelAnalyzerGUI::getSinkSampleRate() | ||||||
|  | { | ||||||
|  |     return m_settings.m_rationalDownSample ? | ||||||
|  |         m_settings.m_rationalDownSamplerRate | ||||||
|  |         : m_basebandSampleRate / (1<<m_settings.m_log2Decim); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void ChannelAnalyzerGUI::setSinkSampleRate() | void ChannelAnalyzerGUI::setSinkSampleRate() | ||||||
| { | { | ||||||
|     unsigned int nominalSinkSampleRate = m_basebandSampleRate / (1<<m_settings.m_log2Decim); |     unsigned int nominalSinkSampleRate = m_basebandSampleRate / (1<<m_settings.m_log2Decim); | ||||||
|  | |||||||
| @ -34,8 +34,6 @@ ChannelAnalyzerSink::ChannelAnalyzerSink() : | |||||||
| { | { | ||||||
| 	m_usb = true; | 	m_usb = true; | ||||||
| 	m_magsq = 0; | 	m_magsq = 0; | ||||||
| 	m_interpolatorDistance = 1.0f; |  | ||||||
| 	m_interpolatorDistanceRemain = 0.0f; |  | ||||||
| 	SSBFilter = new fftfilt(m_settings.m_lowCutoff / m_channelSampleRate, m_settings.m_bandwidth / m_channelSampleRate, m_ssbFftLen); | 	SSBFilter = new fftfilt(m_settings.m_lowCutoff / m_channelSampleRate, m_settings.m_bandwidth / m_channelSampleRate, m_ssbFftLen); | ||||||
| 	DSBFilter = new fftfilt(m_settings.m_bandwidth / m_channelSampleRate, 2*m_ssbFftLen); | 	DSBFilter = new fftfilt(m_settings.m_bandwidth / m_channelSampleRate, 2*m_ssbFftLen); | ||||||
| 	RRCFilter = new fftfilt(m_settings.m_bandwidth / m_channelSampleRate, 2*m_ssbFftLen); | 	RRCFilter = new fftfilt(m_settings.m_bandwidth / m_channelSampleRate, 2*m_ssbFftLen); | ||||||
| @ -57,30 +55,33 @@ ChannelAnalyzerSink::~ChannelAnalyzerSink() | |||||||
| void ChannelAnalyzerSink::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end) | void ChannelAnalyzerSink::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end) | ||||||
| { | { | ||||||
| 	fftfilt::cmplx *sideband = 0; | 	fftfilt::cmplx *sideband = 0; | ||||||
| 	Complex ci; |  | ||||||
| 
 | 
 | ||||||
| 	for (SampleVector::const_iterator it = begin; it < end; ++it) | 	for (SampleVector::const_iterator it = begin; it < end; ++it) | ||||||
| 	{ | 	{ | ||||||
|  |     	Complex ci; | ||||||
| 		Complex c(it->real(), it->imag()); | 		Complex c(it->real(), it->imag()); | ||||||
| 		c *= m_nco.nextIQ(); | 		c *= m_nco.nextIQ(); | ||||||
| 
 | 
 | ||||||
| 		if (m_interpolatorDistance == 1) | 		if (m_decimator.getDecim() == 1) | ||||||
| 		{ | 		{ | ||||||
| 	        processOneSample(c, sideband); | 	        processOneSample(c, sideband); | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
|  | 		{ | ||||||
|  |             if (m_decimator.decimate(c, ci)) | ||||||
|             { |             { | ||||||
|                 if (m_settings.m_rationalDownSample) |                 if (m_settings.m_rationalDownSample) | ||||||
|                 { |                 { | ||||||
|                 if (m_interpolator.decimate(&m_interpolatorDistanceRemain, c, &ci)) |                     Complex cj; | ||||||
|  | 
 | ||||||
|  |                     if (m_interpolator.decimate(&m_interpolatorDistanceRemain, ci, &cj)) | ||||||
|                     { |                     { | ||||||
|                     processOneSample(ci, sideband); |                         processOneSample(cj, sideband); | ||||||
|                         m_interpolatorDistanceRemain += m_interpolatorDistance; |                         m_interpolatorDistanceRemain += m_interpolatorDistance; | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 else |                 else | ||||||
|                 { |                 { | ||||||
|                 if (m_decimator.decimate(c, ci)) { |  | ||||||
|                     processOneSample(ci, sideband); |                     processOneSample(ci, sideband); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| @ -146,6 +147,7 @@ void ChannelAnalyzerSink::applyChannelSettings(int channelSampleRate, int sinkSa | |||||||
|             << " channelSampleRate: " << channelSampleRate |             << " channelSampleRate: " << channelSampleRate | ||||||
|             << " sinkSampleRate: " << sinkSampleRate |             << " sinkSampleRate: " << sinkSampleRate | ||||||
|             << " channelFrequencyOffset: " << channelFrequencyOffset; |             << " channelFrequencyOffset: " << channelFrequencyOffset; | ||||||
|  |     bool doApplySampleRate = false; | ||||||
| 
 | 
 | ||||||
|     if ((m_channelFrequencyOffset != channelFrequencyOffset) || |     if ((m_channelFrequencyOffset != channelFrequencyOffset) || | ||||||
|         (m_channelSampleRate != channelSampleRate) || force) |         (m_channelSampleRate != channelSampleRate) || force) | ||||||
| @ -156,13 +158,9 @@ void ChannelAnalyzerSink::applyChannelSettings(int channelSampleRate, int sinkSa | |||||||
|     if ((m_channelSampleRate != channelSampleRate) |     if ((m_channelSampleRate != channelSampleRate) | ||||||
|      || (m_sinkSampleRate != sinkSampleRate) || force) |      || (m_sinkSampleRate != sinkSampleRate) || force) | ||||||
|     { |     { | ||||||
|         m_interpolator.create(16, channelSampleRate, channelSampleRate / 2.2f); |         m_interpolator.create(16, sinkSampleRate, sinkSampleRate / 4.0f); | ||||||
|         m_interpolatorDistanceRemain = 0; |         m_interpolatorDistanceRemain = 0; | ||||||
|         m_interpolatorDistance = (Real) channelSampleRate / (Real) sinkSampleRate; |         m_interpolatorDistance = (Real) sinkSampleRate / (Real) m_settings.m_rationalDownSamplerRate; | ||||||
| 
 |  | ||||||
|         setFilters(sinkSampleRate, m_settings.m_bandwidth, m_settings.m_lowCutoff); |  | ||||||
|         m_pll.setSampleRate(sinkSampleRate); |  | ||||||
|         m_fll.setSampleRate(sinkSampleRate); |  | ||||||
| 
 | 
 | ||||||
|         int decim = channelSampleRate / sinkSampleRate; |         int decim = channelSampleRate / sinkSampleRate; | ||||||
|         m_decimator.setLog2Decim(0); |         m_decimator.setLog2Decim(0); | ||||||
| @ -178,11 +176,17 @@ void ChannelAnalyzerSink::applyChannelSettings(int channelSampleRate, int sinkSa | |||||||
| 
 | 
 | ||||||
|             decim >>= 1; |             decim >>= 1; | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         doApplySampleRate = true; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     m_channelSampleRate = channelSampleRate; |     m_channelSampleRate = channelSampleRate; | ||||||
|     m_channelFrequencyOffset = channelFrequencyOffset; |     m_channelFrequencyOffset = channelFrequencyOffset; | ||||||
|     m_sinkSampleRate = sinkSampleRate; |     m_sinkSampleRate = sinkSampleRate; | ||||||
|  | 
 | ||||||
|  |     if (doApplySampleRate) { | ||||||
|  |         applySampleRate(); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ChannelAnalyzerSink::setFilters(int sampleRate, float bandwidth, float lowCutoff) | void ChannelAnalyzerSink::setFilters(int sampleRate, float bandwidth, float lowCutoff) | ||||||
| @ -216,29 +220,25 @@ void ChannelAnalyzerSink::applySettings(const ChannelAnalyzerSettings& settings, | |||||||
| { | { | ||||||
|     qDebug() << "ChannelAnalyzerSink::applySettings:" |     qDebug() << "ChannelAnalyzerSink::applySettings:" | ||||||
|             << " m_inputFrequencyOffset: " << settings.m_inputFrequencyOffset |             << " m_inputFrequencyOffset: " << settings.m_inputFrequencyOffset | ||||||
|             << " m_rationalDownSample: " << settings.m_rationalDownSample |  | ||||||
|             << " m_rationalDownSamplerRate: " << settings.m_rationalDownSamplerRate |  | ||||||
|             << " m_rcc: " << settings.m_rrc |             << " m_rcc: " << settings.m_rrc | ||||||
|             << " m_rrcRolloff: " << settings.m_rrcRolloff / 100.0 |             << " m_rrcRolloff: " << settings.m_rrcRolloff / 100.0 | ||||||
|             << " m_bandwidth: " << settings.m_bandwidth |             << " m_bandwidth: " << settings.m_bandwidth | ||||||
|             << " m_lowCutoff: " << settings.m_lowCutoff |             << " m_lowCutoff: " << settings.m_lowCutoff | ||||||
|             << " m_log2Decim: " << settings.m_log2Decim |             << " m_log2Decim: " << settings.m_log2Decim | ||||||
|  |             << " m_rationalDownSample: " << settings.m_rationalDownSample | ||||||
|  |             << " m_rationalDownSamplerRate: " << settings.m_rationalDownSamplerRate | ||||||
|             << " m_ssb: " << settings.m_ssb |             << " m_ssb: " << settings.m_ssb | ||||||
|             << " m_pll: " << settings.m_pll |             << " m_pll: " << settings.m_pll | ||||||
|             << " m_fll: " << settings.m_fll |             << " m_fll: " << settings.m_fll | ||||||
|             << " m_pllPskOrder: " << settings.m_pllPskOrder |             << " m_pllPskOrder: " << settings.m_pllPskOrder | ||||||
|             << " m_inputType: " << (int) settings.m_inputType; |             << " m_inputType: " << (int) settings.m_inputType; | ||||||
|  |     bool doApplySampleRate = false; | ||||||
| 
 | 
 | ||||||
|     if ((settings.m_bandwidth != m_settings.m_bandwidth) || |     if ((settings.m_bandwidth != m_settings.m_bandwidth) || | ||||||
|         (settings.m_lowCutoff != m_settings.m_lowCutoff)|| force) |         (settings.m_lowCutoff != m_settings.m_lowCutoff) || | ||||||
|  |         (settings.m_rrcRolloff != m_settings.m_rrcRolloff) || force) | ||||||
|     { |     { | ||||||
|         setFilters(m_sinkSampleRate, settings.m_bandwidth, settings.m_lowCutoff); |         doApplySampleRate = true; | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if ((settings.m_rrcRolloff != m_settings.m_rrcRolloff) || force) |  | ||||||
|     { |  | ||||||
|         float sinkSampleRate = (float) m_sinkSampleRate; |  | ||||||
|         RRCFilter->create_rrc_filter(settings.m_bandwidth / sinkSampleRate, settings.m_rrcRolloff / 100.0); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (settings.m_pll != m_settings.m_pll || force) |     if (settings.m_pll != m_settings.m_pll || force) | ||||||
| @ -264,7 +264,20 @@ void ChannelAnalyzerSink::applySettings(const ChannelAnalyzerSettings& settings, | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     if ((settings.m_rationalDownSample != m_settings.m_rationalDownSample) || | ||||||
|  |         (settings.m_rationalDownSamplerRate != m_settings.m_rationalDownSamplerRate) || force) | ||||||
|  |     { | ||||||
|  |         m_interpolator.create(16, m_sinkSampleRate, m_sinkSampleRate / 4.0f); | ||||||
|  |         m_interpolatorDistanceRemain = 0; | ||||||
|  |         m_interpolatorDistance = (Real) m_sinkSampleRate / (Real) settings.m_rationalDownSamplerRate; | ||||||
|  |         doApplySampleRate = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     m_settings = settings; |     m_settings = settings; | ||||||
|  | 
 | ||||||
|  |     if (doApplySampleRate) { | ||||||
|  |         applySampleRate(); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Real ChannelAnalyzerSink::getPllFrequency() const | Real ChannelAnalyzerSink::getPllFrequency() const | ||||||
| @ -277,3 +290,22 @@ Real ChannelAnalyzerSink::getPllFrequency() const | |||||||
|         return 0.0; |         return 0.0; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | int ChannelAnalyzerSink::getActualSampleRate() | ||||||
|  | { | ||||||
|  |     if (m_settings.m_rationalDownSample) { | ||||||
|  |         return m_settings.m_rationalDownSamplerRate; | ||||||
|  |     } else { | ||||||
|  |         return m_sinkSampleRate; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ChannelAnalyzerSink::applySampleRate() | ||||||
|  | { | ||||||
|  |     int sampleRate = getActualSampleRate(); | ||||||
|  |     qDebug("ChannelAnalyzerSink::applySampleRate: sampleRate: %d m_interpolatorDistance: %f", sampleRate, m_interpolatorDistance); | ||||||
|  |     setFilters(sampleRate, m_settings.m_bandwidth, m_settings.m_lowCutoff); | ||||||
|  |     m_pll.setSampleRate(sampleRate); | ||||||
|  |     m_fll.setSampleRate(sampleRate); | ||||||
|  |     RRCFilter->create_rrc_filter(m_settings.m_bandwidth / (float) sampleRate, m_settings.m_rrcRolloff / 100.0); | ||||||
|  | } | ||||||
| @ -65,11 +65,11 @@ private: | |||||||
| 	double m_magsq; | 	double m_magsq; | ||||||
| 
 | 
 | ||||||
| 	NCOF m_nco; | 	NCOF m_nco; | ||||||
| 	PhaseLockComplex m_pll; |  | ||||||
| 	FreqLockComplex m_fll; |  | ||||||
| 	Interpolator m_interpolator; | 	Interpolator m_interpolator; | ||||||
| 	Real m_interpolatorDistance; | 	Real m_interpolatorDistance; | ||||||
| 	Real m_interpolatorDistanceRemain; | 	Real m_interpolatorDistanceRemain; | ||||||
|  | 	PhaseLockComplex m_pll; | ||||||
|  | 	FreqLockComplex m_fll; | ||||||
|     DecimatorC m_decimator; |     DecimatorC m_decimator; | ||||||
| 
 | 
 | ||||||
| 	fftfilt* SSBFilter; | 	fftfilt* SSBFilter; | ||||||
| @ -84,6 +84,8 @@ private: | |||||||
| 
 | 
 | ||||||
| 	void setFilters(int sampleRate, float bandwidth, float lowCutoff); | 	void setFilters(int sampleRate, float bandwidth, float lowCutoff); | ||||||
| 	void processOneSample(Complex& c, fftfilt::cmplx *sideband); | 	void processOneSample(Complex& c, fftfilt::cmplx *sideband); | ||||||
|  |     int getActualSampleRate(); | ||||||
|  |     void applySampleRate(); | ||||||
| 
 | 
 | ||||||
| 	inline void feedOneSample(const fftfilt::cmplx& s, const fftfilt::cmplx& pll) | 	inline void feedOneSample(const fftfilt::cmplx& s, const fftfilt::cmplx& pll) | ||||||
| 	{ | 	{ | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user