diff --git a/build/Makefile b/build/Makefile index b940a77..d3000a6 100644 --- a/build/Makefile +++ b/build/Makefile @@ -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) diff --git a/src/broadcast_fm/broadcast_fm.c b/src/broadcast_fm/broadcast_fm.c index 5c4a397..5c58399 100644 --- a/src/broadcast_fm/broadcast_fm.c +++ b/src/broadcast_fm/broadcast_fm.c @@ -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 | +// |___________| +// // // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/src/broadcast_fm/rds.c b/src/broadcast_fm/rds.c index a3a95ec..3e8a401 100644 --- a/src/broadcast_fm/rds.c +++ b/src/broadcast_fm/rds.c @@ -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; } diff --git a/src/broadcast_fm/rds.h b/src/broadcast_fm/rds.h index 5338265..cfdf9bf 100644 --- a/src/broadcast_fm/rds.h +++ b/src/broadcast_fm/rds.h @@ -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); diff --git a/src/common/modulator.c b/src/common/modulator.c index ae5654c..4e16593 100644 --- a/src/common/modulator.c +++ b/src/common/modulator.c @@ -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; diff --git a/src/common/modulator.h b/src/common/modulator.h index 32fb3f4..1ba4060 100644 --- a/src/common/modulator.h +++ b/src/common/modulator.h @@ -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_