mirror of
https://github.com/jfdelnero/rf-tools.git
synced 2024-11-24 12:48:39 -05:00
The RDS encoder and modulator is now working ! :)
This commit is contained in:
parent
ce0cb6448f
commit
3b959d2776
@ -28,7 +28,7 @@ EXEC=broadcast_fm rf_jammer
|
||||
|
||||
all: $(EXEC)
|
||||
|
||||
broadcast_fm: broadcast_fm.o rds.o wave.o modulator.o FIR_Audio_Filter_Filter.o FM_Baseband_Filter.o AudioPreemphasis_Filter.o hxcmod.o rand_gen.o
|
||||
broadcast_fm: broadcast_fm.o rds.o rds_stream_dump.o wave.o modulator.o FIR_Audio_Filter_Filter.o FM_Baseband_Filter.o AudioPreemphasis_Filter.o hxcmod.o rand_gen.o
|
||||
$(CC) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
rf_jammer: rf_jammer.o wave.o modulator.o rand_gen.o
|
||||
@ -43,6 +43,9 @@ rf_jammer.o: ../src/rf_jammer/rf_jammer.c
|
||||
rds.o: ../src/broadcast_fm/rds.c
|
||||
$(CC) -o $@ -c $< $(CFLAGS)
|
||||
|
||||
rds_stream_dump.o: ../src/broadcast_fm/rds_stream_dump.c
|
||||
$(CC) -o $@ -c $< $(CFLAGS)
|
||||
|
||||
utils.o: ../src/common/utils.c
|
||||
$(CC) -o $@ -c $< $(CFLAGS)
|
||||
|
||||
|
@ -96,7 +96,7 @@
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// Current software design :
|
||||
//
|
||||
// Mod player / Left Audio -> Preemphasis (FIR) -> \ / -> Left + Right -> 15KHz low pass (FIR) -------------------------------|
|
||||
// Mod player / Left Audio -> Preemphasis (FIR) -> \ / -> Left + Right -> 15KHz low pass (FIR) >------------------------------|
|
||||
// Sound \/ |
|
||||
// generator /\ |
|
||||
// \ Right Audio -> Preemphasis (FIR) -> / \ -> Left - Right -> 15KHz low pass (FIR) |
|
||||
@ -108,7 +108,17 @@
|
||||
// | 38KHz Osc |
|
||||
// | (|) (These oscillators |
|
||||
// | (|) must be kept in phase) |
|
||||
// 19KHz Pilot Osc ------------------|
|
||||
// | 19KHz Pilot Osc >-----------------+
|
||||
// | (|) |
|
||||
// | (|) (57KHz DSB-SC modulated)|
|
||||
// | 57KHz Osc-->|MUL|>-----------------+
|
||||
// | ^
|
||||
// ____ v_____ |
|
||||
// | | |
|
||||
// | RDS |>----
|
||||
// | Generator |
|
||||
// |___________|
|
||||
//
|
||||
//
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -31,6 +31,24 @@
|
||||
|
||||
#include "modulator.h"
|
||||
#include "rds.h"
|
||||
#include "rds_stream_dump.h"
|
||||
|
||||
const uint16_t crc_group_xor[]=
|
||||
{
|
||||
0xFC, // A
|
||||
0x198, // B
|
||||
0x168, // C
|
||||
0x1B4, // D
|
||||
0x350 // C'
|
||||
};
|
||||
|
||||
const uint16_t rds_codes[]=
|
||||
{
|
||||
0xF849,
|
||||
0x0CE8,
|
||||
0xF849,
|
||||
0x0000 // Char code.
|
||||
};
|
||||
|
||||
void init_rds_encoder(rds_stat * stat,int sample_rate)
|
||||
{
|
||||
@ -38,6 +56,7 @@ void init_rds_encoder(rds_stat * stat,int sample_rate)
|
||||
stat->bit_rate = RDS_BIT_RATE;
|
||||
stat->old_pilot_phase = 0;
|
||||
stat->sample_rate = sample_rate;
|
||||
strcpy(stat->station_name,"- RDS - - RDS - - RDS - - RDS - --TEST----TEST----TEST----TEST----TEST----TEST--\n");
|
||||
}
|
||||
|
||||
int rds_differential_encoder(rds_stat * stat)
|
||||
@ -47,30 +66,147 @@ int rds_differential_encoder(rds_stat * stat)
|
||||
return stat->current_diff_dat_state;
|
||||
}
|
||||
|
||||
uint32_t rds_crc (uint16_t data)
|
||||
{
|
||||
int i;
|
||||
uint16_t crc = 0;
|
||||
int crc_msb;
|
||||
|
||||
for(i=0; i<16; i++)
|
||||
{
|
||||
crc_msb = (crc >> (10-1)) & 1;
|
||||
|
||||
crc <<= 1;
|
||||
if( crc_msb ^ (data >> 15 ) )
|
||||
{
|
||||
crc ^= 0x1B9;
|
||||
}
|
||||
|
||||
data <<= 1;
|
||||
}
|
||||
|
||||
return crc & 0x3FF;
|
||||
}
|
||||
|
||||
uint32_t encode_rds_bloc(uint16_t data, int group)
|
||||
{
|
||||
uint32_t word;
|
||||
|
||||
word = ((uint32_t)data)<<10;
|
||||
word |= (rds_crc (data) ^ crc_group_xor[group]);
|
||||
|
||||
//printf("rds(%d): dat:0x%.4X grp:0x%.4X 0x%.4X\n",group,data,word&0x3FF,word);
|
||||
|
||||
return word;
|
||||
}
|
||||
|
||||
int get_next_rds_bit(rds_stat * stat)
|
||||
{
|
||||
int dat;
|
||||
uint16_t rdsc;
|
||||
|
||||
#ifdef USE_RDS_STREAM_BIT
|
||||
if(!rds_stream_dump[stat->current_rds_code_index])
|
||||
{
|
||||
stat->current_rds_code_index = 0;
|
||||
dat = rds_stream_dump[stat->current_rds_code_index];
|
||||
}
|
||||
else
|
||||
dat = rds_stream_dump[stat->current_rds_code_index];
|
||||
|
||||
stat->current_rds_code_index++;
|
||||
|
||||
return dat;
|
||||
#endif
|
||||
|
||||
stat->current_bloc_index--;
|
||||
|
||||
if(stat->current_bloc_index<0)
|
||||
{
|
||||
// prepare next bloc
|
||||
|
||||
#ifdef USE_RDS_STREAM
|
||||
rdsc = rds_dump[stat->current_rds_code_index];
|
||||
stat->current_bloc = encode_rds_bloc(rdsc, stat->current_rds_code_index&3 );
|
||||
stat->current_rds_code_index++;
|
||||
|
||||
if(stat->current_rds_code_index >= 327*4 )
|
||||
{
|
||||
stat->current_rds_code_index = 0;
|
||||
}
|
||||
#else
|
||||
rdsc = rds_codes[stat->current_rds_code_index];
|
||||
if(rdsc)
|
||||
{
|
||||
if( stat->current_rds_code_index == 1)
|
||||
{
|
||||
stat->current_bloc = encode_rds_bloc(rdsc | (stat->station_name_index>>1),stat->current_rds_code_index );
|
||||
stat->current_rds_code_index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
stat->current_bloc = encode_rds_bloc(rdsc,stat->current_rds_code_index);
|
||||
stat->current_rds_code_index++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rdsc = stat->station_name[stat->station_name_index++];
|
||||
rdsc <<= 8;
|
||||
rdsc |= stat->station_name[stat->station_name_index++];
|
||||
|
||||
stat->current_bloc = encode_rds_bloc(rdsc,stat->current_rds_code_index);
|
||||
|
||||
if(!stat->station_name[stat->station_name_index])
|
||||
{
|
||||
stat->station_name_index = 0;
|
||||
}
|
||||
|
||||
stat->current_rds_code_index = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
stat->current_bloc_index = 25;
|
||||
}
|
||||
|
||||
if( (stat->current_bloc >> (stat->current_bloc_index)) & 0x1 )
|
||||
{
|
||||
dat = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
dat = 0;
|
||||
}
|
||||
|
||||
//printf("%d",dat);
|
||||
|
||||
return dat;
|
||||
}
|
||||
|
||||
double get_rds_bit_state(rds_stat * stat, double pilot_phase)
|
||||
{
|
||||
double sample;
|
||||
double phase_diff;
|
||||
|
||||
if(pilot_phase < stat->old_pilot_phase)
|
||||
phase_diff = (2*PI + pilot_phase) - stat->old_pilot_phase;
|
||||
phase_diff = ( 2.0 * PI - stat->old_pilot_phase) + pilot_phase;
|
||||
else
|
||||
phase_diff = pilot_phase - stat->old_pilot_phase;
|
||||
|
||||
if( phase_diff >= ((2*PI) / 3) )
|
||||
if( phase_diff >= ( ( 2.0 * PI ) / 3.0 ) ) // 19KHz period / 3 -> 57KHz
|
||||
{
|
||||
// New 57KHz tick clock
|
||||
stat->old_pilot_phase = pilot_phase;//+= ((2*PI) / 3);
|
||||
stat->old_pilot_phase += ( ( 2.0 * PI ) / 3.0 );
|
||||
|
||||
if(stat->old_pilot_phase >= (2*PI))
|
||||
stat->old_pilot_phase = 0;
|
||||
if(stat->old_pilot_phase >= ( 2.0 * PI ))
|
||||
stat->old_pilot_phase -= ( 2.0 * PI );
|
||||
|
||||
stat->cycles_count++;
|
||||
if(stat->cycles_count >= 16*2)
|
||||
if(stat->cycles_count >= 48)
|
||||
{
|
||||
stat->test++;
|
||||
|
||||
stat->ser_data_in = rand()&1;
|
||||
stat->ser_data_in = get_next_rds_bit(stat);
|
||||
|
||||
rds_differential_encoder(stat);
|
||||
|
||||
@ -80,13 +216,13 @@ double get_rds_bit_state(rds_stat * stat, double pilot_phase)
|
||||
}
|
||||
|
||||
// Delayed signal
|
||||
if(stat->cycles_count == 8*2)
|
||||
if(stat->cycles_count == 24)
|
||||
{
|
||||
stat->current_data_state = stat->current_diff_dat_state ^ 1;
|
||||
}
|
||||
}
|
||||
|
||||
#define FREQ_FILTER (1187.5*1.0)
|
||||
#define FREQ_FILTER (1187.5*0.50)
|
||||
|
||||
if(stat->current_data_state)
|
||||
{
|
||||
@ -113,7 +249,7 @@ double get_rds_bit_state(rds_stat * stat, double pilot_phase)
|
||||
}
|
||||
}
|
||||
|
||||
sample = ( cos( stat->phase ) * 3.0 );
|
||||
sample = ( cos( stat->phase ) * ( 5.0 ) );
|
||||
|
||||
return sample;
|
||||
}
|
||||
|
@ -40,6 +40,15 @@ typedef struct _rds_stat
|
||||
|
||||
int test;
|
||||
int cycles_count;
|
||||
|
||||
char station_name[256+1];
|
||||
int station_name_index;
|
||||
|
||||
uint32_t current_bloc;
|
||||
int current_bloc_index;
|
||||
|
||||
int current_rds_code_index;
|
||||
|
||||
}rds_stat;
|
||||
|
||||
void init_rds_encoder(rds_stat * stat,int sample_rate);
|
||||
|
@ -76,10 +76,10 @@ double f_get_next_sample(wave_gen * wg)
|
||||
|
||||
wg->phase += ( (2.0 * PI * wg->Frequency) / (double)wg->sample_rate );
|
||||
|
||||
if(wg->phase > (2.0 * PI) )
|
||||
if(wg->phase >= (2.0 * PI) )
|
||||
wg->phase -= (2.0 * PI);
|
||||
|
||||
if(wg->phase < (-2.0 * PI) )
|
||||
if(wg->phase <= (-2.0 * PI) )
|
||||
wg->phase += (2.0 * PI);
|
||||
|
||||
return sample;
|
||||
|
@ -30,7 +30,7 @@
|
||||
#if defined(M_PI)
|
||||
#define PI M_PI
|
||||
#else
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
#define PI ((double)(3.1415926535897932384626433832795))
|
||||
#endif
|
||||
|
||||
typedef struct iq_wave_gen_
|
||||
|
Loading…
Reference in New Issue
Block a user