ecc
This commit is contained in:
parent
5df55ed946
commit
cf8dfdee1c
|
|
@ -152,6 +152,11 @@ ResultAndArg poll_control_pipe(int log) {
|
||||||
printf("Wrong PTY identifier! The PTY range is 0 - 31.\n");
|
printf("Wrong PTY identifier! The PTY range is 0 - 31.\n");
|
||||||
}
|
}
|
||||||
resarg.res = CONTROL_PIPE_PTY_SET;
|
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') {
|
} else if(fifo[0] == 'P' && fifo[1] == 'W' && fifo[2] == 'R') {
|
||||||
int power_level = atoi(arg);
|
int power_level = atoi(arg);
|
||||||
resarg.arg_int = power_level;
|
resarg.arg_int = power_level;
|
||||||
|
|
|
||||||
|
|
@ -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_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_38 = 0;
|
||||||
int phase_3125 = 0;
|
|
||||||
int phase_19 = 0;
|
int phase_19 = 0;
|
||||||
|
|
||||||
float downsample_factor;
|
float downsample_factor;
|
||||||
|
|
@ -349,21 +346,14 @@ int fm_mpx_get_samples(float *mpx_buffer, fm_mpx_data *data) {
|
||||||
|
|
||||||
// Generate the stereo mpx
|
// Generate the stereo mpx
|
||||||
if(channels == 2 && !data->dstereo) {
|
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
|
||||||
// 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
|
||||||
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
|
||||||
4.5 * carrier_38[phase_38] * (out_left-out_right) + // Stereo difference signal
|
0.9*carrier_19[phase_19]; // Stereo pilot tone
|
||||||
0.9*carrier_19[phase_19]; // Stereo pilot tone
|
phase_19++;
|
||||||
phase_19++;
|
phase_38++;
|
||||||
phase_38++;
|
if(phase_19 >= 12) phase_19 = 0;
|
||||||
if(phase_19 >= 12) phase_19 = 0;
|
if(phase_38 >= 6) phase_38 = 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;
|
|
||||||
}
|
|
||||||
} else if(channels == 1 || data->dstereo)
|
} else if(channels == 1 || data->dstereo)
|
||||||
{
|
{
|
||||||
if(data->generate_multiplex) {
|
if(data->generate_multiplex) {
|
||||||
|
|
|
||||||
|
|
@ -43,30 +43,31 @@ typedef struct tx_data {
|
||||||
uint32_t carrier_freq;
|
uint32_t carrier_freq;
|
||||||
char *audio_file;
|
char *audio_file;
|
||||||
uint16_t pi;
|
uint16_t pi;
|
||||||
|
uint16_t ecc;
|
||||||
char *ps;
|
char *ps;
|
||||||
char *rt;
|
char *rt;
|
||||||
char *control_pipe;
|
char *control_pipe;
|
||||||
int pty;
|
uint8_t pty;
|
||||||
int af_array[100];
|
int af_array[100];
|
||||||
int raw;
|
uint8_t raw;
|
||||||
int drds;
|
uint8_t drds;
|
||||||
double preemp;
|
float preemp;
|
||||||
int power;
|
int power;
|
||||||
int rawSampleRate;
|
int rawSampleRate;
|
||||||
int rawChannels;
|
int rawChannels;
|
||||||
int deviation;
|
int deviation;
|
||||||
int ta;
|
uint8_t ta;
|
||||||
int tp;
|
uint8_t tp;
|
||||||
float cutoff_freq;
|
float cutoff_freq;
|
||||||
float audio_gain;
|
float audio_gain;
|
||||||
float compressor_decay;
|
float compressor_decay;
|
||||||
float compressor_attack;
|
float compressor_attack;
|
||||||
float compressor_max_gain_recip;
|
float compressor_max_gain_recip;
|
||||||
int enablecompressor;
|
uint8_t enablecompressor;
|
||||||
int rds_ct_enabled;
|
uint8_t rds_ct_enabled;
|
||||||
float rds_volume;
|
float rds_volume;
|
||||||
int disablestereo;
|
uint8_t disablestereo;
|
||||||
int log;
|
uint8_t log;
|
||||||
float limiter_threshold;
|
float limiter_threshold;
|
||||||
} tx_data;
|
} tx_data;
|
||||||
|
|
||||||
|
|
@ -111,6 +112,7 @@ int tx(tx_data *data) {
|
||||||
// Initialize the RDS modulator
|
// Initialize the RDS modulator
|
||||||
char myps[9] = {0};
|
char myps[9] = {0};
|
||||||
set_rds_pi(data->pi);
|
set_rds_pi(data->pi);
|
||||||
|
set_rds_ecc(data->ecc);
|
||||||
set_rds_ps(data->ps);
|
set_rds_ps(data->ps);
|
||||||
set_rds_rt(data->rt);
|
set_rds_rt(data->rt);
|
||||||
set_rds_pty(data->pty);
|
set_rds_pty(data->pty);
|
||||||
|
|
@ -129,7 +131,7 @@ int tx(tx_data *data) {
|
||||||
if(drds == 1) {
|
if(drds == 1) {
|
||||||
printf("RDS Disabled (you can enable with control fifo with the RDS command)\n");
|
printf("RDS Disabled (you can enable with control fifo with the RDS command)\n");
|
||||||
} else {
|
} 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);
|
printf("RT: \"%s\"\n", data->rt);
|
||||||
|
|
||||||
if(data->af_array[0]) {
|
if(data->af_array[0]) {
|
||||||
|
|
@ -226,6 +228,7 @@ int main(int argc, char **argv) {
|
||||||
.carrier_freq = 100000000,
|
.carrier_freq = 100000000,
|
||||||
.audio_file = NULL,
|
.audio_file = NULL,
|
||||||
.pi = 0x00ff,
|
.pi = 0x00ff,
|
||||||
|
.ecc = 0x0,
|
||||||
.ps = "Pi-FmSa",
|
.ps = "Pi-FmSa",
|
||||||
.rt = "Broadcasting on a Raspberry Pi: Simply Advanced",
|
.rt = "Broadcasting on a Raspberry Pi: Simply Advanced",
|
||||||
.control_pipe = NULL,
|
.control_pipe = NULL,
|
||||||
|
|
@ -275,6 +278,9 @@ int main(int argc, char **argv) {
|
||||||
} else if(strcmp("-pi", arg)==0 && param != NULL) {
|
} else if(strcmp("-pi", arg)==0 && param != NULL) {
|
||||||
i++;
|
i++;
|
||||||
data.pi = atoi(param);
|
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) {
|
} else if(strcmp("-ps", arg)==0 && param != NULL) {
|
||||||
i++;
|
i++;
|
||||||
data.ps = param;
|
data.ps = param;
|
||||||
|
|
@ -393,7 +399,7 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fatal("Unrecognised argument: %s.\n"
|
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);
|
" [-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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ float carrier_57[] = {0.0, 1.0, 1.2246467991473532e-16, -1.0}; // sine wave at 5
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint16_t pi;
|
uint16_t pi;
|
||||||
|
uint16_t ecc;
|
||||||
int ta;
|
int ta;
|
||||||
int pty;
|
int pty;
|
||||||
int tp;
|
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];
|
blocks[3] = rds_params.ps[ps_state*2] << 8 | rds_params.ps[ps_state*2+1];
|
||||||
ps_state++;
|
ps_state++;
|
||||||
if(ps_state >= 4) ps_state = 0;
|
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[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[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];
|
blocks[3] = rds_params.rt[rt_state*4+2] << 8 | rds_params.rt[rt_state*4+3];
|
||||||
rt_state++;
|
rt_state++;
|
||||||
if(rt_state >= 16) rt_state = 0;
|
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++;
|
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
|
// 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) {
|
void set_rds_ab(int ab) {
|
||||||
rds_params.ab = ab;
|
rds_params.ab = ab;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_rds_ecc(uint16_t ecc) {
|
||||||
|
rds_params.ecc = ecc;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,6 @@ extern void set_rds_af(int *af_array);
|
||||||
extern void set_rds_tp(int tp);
|
extern void set_rds_tp(int tp);
|
||||||
extern void set_rds_ms(int ms);
|
extern void set_rds_ms(int ms);
|
||||||
extern void set_rds_ab(int ab);
|
extern void set_rds_ab(int ab);
|
||||||
|
extern void set_rds_ecc(uint16_t ecc);
|
||||||
|
|
||||||
#endif /* RDS_H */
|
#endif /* RDS_H */
|
||||||
|
|
@ -10,9 +10,10 @@ extern "C"
|
||||||
int main() {
|
int main() {
|
||||||
set_rds_pi(0xff);
|
set_rds_pi(0xff);
|
||||||
set_rds_ps("TEST");
|
set_rds_ps("TEST");
|
||||||
|
set_rds_ecc(0xFF);
|
||||||
int af_array[] = {3, 2, 1, 0};
|
int af_array[] = {3, 2, 1, 0};
|
||||||
set_rds_af(af_array);
|
set_rds_af(af_array);
|
||||||
for(int i = 0; i < 32; i++) {
|
for(int i = 0; i < 10; i++) {
|
||||||
int buffer[BITS_PER_GROUP];
|
int buffer[BITS_PER_GROUP];
|
||||||
get_rds_group(buffer, 0, 0);
|
get_rds_group(buffer, 0, 0);
|
||||||
for(int j = 0; j < BITS_PER_GROUP; j++) {
|
for(int j = 0; j < BITS_PER_GROUP; j++) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue