mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-26 02:20:26 -04:00 
			
		
		
		
	Up channelizer: implemented direct setting of filter chain
This commit is contained in:
		
							parent
							
								
									3a5bc0ac3a
								
							
						
					
					
						commit
						e55f33ffc9
					
				| @ -25,6 +25,7 @@ | |||||||
| #include <QDebug> | #include <QDebug> | ||||||
| 
 | 
 | ||||||
| MESSAGE_CLASS_DEFINITION(UpChannelizer::MsgChannelizerNotification, Message) | MESSAGE_CLASS_DEFINITION(UpChannelizer::MsgChannelizerNotification, Message) | ||||||
|  | MESSAGE_CLASS_DEFINITION(UpChannelizer::MsgSetChannelizer, Message) | ||||||
| 
 | 
 | ||||||
| UpChannelizer::UpChannelizer(BasebandSampleSource* sampleSource) : | UpChannelizer::UpChannelizer(BasebandSampleSource* sampleSource) : | ||||||
|     m_sampleSource(sampleSource), |     m_sampleSource(sampleSource), | ||||||
| @ -157,6 +158,14 @@ bool UpChannelizer::handleMessage(const Message& cmd) | |||||||
| 
 | 
 | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|  |     else if (MsgSetChannelizer::match(cmd)) | ||||||
|  |     { | ||||||
|  |         MsgSetChannelizer& chan = (MsgSetChannelizer&) cmd; | ||||||
|  |         qDebug() << "UpChannelizer::handleMessage: MsgSetChannelizer"; | ||||||
|  |         applySetting(chan.getStageIndexes()); | ||||||
|  | 
 | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|         return false; |         return false; | ||||||
| @ -208,6 +217,30 @@ void UpChannelizer::applyConfiguration() | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void UpChannelizer::applySetting(const std::vector<unsigned int>& stageIndexes) | ||||||
|  | { | ||||||
|  |     m_mutex.lock(); | ||||||
|  | 
 | ||||||
|  |     freeFilterChain(); | ||||||
|  | 
 | ||||||
|  |     m_currentCenterFrequency = m_outputSampleRate * setFilterChain(stageIndexes); | ||||||
|  | 
 | ||||||
|  |     m_mutex.unlock(); | ||||||
|  | 
 | ||||||
|  |     m_currentInputSampleRate = m_outputSampleRate / (1 << m_filterStages.size()); | ||||||
|  |     m_requestedInputSampleRate = m_currentInputSampleRate; | ||||||
|  | 
 | ||||||
|  | 	qDebug() << "UpChannelizer::applySetting in=" << m_outputSampleRate | ||||||
|  | 			<< ", out=" << m_currentInputSampleRate | ||||||
|  | 			<< ", fc=" << m_currentCenterFrequency; | ||||||
|  | 
 | ||||||
|  | 	if (m_sampleSource != 0) | ||||||
|  | 	{ | ||||||
|  | 		MsgChannelizerNotification *notif = MsgChannelizerNotification::create(m_outputSampleRate, m_currentInputSampleRate, m_currentCenterFrequency); | ||||||
|  | 		m_sampleSource->getInputMessageQueue()->push(notif); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #ifdef USE_SSE4_1 | #ifdef USE_SSE4_1 | ||||||
| UpChannelizer::FilterStage::FilterStage(Mode mode) : | UpChannelizer::FilterStage::FilterStage(Mode mode) : | ||||||
|     m_filter(new IntHalfbandFilterEO1<UPCHANNELIZER_HB_FILTER_ORDER>), |     m_filter(new IntHalfbandFilterEO1<UPCHANNELIZER_HB_FILTER_ORDER>), | ||||||
| @ -266,21 +299,17 @@ bool UpChannelizer::signalContainsChannel(Real sigStart, Real sigEnd, Real chanS | |||||||
| Real UpChannelizer::createFilterChain(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd) | Real UpChannelizer::createFilterChain(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd) | ||||||
| { | { | ||||||
|     Real sigBw = sigEnd - sigStart; |     Real sigBw = sigEnd - sigStart; | ||||||
|     Real safetyMargin = sigBw / 20; |  | ||||||
|     Real rot = sigBw / 4; |     Real rot = sigBw / 4; | ||||||
|     Sample s; |     Sample s; | ||||||
| 
 | 
 | ||||||
|     safetyMargin = 0; |  | ||||||
| 
 |  | ||||||
|     qDebug() << "UpChannelizer::createFilterChain: start:" |     qDebug() << "UpChannelizer::createFilterChain: start:" | ||||||
|             << " sig: ["  << sigStart << ":" << sigEnd << "]" |             << " sig: ["  << sigStart << ":" << sigEnd << "]" | ||||||
|             << " BW: " << sigBw |             << " BW: " << sigBw | ||||||
|             << " chan: [" << chanStart << ":" << chanEnd << "]" |             << " chan: [" << chanStart << ":" << chanEnd << "]" | ||||||
|             << " rot: " << rot |             << " rot: " << rot; | ||||||
|             << " safety: " << safetyMargin; |  | ||||||
| 
 | 
 | ||||||
|     // check if it fits into the left half
 |     // check if it fits into the left half
 | ||||||
|     if(signalContainsChannel(sigStart + safetyMargin, sigStart + sigBw / 2.0 - safetyMargin, chanStart, chanEnd)) |     if(signalContainsChannel(sigStart, sigStart + sigBw / 2.0, chanStart, chanEnd)) | ||||||
|     { |     { | ||||||
|         qDebug() << "UpChannelizer::createFilterChain: take left half (rotate by +1/4 and decimate by 2):" |         qDebug() << "UpChannelizer::createFilterChain: take left half (rotate by +1/4 and decimate by 2):" | ||||||
|                 << " [" << m_filterStages.size() << "]" |                 << " [" << m_filterStages.size() << "]" | ||||||
| @ -291,7 +320,7 @@ Real UpChannelizer::createFilterChain(Real sigStart, Real sigEnd, Real chanStart | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // check if it fits into the right half
 |     // check if it fits into the right half
 | ||||||
|     if(signalContainsChannel(sigEnd - sigBw / 2.0f + safetyMargin, sigEnd - safetyMargin, chanStart, chanEnd)) |     if(signalContainsChannel(sigEnd - sigBw / 2.0f, sigEnd, chanStart, chanEnd)) | ||||||
|     { |     { | ||||||
|         qDebug() << "UpChannelizer::createFilterChain: take right half (rotate by -1/4 and decimate by 2):" |         qDebug() << "UpChannelizer::createFilterChain: take right half (rotate by -1/4 and decimate by 2):" | ||||||
|                 << " [" << m_filterStages.size() << "]" |                 << " [" << m_filterStages.size() << "]" | ||||||
| @ -303,7 +332,7 @@ Real UpChannelizer::createFilterChain(Real sigStart, Real sigEnd, Real chanStart | |||||||
| 
 | 
 | ||||||
|     // check if it fits into the center
 |     // check if it fits into the center
 | ||||||
|     // Was: if(signalContainsChannel(sigStart + rot + safetyMargin, sigStart + rot + sigBw / 2.0f - safetyMargin, chanStart, chanEnd)) {
 |     // Was: if(signalContainsChannel(sigStart + rot + safetyMargin, sigStart + rot + sigBw / 2.0f - safetyMargin, chanStart, chanEnd)) {
 | ||||||
|     if(signalContainsChannel(sigStart + rot + safetyMargin, sigEnd - rot - safetyMargin, chanStart, chanEnd)) |     if(signalContainsChannel(sigStart + rot, sigEnd - rot, chanStart, chanEnd)) | ||||||
|     { |     { | ||||||
|         qDebug() << "UpChannelizer::createFilterChain: take center half (decimate by 2):" |         qDebug() << "UpChannelizer::createFilterChain: take center half (decimate by 2):" | ||||||
|                 << " [" << m_filterStages.size() << "]" |                 << " [" << m_filterStages.size() << "]" | ||||||
| @ -324,6 +353,38 @@ Real UpChannelizer::createFilterChain(Real sigStart, Real sigEnd, Real chanStart | |||||||
|     return ofs; |     return ofs; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | double UpChannelizer::setFilterChain(const std::vector<unsigned int>& stageIndexes) | ||||||
|  | { | ||||||
|  |     // filters are described from lower to upper level but the chain is constructed the other way round
 | ||||||
|  |     std::vector<unsigned int>::const_reverse_iterator rit = stageIndexes.rbegin(); | ||||||
|  |     double ofs = 0.0, ofs_stage = 0.25; | ||||||
|  | 
 | ||||||
|  |     // Each index is a base 3 number with 0 = low, 1 = center, 2 = high
 | ||||||
|  |     // Functions at upper level will convert a number to base 3 to describe the filter chain. Common converting
 | ||||||
|  |     // algorithms will go from LSD to MSD. This explains the reverse order.
 | ||||||
|  |     for (; rit != stageIndexes.rend(); ++rit) | ||||||
|  |     { | ||||||
|  |         if (*rit == 0) | ||||||
|  |         { | ||||||
|  |             m_filterStages.push_back(new FilterStage(FilterStage::ModeLowerHalf)); | ||||||
|  |             ofs -= ofs_stage; | ||||||
|  |         } | ||||||
|  |         else if (*rit == 1) | ||||||
|  |         { | ||||||
|  |             m_filterStages.push_back(new FilterStage(FilterStage::ModeCenter)); | ||||||
|  |         } | ||||||
|  |         else if (*rit == 2) | ||||||
|  |         { | ||||||
|  |             m_filterStages.push_back(new FilterStage(FilterStage::ModeUpperHalf)); | ||||||
|  |             ofs += ofs_stage; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         ofs_stage /= 2; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return ofs; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void UpChannelizer::freeFilterChain() | void UpChannelizer::freeFilterChain() | ||||||
| { | { | ||||||
|     for(FilterStages::iterator it = m_filterStages.begin(); it != m_filterStages.end(); ++it) |     for(FilterStages::iterator it = m_filterStages.begin(); it != m_filterStages.end(); ++it) | ||||||
|  | |||||||
| @ -63,6 +63,20 @@ public: | |||||||
|         qint64 m_frequencyOffset; |         qint64 m_frequencyOffset; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |     class SDRBASE_API MsgSetChannelizer : public Message { | ||||||
|  |         MESSAGE_CLASS_DECLARATION | ||||||
|  | 
 | ||||||
|  |     public: | ||||||
|  |         MsgSetChannelizer() : | ||||||
|  |             Message() | ||||||
|  |         { } | ||||||
|  | 
 | ||||||
|  |         std::vector<unsigned int>& getStageIndexes() { return m_stageIndexes; } | ||||||
|  | 
 | ||||||
|  |     private: | ||||||
|  |         std::vector<unsigned int> m_stageIndexes; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|     UpChannelizer(BasebandSampleSource* sampleSink); |     UpChannelizer(BasebandSampleSource* sampleSink); | ||||||
|     virtual ~UpChannelizer(); |     virtual ~UpChannelizer(); | ||||||
| 
 | 
 | ||||||
| @ -115,8 +129,10 @@ protected: | |||||||
|     QMutex m_mutex; |     QMutex m_mutex; | ||||||
| 
 | 
 | ||||||
|     void applyConfiguration(); |     void applyConfiguration(); | ||||||
|  |     void applySetting(const std::vector<unsigned int>& stageIndexes); | ||||||
|     bool signalContainsChannel(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd) const; |     bool signalContainsChannel(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd) const; | ||||||
|     Real createFilterChain(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd); |     Real createFilterChain(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd); | ||||||
|  |     double setFilterChain(const std::vector<unsigned int>& stageIndexes); //!< returns offset in ratio of sample rate
 | ||||||
|     void freeFilterChain(); |     void freeFilterChain(); | ||||||
| 
 | 
 | ||||||
| signals: | signals: | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user