Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix "my" RDS2 as it did not work anymore #20

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions forms/radio.ui
Original file line number Diff line number Diff line change
Expand Up @@ -1340,7 +1340,7 @@
<item>
<widget class="QPushButton" name="btnRestartPSS">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Restarts the PSS (Perfect Stereo Separation) analyzer&lt;/p&gt;&lt;p&gt;This could be important when the analyzing failed if too little Stereo difference signal was existing while analyzing before (e.g, only a new report without music).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Restarts the PSS (Perfect Stereo Separation) analyzer&lt;/p&gt;&lt;p&gt;This could be important when the analyzing failed if too little Stereo difference signal was existing while analyzing before (e.g, only a news report without music).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Restart PSS analyzer</string>
Expand Down Expand Up @@ -1625,7 +1625,7 @@
<item>
<widget class="QComboBox" name="fmRdsSelector">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Select RDS decoding:&lt;/p&gt;&lt;p&gt;RDS OFF: RDS is off at all&lt;/p&gt;&lt;p&gt;RDS 1: RDS works with a matched filter recognition based on cuteSDR&lt;br/&gt;&lt;br/&gt;RDS 2: RDS works with Matched Filter contributed by Tomneda&lt;br/&gt;&lt;br/&gt;RDS 2: RDS works with a classic approach of detecting the phases of the RDS signal&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The state, i.e. the setting of the selector, is maintained between program invocations&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Select RDS decoding:&lt;/p&gt;&lt;p&gt;RDS OFF: RDS is off at all&lt;/p&gt;&lt;p&gt;RDS 1: RDS works with a matched filter recognition based on cuteSDR&lt;br/&gt;&lt;br/&gt;RDS 2: RDS works with matched Filter and M&amp;amp;M time synchronizer contributed by Tomneda&lt;br/&gt;&lt;br/&gt;RDS 3: RDS works with a classic approach of detecting the phases of the RDS signal&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;The state, i.e. the setting of the selector, is maintained between program invocations&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<item>
<property name="text">
Expand Down
4 changes: 3 additions & 1 deletion includes/rds/rds-decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include "rds-blocksynchronizer.h"
#include "rds-groupdecoder.h"
#include "costas.h"
#include "agc.h"

class RadioInterface;
class rdsDecoder_1;
Expand All @@ -60,7 +61,7 @@ Q_OBJECT
RDS_OFF,
RDS_1,
RDS_2,
RDS_3
RDS_3
};

bool doDecode (const DSPCOMPLEX,
Expand All @@ -72,6 +73,7 @@ Q_OBJECT
RDSGroup my_rdsGroup;
rdsGroupDecoder my_rdsGroupDecoder;
rdsBlockSynchronizer my_rdsBlockSync;
AGC my_AGC;
Costas my_costas;
rdsDecoder_1 *decoder_1;
rdsDecoder_2 *decoder_2;
Expand Down
4 changes: 4 additions & 0 deletions includes/various/costas.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ class Costas {

inline
DSPCOMPLEX process_sample (const DSPCOMPLEX z) {
#ifdef DO_STEREO_SEPARATION_TEST
return z; // do nothing here
#endif

const DSPCOMPLEX r = z * std::exp (DSPCOMPLEX (0, -phase));
const float error = real (r) * imag (r);

Expand Down
2 changes: 1 addition & 1 deletion src/fm/fm-processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,7 @@ void fmProcessor::process_signal_with_rds (const float demod,
float rdsBaseBp = rdsBandPassFilter. Pass (demod);
std::complex<float> rdsBaseHilb =
rdsHilbertFilter. Pass (rdsBaseBp);
float thePhase = 3 * rdsPhaseBuffer [rdsPhaseIndex];
float thePhase = 3 * (rdsPhaseBuffer [rdsPhaseIndex] + PILOTTESTDELAY);
rdsPhaseBuffer [rdsPhaseIndex] = currentPilotPhase;
rdsPhaseIndex = (rdsPhaseIndex + 1) % RDS_SAMPLE_DELAY;
//
Expand Down
11 changes: 5 additions & 6 deletions src/rds/ebu-codetables.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ const char * const pty_table[][2] = {
{"Alarm", "Emergency"}
};

uint16_t pty_locale = 0;
// set to 0 for Europe (1 for USA) which will use first column instead


// mapping from EBU code tables to 16 bit codes for QChar

Expand All @@ -62,8 +59,10 @@ const uint16_t EBU_E1[16][14] = {
};

uint16_t mapEBUtoUnicode(uint8_t alfabet, uint8_t character) {
uint8_t columnnibble = (character & 0xF0) >> 4;
uint8_t rownibble = character & 0x0F;
int8_t columnnibble = ((character & 0xF0) >> 4) - 2;
int8_t rownibble = character & 0x0F;
(void)alfabet;
return EBU_E1 [rownibble][columnnibble - 2];
if (columnnibble < 0)
return ' '; // e.g. when END_OF_RADIO_TEXT is received
return EBU_E1 [rownibble][columnnibble];
}
10 changes: 1 addition & 9 deletions src/rds/rds-decoder-1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@
* RDS is a bpsk-like signal, with a baudrate 1187.5
* on a carrier of 3 * 19 k.
* 48 cycles per bit, 1187.5 bits per second.
* With a reduced sample rate of 19k this would mean
* 19000 / 1187.5 samples per bit, i.e. 16
* samples per bit.
*/

rdsDecoder_1::rdsDecoder_1 (RadioInterface *myRadio,
Expand Down Expand Up @@ -71,12 +68,7 @@ float synchronizerSamples;
rdsKernel. resize (rdsBufferSize);
rdsKernel [length] = 0;
//
//
// While the original samplerate (24000) gave a perfect match,
// the samplerate as changed by Tomneda (19000) gave 4 "inf"
// values (that is probably why tomneda was not content with
// the results of the match).
// To catch the inf values, I at first dded an "isinf" test,
// To catch the inf values, I at first addded an "isinf" test,
// this "isinf" check was with the "fast math" option
// in the "pro" file disregarded.
// Anyway, a minor mod in the formula, changing 64 to 64.01, solved
Expand Down
28 changes: 10 additions & 18 deletions src/rds/rds-decoder-2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,15 @@ constexpr float RDS_BITCLK_HZ = 1187.5;
* RDS is a bpsk-like signal, with a baudrate 1187.5
* on a carrier of 3 * 19 k.
* 48 cycles per bit, 1187.5 bits per second.
* With a reduced sample rate of 19k this would mean
* 19000 / 1187.5 samples per bit, i.e. 16
* samples per bit.
*/
rdsDecoder_2::rdsDecoder_2 (RadioInterface *myRadio,
rdsDecoder_2::rdsDecoder_2 (RadioInterface *myRadio,
int32_t rate):
my_AGC (2e-3f, 0.38f, 9.0f),
my_Costas (rate, 1.0f / 16.0f, 0.02f / 16.0f, 10.0f)
{
my_Costas (rate, 1.0f, 0.02f, 10.0f) {

this -> myRadioInterface = myRadio;
this -> sampleRate = rate;

this -> samplesPerSymbol = ceil (rate / (float)RDS_BITCLK_HZ);
this -> samplesPerSymbol = ((float)rate / (float)RDS_BITCLK_HZ);
for (int i = 0; i < 3; i ++) {
sampleBuffer [i] = std::complex<float> (0, 0);
sampleBufferRail [i] = std::complex<float> (0, 0);
Expand All @@ -62,10 +57,9 @@ constexpr float RDS_BITCLK_HZ = 1187.5;
this -> sampleCount = 0;

// Tomneda: a double inverted pulse (manchester code)
// as matched filter is not working in my opinion
// (got also no good results) <-- since you ruined the filter
// so I use a matched RRC filter design with
// Ts = 1/(2 * 1187.5Hz), one side of the bi-phase puls
// as matched filter is not working with this M&M time sync variation.
// So I use a matched RRC filter design with Ts = 1/(2 * 1187.5Hz),
// one side of the bi-phase pulse.
my_matchedFltKernelVec =
ShapingFilter ().
root_raised_cosine (1.0, sampleRate,
Expand All @@ -80,7 +74,8 @@ constexpr float RDS_BITCLK_HZ = 1187.5;
my_matchedFltBufIdx = 0;
}

rdsDecoder_2::~rdsDecoder_2 () {
rdsDecoder_2::~rdsDecoder_2 () {
//symsync_crcf_destroy(q);
}

DSPCOMPLEX rdsDecoder_2::doMatchFiltering (DSPCOMPLEX v) {
Expand All @@ -107,11 +102,9 @@ std::complex<float> r;

v = doMatchFiltering (v);
v = my_AGC. process_sample (v);
#ifndef DO_STEREO_SEPARATION_TEST
v = my_Costas. process_sample (v);
#endif

if (process_sample (v, r)) {
// this runs 19000/16 = 1187.5 1/s times
r = my_Costas. process_sample (r);
bool theBit = (real (r) >= 0);
*d = theBit ^ previousBit;
previousBit = theBit;
Expand All @@ -122,7 +115,6 @@ std::complex<float> r;
}

bool rdsDecoder_2::process_sample (const DSPCOMPLEX iZ, DSPCOMPLEX &oZ) {

sampleBuffer [0] = sampleBuffer [1];
sampleBuffer [1] = sampleBuffer [2];
sampleBuffer [2] = iZ;
Expand Down
3 changes: 0 additions & 3 deletions src/rds/rds-decoder-3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@
* RDS is a bpsk-like signal, with a baudrate 1187.5
* on a carrier of 3 * 19 k.
* 48 cycles per bit, 1187.5 bits per second.
* With a reduced sample rate of 19k this would mean
* 19000 / 1187.5 samples per bit, i.e. 16
* samples per bit.
*/
rdsDecoder_3::rdsDecoder_3 (RadioInterface *myRadio,
int32_t rate,
Expand Down
11 changes: 6 additions & 5 deletions src/rds/rds-decoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
int32_t rate):
my_rdsBlockSync (myRadioInterface),
my_rdsGroupDecoder (myRadioInterface),
my_AGC (2e-3f, 0.38f, 9.0f),
my_costas (rate, 1.0f / 16.0f,
0.02f/16.0f, 10.0f) {
decoder_1 = new rdsDecoder_1 (myRadioInterface, rate);
Expand Down Expand Up @@ -68,15 +69,14 @@ void rdsDecoder::reset () {
bool rdsDecoder::doDecode (DSPCOMPLEX v,
DSPCOMPLEX *m,
ERdsMode mode, int ptyLocale) {
// this is called typ. 19000 1/s
DSPCOMPLEX r;
// this is called typ. 24000 1/s
bool b;
uint8_t theBit;

v = my_costas. process_sample (v);
switch (mode) {
case rdsDecoder::ERdsMode::RDS_1:
*m = v * 4.0f;
v = my_costas. process_sample (v);
*m = my_AGC. process_sample(v);
b = decoder_1 -> doDecode (real (v), &theBit);
if (b)
processBit (theBit, ptyLocale);
Expand All @@ -89,7 +89,8 @@ uint8_t theBit;
return b;

case rdsDecoder::ERdsMode::RDS_3:
*m = v * 4.0f;
v = my_costas. process_sample (v);
*m = my_AGC. process_sample(v);
b = decoder_3 -> doDecode (real (v), &theBit);
if (b)
processBit (theBit, ptyLocale);
Expand Down