mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-29 20:10:22 -04:00 
			
		
		
		
	IntHalfbandFilters: Optimized versions of workInterpolateCenter and myInterpolate
This commit is contained in:
		
							parent
							
								
									02981b4f08
								
							
						
					
					
						commit
						6b3bdef3a7
					
				| @ -26,7 +26,16 @@ | |||||||
| template<uint32_t HBFilterOrder> | template<uint32_t HBFilterOrder> | ||||||
| class SDRANGEL_API IntHalfbandFilter { | class SDRANGEL_API IntHalfbandFilter { | ||||||
| public: | public: | ||||||
| 	IntHalfbandFilter(); | 	IntHalfbandFilter() : | ||||||
|  | 	    m_ptr(0), | ||||||
|  | 	    m_state(0) | ||||||
|  |     { | ||||||
|  | 	    for (int i = 0; i < HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1; i++) | ||||||
|  | 	    { | ||||||
|  | 	        m_samples[i][0] = 0; | ||||||
|  | 	        m_samples[i][1] = 0; | ||||||
|  | 	    } | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
| 	// downsample by 2, return center part of original spectrum
 | 	// downsample by 2, return center part of original spectrum
 | ||||||
| 	bool workDecimateCenter(Sample* sample) | 	bool workDecimateCenter(Sample* sample) | ||||||
| @ -103,6 +112,40 @@ public: | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** Optimized upsampler by 2 not calculating FIR with inserted null samples */ | ||||||
|  |     bool workInterpolateCenterOptimized(Sample* sampleIn, Sample *SampleOut) | ||||||
|  |     { | ||||||
|  |         switch(m_state) | ||||||
|  |         { | ||||||
|  |         case 0: | ||||||
|  |             // return the middle peak
 | ||||||
|  |             SampleOut->setReal(m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]); | ||||||
|  |             SampleOut->setImag(m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]); | ||||||
|  |             m_state = 1;  // next state
 | ||||||
|  |             return false; // tell caller we didn't consume the sample
 | ||||||
|  | 
 | ||||||
|  |         default: | ||||||
|  |             // calculate with non null samples
 | ||||||
|  |             doInterpolateFIR(SampleOut); | ||||||
|  | 
 | ||||||
|  |             // insert sample into ring double buffer
 | ||||||
|  |             m_samples[m_ptr][0] = sampleIn->real(); | ||||||
|  |             m_samples[m_ptr][1] = sampleIn->imag(); | ||||||
|  |             m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = sampleIn->real(); | ||||||
|  |             m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = sampleIn->imag(); | ||||||
|  | 
 | ||||||
|  |             // advance pointer
 | ||||||
|  |             if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) { | ||||||
|  |                 m_ptr++; | ||||||
|  |             } else { | ||||||
|  |                 m_ptr = 0; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             m_state = 0; // next state
 | ||||||
|  |             return true; // tell caller we consumed the sample
 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| 	bool workDecimateCenter(qint32 *x, qint32 *y) | 	bool workDecimateCenter(qint32 *x, qint32 *y) | ||||||
| 	{ | 	{ | ||||||
| 		// insert sample into ring-buffer
 | 		// insert sample into ring-buffer
 | ||||||
| @ -544,6 +587,29 @@ public: | |||||||
|         m_ptr = HBFIRFilterTraits<HBFilterOrder>::hbMod[m_ptr + 2 - 1]; |         m_ptr = HBFIRFilterTraits<HBFilterOrder>::hbMod[m_ptr + 2 - 1]; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     void myInterpolateOptimized(qint32 *x1, qint32 *y1, qint32 *x2, qint32 *y2) | ||||||
|  |     { | ||||||
|  |         // insert sample into ring double buffer
 | ||||||
|  |         m_samples[m_ptr][0] = *x1; | ||||||
|  |         m_samples[m_ptr][1] = *y1; | ||||||
|  |         m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = *x1; | ||||||
|  |         m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = *y1; | ||||||
|  | 
 | ||||||
|  |         // advance pointer
 | ||||||
|  |         if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) { | ||||||
|  |             m_ptr++; | ||||||
|  |         } else { | ||||||
|  |             m_ptr = 0; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // first output sample calculated with the middle peak
 | ||||||
|  |         *x1 = m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]; | ||||||
|  |         *y1 = m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]; | ||||||
|  | 
 | ||||||
|  |         // second sample calculated with the filter
 | ||||||
|  |         doInterpolateFIR(x2, y2); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| protected: | protected: | ||||||
| 	qint32 m_samples[HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1][2];     // Valgrind optim (from qint16)
 | 	qint32 m_samples[HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1][2];     // Valgrind optim (from qint16)
 | ||||||
| 	qint16 m_ptr; | 	qint16 m_ptr; | ||||||
| @ -581,6 +647,48 @@ protected: | |||||||
| 		sample->setImag(qAcc >> (HBFIRFilterTraits<HBFilterOrder>::hbShift -1)); | 		sample->setImag(qAcc >> (HBFIRFilterTraits<HBFilterOrder>::hbShift -1)); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	void doInterpolateFIR(Sample* sample) | ||||||
|  | 	{ | ||||||
|  | 	    qint16 a = m_ptr; | ||||||
|  | 	    qint16 b = m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder / 2) - 1; | ||||||
|  | 
 | ||||||
|  |         // go through samples in buffer
 | ||||||
|  |         qint32 iAcc = 0; | ||||||
|  |         qint32 qAcc = 0; | ||||||
|  | 
 | ||||||
|  |         for (int i = 0; i < HBFIRFilterTraits<HBFilterOrder>::hbOrder / 4; i++) | ||||||
|  |         { | ||||||
|  |             iAcc += (m_samples[a][0] + m_samples[b][0]) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i]; | ||||||
|  |             qAcc += (m_samples[a][1] + m_samples[b][1]) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i]; | ||||||
|  |             a++; | ||||||
|  |             b--; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         sample->setReal(iAcc >> (HBFIRFilterTraits<HBFilterOrder>::hbShift -1)); | ||||||
|  |         sample->setImag(qAcc >> (HBFIRFilterTraits<HBFilterOrder>::hbShift -1)); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  |     void doInterpolateFIR(qint32 *x, qint32 *y) | ||||||
|  |     { | ||||||
|  |         qint16 a = m_ptr; | ||||||
|  |         qint16 b = m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder / 2) - 1; | ||||||
|  | 
 | ||||||
|  |         // go through samples in buffer
 | ||||||
|  |         qint32 iAcc = 0; | ||||||
|  |         qint32 qAcc = 0; | ||||||
|  | 
 | ||||||
|  |         for (int i = 0; i < HBFIRFilterTraits<HBFilterOrder>::hbOrder / 4; i++) | ||||||
|  |         { | ||||||
|  |             iAcc += (m_samples[a][0] + m_samples[b][0]) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i]; | ||||||
|  |             qAcc += (m_samples[a][1] + m_samples[b][1]) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i]; | ||||||
|  |             a++; | ||||||
|  |             b--; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         *x = iAcc >> (HBFIRFilterTraits<HBFilterOrder>::hbShift -1); | ||||||
|  |         *y = qAcc >> (HBFIRFilterTraits<HBFilterOrder>::hbShift -1); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| 	void doFIR(qint32 *x, qint32 *y) | 	void doFIR(qint32 *x, qint32 *y) | ||||||
| 	{ | 	{ | ||||||
| 		// Coefficents. This is a sinc function:
 | 		// Coefficents. This is a sinc function:
 | ||||||
| @ -621,18 +729,17 @@ protected: | |||||||
| 
 | 
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<uint32_t HBFilterOrder> | //template<uint32_t HBFilterOrder>
 | ||||||
| IntHalfbandFilter<HBFilterOrder>::IntHalfbandFilter() | //IntHalfbandFilter<HBFilterOrder>::IntHalfbandFilter()
 | ||||||
| { | //{
 | ||||||
|     for (int i = 0; i < HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1; i++) | //    for (int i = 0; i < HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1; i++)
 | ||||||
|     { | //    {
 | ||||||
|         m_samples[i][0] = 0; | //        m_samples[i][0] = 0;
 | ||||||
|         m_samples[i][1] = 0; | //        m_samples[i][1] = 0;
 | ||||||
|     } | //    }
 | ||||||
| 
 | //
 | ||||||
|     m_ptr = 0; | //    m_ptr = 0;
 | ||||||
| 
 | //    m_state = 0;
 | ||||||
|     m_state = 0; | //}
 | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| #endif // INCLUDE_INTHALFBANDFILTER_H
 | #endif // INCLUDE_INTHALFBANDFILTER_H
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user