1
/***************************************************************************
2
rttydemodulator.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
***************************************************************************/
18
#include "rttydemodulator.h"
20
RTTYDemodulator::RTTYDemodulator():CDemodulator()
32
FrequencyNumber = NULL;
33
// Disable PhaseDisplay
36
RTTYDemodulator::~RTTYDemodulator()
46
if (FrequencyNumber != NULL)
47
delete FrequencyNumber;
49
/** returns the asci char corresponding to the baudot code */
50
char RTTYDemodulator::baudot_code(char data)
52
/** Table of letters */
54
static const char letters[32] = {0x00,'E','\n','A',' ','S','I','U',
55
'\n','D','R','J','N','F','C','K',
56
'T','Z','L','W','H','Y','P','Q',
57
'O','B','G','^','M','X','V','^'};
60
/** Table of symbols */
61
static const char symbols[32] = {0x00,'3','\n','-',' ',',','8','7',
62
'\n','$','4','#',',','�',':','(',
63
'5','+',')','2','�','6','0','1',
64
'9','7','�','^','.','/','=','^'};
71
ShiftOn = false; //LTRS
75
ShiftOn = true; //FIGS
78
default: if (!ShiftOn)
86
if ( c == ' ') // Unshift on Space
92
bool RTTYDemodulator::Init(double FS,int NumberOfSamples)
100
NxSamples=NumberOfSamples;
101
SamplesPerBit=int (FS/Baudrate+0.5);
103
Status = WaitingForMark;
111
FrequencyChanged = false;
119
if ( (twiddles = new float_complex [SamplesPerBit]) == NULL )
122
if ( (bins = new float_complex[NumberofTones]) == NULL )
125
if ( (history = new float[SamplesPerBit] ) == NULL )
127
if ( (FrequencyNumber=new int[NumberofTones]) == NULL )
131
setRxFrequency(1000.);
133
// Initialize the coefficients for the slfft
135
for (i=0;i < SamplesPerBit; i++)
137
x =2*i * M_PI*Baudrate/FS;
138
twiddles[i] = float_complex( cos(x), sin(x) ) ;
141
for (i=0;i<SamplesPerBit; i++)
145
for(i=0;i<NumberofTones;i++)
146
bins[i]= float_complex(0.,0.);
150
void RTTYDemodulator::ProcessInput(double *input)
161
DataAvailable = true; // Just read the data
162
actSample = 0; // Start processing, counter will be incremented while processing
165
while (DataAvailable)
170
while ( DataAvailable ) // Waiting for Mark
171
if (ProcessNextSample() > 0)
173
Status = WaitingForSpace; // We seem to have found Mark, so we can wait for
178
case WaitingForSpace: // Mark seems to be found, now waiting for transition
179
while ( DataAvailable ) // Waiting for transition
180
if (ProcessNextSample() < 0 )
182
Status = CheckingStartBit; // Transition seems to be found
183
bitcounter = SamplesPerBit/2;
189
case CheckingStartBit:
191
while ( DataAvailable )
192
if ( --bitcounter > 0)
195
if ( ProcessNextSample() > 0 ) // 0.5 bit processed
197
Status = WaitingForSpace; // Was'nt the correct start bit, as we found Mark
198
break; // here , so go and look for another Space
202
/// Status = SkipRestOfStartBit; // We are tight behind the midle of the Startbit
203
Status = CollectingByte; // We are tight behind the midle of the Startbit
205
/// bitcounter = SamplesPerBit/4;
215
break; // We've reached the end of the available data or completed Status
217
case SkipRestOfStartBit:
218
while ( DataAvailable && (--bitcounter > 0) )
219
if ( ProcessNextSample() > 0 ) // Oops, already Mark
221
Status = CollectingByte;
224
count = 10; // This is only aguess
227
if ( bitcounter == 0 ) // Normal end of skip
229
Status = CollectingByte;
236
while( DataAvailable && (bitcounter > 0) )
249
break; // No more data to be processed at the moment
252
if ( bitcounter == 0 ) // Data 'byte' completed
254
c >>= (8- NumberOfBits);
255
Status = CheckingParity;
257
c1 = baudot_code(c1); // FIGS or LTRS result in c1 = 0 !
259
emit newSymbol( c1 );
273
if (parity == 1 ) // even
275
if ( BitsInData & 1) // error
284
if (! (BitsInData & 1)) // error
296
Status =WaitingForStopBits;
298
// bitcounter=NumberOfStopBits;
303
case WaitingForStopBits:
304
while ( DataAvailable && bitcounter >0 )
306
bit = get_next_bit();
307
if ( DataAvailable) // We've got a bit
310
if (!bit) // Framing Error
315
Status = CollectingByte; // Lets try whether this was already the start bit
316
/// Status = WaitingForMark;
317
bitcounter=NumberOfBits;
319
if ( (Frequencykor != 0) && UseAfc && (ave1 > 0.35))
321
emit rxFrequencyChanged( RxFrequency + Frequencykor);
322
setRxFrequency ( RxFrequency + Frequencykor);
331
/// Status=WaitingForSpace;
332
Status=WaitingForMark;
334
if ( ( Frequencykor != 0) && UseAfc && ( ave1 >0.35 ))
336
emit rxFrequencyChanged( RxFrequency + Frequencykor);
337
setRxFrequency ( RxFrequency + Frequencykor);
349
while ( DataAvailable && --bitcounter > 0)
351
if ( bitcounter == 0 )
352
Status = WaitingForMark;
359
int RTTYDemodulator::ProcessNextSample()
362
float z[NumberofTones];
364
if ( actSample<NxSamples )
366
DataAvailable = true;
367
x= (float) data[actSample];
370
for (i=0;i < NumberofTones; i++)
375
for (i=1;i <NumberofTones;i++)
389
DataAvailable = false;
396
bool RTTYDemodulator::get_next_bit()
400
float z[NumberofTones],y;
403
/*while (DataAvailable)
405
if (count != SamplesPerBit )
407
if ( actSample<NxSamples )
409
z= (float) data[actSample];
415
DataAvailable = false;
420
x = ProcessNextSample();
426
while (DataAvailable)
428
if ( actSample < NxSamples)
430
y= (float) data[actSample];
434
if ( count == SamplesPerBit)
438
for (i=0;i < NumberofTones; i++)
443
for (i=1;i <NumberofTones;i++)
457
case 1: // Frequency is ok
460
case 0: // Frequency is too high
464
case 2: // Frequency is too low
474
if ( abs(bins[1]) > abs(bins[5]) )
485
DataAvailable = false;
489
return ( (x > 0 ) ? true : false) ;
492
void RTTYDemodulator::slfft(float x)
496
///old = x - history[ptr];
500
ptr = (ptr +1) % SamplesPerBit;
502
for (int i=0; i <NumberofTones;i++)
503
bins[i] = bins[i]*twiddles[FrequencyNumber[i]] +x - old;
507
void RTTYDemodulator::setRxFrequency(double freq)
510
if ( freq != RxFrequency)
513
for(i=0; i < NumberofTones; i++)
514
bins[i]=float_complex(0.0,0.0);
516
FrequencyNumber[1]= (RxFrequency*SamplesPerBit)/SampleRate+0.5;
517
FrequencyNumber[0] = FrequencyNumber[1] - 1;
518
FrequencyNumber[2] = FrequencyNumber[1] + 1;
519
FrequencyNumber[3] = FrequencyNumber[2] + 1;
520
FrequencyNumber[5]= ( (RxFrequency+170) *SamplesPerBit)/SampleRate+0.5;
521
FrequencyNumber[4] = FrequencyNumber[5] - 1;
522
FrequencyNumber[6] = FrequencyNumber[5] + 1;
526
void RTTYDemodulator::CalcQuality()
530
sum=abs(bins[1])+abs(bins[5]);
531
diff=abs( abs(bins[1])-abs(bins[5]));
532
//ave1=0.8*ave1 + 0.2 * abs(y0-y1)/(y0+y1);
534
ave1=0.7*ave1 + 0.25 * ave2 + 0.05 * diff/sum;
536
ave1 = 0.5*ave1 + 0.3 *ave2;
537
emit setSquelchValue((int)(100*ave1));
543
void RTTYDemodulator::reset()
547
for(i=0;i<NumberofTones;i++)
548
bins[i]=float_complex(0.0,0.0);
549
for(i=0;i < SamplesPerBit; i++)