| 
									
										
										
										
											2016-11-01 15:02:50 +01:00
										 |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // Copyright (C) 2016 F4EXB                                                      //
 | 
					
						
							|  |  |  | // written by Edouard Griffiths                                                  //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // This program is free software; you can redistribute it and/or modify          //
 | 
					
						
							|  |  |  | // it under the terms of the GNU General Public License as published by          //
 | 
					
						
							|  |  |  | // the Free Software Foundation as version 3 of the License, or                  //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // This program is distributed in the hope that it will be useful,               //
 | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of                //
 | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
 | 
					
						
							|  |  |  | // GNU General Public License V3 for more details.                               //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // You should have received a copy of the GNU General Public License             //
 | 
					
						
							|  |  |  | // along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | 
					
						
							|  |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | #ifndef INCLUDE_INTHALFBANDFILTER_H
 | 
					
						
							|  |  |  | #define INCLUDE_INTHALFBANDFILTER_H
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | #include <stdint.h>
 | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | #include "dsp/dsptypes.h"
 | 
					
						
							| 
									
										
										
										
											2016-11-01 11:55:16 +01:00
										 |  |  | #include "dsp/hbfiltertraits.h"
 | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | #include "util/export.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | template<uint32_t HBFilterOrder> | 
					
						
							| 
									
										
										
										
											2015-08-30 01:26:51 +02:00
										 |  |  | class SDRANGEL_API IntHalfbandFilter { | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | public: | 
					
						
							|  |  |  | 	IntHalfbandFilter(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// downsample by 2, return center part of original spectrum
 | 
					
						
							|  |  |  | 	bool workDecimateCenter(Sample* sample) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		// insert sample into ring-buffer
 | 
					
						
							|  |  |  | 		m_samples[m_ptr][0] = sample->real(); | 
					
						
							|  |  |  | 		m_samples[m_ptr][1] = sample->imag(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 		switch(m_state) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 			case 0: | 
					
						
							|  |  |  | 				// advance write-pointer
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | 				m_ptr = (m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder) % (HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				// next state
 | 
					
						
							|  |  |  | 				m_state = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// tell caller we don't have a new sample
 | 
					
						
							|  |  |  | 				return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				// save result
 | 
					
						
							|  |  |  | 				doFIR(sample); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// advance write-pointer
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | 				m_ptr = (m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder) % (HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				// next state
 | 
					
						
							|  |  |  | 				m_state = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// tell caller we have a new sample
 | 
					
						
							|  |  |  | 				return true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  |     // upsample by 2, return center part of original spectrum
 | 
					
						
							|  |  |  |     bool workInterpolateCenter(Sample* sampleIn, Sample *SampleOut) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         switch(m_state) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             case 0: | 
					
						
							|  |  |  |                 // insert sample into ring-buffer
 | 
					
						
							|  |  |  |                 m_samples[m_ptr][0] = 0; | 
					
						
							|  |  |  |                 m_samples[m_ptr][1] = 0; | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  |                 // save result
 | 
					
						
							|  |  |  |                 doFIR(SampleOut); | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  |                 // advance write-pointer
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  |                 m_ptr = (m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder) % (HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1); | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  |                 // next state
 | 
					
						
							|  |  |  |                 m_state = 1; | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  |                 // tell caller we didn't consume the sample
 | 
					
						
							|  |  |  |                 return false; | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  |             default: | 
					
						
							|  |  |  |                 // insert sample into ring-buffer
 | 
					
						
							|  |  |  |                 m_samples[m_ptr][0] = sampleIn->real(); | 
					
						
							|  |  |  |                 m_samples[m_ptr][1] = sampleIn->imag(); | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  |                 // save result
 | 
					
						
							|  |  |  |                 doFIR(SampleOut); | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  |                 // advance write-pointer
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  |                 m_ptr = (m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder) % (HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1); | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 // next state
 | 
					
						
							|  |  |  |                 m_state = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 // tell caller we consumed the sample
 | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 	bool workDecimateCenter(qint32 *x, qint32 *y) | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 		// insert sample into ring-buffer
 | 
					
						
							|  |  |  | 		m_samples[m_ptr][0] = *x; | 
					
						
							|  |  |  | 		m_samples[m_ptr][1] = *y; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 		switch(m_state) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 			case 0: | 
					
						
							|  |  |  | 				// advance write-pointer
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | 				m_ptr = (m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder) % (HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				// next state
 | 
					
						
							|  |  |  | 				m_state = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// tell caller we don't have a new sample
 | 
					
						
							|  |  |  | 				return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				// save result
 | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 				doFIR(x, y); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				// advance write-pointer
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | 				m_ptr = (m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder) % (HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				// next state
 | 
					
						
							|  |  |  | 				m_state = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// tell caller we have a new sample
 | 
					
						
							|  |  |  | 				return true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 	// downsample by 2, return edges of spectrum rotated into center - unused
 | 
					
						
							|  |  |  | //	bool workDecimateFullRotate(Sample* sample)
 | 
					
						
							|  |  |  | //	{
 | 
					
						
							|  |  |  | //		switch(m_state)
 | 
					
						
							|  |  |  | //		{
 | 
					
						
							|  |  |  | //			case 0:
 | 
					
						
							|  |  |  | //				// insert sample into ring-buffer
 | 
					
						
							|  |  |  | //				m_samples[m_ptr][0] = sample->real();
 | 
					
						
							|  |  |  | //				m_samples[m_ptr][1] = sample->imag();
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //				// advance write-pointer
 | 
					
						
							|  |  |  | //				m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1);
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //				// next state
 | 
					
						
							|  |  |  | //				m_state = 1;
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //				// tell caller we don't have a new sample
 | 
					
						
							|  |  |  | //				return false;
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //			default:
 | 
					
						
							|  |  |  | //				// insert sample into ring-buffer
 | 
					
						
							|  |  |  | //				m_samples[m_ptr][0] = -sample->real();
 | 
					
						
							|  |  |  | //				m_samples[m_ptr][1] = sample->imag();
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //				// save result
 | 
					
						
							|  |  |  | //				doFIR(sample);
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //				// advance write-pointer
 | 
					
						
							|  |  |  | //				m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1);
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //				// next state
 | 
					
						
							|  |  |  | //				m_state = 0;
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //				// tell caller we have a new sample
 | 
					
						
							|  |  |  | //				return true;
 | 
					
						
							|  |  |  | //		}
 | 
					
						
							|  |  |  | //	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 	// downsample by 2, return lower half of original spectrum
 | 
					
						
							|  |  |  | 	bool workDecimateLowerHalf(Sample* sample) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 		switch(m_state) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			case 0: | 
					
						
							|  |  |  | 				// insert sample into ring-buffer
 | 
					
						
							|  |  |  | 				m_samples[m_ptr][0] = -sample->imag(); | 
					
						
							|  |  |  | 				m_samples[m_ptr][1] = sample->real(); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// advance write-pointer
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | 				m_ptr = (m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder) % (HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// next state
 | 
					
						
							|  |  |  | 				m_state = 1; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// tell caller we don't have a new sample
 | 
					
						
							|  |  |  | 				return false; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 			case 1: | 
					
						
							|  |  |  | 				// insert sample into ring-buffer
 | 
					
						
							|  |  |  | 				m_samples[m_ptr][0] = -sample->real(); | 
					
						
							|  |  |  | 				m_samples[m_ptr][1] = -sample->imag(); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// save result
 | 
					
						
							|  |  |  | 				doFIR(sample); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// advance write-pointer
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | 				m_ptr = (m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder) % (HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// next state
 | 
					
						
							|  |  |  | 				m_state = 2; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// tell caller we have a new sample
 | 
					
						
							|  |  |  | 				return true; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 			case 2: | 
					
						
							|  |  |  | 				// insert sample into ring-buffer
 | 
					
						
							|  |  |  | 				m_samples[m_ptr][0] = sample->imag(); | 
					
						
							|  |  |  | 				m_samples[m_ptr][1] = -sample->real(); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// advance write-pointer
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | 				m_ptr = (m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder) % (HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// next state
 | 
					
						
							|  |  |  | 				m_state = 3; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// tell caller we don't have a new sample
 | 
					
						
							|  |  |  | 				return false; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 			default: | 
					
						
							|  |  |  | 				// insert sample into ring-buffer
 | 
					
						
							|  |  |  | 				m_samples[m_ptr][0] = sample->real(); | 
					
						
							|  |  |  | 				m_samples[m_ptr][1] = sample->imag(); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// save result
 | 
					
						
							|  |  |  | 				doFIR(sample); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// advance write-pointer
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | 				m_ptr = (m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder) % (HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// next state
 | 
					
						
							|  |  |  | 				m_state = 0; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// tell caller we have a new sample
 | 
					
						
							|  |  |  | 				return true; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  |     // upsample by 2, from lower half of original spectrum
 | 
					
						
							|  |  |  |     bool workInterpolateLowerHalf(Sample* sampleIn, Sample *sampleOut) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |         Sample s; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  |         switch(m_state) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |         case 0: | 
					
						
							|  |  |  |             // insert sample into ring-buffer
 | 
					
						
							|  |  |  |             m_samples[m_ptr][0] = 0; | 
					
						
							|  |  |  |             m_samples[m_ptr][1] = 0; | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             // save result
 | 
					
						
							|  |  |  |             doFIR(&s); | 
					
						
							|  |  |  |             sampleOut->setReal(s.imag()); | 
					
						
							|  |  |  |             sampleOut->setImag(-s.real()); | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             // advance write-pointer
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  |             m_ptr = (m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder) % (HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1); | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             // next state
 | 
					
						
							|  |  |  |             m_state = 1; | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-01 05:54:25 +01:00
										 |  |  |             // tell caller we didn't consume the sample
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             return false; | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |         case 1: | 
					
						
							|  |  |  |             // insert sample into ring-buffer
 | 
					
						
							|  |  |  |             m_samples[m_ptr][0] = sampleIn->real(); | 
					
						
							|  |  |  |             m_samples[m_ptr][1] = sampleIn->imag(); | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             // save result
 | 
					
						
							|  |  |  |             doFIR(&s); | 
					
						
							|  |  |  |             sampleOut->setReal(-s.real()); | 
					
						
							|  |  |  |             sampleOut->setImag(-s.imag()); | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             // advance write-pointer
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  |             m_ptr = (m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder) % (HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1); | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             // next state
 | 
					
						
							|  |  |  |             m_state = 2; | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-01 05:54:25 +01:00
										 |  |  |             // tell caller we consumed the sample
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             return true; | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |         case 2: | 
					
						
							|  |  |  |             // insert sample into ring-buffer
 | 
					
						
							|  |  |  |             m_samples[m_ptr][0] = 0; | 
					
						
							|  |  |  |             m_samples[m_ptr][1] = 0; | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             // save result
 | 
					
						
							|  |  |  |             doFIR(&s); | 
					
						
							|  |  |  |             sampleOut->setReal(-s.imag()); | 
					
						
							|  |  |  |             sampleOut->setImag(s.real()); | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             // advance write-pointer
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  |             m_ptr = (m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder) % (HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1); | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             // next state
 | 
					
						
							|  |  |  |             m_state = 3; | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-01 05:54:25 +01:00
										 |  |  |             // tell caller we didn't consume the sample
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             return false; | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |         default: | 
					
						
							|  |  |  |             // insert sample into ring-buffer
 | 
					
						
							|  |  |  |             m_samples[m_ptr][0] = sampleIn->real(); | 
					
						
							|  |  |  |             m_samples[m_ptr][1] = sampleIn->imag(); | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             // save result
 | 
					
						
							|  |  |  |             doFIR(&s); | 
					
						
							|  |  |  |             sampleOut->setReal(s.real()); | 
					
						
							|  |  |  |             sampleOut->setImag(s.imag()); | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             // advance write-pointer
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  |             m_ptr = (m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder) % (HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1); | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             // next state
 | 
					
						
							|  |  |  |             m_state = 0; | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-01 05:54:25 +01:00
										 |  |  |             // tell caller we consumed the sample
 | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 	// downsample by 2, return upper half of original spectrum
 | 
					
						
							|  |  |  | 	bool workDecimateUpperHalf(Sample* sample) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 		switch(m_state) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			case 0: | 
					
						
							|  |  |  | 				// insert sample into ring-buffer
 | 
					
						
							|  |  |  | 				m_samples[m_ptr][0] = sample->imag(); | 
					
						
							|  |  |  | 				m_samples[m_ptr][1] = -sample->real(); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// advance write-pointer
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | 				m_ptr = (m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder) % (HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// next state
 | 
					
						
							|  |  |  | 				m_state = 1; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// tell caller we don't have a new sample
 | 
					
						
							|  |  |  | 				return false; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 			case 1: | 
					
						
							|  |  |  | 				// insert sample into ring-buffer
 | 
					
						
							|  |  |  | 				m_samples[m_ptr][0] = -sample->real(); | 
					
						
							|  |  |  | 				m_samples[m_ptr][1] = -sample->imag(); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// save result
 | 
					
						
							|  |  |  | 				doFIR(sample); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// advance write-pointer
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | 				m_ptr = (m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder) % (HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// next state
 | 
					
						
							|  |  |  | 				m_state = 2; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// tell caller we have a new sample
 | 
					
						
							|  |  |  | 				return true; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 			case 2: | 
					
						
							|  |  |  | 				// insert sample into ring-buffer
 | 
					
						
							|  |  |  | 				m_samples[m_ptr][0] = -sample->imag(); | 
					
						
							|  |  |  | 				m_samples[m_ptr][1] = sample->real(); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// advance write-pointer
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | 				m_ptr = (m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder) % (HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// next state
 | 
					
						
							|  |  |  | 				m_state = 3; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// tell caller we don't have a new sample
 | 
					
						
							|  |  |  | 				return false; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 			default: | 
					
						
							|  |  |  | 				// insert sample into ring-buffer
 | 
					
						
							|  |  |  | 				m_samples[m_ptr][0] = sample->real(); | 
					
						
							|  |  |  | 				m_samples[m_ptr][1] = sample->imag(); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// save result
 | 
					
						
							|  |  |  | 				doFIR(sample); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// advance write-pointer
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | 				m_ptr = (m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder) % (HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// next state
 | 
					
						
							|  |  |  | 				m_state = 0; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 				// tell caller we have a new sample
 | 
					
						
							|  |  |  | 				return true; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-28 18:39:45 +02:00
										 |  |  |     // upsample by 2, move original spectrum to upper half
 | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  |     bool workInterpolateUpperHalf(Sample* sampleIn, Sample *sampleOut) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |         Sample s; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  |         switch(m_state) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |         case 0: | 
					
						
							|  |  |  |             // insert sample into ring-buffer
 | 
					
						
							|  |  |  |             m_samples[m_ptr][0] = 0; | 
					
						
							|  |  |  |             m_samples[m_ptr][1] = 0; | 
					
						
							| 
									
										
										
										
											2016-10-28 18:39:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             // save result
 | 
					
						
							|  |  |  |             doFIR(&s); | 
					
						
							|  |  |  |             sampleOut->setReal(-s.imag()); | 
					
						
							|  |  |  |             sampleOut->setImag(s.real()); | 
					
						
							| 
									
										
										
										
											2016-10-28 18:39:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             // advance write-pointer
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  |             m_ptr = (m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder) % (HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1); | 
					
						
							| 
									
										
										
										
											2016-10-28 18:39:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             // next state
 | 
					
						
							|  |  |  |             m_state = 1; | 
					
						
							| 
									
										
										
										
											2016-10-28 18:39:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-01 05:54:25 +01:00
										 |  |  |             // tell caller we didn't consume the sample
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             return false; | 
					
						
							| 
									
										
										
										
											2016-10-28 18:39:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |         case 1: | 
					
						
							|  |  |  |             // insert sample into ring-buffer
 | 
					
						
							|  |  |  |             m_samples[m_ptr][0] = sampleIn->real(); | 
					
						
							|  |  |  |             m_samples[m_ptr][1] = sampleIn->imag(); | 
					
						
							| 
									
										
										
										
											2016-10-28 18:39:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             // save result
 | 
					
						
							|  |  |  |             doFIR(&s); | 
					
						
							|  |  |  |             sampleOut->setReal(-s.real()); | 
					
						
							|  |  |  |             sampleOut->setImag(-s.imag()); | 
					
						
							| 
									
										
										
										
											2016-10-28 18:39:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             // advance write-pointer
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  |             m_ptr = (m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder) % (HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1); | 
					
						
							| 
									
										
										
										
											2016-10-28 18:39:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             // next state
 | 
					
						
							|  |  |  |             m_state = 2; | 
					
						
							| 
									
										
										
										
											2016-10-28 18:39:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-01 05:54:25 +01:00
										 |  |  |             // tell caller we consumed the sample
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             return true; | 
					
						
							| 
									
										
										
										
											2016-10-28 18:39:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |         case 2: | 
					
						
							|  |  |  |             // insert sample into ring-buffer
 | 
					
						
							|  |  |  |             m_samples[m_ptr][0] = 0; | 
					
						
							|  |  |  |             m_samples[m_ptr][1] = 0; | 
					
						
							| 
									
										
										
										
											2016-10-28 18:39:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             // save result
 | 
					
						
							|  |  |  |             doFIR(&s); | 
					
						
							|  |  |  |             sampleOut->setReal(s.imag()); | 
					
						
							|  |  |  |             sampleOut->setImag(-s.real()); | 
					
						
							| 
									
										
										
										
											2016-10-28 18:39:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             // advance write-pointer
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  |             m_ptr = (m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder) % (HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1); | 
					
						
							| 
									
										
										
										
											2016-10-28 18:39:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             // next state
 | 
					
						
							|  |  |  |             m_state = 3; | 
					
						
							| 
									
										
										
										
											2016-10-28 18:39:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-01 05:54:25 +01:00
										 |  |  |             // tell caller we didn't consume the sample
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             return false; | 
					
						
							| 
									
										
										
										
											2016-10-28 18:39:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |         default: | 
					
						
							|  |  |  |             // insert sample into ring-buffer
 | 
					
						
							|  |  |  |             m_samples[m_ptr][0] = sampleIn->real(); | 
					
						
							|  |  |  |             m_samples[m_ptr][1] = sampleIn->imag(); | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             // save result
 | 
					
						
							|  |  |  |             doFIR(&s); | 
					
						
							|  |  |  |             sampleOut->setReal(s.real()); | 
					
						
							|  |  |  |             sampleOut->setImag(s.imag()); | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             // advance write-pointer
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  |             m_ptr = (m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder) % (HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1); | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |             // next state
 | 
					
						
							|  |  |  |             m_state = 0; | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-01 05:54:25 +01:00
										 |  |  |             // tell caller we consumed the sample
 | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-17 08:58:49 +02:00
										 |  |  |     void myDecimate(const Sample* sample1, Sample* sample2) | 
					
						
							| 
									
										
										
										
											2015-08-29 03:09:00 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |         m_samples[m_ptr][0] = sample1->real(); | 
					
						
							|  |  |  |         m_samples[m_ptr][1] = sample1->imag(); | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  |         m_ptr = HBFIRFilterTraits<HBFilterOrder>::hbMod[m_ptr + 2 - 1]; | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         m_samples[m_ptr][0] = sample2->real(); | 
					
						
							|  |  |  |         m_samples[m_ptr][1] = sample2->imag(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         doFIR(sample2); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  |         m_ptr = HBFIRFilterTraits<HBFilterOrder>::hbMod[m_ptr + 2 - 1]; | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |     void myDecimate(qint32 x1, qint32 y1, qint32 *x2, qint32 *y2) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_samples[m_ptr][0] = x1; | 
					
						
							|  |  |  |         m_samples[m_ptr][1] = y1; | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  |         m_ptr = HBFIRFilterTraits<HBFilterOrder>::hbMod[m_ptr + 2 - 1]; | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         m_samples[m_ptr][0] = *x2; | 
					
						
							|  |  |  |         m_samples[m_ptr][1] = *y2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         doFIR(x2, y2); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  |         m_ptr = HBFIRFilterTraits<HBFilterOrder>::hbMod[m_ptr + 2 - 1]; | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-31 04:23:59 +01:00
										 |  |  |     void myInterpolate(Sample* sample1, Sample* sample2) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_samples[m_ptr][0] = sample1->real(); | 
					
						
							|  |  |  |         m_samples[m_ptr][1] = sample1->imag(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         doFIR(sample1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         m_ptr = HBFIRFilterTraits<HBFilterOrder>::hbMod[m_ptr + 2 - 1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         m_samples[m_ptr][0] = 0; | 
					
						
							|  |  |  |         m_samples[m_ptr][1] = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         doFIR(sample2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         m_ptr = HBFIRFilterTraits<HBFilterOrder>::hbMod[m_ptr + 2 - 1]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void myInterpolate(qint32 *x1, qint32 *y1, qint32 *x2, qint32 *y2) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_samples[m_ptr][0] = *x1; | 
					
						
							|  |  |  |         m_samples[m_ptr][1] = *y1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         doFIR(x1, y1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         m_ptr = HBFIRFilterTraits<HBFilterOrder>::hbMod[m_ptr + 2 - 1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         m_samples[m_ptr][0] = 0; | 
					
						
							|  |  |  |         m_samples[m_ptr][1] = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         doFIR(x2, y2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         m_ptr = HBFIRFilterTraits<HBFilterOrder>::hbMod[m_ptr + 2 - 1]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | protected: | 
					
						
							| 
									
										
										
										
											2016-11-01 05:54:25 +01:00
										 |  |  | 	qint32 m_samples[HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1][2];     // Valgrind optim (from qint16)
 | 
					
						
							| 
									
										
										
										
											2014-11-17 19:51:36 +00:00
										 |  |  | 	qint16 m_ptr; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 	int m_state; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	void doFIR(Sample* sample) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		// init read-pointer
 | 
					
						
							| 
									
										
										
										
											2016-11-01 15:02:50 +01:00
										 |  |  | 		int a = HBFIRFilterTraits<HBFilterOrder>::hbMod[m_ptr + 2 + 1]; // 0 + 1
 | 
					
						
							|  |  |  | 		int b = HBFIRFilterTraits<HBFilterOrder>::hbMod[m_ptr + 2 - 2]; //-1 - 1
 | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// go through samples in buffer
 | 
					
						
							|  |  |  | 		qint32 iAcc = 0; | 
					
						
							|  |  |  | 		qint32 qAcc = 0; | 
					
						
							| 
									
										
										
										
											2015-08-29 03:09:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | 		for (int i = 0; i < HBFIRFilterTraits<HBFilterOrder>::hbOrder / 4; i++) | 
					
						
							| 
									
										
										
										
											2015-08-29 03:09:00 +02:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 			// do multiply-accumulate
 | 
					
						
							| 
									
										
										
										
											2015-08-29 03:09:00 +02:00
										 |  |  | 			//qint32 iTmp = m_samples[a][0] + m_samples[b][0]; // Valgrind optim
 | 
					
						
							|  |  |  | 			//qint32 qTmp = m_samples[a][1] + m_samples[b][1]; // Valgrind optim
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | 			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]; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// update read-pointer
 | 
					
						
							| 
									
										
										
										
											2016-11-01 15:02:50 +01:00
										 |  |  | 			a = HBFIRFilterTraits<HBFilterOrder>::hbMod[a + 2 + 2]; | 
					
						
							|  |  |  | 			b = HBFIRFilterTraits<HBFilterOrder>::hbMod[b + 2 - 2]; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-01 15:02:50 +01:00
										 |  |  | 		a = HBFIRFilterTraits<HBFilterOrder>::hbMod[a + 2 - 1]; | 
					
						
							| 
									
										
										
										
											2015-08-29 03:09:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | 		iAcc += ((qint32)m_samples[a][0] + 1) << (HBFIRFilterTraits<HBFilterOrder>::hbShift - 1); | 
					
						
							|  |  |  | 		qAcc += ((qint32)m_samples[a][1] + 1) << (HBFIRFilterTraits<HBFilterOrder>::hbShift - 1); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-21 18:01:55 +01:00
										 |  |  | 		sample->setReal(iAcc >> (HBFIRFilterTraits<HBFilterOrder>::hbShift -1)); | 
					
						
							|  |  |  | 		sample->setImag(qAcc >> (HBFIRFilterTraits<HBFilterOrder>::hbShift -1)); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-02 00:25:29 +02:00
										 |  |  | 	void doFIR(qint32 *x, qint32 *y) | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  | 		// Coefficents. This is a sinc function:
 | 
					
						
							|  |  |  | 	    // Half of the half of coefficients are stored because:
 | 
					
						
							|  |  |  | 	    // - half of the coefficients are 0
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | 	    // - there is a symmertry around the central 0.5 coefficient (not stored either)
 | 
					
						
							| 
									
										
										
										
											2016-10-29 12:29:24 +02:00
										 |  |  | 	    // There are actually order+1 coefficients
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// init read-pointer
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | 		int a = HBFIRFilterTraits<HBFilterOrder>::hbMod[m_ptr + 2 + 1]; // 0 + 1
 | 
					
						
							|  |  |  | 		int b = HBFIRFilterTraits<HBFilterOrder>::hbMod[m_ptr + 2 - 2]; //-1 - 1
 | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// go through samples in buffer
 | 
					
						
							|  |  |  | 		qint32 iAcc = 0; | 
					
						
							|  |  |  | 		qint32 qAcc = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | 		for (int i = 0; i < HBFIRFilterTraits<HBFilterOrder>::hbOrder / 4; i++) | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			// do multiply-accumulate
 | 
					
						
							|  |  |  | 			//qint32 iTmp = m_samples[a][0] + m_samples[b][0]; // Valgrind optim
 | 
					
						
							|  |  |  | 			//qint32 qTmp = m_samples[a][1] + m_samples[b][1]; // Valgrind optim
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | 			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]; | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// update read-pointer
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | 			a = HBFIRFilterTraits<HBFilterOrder>::hbMod[a + 2 + 2]; | 
					
						
							|  |  |  | 			b = HBFIRFilterTraits<HBFilterOrder>::hbMod[b + 2 - 2]; | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | 		a = HBFIRFilterTraits<HBFilterOrder>::hbMod[a + 2 - 1]; | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | 		iAcc += ((qint32)m_samples[a][0] + 1) << (HBFIRFilterTraits<HBFilterOrder>::hbShift - 1); | 
					
						
							|  |  |  | 		qAcc += ((qint32)m_samples[a][1] + 1) << (HBFIRFilterTraits<HBFilterOrder>::hbShift - 1); | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | 		*x = iAcc >> (HBFIRFilterTraits<HBFilterOrder>::hbShift -1); // HB_SHIFT incorrect do not loose the gained bit
 | 
					
						
							|  |  |  | 		*y = qAcc >> (HBFIRFilterTraits<HBFilterOrder>::hbShift -1); | 
					
						
							| 
									
										
										
										
											2015-09-01 08:36:10 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  | template<uint32_t HBFilterOrder> | 
					
						
							|  |  |  | IntHalfbandFilter<HBFilterOrder>::IntHalfbandFilter() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-11-01 05:54:25 +01:00
										 |  |  |     for (int i = 0; i < HBFIRFilterTraits<HBFilterOrder>::hbOrder + 1; i++) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  |         m_samples[i][0] = 0; | 
					
						
							|  |  |  |         m_samples[i][1] = 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-11-01 05:54:25 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  |     m_ptr = 0; | 
					
						
							| 
									
										
										
										
											2016-11-01 05:54:25 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 17:01:02 +02:00
										 |  |  |     m_state = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | #endif // INCLUDE_INTHALFBANDFILTER_H
 |