#pragma once #include "common.h" #define LUA_USER_DATA 1024 /* The RDS error-detection code generator polynomial is * x^10 + x^8 + x^7 + x^5 + x^4 + x^3 + x^0 */ #define POLY 0x1B9 #define POLY_DEG 10 #define BLOCK_SIZE 16 #define GROUP_LENGTH 4 #define BITS_PER_GROUP (GROUP_LENGTH * (BLOCK_SIZE + POLY_DEG)) #define RDS_SAMPLE_RATE 4750 #define RT_LENGTH 64 #define PS_LENGTH 8 #define PTYN_LENGTH 8 #define LPS_LENGTH 32 #define DEFAULT_GRPSQC "002222XYOK" #define MAX_AFS 25 #define AF_CODE_FILLER 205 #define AF_CODE_NUM_AFS_BASE 224 #define AF_CODE_LFMF_FOLLOWS 250 #define PROGRAMS 3 #define EONs 4 // List of ODAs: https://www.nrscstandards.org/committees/dsm/archive/rds-oda-aids.pdf #define ODA_AID_ODAAF 0x6365 typedef struct { uint8_t num_entries : 6; uint8_t num_afs : 5; uint16_t afs[MAX_AFS]; // 9 bit, there was no uint9_t } RDSAFsODA; typedef struct { uint8_t num_entries : 6; uint8_t num_afs : 5; uint8_t afs[MAX_AFS]; } RDSAFs; typedef struct { uint16_t pi; uint8_t enabled : 1; uint8_t ta : 1; uint8_t tp : 1; uint8_t pty : 5; char ps[8]; RDSAFs af; uint16_t data : 16; } RDSEON; typedef struct { uint16_t pi; char ps[PS_LENGTH]; char rt1[RT_LENGTH]; uint8_t ecc; uint16_t slc_data : 12; uint8_t ta : 1; uint8_t pty : 5; uint8_t tp : 1; uint8_t dpty : 1; char tps[PS_LENGTH]; uint8_t rt1_enabled : 1; uint8_t rt2_enabled : 1; uint8_t rt_type : 2; uint8_t rt_text_timeout; uint8_t rt_switching_period; uint8_t current_rt : 1; char default_rt[RT_LENGTH]; char rt2[RT_LENGTH]; uint8_t ptyn_enabled : 1; char ptyn[PTYN_LENGTH]; RDSAFs af; RDSAFsODA af_oda; uint8_t ct : 1; char lps[LPS_LENGTH]; char grp_sqc[32]; char grp_sqc_rds2[32]; uint8_t udg1_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 udg2[8][3]; uint16_t udg1_rds2[8][4]; uint16_t udg2_rds2[8][4]; RDSEON eon[EONs]; uint8_t lua_data[LUA_USER_DATA]; } RDSData; typedef struct { uint8_t af_state : 6; } RDSEONState; typedef struct { uint8_t group : 4; uint8_t group_version : 1; uint16_t id; uint16_t id_data; int lua_handler; } RDSODA; typedef struct { uint8_t oda_len; uint8_t oda_pointer; uint8_t oda_runner_pointer; RDSODA odas[32]; } RDSODAState; typedef struct { uint8_t ps_update : 1; uint8_t tps_update : 1; char ps_text[PS_LENGTH]; char tps_text[PS_LENGTH]; uint8_t ps_csegment : 3; char rt_text[RT_LENGTH]; uint8_t rt_state : 5; uint8_t rt_update : 1; uint8_t rt2_update : 1; uint8_t rt_ab : 1; uint8_t rt_segments : 5; uint8_t rt2_segments : 5; uint8_t default_rt_segments : 5; char ptyn_text[PTYN_LENGTH]; uint8_t ptyn_state : 1; uint8_t ptyn_update : 1; uint8_t ptyn_ab : 1; char lps_text[LPS_LENGTH]; uint8_t lps_state : 4; uint8_t lps_update : 1; uint8_t lps_segments : 4; uint16_t custom_group[GROUP_LENGTH]; uint16_t custom_group2[GROUP_LENGTH + 1]; uint8_t rt_switching_period_state; uint8_t rt_text_timeout_state; uint8_t af_oda : 1; uint8_t data_ecc : 1; uint8_t grp_seq_idx[4]; uint8_t udg_idxs[2]; uint8_t udg_idxs_rds2[2]; uint8_t fasttuning_state : 3; uint8_t last_minute : 6; uint8_t last_second : 6; uint8_t ta_timeout : 7; uint8_t ta_timeout_state : 7; uint8_t eon_index : 3; uint8_t eon_state : 4; RDSEONState eon_states[4]; uint8_t af_state : 6; uint8_t af_oda_state : 6; uint8_t eon_linkage : 1; uint16_t last_stream0_group[3]; uint8_t last_stream0_group_type_b : 1; RDSODAState user_oda; } RDSState; typedef struct { uint16_t special_features; uint8_t rds2_mode : 1; // uint8_t rds2_buffer[16384]; } RDSEncoderData; typedef struct { RDSEncoderData encoder_data; RDSData data[PROGRAMS]; RDSState state[PROGRAMS]; uint8_t program : 3; } RDSEncoder; typedef struct { uint8_t file_starter; // Always is 225 first polish radio programme am frequency RDSData data[PROGRAMS]; uint8_t file_middle; // Always is 160, average of both RDSEncoderData encoder_data; uint8_t program : 3; uint8_t file_ender; // Always is 95 my freq uint16_t crc; } RDSEncoderFile; typedef struct { uint16_t a; uint16_t b; uint16_t c; uint16_t d; uint8_t is_type_b : 1; } RDSGroup; #define IS_TYPE_B(b) (b & 0x0800) void reset_rds_state(RDSEncoder* enc, uint8_t program); void set_rds_defaults(RDSEncoder* enc, uint8_t program); void init_rds_encoder(RDSEncoder* enc); void add_checkwords(RDSGroup *group, uint8_t *bits); void get_rds_bits(RDSEncoder* enc, uint8_t *bits, uint8_t stream); void set_rds_rt1(RDSEncoder* enc, const char *rt1); void set_rds_rt2(RDSEncoder* enc, const char *rt2); void set_rds_default_rt(RDSEncoder* enc, const char *rt); void set_rds_ps(RDSEncoder* enc, const char *ps); void set_rds_tps(RDSEncoder* enc, const char *tps); void set_rds_lps(RDSEncoder* enc, const char *lps); void set_rds_ptyn(RDSEncoder *enc, const char *ptyn); void set_rds_grpseq(RDSEncoder* enc, const char *grpseq); void set_rds_grpseq2(RDSEncoder* enc, const char *grpseq2);