diff --git a/src/pifmrds/control_pipe.c b/src/pifmrds/control_pipe.c index f518d88..83c4a7f 100644 --- a/src/pifmrds/control_pipe.c +++ b/src/pifmrds/control_pipe.c @@ -152,6 +152,11 @@ ResultAndArg poll_control_pipe(int log) { printf("Wrong PTY identifier! The PTY range is 0 - 31.\n"); } resarg.res = CONTROL_PIPE_PTY_SET; + } else if(fifo[0] == 'E' && fifo[1] == 'C' && fifo[2] == 'C') { + arg[3] = 0; + set_rds_ecc((uint16_t) strtol(arg, NULL, 16)); + if(log==1) printf("ECC set to: \"%s\"\n", arg); + resarg.res = CONTROL_PIPE_GENERIC_SET; } else if(fifo[0] == 'P' && fifo[1] == 'W' && fifo[2] == 'R') { int power_level = atoi(arg); resarg.arg_int = power_level; diff --git a/src/pifmrds/fm_mpx.c b/src/pifmrds/fm_mpx.c index e3ddc95..9cd07af 100644 --- a/src/pifmrds/fm_mpx.c +++ b/src/pifmrds/fm_mpx.c @@ -48,10 +48,7 @@ float carrier_38[] = {0.0, 0.8660254037844386, 0.8660254037844388, 1.22464679914 float carrier_19[] = {0.0, 0.5, 0.8660254037844386, 1.0, 0.8660254037844388, 0.5, 1.2246467991473532e-16, -0.5, -0.8660254037844384, -1.0, -0.8660254037844386, -0.5}; -float carrier_3125[] = {0.0, 0.7586133425663026, 0.9885355334735083, 0.5295297022607088, -0.29851481100169425, -0.918519035014914, -0.898390981891979, -0.2521582503964708}; // sine wave - int phase_38 = 0; -int phase_3125 = 0; int phase_19 = 0; float downsample_factor; @@ -349,21 +346,14 @@ int fm_mpx_get_samples(float *mpx_buffer, fm_mpx_data *data) { // Generate the stereo mpx if(channels == 2 && !data->dstereo) { - if(1) { - // 4.5 and 0.9 are the volumes, thats because we dont have 75000 khz of deviation, instead we have 7500 khz, so that needs to be louder by 10 times than normal - mpx_buffer[i] += 4.5*(out_left+out_right) + // Stereo sum signal - 4.5 * carrier_38[phase_38] * (out_left-out_right) + // Stereo difference signal - 0.9*carrier_19[phase_19]; // Stereo pilot tone - phase_19++; - phase_38++; - if(phase_19 >= 12) phase_19 = 0; - if(phase_38 >= 6) phase_38 = 0; - } else { // polar stereo (https://forums.stereotool.com/viewtopic.php?t=6233, https://personal.utdallas.edu/~dlm/3350%20comm%20sys/ITU%20std%20on%20FM%20--%20R-REC-BS.450-3-200111-I!!PDF-E.pdf) - mpx_buffer[i] += 4.5*(out_left+out_right) + // Stereo sum signal (L+R) - 4.5 * carrier_3125[phase_3125] * (out_left-out_right); // Stereo difference signal - phase_3125++; - if(phase_3125 >= 8) phase_3125 = 0; - } + // 4.5 and 0.9 are the volumes, thats because we dont have 75000 khz of deviation, instead we have 7500 khz, so that needs to be louder by 10 times than normal + mpx_buffer[i] += 4.5*(out_left+out_right) + // Stereo sum signal + 4.5 * carrier_38[phase_38] * (out_left-out_right) + // Stereo difference signal + 0.9*carrier_19[phase_19]; // Stereo pilot tone + phase_19++; + phase_38++; + if(phase_19 >= 12) phase_19 = 0; + if(phase_38 >= 6) phase_38 = 0; } else if(channels == 1 || data->dstereo) { if(data->generate_multiplex) { diff --git a/src/pifmrds/pi_fm_rds.cpp b/src/pifmrds/pi_fm_rds.cpp index f0e3459..c348cbe 100644 --- a/src/pifmrds/pi_fm_rds.cpp +++ b/src/pifmrds/pi_fm_rds.cpp @@ -43,30 +43,31 @@ typedef struct tx_data { uint32_t carrier_freq; char *audio_file; uint16_t pi; + uint16_t ecc; char *ps; char *rt; char *control_pipe; - int pty; + uint8_t pty; int af_array[100]; - int raw; - int drds; - double preemp; + uint8_t raw; + uint8_t drds; + float preemp; int power; int rawSampleRate; int rawChannels; int deviation; - int ta; - int tp; + uint8_t ta; + uint8_t tp; float cutoff_freq; float audio_gain; float compressor_decay; float compressor_attack; float compressor_max_gain_recip; - int enablecompressor; - int rds_ct_enabled; + uint8_t enablecompressor; + uint8_t rds_ct_enabled; float rds_volume; - int disablestereo; - int log; + uint8_t disablestereo; + uint8_t log; float limiter_threshold; } tx_data; @@ -111,6 +112,7 @@ int tx(tx_data *data) { // Initialize the RDS modulator char myps[9] = {0}; set_rds_pi(data->pi); + set_rds_ecc(data->ecc); set_rds_ps(data->ps); set_rds_rt(data->rt); set_rds_pty(data->pty); @@ -129,7 +131,7 @@ int tx(tx_data *data) { if(drds == 1) { printf("RDS Disabled (you can enable with control fifo with the RDS command)\n"); } else { - printf("PI: %04X, PS: \"%s\".\n", data->pi, data->ps); + printf("PI: %04X, ECC: %02X, PS: \"%s\".\n", data->pi, data->ecc, data->ps); printf("RT: \"%s\"\n", data->rt); if(data->af_array[0]) { @@ -226,6 +228,7 @@ int main(int argc, char **argv) { .carrier_freq = 100000000, .audio_file = NULL, .pi = 0x00ff, + .ecc = 0x0, .ps = "Pi-FmSa", .rt = "Broadcasting on a Raspberry Pi: Simply Advanced", .control_pipe = NULL, @@ -275,6 +278,9 @@ int main(int argc, char **argv) { } else if(strcmp("-pi", arg)==0 && param != NULL) { i++; data.pi = atoi(param); + } else if(strcmp("-ecc", arg)==0 && param != NULL) { + i++; + data.ecc = atoi(param); } else if(strcmp("-ps", arg)==0 && param != NULL) { i++; data.ps = param; @@ -393,7 +399,7 @@ int main(int argc, char **argv) { } else { fatal("Unrecognised argument: %s.\n" - "Syntax: pi_fm_rds [-freq freq] [-audio file] [-pi pi_code]\n" + "Syntax: pi_fm_rds [-freq freq] [-audio file] [-pi pi_code] [-ecc ecc_code]\n" " [-ps ps_text] [-rt rt_text] [-ctl control_pipe] [-pty program_type] [-raw play raw audio from stdin] [-disablerds] [-af alt freq] [-preemphasis us] [-rawchannels when using the raw option you can change this] [-rawsamplerate same business] [-deviation the deviation, default is 75000] [-tp] [-ta]\n", arg); } } diff --git a/src/pifmrds/rds.c b/src/pifmrds/rds.c index a2103d3..ed0239d 100644 --- a/src/pifmrds/rds.c +++ b/src/pifmrds/rds.c @@ -30,6 +30,7 @@ float carrier_57[] = {0.0, 1.0, 1.2246467991473532e-16, -1.0}; // sine wave at 5 struct { uint16_t pi; + uint16_t ecc; int ta; int pty; int tp; @@ -145,16 +146,21 @@ void get_rds_group(int *buffer, int stereo, int ct_clock_enabled) { //ptyn? blocks[3] = rds_params.ps[ps_state*2] << 8 | rds_params.ps[ps_state*2+1]; ps_state++; if(ps_state >= 4) ps_state = 0; - } else { // Type 2A groups + } else if(state < 8) { // Type 2A groups blocks[1] = 0x2000 | rds_params.tp << 10 | rds_params.pty << 5 | rds_params.ab << 4 | rt_state; blocks[2] = rds_params.rt[rt_state*4+0] << 8 | rds_params.rt[rt_state*4+1]; blocks[3] = rds_params.rt[rt_state*4+2] << 8 | rds_params.rt[rt_state*4+3]; rt_state++; if(rt_state >= 16) rt_state = 0; + } else { + blocks[1] = 0x1000 | rds_params.tp << 10 | rds_params.pty << 5; + blocks[2] = rds_params.ecc; // Things like LIC would require the first 1-3 bits set, but ecc has just 0s there + // block 3 unused } state++; - if(state >= 8) state = 0; + if(state >= 8 && rds_params.ecc == 0) state = 0; + if(state >= 9 && rds_params.ecc != 0) state = 0; } // Calculate the checkword for each block and emit the bits @@ -287,3 +293,7 @@ void set_rds_ms(int ms) { void set_rds_ab(int ab) { rds_params.ab = ab; } + +void set_rds_ecc(uint16_t ecc) { + rds_params.ecc = ecc; +} diff --git a/src/pifmrds/rds.h b/src/pifmrds/rds.h index 829435c..b4013e5 100644 --- a/src/pifmrds/rds.h +++ b/src/pifmrds/rds.h @@ -49,6 +49,6 @@ extern void set_rds_af(int *af_array); extern void set_rds_tp(int tp); extern void set_rds_ms(int ms); extern void set_rds_ab(int ab); - +extern void set_rds_ecc(uint16_t ecc); #endif /* RDS_H */ \ No newline at end of file diff --git a/src/pifmrds/rds_test.cpp b/src/pifmrds/rds_test.cpp index 3d1a974..c73643f 100644 --- a/src/pifmrds/rds_test.cpp +++ b/src/pifmrds/rds_test.cpp @@ -10,9 +10,10 @@ extern "C" int main() { set_rds_pi(0xff); set_rds_ps("TEST"); + set_rds_ecc(0xFF); int af_array[] = {3, 2, 1, 0}; set_rds_af(af_array); - for(int i = 0; i < 32; i++) { + for(int i = 0; i < 10; i++) { int buffer[BITS_PER_GROUP]; get_rds_group(buffer, 0, 0); for(int j = 0; j < BITS_PER_GROUP; j++) {