1
/***************************************************************************
2
cpskdemodulator.cpp - description
5
copyright : (C) 2001 by Volker Schroer
7
***************************************************************************/
9
/***************************************************************************
11
* This program is free software; you can redistribute it and/or modify *
12
* it under the terms of the GNU General Public License as published by *
13
* the Free Software Foundation; either version 2 of the License, or *
14
* (at your option) any later version. *
15
* based on the work of Moe Wheatly, AE4JY *
16
***************************************************************************/
21
#include "cpskdemodulator.h"
22
#include "fircoeffs.h"
26
//define the PSK31 symbols
27
#define SYM_NOCHANGE 0 //Stay the same phase
28
#define SYM_P90 1 //Plus 90 deg
29
#define SYM_P180 2 //Plus 180 deg
30
#define SYM_M90 3 //Minus 90 deg
32
// phase wraparound correction table for viterbi decoder
33
const double AngleTbl1[4] = { 3.0*PI2/4.0, 0.0, PI2/4.0, PI2/2.0};
34
const double AngleTbl2[4] = { 3.0*PI2/4.0, PI2, PI2/4.0, PI2/2.0 };
37
//////////////////////////////////////////////////////////////////////
38
// Construction/Destruction
39
//////////////////////////////////////////////////////////////////////
41
CPskDemodulator::CPskDemodulator(): CDemodulator()
46
m_VaricodeDecTbl = NULL;
49
CPskDemodulator::~CPskDemodulator()
58
delete m_VaricodeDecTbl;
62
/////////////////////////////////////////////////////////////////
63
// Initialize PskDet buffers and pointers
64
/////////////////////////////////////////////////////////////////
65
bool CPskDemodulator::Init( double Fs, int BlockSize )
67
unsigned short int wTemp;
69
//circular delay lines.(data stays put and the pointers move)
70
if( (m_pQue1 = new double_complex[sizeof(double_complex)*DEC3_LPFIR_LENGTH] ) == NULL)
72
if( (m_pQue2 = new double_complex[sizeof(double_complex)*DEC3_LPFIR_LENGTH] ) == NULL)
74
if( (m_pQue3 = new double_complex[sizeof(double_complex)*BITFIR_LENGTH] ) == NULL)
76
if( ( m_VaricodeDecTbl = new unsigned char[sizeof(unsigned char)*2048] )== NULL)
78
for(int i=0; i<DEC3_LPFIR_LENGTH; i++)
80
// fill delay buffer with zero
81
m_pQue1[i] = double_complex(0.0,0.0);
83
for(i=0; i<DEC3_LPFIR_LENGTH; i++)
85
// fill delay buffer with zero
86
m_pQue2[i] = double_complex(0.0,0.0);
89
for( i=0; i<BITFIR_LENGTH; i++)
91
// fill delay buffer with zero
92
m_pQue3[i] = double_complex(0.0,0.0);
95
for( int j=0; j<2048; j++) //init inverse varicode lookup decoder table
97
m_VaricodeDecTbl[j] = 0;
98
for(int i=0; i<256;i++)
101
wTemp = VARICODE_TABLE[i];
107
m_VaricodeDecTbl[j] = (unsigned char)i;
110
m_pInPtr1 = m_pQue1; //initialize que ptrs
113
m_Fs = Fs; //sample rate
114
m_BlockSize = BlockSize; //size data input buffer
115
m_phzinc = 1000.0*PI2/m_Fs;
116
m_BitPhaseInc = 9.0/m_Fs; //bit oversampling period
120
m_LastBitZero = false;
126
m_SyncAve[i] = 0.0; // initialize the array
129
// Init a bunch of "static" variables used in various member fuctions
143
m_z1=double_complex(0.0,0.0);
151
// Initializing Variables for AFC
164
//////////////////////////////////////////////////////////////////////
165
// Main routine called to process the next block of data 'pIn'.
166
// The center frequency is specified by 'Freq'.
167
// The function returns the new AFC'd frequency.
168
// 'UseAFC' specifies whether to automatically lock to the frequency.
169
// 30mSec for BPSK, 38mSec for QPSK( 133MHz Pentium )
170
//////////////////////////////////////////////////////////////////////
172
void CPskDemodulator::ProcessInput( double* pIn)
175
double vcophz = m_VcoPhz;
179
double_complex* Firptr;
180
double_complex* Inptr1; //decimation FIR #1 variables
181
double_complex* Qptr1;
182
double_complex* Inptr2; //decimation FIR #2 variables
183
double_complex* Qptr2;
186
freqerror= m_FreqError;
192
if( RxFrequency != m_LastFreq ) //caller is changing center frequency
193
{ //so recalc freq error value
194
/// freqerror = freqerror + m_phzinc; //current center freq inc
195
m_phzinc = (PI2/m_Fs)*RxFrequency; //new center freq inc
197
/// freqerror = m_phzinc - freqerror;
200
m_LastFreq = RxFrequency;
202
Inptr1 = m_pInPtr1; //use local copies of member variables
203
Qptr1 = m_pQue1; // for better speed.
206
for( i = 0; i<m_BlockSize; i++ ) // put new samples into Queue
208
if( --Inptr1 < Qptr1 ) //deal with FIR pointer wrap around
209
Inptr1 = Qptr1+DEC3_LPFIR_LENGTH-1;
210
//Generate complex sample by mixing input sample with NCO's sin/cos
211
vcophz = vcophz + (m_phzinc + freqerror);
212
// *Inptr1=pIn[i]*exp(float_complex(0,vcophz));
213
*Inptr1=pIn[i]*double_complex(cos(vcophz),sin(vcophz));
214
// vcophz = vcophz + (m_phzinc + freqerror);
215
if(vcophz > PI2) //handle 2 Pi wrap around
217
//decimate by 3 filter
218
// 10uSec( 133MHz Pentium )
219
if( ( (++m_SampCnt)%3 ) == 0 ) //calc first decimation filter every 3 samples
222
acc=double_complex(0.0,0.0);
225
while( Kptr < (Dec3LPCoef + DEC3_LPFIR_LENGTH) ) //do the MAC's
228
acc +=(*Firptr)*(*Kptr++);
229
if( (++Firptr) >= Qptr1+DEC3_LPFIR_LENGTH ) //deal with wraparound
232
if( --Inptr2 < Qptr2 ) //deal with FIR pointer wrap around
233
Inptr2 = Qptr2+DEC3_LPFIR_LENGTH-1;
237
//decimate by 3 filter
238
// 10uSec( 133MHz Pentium )
239
if( (m_SampCnt%9) == 0 ) //calc second decimation filter every 9 samples
242
acc=double_complex(0.0,0.0);
245
while( Kptr < (Dec3LPCoef + DEC3_LPFIR_LENGTH) ) //do the MAC's
248
acc=(*Firptr)*(*Kptr);
250
if( (++Firptr) >= Qptr2+DEC3_LPFIR_LENGTH ) //deal with wraparound
253
// here at Fs/9 = 612.5 Hz rate with latest sample in acc.
254
// Matched Filter the I and Q data and also a frequency error filter
255
// filter puts filtered signals in m_FreqSignal and m_BitSignal.
256
CalcBitFilter( acc ); // 25 uSec( 133MHz Pentium )
257
// Perform AGC operation
258
m_SignalLevel = CalcAGC( m_FreqSignal ); // 9 uSec( 133MHz Pentium )
260
if( m_DispTrig ) //j ranges 0 to 2048/9 or 227
262
emit newPhaseValue(j++,float_complex(m_BitSignal));
263
// Calculate frequency error
266
freqerror = CalcFreqError(m_FreqSignal); // 10 uSec( 133MHz Pentium )
267
// Perhaps I should introduce a narrow / wid switch for the AFC
268
// freqerror = CalcFreqError(m_BitSignal); // 10 uSec( 133MHz Pentium )
272
freqerror = CalcFreqError(m_BitSignal); // 10 uSec( 133MHz Pentium )
276
// Bit Timing synchronization
278
if( SymbSync(m_BitSignal) ) // 8 uSec( 133MHz Pentium )
280
DecodeSymbol( m_BitSignal); //615uS(QPSK)
286
m_SampCnt = m_SampCnt%9;
287
m_pInPtr1 = Inptr1; // save position in circular delay line
288
m_pInPtr2 = Inptr2; // save position in circular delay line
290
m_FreqError = freqerror;
293
if (UseAfc) // Change RxFrequency, but slowly
295
freqerror=freqerror*m_Fs/PI2;
296
RxFrequency = RxFrequency + freqerror;
297
emit rxFrequencyChanged(RxFrequency);
301
settings.clockerror=m_ClkError;
305
//////////////////////////////////////////////////////////////////////
306
// Called at Fs/9 rate to calculate the symbol sync position
307
// Returns true if at center of symbol.
308
// Sums up the energy at each sample time, averages it, and picks the
309
// sample time with the highest energy content.
310
//////////////////////////////////////////////////////////////////////
312
bool CPskDemodulator::SymbSync(double_complex sample)
319
int BitPos = m_BitPos;
320
energy = sample.real()*sample.real()+sample.imag()*sample.imag();
321
if( energy > 4.0) //wait for AGC to settle down
323
m_SyncAve[BitPos] = (1.0-1.0/100.0)*m_SyncAve[BitPos] + (1.0/100.0)*energy;
324
if( BitPos == m_PkPos ) // see if at middle of symbol
327
// display->m_SyncHist[m_PkPos] = (int)(10000.0*m_SyncAve[m_PkPos]);
332
// display->m_SyncHist[BitPos] = (int)(7000.0*m_SyncAve[BitPos]);
335
if( BitPos == HALF_TBL[m_PkPos] ) //don't change pk pos until
336
m_PkPos = m_NewPkPos; // halfway into next bit.
338
m_BitPhasePos += (m_BitPhaseInc);
339
if( m_BitPhasePos >= Ts )
340
{ // here every symbol time
341
m_BitPhasePos -= Ts; //keep phase bounded
344
for( int i=0; i<19; i++) //find maximum energy pk
346
energy = m_SyncAve[i];
353
if( m_PkPos == m_LastPkPos+1 ) //calculate clock error
356
if( m_PkPos == m_LastPkPos-1 )
358
if( m_ClkErrTimer++ > 313 ) // every 10 seconds sample clk drift
360
m_ClkError = m_ClkErrCounter*180;
364
m_LastPkPos = m_PkPos;
371
//////////////////////////////////////////////////////////////////////
372
// Frequency error calculator
373
// calculates the derivative of the tan(I/Q).
374
// returns frequency error ~= .0034 per Hz error.
375
//////////////////////////////////////////////////////////////////////
376
double CPskDemodulator::CalcFreqError( double_complex IQ )
386
dp=0.98*dp+0.01*dp1-0.01*dp2;
387
ferror = (IQ.real() - m_z2.real()) * m_z1.imag() - (IQ.imag() - m_z2.imag()) * m_z1.real();
391
if( ferror > .15 ) //clamp range
395
//ftotal=0.03*ferror+0.02*ferror1-0.02*ferror2+0.5*fe1+0.4*fe2;
396
ftotal=0.01*ferror+0.01*ferror1-0.01*ferror2+0.5*fe1+0.4*fe2;
400
m_FerAve = 0.99 *m_FerAve + 0.008*ftotal + 0.002 * dp;
405
//////////////////////////////////////////////////////////////////////
406
// Automatic gain control calculator
407
//////////////////////////////////////////////////////////////////////
408
double CPskDemodulator::CalcAGC( double_complex Samp)
412
mag = sqrt(Samp.real()*Samp.real() + Samp.imag()*Samp.imag());
415
m_AGCave = (1.0-1.0/250.0)*m_AGCave + (1.0/250.0)*mag;
417
m_AGCave = (1.0-1.0/1000.0)*m_AGCave + (1.0/1000.0)*mag;
418
if( m_AGCave >= 1.0 ) // divide signal by ave if not almost zero
420
m_BitSignal /= m_AGCave;
421
// m_BitSignal.y /= m_AGCave;
422
m_FreqSignal /= m_AGCave;
423
// m_FreqSignal.y /= m_AGCave;
429
//////////////////////////////////////////////////////////////////////
430
// BIT FIR filters. A narrow matched(?) data filter for data
431
// and wider filter for the AFC/AGC functions
432
//////////////////////////////////////////////////////////////////////
433
void CPskDemodulator::CalcBitFilter(double_complex Samp)
439
double_complex* Firptr;
440
double_complex* Qptr;
441
double_complex* Inptr;
442
Inptr = m_pInPtr3; //use local copies of member variables
443
Qptr = m_pQue3; // for better speed.
444
if( --Inptr < Qptr ) //deal with LPFIR pointer wrap around
445
Inptr = Qptr+BITFIR_LENGTH-1;
446
// Inptr->x = Samp.x; //place in circular Queue
449
acc1 = double_complex(0.0,0.0);
451
acc2 = double_complex(0.0,0.0);
453
Kptr1 = FreqFirCoef; //frequency error filter
454
Kptr2 = BitFirCoef; //bit data filter
455
while( Kptr2 < (BitFirCoef + BITFIR_LENGTH) ) //do the MAC's
457
// acc1.x += ( (Firptr->x)*(*Kptr1) );
458
acc1 += ( (*Firptr)*(*Kptr1++) );
460
// acc2.x += ( (Firptr->x)*(*Kptr2) );
461
acc2 += ( (*Firptr)*(*Kptr2++) );
463
if( (++Firptr) >= (Qptr+BITFIR_LENGTH) ) //deal with wraparound
466
m_pInPtr3 = Inptr; // save position in circular delay line
467
// m_FreqSignal.x = acc1.x;
469
// m_BitSignal.x = acc2.x;