SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
Public Member Functions | Public Attributes | Protected Member Functions | Private Types | Private Attributes | Static Private Attributes | List of all members
RDSDecoder Class Reference

#include <rdsdecoder.h>

Public Member Functions

 RDSDecoder ()
 
 ~RDSDecoder ()
 
bool frameSync (bool bit)
 
unsigned int * getGroup ()
 
bool synced () const
 

Public Attributes

float m_qua
 

Protected Member Functions

unsigned int calc_syndrome (unsigned long message, unsigned char mlen)
 
void enter_sync (unsigned int sync_block_number)
 
void enter_no_sync ()
 

Private Types

enum  { NO_SYNC, SYNC }
 

Private Attributes

unsigned long m_reg
 
enum RDSDecoder:: { ... }  m_sync
 
bool m_presync
 
unsigned long m_lastseenOffsetCounter
 
unsigned long m_bitCounter
 
unsigned char m_lastseenOffset
 
unsigned int m_blockBitCounter
 
unsigned int m_wrongBlocksCounter
 
unsigned int m_blocksCounter
 
unsigned int m_groupGoodBlocksCounter
 
unsigned char m_blockNumber
 
bool m_groupAssemblyStarted
 
bool m_goodBlock
 
unsigned int m_group [4]
 

Static Private Attributes

static const unsigned int offset_pos [5] = {0,1,2,3,2}
 
static const unsigned int offset_word [5] = {252,408,360,436,848}
 
static const unsigned int syndrome [5] = {383,14,303,663,748}
 

Detailed Description

Definition at line 22 of file rdsdecoder.h.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
private
Enumerator
NO_SYNC 
SYNC 

Definition at line 41 of file rdsdecoder.h.

Constructor & Destructor Documentation

◆ RDSDecoder()

RDSDecoder::RDSDecoder ( )

Definition at line 28 of file rdsdecoder.cpp.

References m_bitCounter, m_blockBitCounter, m_blockNumber, m_blocksCounter, m_goodBlock, m_group, m_groupAssemblyStarted, m_groupGoodBlocksCounter, m_lastseenOffset, m_lastseenOffsetCounter, m_presync, m_qua, m_reg, m_sync, m_wrongBlocksCounter, and SYNC.

29 {
30  m_reg = 0;
31  m_presync = false;
33  m_bitCounter = 0;
34  m_lastseenOffset = 0;
35  m_blocksCounter = 0;
37  m_blockNumber = 0;
38  m_groupAssemblyStarted = false;
39  m_sync = SYNC;
42  m_goodBlock = false;
43  m_qua = 0.0f;
44  memset(m_group, 0, 4*sizeof(int));
45 }
bool m_goodBlock
Definition: rdsdecoder.h:52
unsigned int m_group[4]
Definition: rdsdecoder.h:53
bool m_groupAssemblyStarted
Definition: rdsdecoder.h:51
enum RDSDecoder::@0 m_sync
bool m_presync
Definition: rdsdecoder.h:42
unsigned long m_bitCounter
Definition: rdsdecoder.h:44
unsigned long m_lastseenOffsetCounter
Definition: rdsdecoder.h:43
unsigned int m_blockBitCounter
Definition: rdsdecoder.h:46
unsigned int m_blocksCounter
Definition: rdsdecoder.h:48
unsigned char m_blockNumber
Definition: rdsdecoder.h:50
unsigned int m_groupGoodBlocksCounter
Definition: rdsdecoder.h:49
float m_qua
Definition: rdsdecoder.h:32
unsigned int m_wrongBlocksCounter
Definition: rdsdecoder.h:47
unsigned long m_reg
Definition: rdsdecoder.h:40
unsigned char m_lastseenOffset
Definition: rdsdecoder.h:45

◆ ~RDSDecoder()

RDSDecoder::~RDSDecoder ( )

Definition at line 47 of file rdsdecoder.cpp.

48 {
49 }

Member Function Documentation

◆ calc_syndrome()

unsigned int RDSDecoder::calc_syndrome ( unsigned long  message,
unsigned char  mlen 
)
protected

see Annex B, page 64 of the standard

Definition at line 240 of file rdsdecoder.cpp.

References i.

Referenced by frameSync().

241 {
242  unsigned long reg = 0;
243  unsigned int i;
244  const unsigned long poly = 0x5B9;
245  const unsigned char plen = 10;
246 
247  for (i = mlen; i > 0; i--)
248  {
249  reg = (reg << 1) | ((message >> (i-1)) & 0x01);
250  if (reg & (1 << plen)) reg = reg ^ poly;
251  }
252 
253  for (i = plen; i > 0; i--)
254  {
255  reg = reg << 1;
256  if (reg & (1<<plen)) {
257  reg = reg ^ poly;
258  }
259  }
260 
261  return (reg & ((1<<plen)-1)); // select the bottom plen bits of reg
262 }
int32_t i
Definition: decimators.h:244
+ Here is the caller graph for this function:

◆ enter_no_sync()

void RDSDecoder::enter_no_sync ( )
protected

Definition at line 231 of file rdsdecoder.cpp.

References m_presync, m_sync, and NO_SYNC.

Referenced by frameSync().

232 {
233  m_presync = false;
234  m_sync = NO_SYNC;
235 }
enum RDSDecoder::@0 m_sync
bool m_presync
Definition: rdsdecoder.h:42
+ Here is the caller graph for this function:

◆ enter_sync()

void RDSDecoder::enter_sync ( unsigned int  sync_block_number)
protected

Definition at line 221 of file rdsdecoder.cpp.

References m_blockBitCounter, m_blockNumber, m_blocksCounter, m_groupAssemblyStarted, m_sync, m_wrongBlocksCounter, and SYNC.

Referenced by frameSync().

222 {
224  m_blocksCounter = 0;
225  m_blockBitCounter = 0;
226  m_blockNumber = (sync_block_number + 1) % 4;
227  m_groupAssemblyStarted = false;
228  m_sync = SYNC;
229 }
bool m_groupAssemblyStarted
Definition: rdsdecoder.h:51
enum RDSDecoder::@0 m_sync
unsigned int m_blockBitCounter
Definition: rdsdecoder.h:46
unsigned int m_blocksCounter
Definition: rdsdecoder.h:48
unsigned char m_blockNumber
Definition: rdsdecoder.h:50
unsigned int m_wrongBlocksCounter
Definition: rdsdecoder.h:47
+ Here is the caller graph for this function:

◆ frameSync()

bool RDSDecoder::frameSync ( bool  bit)

Definition at line 51 of file rdsdecoder.cpp.

References calc_syndrome(), enter_no_sync(), enter_sync(), m_bitCounter, m_blockBitCounter, m_blockNumber, m_blocksCounter, m_goodBlock, m_group, m_groupAssemblyStarted, m_groupGoodBlocksCounter, m_lastseenOffset, m_lastseenOffsetCounter, m_presync, m_qua, m_reg, m_sync, m_wrongBlocksCounter, NO_SYNC, offset_pos, offset_word, SYNC, and syndrome.

Referenced by BFMDemod::feed().

52 {
53  bool group_ready = false;
54  unsigned int reg_syndrome;
55  unsigned long bit_distance, block_distance;
56  unsigned int block_calculated_crc, block_received_crc, checkword, dataword;
57 
58  m_reg = (m_reg<<1) | bit;
59 
60  switch (m_sync)
61  {
62  case NO_SYNC:
63  reg_syndrome = calc_syndrome(m_reg,26);
64 
65  for (int j = 0; j < 5; j++)
66  {
67  if (reg_syndrome == syndrome[j])
68  {
69  if (!m_presync)
70  {
71  m_lastseenOffset = j;
73  m_presync=true;
74  }
75  else
76  {
77  bit_distance = m_bitCounter - m_lastseenOffsetCounter;
78 
80  {
81  block_distance = offset_pos[j] + 4 - offset_pos[m_lastseenOffset];
82  }
83  else
84  {
85  block_distance = offset_pos[j] - offset_pos[m_lastseenOffset];
86  }
87 
88  if ((block_distance*26)!=bit_distance)
89  {
90  m_presync = false;
91  }
92  else
93  {
94  //qDebug("RDSDecoder::frameSync: Sync State Detected");
95  enter_sync(j);
96  }
97  }
98 
99  break; //syndrome found, no more cycles
100  }
101  }
102  break;
103 
104  case SYNC:
105  // wait until 26 bits enter the buffer
106  if (m_blockBitCounter < 25)
107  {
109  }
110  else
111  {
112  m_goodBlock = false;
113  dataword = (m_reg>>10) & 0xffff;
114  block_calculated_crc = calc_syndrome(dataword, 16);
115  checkword = m_reg & 0x3ff;
116 
117  // manage special case of C or C' offset word
118  if (m_blockNumber == 2)
119  {
120  block_received_crc = checkword ^ offset_word[m_blockNumber];
121 
122  if (block_received_crc==block_calculated_crc)
123  {
124  m_goodBlock = true;
125  }
126  else
127  {
128  block_received_crc=checkword^offset_word[4];
129 
130  if (block_received_crc==block_calculated_crc)
131  {
132  m_goodBlock = true;
133  }
134  else
135  {
137  m_goodBlock = false;
138  }
139  }
140  }
141  else
142  {
143  block_received_crc = checkword ^ offset_word[m_blockNumber];
144 
145  if (block_received_crc==block_calculated_crc)
146  {
147  m_goodBlock = true;
148  }
149  else
150  {
152  m_goodBlock = false;
153  }
154  }
155 
156  //done checking CRC
157  if (m_blockNumber == 0 && m_goodBlock)
158  {
159  m_groupAssemblyStarted = true;
161  }
162 
164  {
165  if (!m_goodBlock)
166  {
167  m_groupAssemblyStarted = false;
168  }
169  else
170  {
171  m_group[m_blockNumber] = dataword;
173  }
174 
175  if (m_groupGoodBlocksCounter == 5)
176  {
177  group_ready = true; //decode_group(group); pass on to the group parser
178  }
179  }
180 
181  m_blockBitCounter = 0;
182  m_blockNumber = (m_blockNumber + 1) % 4;
183  m_blocksCounter++;
184 
185  // 1187.5 bps / 104 bits = 11.4 groups/sec, or 45.7 blocks/sec
186  if (m_blocksCounter == 50)
187  {
188  if (m_wrongBlocksCounter > 35)
189  {
190  /*
191  qDebug() << "RDSDecoder::frameSync: Lost Sync (Got " << m_wrongBlocksCounter
192  << " bad blocks on " << m_blocksCounter
193  << " total)";*/
194  enter_no_sync();
195  }
196  else
197  {
198  /*
199  qDebug() << "RDSDecoder::frameSync: Still Sync-ed (Got " << m_wrongBlocksCounter
200  << " bad blocks on " << m_blocksCounter
201  << " total)";*/
202  }
203 
204  m_qua = 2.0 * (50 - m_wrongBlocksCounter);
205  m_blocksCounter = 0;
207  }
208  }
209  break;
210  default:
211  break;
212  }
213 
214  m_bitCounter++;
215 
216  return group_ready;
217 }
bool m_goodBlock
Definition: rdsdecoder.h:52
static const unsigned int offset_word[5]
Definition: rdsdecoder.h:58
unsigned int m_group[4]
Definition: rdsdecoder.h:53
void enter_no_sync()
Definition: rdsdecoder.cpp:231
bool m_groupAssemblyStarted
Definition: rdsdecoder.h:51
enum RDSDecoder::@0 m_sync
bool m_presync
Definition: rdsdecoder.h:42
unsigned long m_bitCounter
Definition: rdsdecoder.h:44
unsigned long m_lastseenOffsetCounter
Definition: rdsdecoder.h:43
unsigned int m_blockBitCounter
Definition: rdsdecoder.h:46
static const unsigned int offset_pos[5]
Definition: rdsdecoder.h:57
unsigned int m_blocksCounter
Definition: rdsdecoder.h:48
unsigned char m_blockNumber
Definition: rdsdecoder.h:50
unsigned int m_groupGoodBlocksCounter
Definition: rdsdecoder.h:49
float m_qua
Definition: rdsdecoder.h:32
void enter_sync(unsigned int sync_block_number)
Definition: rdsdecoder.cpp:221
static const unsigned int syndrome[5]
Definition: rdsdecoder.h:59
unsigned int m_wrongBlocksCounter
Definition: rdsdecoder.h:47
unsigned int calc_syndrome(unsigned long message, unsigned char mlen)
Definition: rdsdecoder.cpp:240
unsigned long m_reg
Definition: rdsdecoder.h:40
unsigned char m_lastseenOffset
Definition: rdsdecoder.h:45
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getGroup()

unsigned int* RDSDecoder::getGroup ( )
inline

Definition at line 29 of file rdsdecoder.h.

References m_group.

Referenced by BFMDemod::feed().

29 { return m_group; }
unsigned int m_group[4]
Definition: rdsdecoder.h:53
+ Here is the caller graph for this function:

◆ synced()

bool RDSDecoder::synced ( ) const
inline

Definition at line 30 of file rdsdecoder.h.

References m_sync, and SYNC.

30 { return m_sync == SYNC; }
enum RDSDecoder::@0 m_sync

Member Data Documentation

◆ m_bitCounter

unsigned long RDSDecoder::m_bitCounter
private

Definition at line 44 of file rdsdecoder.h.

Referenced by frameSync(), and RDSDecoder().

◆ m_blockBitCounter

unsigned int RDSDecoder::m_blockBitCounter
private

Definition at line 46 of file rdsdecoder.h.

Referenced by enter_sync(), frameSync(), and RDSDecoder().

◆ m_blockNumber

unsigned char RDSDecoder::m_blockNumber
private

Definition at line 50 of file rdsdecoder.h.

Referenced by enter_sync(), frameSync(), and RDSDecoder().

◆ m_blocksCounter

unsigned int RDSDecoder::m_blocksCounter
private

Definition at line 48 of file rdsdecoder.h.

Referenced by enter_sync(), frameSync(), and RDSDecoder().

◆ m_goodBlock

bool RDSDecoder::m_goodBlock
private

Definition at line 52 of file rdsdecoder.h.

Referenced by frameSync(), and RDSDecoder().

◆ m_group

unsigned int RDSDecoder::m_group[4]
private

Definition at line 53 of file rdsdecoder.h.

Referenced by frameSync(), getGroup(), and RDSDecoder().

◆ m_groupAssemblyStarted

bool RDSDecoder::m_groupAssemblyStarted
private

Definition at line 51 of file rdsdecoder.h.

Referenced by enter_sync(), frameSync(), and RDSDecoder().

◆ m_groupGoodBlocksCounter

unsigned int RDSDecoder::m_groupGoodBlocksCounter
private

Definition at line 49 of file rdsdecoder.h.

Referenced by frameSync(), and RDSDecoder().

◆ m_lastseenOffset

unsigned char RDSDecoder::m_lastseenOffset
private

Definition at line 45 of file rdsdecoder.h.

Referenced by frameSync(), and RDSDecoder().

◆ m_lastseenOffsetCounter

unsigned long RDSDecoder::m_lastseenOffsetCounter
private

Definition at line 43 of file rdsdecoder.h.

Referenced by frameSync(), and RDSDecoder().

◆ m_presync

bool RDSDecoder::m_presync
private

Definition at line 42 of file rdsdecoder.h.

Referenced by enter_no_sync(), frameSync(), and RDSDecoder().

◆ m_qua

float RDSDecoder::m_qua

Definition at line 32 of file rdsdecoder.h.

Referenced by frameSync(), and RDSDecoder().

◆ m_reg

unsigned long RDSDecoder::m_reg
private

Definition at line 40 of file rdsdecoder.h.

Referenced by frameSync(), and RDSDecoder().

◆ m_sync

enum { ... } RDSDecoder::m_sync

◆ m_wrongBlocksCounter

unsigned int RDSDecoder::m_wrongBlocksCounter
private

Definition at line 47 of file rdsdecoder.h.

Referenced by enter_sync(), frameSync(), and RDSDecoder().

◆ offset_pos

const unsigned int RDSDecoder::offset_pos = {0,1,2,3,2}
staticprivate

Definition at line 57 of file rdsdecoder.h.

Referenced by frameSync().

◆ offset_word

const unsigned int RDSDecoder::offset_word = {252,408,360,436,848}
staticprivate

Definition at line 58 of file rdsdecoder.h.

Referenced by frameSync().

◆ syndrome

const unsigned int RDSDecoder::syndrome = {383,14,303,663,748}
staticprivate

Definition at line 59 of file rdsdecoder.h.

Referenced by frameSync().


The documentation for this class was generated from the following files: