mirror of
https://github.com/radio95-rnt/rds95.git
synced 2026-02-27 04:43:52 +01:00
add user defined groups for rds2
This commit is contained in:
2
.vscode/.server-controller-port.log
vendored
2
.vscode/.server-controller-port.log
vendored
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"port": 13452,
|
"port": 13452,
|
||||||
"time": 1744724934249,
|
"time": 1745323988035,
|
||||||
"version": "0.0.3"
|
"version": "0.0.3"
|
||||||
}
|
}
|
||||||
@@ -370,6 +370,39 @@ static void handle_udg(char *arg, char *pattern, RDSModulator* mod, char* output
|
|||||||
else strcpy(output, "/\0");
|
else strcpy(output, "/\0");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_udg2(char *arg, char *pattern, RDSModulator* mod, char* output) {
|
||||||
|
uint8_t all_scanned = 1, bad_format = 0;
|
||||||
|
uint16_t blocks[8][4];
|
||||||
|
int sets = 0;
|
||||||
|
char *ptr = arg;
|
||||||
|
|
||||||
|
while (sets < 8) {
|
||||||
|
int count = sscanf(ptr, "%4hx%4hx%4hx%4hx", &blocks[sets][0], &blocks[sets][1], &blocks[sets][2], &blocks[sets][3]);
|
||||||
|
if (count != 4) {
|
||||||
|
all_scanned = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sets++;
|
||||||
|
while (*ptr && *ptr != ',') ptr++;
|
||||||
|
if (*ptr == ',') ptr++;
|
||||||
|
else {
|
||||||
|
bad_format = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(pattern, "1") == 0) {
|
||||||
|
memcpy(&(mod->enc->data[mod->enc->program].udg1_rds2), &blocks, sets * sizeof(uint16_t[4]));
|
||||||
|
mod->enc->data[mod->enc->program].udg1_len_rds2 = sets;
|
||||||
|
} else if(strcmp(pattern, "2") == 0) {
|
||||||
|
memcpy(&(mod->enc->data[mod->enc->program].udg2_rds2), &blocks, sets * sizeof(uint16_t[4]));
|
||||||
|
mod->enc->data[mod->enc->program].udg2_len_rds2 = sets;
|
||||||
|
} else strcpy(output, "!\0");
|
||||||
|
if(bad_format) strcpy(output, "-\0");
|
||||||
|
else if(all_scanned) strcpy(output, "+\0");
|
||||||
|
else strcpy(output, "/\0");
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_rttype(char *arg, RDSModulator* mod, char* output) {
|
static void handle_rttype(char *arg, RDSModulator* mod, char* output) {
|
||||||
mod->enc->data[mod->enc->program].rt_type = atoi(arg);
|
mod->enc->data[mod->enc->program].rt_type = atoi(arg);
|
||||||
strcpy(output, "+\0");
|
strcpy(output, "+\0");
|
||||||
@@ -544,6 +577,7 @@ static const pattern_command_handler_t pattern_commands[] = {
|
|||||||
{"EON", "AF", handle_eonaf},
|
{"EON", "AF", handle_eonaf},
|
||||||
{"EON", "DT", handle_eondt},
|
{"EON", "DT", handle_eondt},
|
||||||
{"UDG", "", handle_udg},
|
{"UDG", "", handle_udg},
|
||||||
|
{"UDG2", "", handle_udg2},
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool process_command_table(const command_handler_t *table, int table_size,
|
static bool process_command_table(const command_handler_t *table, int table_size,
|
||||||
|
|||||||
45
src/rds.c
45
src/rds.c
@@ -507,53 +507,72 @@ static void get_rds_sequence_group(RDSEncoder* enc, RDSGroup *group, char* grp,
|
|||||||
get_rds_eon_group(enc, group);
|
get_rds_eon_group(enc, group);
|
||||||
goto group_coded;
|
goto group_coded;
|
||||||
case 'X':
|
case 'X':
|
||||||
|
if(stream != 0) {
|
||||||
|
udg_idx = enc->state[enc->program].udg_idxs_rds2[0];
|
||||||
|
group->a = enc->data[enc->program].udg1_rds2[udg_idx][0];
|
||||||
|
group->b = enc->data[enc->program].udg1_rds2[udg_idx][1];
|
||||||
|
group->c = enc->data[enc->program].udg1_rds2[udg_idx][2];
|
||||||
|
group->d = enc->data[enc->program].udg1_rds2[udg_idx][3];
|
||||||
|
enc->state[enc->program].udg_idxs_rds2[0]++;
|
||||||
|
if(enc->state[enc->program].udg_idxs_rds2[0] == enc->data[enc->program].udg1_len_rds2) enc->state[enc->program].udg_idxs_rds2[0] = 0;
|
||||||
|
group->is_type_b = (group->a == 0 && IS_TYPE_B(group->b));
|
||||||
|
break;
|
||||||
|
}
|
||||||
udg_idx = enc->state[enc->program].udg_idxs[0];
|
udg_idx = enc->state[enc->program].udg_idxs[0];
|
||||||
group->b = enc->data[enc->program].udg1[udg_idx][0];
|
group->b = enc->data[enc->program].udg1[udg_idx][0];
|
||||||
group->c = enc->data[enc->program].udg1[udg_idx][1];
|
group->c = enc->data[enc->program].udg1[udg_idx][1];
|
||||||
group->d = enc->data[enc->program].udg1[udg_idx][2];
|
group->d = enc->data[enc->program].udg1[udg_idx][2];
|
||||||
enc->state[enc->program].udg_idxs[0]++;
|
enc->state[enc->program].udg_idxs[0]++;
|
||||||
if(enc->state[enc->program].udg_idxs[0] == enc->data[enc->program].udg1_len) enc->state[enc->program].udg_idxs[0] = 0;
|
if(enc->state[enc->program].udg_idxs[0] == enc->data[enc->program].udg1_len) enc->state[enc->program].udg_idxs[0] = 0;
|
||||||
group->is_type_b = (group->a == 0 && IS_TYPE_B(group->b));
|
group->is_type_b = IS_TYPE_B(group->b);
|
||||||
goto group_coded;
|
break;
|
||||||
case 'Y':
|
case 'Y':
|
||||||
|
if(stream != 0) {
|
||||||
|
udg_idx = enc->state[enc->program].udg_idxs_rds2[1];
|
||||||
|
group->a = enc->data[enc->program].udg2_rds2[udg_idx][0];
|
||||||
|
group->b = enc->data[enc->program].udg2_rds2[udg_idx][1];
|
||||||
|
group->c = enc->data[enc->program].udg2_rds2[udg_idx][2];
|
||||||
|
group->d = enc->data[enc->program].udg2_rds2[udg_idx][3];
|
||||||
|
enc->state[enc->program].udg_idxs_rds2[1]++;
|
||||||
|
if(enc->state[enc->program].udg_idxs_rds2[1] == enc->data[enc->program].udg2_len_rds2) enc->state[enc->program].udg_idxs_rds2[1] = 0;
|
||||||
|
group->is_type_b = (group->a == 0 && IS_TYPE_B(group->b));
|
||||||
|
break;
|
||||||
|
}
|
||||||
udg_idx = enc->state[enc->program].udg_idxs[1];
|
udg_idx = enc->state[enc->program].udg_idxs[1];
|
||||||
group->b = enc->data[enc->program].udg2[udg_idx][0];
|
group->b = enc->data[enc->program].udg2[udg_idx][0];
|
||||||
group->c = enc->data[enc->program].udg2[udg_idx][1];
|
group->c = enc->data[enc->program].udg2[udg_idx][1];
|
||||||
group->d = enc->data[enc->program].udg2[udg_idx][2];
|
group->d = enc->data[enc->program].udg2[udg_idx][2];
|
||||||
enc->state[enc->program].udg_idxs[1]++;
|
enc->state[enc->program].udg_idxs[1]++;
|
||||||
if(enc->state[enc->program].udg_idxs[1] == enc->data[enc->program].udg2_len) enc->state[enc->program].udg_idxs[1] = 0;
|
if(enc->state[enc->program].udg_idxs[1] == enc->data[enc->program].udg2_len) enc->state[enc->program].udg_idxs[1] = 0;
|
||||||
group->is_type_b = (group->a == 0 && IS_TYPE_B(group->b));
|
group->is_type_b = IS_TYPE_B(group->b);
|
||||||
goto group_coded;
|
break;
|
||||||
case 'R':
|
case 'R':
|
||||||
if(enc->state[enc->program].rtp_oda == 0) get_rds_rtplus_group(enc, group);
|
if(enc->state[enc->program].rtp_oda == 0) get_rds_rtplus_group(enc, group);
|
||||||
else get_rds_rtp_oda_group(enc, group);
|
else get_rds_rtp_oda_group(enc, group);
|
||||||
enc->state[enc->program].rtp_oda ^= 1;
|
enc->state[enc->program].rtp_oda ^= 1;
|
||||||
goto group_coded;
|
break;
|
||||||
case 'P':
|
case 'P':
|
||||||
if(enc->state[enc->program].ert_oda == 0) get_rds_ertplus_group(enc, group);
|
if(enc->state[enc->program].ert_oda == 0) get_rds_ertplus_group(enc, group);
|
||||||
else get_rds_ertp_oda_group(enc, group);
|
else get_rds_ertp_oda_group(enc, group);
|
||||||
|
|
||||||
enc->state[enc->program].ert_oda ^= 1;
|
enc->state[enc->program].ert_oda ^= 1;
|
||||||
goto group_coded;
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
if(enc->state[enc->program].ert_oda == 0) get_rds_ert_group(enc, group);
|
if(enc->state[enc->program].ert_oda == 0) get_rds_ert_group(enc, group);
|
||||||
else get_rds_ert_oda_group(enc, group);
|
else get_rds_ert_oda_group(enc, group);
|
||||||
enc->state[enc->program].ert_oda ^= 1;
|
enc->state[enc->program].ert_oda ^= 1;
|
||||||
goto group_coded;
|
break;
|
||||||
case 'F':
|
case 'F':
|
||||||
get_rds_lps_group(enc, group);
|
get_rds_lps_group(enc, group);
|
||||||
goto group_coded;
|
break;
|
||||||
case 'T':
|
case 'T':
|
||||||
get_rds_fasttuning_group(enc, group);
|
get_rds_fasttuning_group(enc, group);
|
||||||
goto group_coded;
|
break;
|
||||||
case 'U':
|
case 'U':
|
||||||
if(enc->state[enc->program].af_oda == 0) get_oda_af_group(enc, group);
|
if(enc->state[enc->program].af_oda == 0) get_oda_af_group(enc, group);
|
||||||
else get_oda_af_oda_group(enc, group);
|
else get_oda_af_oda_group(enc, group);
|
||||||
enc->state[enc->program].af_oda ^= 1;
|
enc->state[enc->program].af_oda ^= 1;
|
||||||
goto group_coded;
|
break;
|
||||||
}
|
}
|
||||||
group_coded:
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t check_rds_good_group(RDSEncoder* enc, char* grp, uint8_t stream) {
|
static uint8_t check_rds_good_group(RDSEncoder* enc, char* grp, uint8_t stream) {
|
||||||
|
|||||||
@@ -101,10 +101,15 @@ typedef struct {
|
|||||||
|
|
||||||
uint8_t udg1_len : 4;
|
uint8_t udg1_len : 4;
|
||||||
uint8_t udg2_len : 4;
|
uint8_t udg2_len : 4;
|
||||||
|
uint8_t udg1_len_rds2 : 4;
|
||||||
|
uint8_t udg2_len_rds2 : 4;
|
||||||
|
|
||||||
uint16_t udg1[8][3];
|
uint16_t udg1[8][3];
|
||||||
uint16_t udg2[8][3];
|
uint16_t udg2[8][3];
|
||||||
|
|
||||||
|
uint16_t udg1_rds2[8][4];
|
||||||
|
uint16_t udg2_rds2[8][4];
|
||||||
|
|
||||||
RDSEON eon[4];
|
RDSEON eon[4];
|
||||||
} RDSData;
|
} RDSData;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -153,6 +158,7 @@ typedef struct {
|
|||||||
uint8_t data_ecc : 1;
|
uint8_t data_ecc : 1;
|
||||||
uint8_t grp_seq_idx[4];
|
uint8_t grp_seq_idx[4];
|
||||||
uint8_t udg_idxs[2];
|
uint8_t udg_idxs[2];
|
||||||
|
uint8_t udg_idxs_rds2[2];
|
||||||
|
|
||||||
uint8_t fasttuning_state : 3;
|
uint8_t fasttuning_state : 3;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user