kopia lustrzana https://github.com/f4exb/sdrangel
				
				
				
			Downsample filtering.
							rodzic
							
								
									ff312a52a3
								
							
						
					
					
						commit
						dcc9f1917c
					
				| 
						 | 
				
			
			@ -223,9 +223,23 @@ public:
 | 
			
		|||
			}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void myDecimate(Sample* sample1, Sample* sample2)
 | 
			
		||||
        {
 | 
			
		||||
		static const qint16 mod33[38] = { 31,32,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
 | 
			
		||||
							20,21,22,23,24,25,26,27,28,29,30,31,32,0,1,2} ;
 | 
			
		||||
		m_samples[m_ptr][0] = sample1->real();
 | 
			
		||||
		m_samples[m_ptr][1] = sample1->imag();
 | 
			
		||||
		m_ptr = mod33[m_ptr + 2 - 1];
 | 
			
		||||
 | 
			
		||||
		m_samples[m_ptr][0] = sample2->real();
 | 
			
		||||
		m_samples[m_ptr][1] = sample2->imag();
 | 
			
		||||
		doFIR(sample2);
 | 
			
		||||
		m_ptr = mod33[m_ptr + 2 - 1];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
	qint16 m_samples[HB_FILTERORDER + 1][2];
 | 
			
		||||
	int m_ptr;
 | 
			
		||||
	qint16 m_ptr;
 | 
			
		||||
	int m_state;
 | 
			
		||||
 | 
			
		||||
	void doFIR(Sample* sample)
 | 
			
		||||
| 
						 | 
				
			
			@ -267,15 +281,17 @@ protected:
 | 
			
		|||
			0.317491986549921390015072120149852707982 * (1 << HB_SHIFT)
 | 
			
		||||
		};
 | 
			
		||||
#elif HB_FILTERORDER == 32
 | 
			
		||||
		static const qint16 mod33[38] = { 31,32,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
 | 
			
		||||
							20,21,22,23,24,25,26,27,28,29,30,31,32,0,1,2} ;
 | 
			
		||||
		static const qint32 COEFF[8] = {
 | 
			
		||||
		   -0.015956912844043127236437484839370881673 * (1 << HB_SHIFT),
 | 
			
		||||
			0.013023031678944928940522274274371739011 * (1 << HB_SHIFT),
 | 
			
		||||
		   -0.01866942273717486777684371190844103694  * (1 << HB_SHIFT),
 | 
			
		||||
			0.026550887571157304190005987720724078827 * (1 << HB_SHIFT),
 | 
			
		||||
		   -0.038350314277854319344740474662103224546 * (1 << HB_SHIFT),
 | 
			
		||||
			0.058429248652825838128421764849917963147 * (1 << HB_SHIFT),
 | 
			
		||||
		   -0.102889802028955756885153505209018476307 * (1 << HB_SHIFT),
 | 
			
		||||
			0.317237706405931241260276465254719369113 * (1 << HB_SHIFT)
 | 
			
		||||
			(qint32)(-0.015956912844043127236437484839370881673 * (1 << HB_SHIFT)),
 | 
			
		||||
			(qint32)( 0.013023031678944928940522274274371739011 * (1 << HB_SHIFT)),
 | 
			
		||||
			(qint32)(-0.01866942273717486777684371190844103694  * (1 << HB_SHIFT)),
 | 
			
		||||
			(qint32)( 0.026550887571157304190005987720724078827 * (1 << HB_SHIFT)),
 | 
			
		||||
			(qint32)(-0.038350314277854319344740474662103224546 * (1 << HB_SHIFT)),
 | 
			
		||||
			(qint32)( 0.058429248652825838128421764849917963147 * (1 << HB_SHIFT)),
 | 
			
		||||
			(qint32)(-0.102889802028955756885153505209018476307 * (1 << HB_SHIFT)),
 | 
			
		||||
			(qint32)( 0.317237706405931241260276465254719369113 * (1 << HB_SHIFT))
 | 
			
		||||
		};
 | 
			
		||||
#else
 | 
			
		||||
#error unsupported filter order
 | 
			
		||||
| 
						 | 
				
			
			@ -283,8 +299,8 @@ protected:
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
		// init read-pointer
 | 
			
		||||
		int a = (m_ptr + 1) % (HB_FILTERORDER + 1);
 | 
			
		||||
		int b = (m_ptr + (HB_FILTERORDER - 1)) % (HB_FILTERORDER + 1);
 | 
			
		||||
		int a = mod33[m_ptr + 2 + 1]; // 0 + 1
 | 
			
		||||
		int b = mod33[m_ptr + 2 - 2]; //-1 - 1
 | 
			
		||||
 | 
			
		||||
		// go through samples in buffer
 | 
			
		||||
		qint32 iAcc = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -297,17 +313,16 @@ protected:
 | 
			
		|||
			qAcc += qTmp * COEFF[i];
 | 
			
		||||
 | 
			
		||||
			// update read-pointer
 | 
			
		||||
			a = (a + 2) % (HB_FILTERORDER + 1);
 | 
			
		||||
			b = (b + (HB_FILTERORDER - 1)) % (HB_FILTERORDER + 1);
 | 
			
		||||
			a = mod33[a + 2 + 2];
 | 
			
		||||
			b = mod33[b + 2 - 2];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		a = (a + HB_FILTERORDER) % (HB_FILTERORDER + 1);
 | 
			
		||||
		iAcc += m_samples[a][0] * (qint32)(0.5 * (1 << HB_SHIFT));
 | 
			
		||||
		qAcc += m_samples[a][1] * (qint32)(0.5 * (1 << HB_SHIFT));
 | 
			
		||||
		a = mod33[a + 2 - 1];
 | 
			
		||||
		iAcc += ((qint32)m_samples[a][0] + 1) << (HB_SHIFT - 1);
 | 
			
		||||
		qAcc += ((qint32)m_samples[a][1] + 1) << (HB_SHIFT - 1);
 | 
			
		||||
 | 
			
		||||
		// done, save result
 | 
			
		||||
		sample->setReal((iAcc + (qint32)(0.5 * (1 << HB_SHIFT))) >> HB_SHIFT);
 | 
			
		||||
		sample->setImag((qAcc + (qint32)(0.5 * (1 << HB_SHIFT))) >> HB_SHIFT);
 | 
			
		||||
		sample->setReal(iAcc >> HB_SHIFT);
 | 
			
		||||
		sample->setImag(qAcc >> HB_SHIFT);
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -96,7 +96,7 @@ void RTLSDRThread::decimate4(SampleVector::iterator* it, const quint8* buf, qint
 | 
			
		|||
		for (int pos = 0; pos < len - 7; pos += 8) {
 | 
			
		||||
		xreal = buf[pos+0] - buf[pos+3] + buf[pos+7] - buf[pos+4];
 | 
			
		||||
		yimag = buf[pos+1] - buf[pos+5] + buf[pos+2] - buf[pos+6];
 | 
			
		||||
		Sample s( xreal << 4, yimag << 4 );
 | 
			
		||||
		Sample s( xreal << 3, yimag << 3 );
 | 
			
		||||
		**it = s;
 | 
			
		||||
		(*it)++;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -122,25 +122,29 @@ void RTLSDRThread::decimate16(SampleVector::iterator* it, const quint8* buf, qin
 | 
			
		|||
{
 | 
			
		||||
	// Offset tuning: 4x downsample and rotate, then
 | 
			
		||||
	// downsample 4x more. [ rotate:  0, 1, -3, 2, -4, -5, 7, -6]
 | 
			
		||||
	qint16 xreal, yimag;
 | 
			
		||||
	for (int step = 0; step < len - 31; step +=32) {
 | 
			
		||||
		xreal = yimag = 0;
 | 
			
		||||
		for (int pos = step; pos < step + 32; pos += 8) {
 | 
			
		||||
			xreal += buf[pos+0] - buf[pos+3] + buf[pos+7] - buf[pos+4];
 | 
			
		||||
			yimag += buf[pos+1] - buf[pos+5] + buf[pos+2] - buf[pos+6];
 | 
			
		||||
	qint16 xreal[4], yimag[4];
 | 
			
		||||
	bool b;
 | 
			
		||||
	for (int pos = 0; pos < len - 31; ) {
 | 
			
		||||
		for (int i = 0; i < 4; i++) {
 | 
			
		||||
			xreal[i] = (buf[pos+0] - buf[pos+3] + buf[pos+7] - buf[pos+4]) << 4;
 | 
			
		||||
			yimag[i] = (buf[pos+1] - buf[pos+5] + buf[pos+2] - buf[pos+6]) << 4;
 | 
			
		||||
			pos += 8;
 | 
			
		||||
		}
 | 
			
		||||
		Sample s( xreal << 3, yimag << 3 );
 | 
			
		||||
		**it = s;
 | 
			
		||||
		Sample s1( xreal[0], yimag[0] );
 | 
			
		||||
		Sample s2( xreal[1], yimag[1] );
 | 
			
		||||
		Sample s3( xreal[2], yimag[2] );
 | 
			
		||||
		Sample s4( xreal[3], yimag[3] );
 | 
			
		||||
		m_decimator2.myDecimate(&s1, &s2);
 | 
			
		||||
		m_decimator2.myDecimate(&s3, &s4);
 | 
			
		||||
		m_decimator4.myDecimate(&s2, &s4);
 | 
			
		||||
		**it = s4;
 | 
			
		||||
		(*it)++;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  Decimate everything by 16x, except 288kHz
 | 
			
		||||
  TODO : no offset tuning for direct sampling
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
//  Decimate everything by 16x, except 288kHz
 | 
			
		||||
void RTLSDRThread::callback(const quint8* buf, qint32 len)
 | 
			
		||||
{
 | 
			
		||||
	qint16 xreal, yimag, phase;
 | 
			
		||||
| 
						 | 
				
			
			@ -149,14 +153,12 @@ void RTLSDRThread::callback(const quint8* buf, qint32 len)
 | 
			
		|||
	int mode = 0;
 | 
			
		||||
	if (m_samplerate < 800000)
 | 
			
		||||
		mode = 2;
 | 
			
		||||
	// if (directsampling) mode++;
 | 
			
		||||
 | 
			
		||||
	switch(mode) {
 | 
			
		||||
		case 0:
 | 
			
		||||
			decimate16(&it, buf, len);
 | 
			
		||||
			break;
 | 
			
		||||
		case 1:
 | 
			
		||||
			// no_rotate16(&it, buf, len);
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case 2:
 | 
			
		||||
| 
						 | 
				
			
			@ -164,7 +166,6 @@ void RTLSDRThread::callback(const quint8* buf, qint32 len)
 | 
			
		|||
			break;
 | 
			
		||||
 | 
			
		||||
		case 3:
 | 
			
		||||
			// norotate4(&it, buf, len);
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
| 
						 | 
				
			
			@ -183,3 +184,4 @@ void RTLSDRThread::callbackHelper(unsigned char* buf, uint32_t len, void* ctx)
 | 
			
		|||
	RTLSDRThread* thread = (RTLSDRThread*)ctx;
 | 
			
		||||
	thread->callback(buf, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,6 +23,7 @@
 | 
			
		|||
#include <QWaitCondition>
 | 
			
		||||
#include <rtl-sdr.h>
 | 
			
		||||
#include "dsp/samplefifo.h"
 | 
			
		||||
#include "dsp/inthalfbandfilter.h"
 | 
			
		||||
 | 
			
		||||
class RTLSDRThread : public QThread {
 | 
			
		||||
	Q_OBJECT
 | 
			
		||||
| 
						 | 
				
			
			@ -46,6 +47,9 @@ private:
 | 
			
		|||
 | 
			
		||||
	int m_samplerate;
 | 
			
		||||
 | 
			
		||||
	IntHalfbandFilter m_decimator2;
 | 
			
		||||
	IntHalfbandFilter m_decimator4;
 | 
			
		||||
 | 
			
		||||
	void run();
 | 
			
		||||
	void decimate2(SampleVector::iterator* it, const quint8* buf, qint32 len);
 | 
			
		||||
	void decimate4(SampleVector::iterator* it, const quint8* buf, qint32 len);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue