mirror of
https://github.com/radio95-rnt/rds95.git
synced 2026-02-26 20:33:53 +01:00
do ert in lua
This commit is contained in:
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -30,5 +30,6 @@
|
|||||||
"jit": "disable",
|
"jit": "disable",
|
||||||
"ffi": "disable",
|
"ffi": "disable",
|
||||||
"package": "disable"
|
"package": "disable"
|
||||||
}
|
},
|
||||||
|
"C_Cpp.dimInactiveRegions": false
|
||||||
}
|
}
|
||||||
@@ -22,20 +22,49 @@ install(CODE
|
|||||||
"
|
"
|
||||||
# Define the paths for the source and destination files
|
# Define the paths for the source and destination files
|
||||||
set(PREFIX_FILE \"${CMAKE_CURRENT_SOURCE_DIR}/.script_prefix.lua\")
|
set(PREFIX_FILE \"${CMAKE_CURRENT_SOURCE_DIR}/.script_prefix.lua\")
|
||||||
|
set(SCRIPTS_DIR \"${CMAKE_CURRENT_SOURCE_DIR}/scripts\")
|
||||||
set(SCRIPT_FILE \"${CMAKE_CURRENT_SOURCE_DIR}/src/script.lua\")
|
set(SCRIPT_FILE \"${CMAKE_CURRENT_SOURCE_DIR}/src/script.lua\")
|
||||||
set(DEST_FILE \"/etc/rds95.lua\")
|
set(DEST_FILE \"/etc/rds95.lua\")
|
||||||
|
|
||||||
|
# Initialize content variable
|
||||||
|
set(FINAL_CONTENT \"\")
|
||||||
|
|
||||||
# Check if the optional prefix file exists
|
# Check if the optional prefix file exists
|
||||||
if(EXISTS \${PREFIX_FILE})
|
if(EXISTS \${PREFIX_FILE})
|
||||||
message(STATUS \"Prefix file found. Combining with script.lua.\")
|
message(STATUS \"Prefix file found. Adding .script_prefix.lua.\")
|
||||||
file(READ \${PREFIX_FILE} PREFIX_CONTENT)
|
file(READ \${PREFIX_FILE} PREFIX_CONTENT)
|
||||||
file(READ \${SCRIPT_FILE} SCRIPT_CONTENT)
|
set(FINAL_CONTENT \"\${PREFIX_CONTENT}\")
|
||||||
set(FINAL_CONTENT \"\${PREFIX_CONTENT}\n\${SCRIPT_CONTENT}\")
|
|
||||||
else()
|
else()
|
||||||
message(STATUS \"Prefix file not found. Using script.lua directly.\")
|
message(STATUS \"Prefix file not found.\")
|
||||||
file(READ \${SCRIPT_FILE} FINAL_CONTENT)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Check if scripts directory exists and contains .lua files
|
||||||
|
if(EXISTS \${SCRIPTS_DIR} AND IS_DIRECTORY \${SCRIPTS_DIR})
|
||||||
|
file(GLOB LUA_SCRIPTS \"\${SCRIPTS_DIR}/*.lua\")
|
||||||
|
list(LENGTH LUA_SCRIPTS SCRIPT_COUNT)
|
||||||
|
|
||||||
|
if(SCRIPT_COUNT GREATER 0)
|
||||||
|
message(STATUS \"Found \${SCRIPT_COUNT} Lua script(s) in scripts directory.\")
|
||||||
|
list(SORT LUA_SCRIPTS)
|
||||||
|
|
||||||
|
foreach(LUA_SCRIPT \${LUA_SCRIPTS})
|
||||||
|
get_filename_component(SCRIPT_NAME \${LUA_SCRIPT} NAME)
|
||||||
|
message(STATUS \"Adding script: \${SCRIPT_NAME}\")
|
||||||
|
file(READ \${LUA_SCRIPT} SCRIPT_CONTENT)
|
||||||
|
set(FINAL_CONTENT \"\${FINAL_CONTENT}\n\${SCRIPT_CONTENT}\")
|
||||||
|
endforeach()
|
||||||
|
else()
|
||||||
|
message(STATUS \"No Lua scripts found in scripts directory.\")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
message(STATUS \"Scripts directory not found.\")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Add the main script file
|
||||||
|
message(STATUS \"Adding main script.lua.\")
|
||||||
|
file(READ \${SCRIPT_FILE} MAIN_SCRIPT_CONTENT)
|
||||||
|
set(FINAL_CONTENT \"\${FINAL_CONTENT}\n\${MAIN_SCRIPT_CONTENT}\")
|
||||||
|
|
||||||
# Write the resulting content to the destination file
|
# Write the resulting content to the destination file
|
||||||
message(STATUS \"Installing script file to \${DEST_FILE}\")
|
message(STATUS \"Installing script file to \${DEST_FILE}\")
|
||||||
file(WRITE \${DEST_FILE} \"\${FINAL_CONTENT}\")
|
file(WRITE \${DEST_FILE} \"\${FINAL_CONTENT}\")
|
||||||
|
|||||||
@@ -170,8 +170,10 @@ function set_rds_lps(lps) end
|
|||||||
---@return string
|
---@return string
|
||||||
function get_rds_lps() end
|
function get_rds_lps() end
|
||||||
|
|
||||||
|
---This is implemented externally
|
||||||
---@param ert string
|
---@param ert string
|
||||||
function set_rds_ert(ert) end
|
function set_rds_ert(ert) end
|
||||||
|
---This is implemented externally
|
||||||
---@return string
|
---@return string
|
||||||
function get_rds_ert() end
|
function get_rds_ert() end
|
||||||
|
|
||||||
|
|||||||
257
readme.md
257
readme.md
@@ -25,263 +25,6 @@ The newer standard which is the IEC one, removes these features:
|
|||||||
|
|
||||||
RDS95 is the only (as far as i can tell) encoder to transmit the 9-bit AF codes
|
RDS95 is the only (as far as i can tell) encoder to transmit the 9-bit AF codes
|
||||||
|
|
||||||
## Commands
|
|
||||||
|
|
||||||
### PS
|
|
||||||
|
|
||||||
Sets the Program Service: `PS=* RDS *`
|
|
||||||
|
|
||||||
### PI
|
|
||||||
|
|
||||||
Sets the PI code: `PI=FFFF`
|
|
||||||
|
|
||||||
### TP
|
|
||||||
|
|
||||||
Sets the TP flag: `TP=1`
|
|
||||||
|
|
||||||
### TA
|
|
||||||
|
|
||||||
Sets the TA flag and triggers Traffic PS: `TA=0`
|
|
||||||
*May be overridden by EON*
|
|
||||||
|
|
||||||
### CT
|
|
||||||
|
|
||||||
Toggles the transmission of CT groups: `CT=1`
|
|
||||||
|
|
||||||
### AF
|
|
||||||
|
|
||||||
Sets the AF frequencies: `AF=95,89.1`
|
|
||||||
Clear the AF: `AF=`
|
|
||||||
|
|
||||||
### TPS
|
|
||||||
|
|
||||||
Sets the Traffic PS: `TPS=Traffic!` (default not set)
|
|
||||||
*TPS is transmitted instead of PS when TA flag is on*
|
|
||||||
|
|
||||||
### RT1
|
|
||||||
|
|
||||||
Sets the first radio text: `RT1=Currently Playing: Jessie Ware - Remember Where You Are` or `TEXT=Currently Playing: Jessie Ware - Remember Where You Are`
|
|
||||||
|
|
||||||
### RT2
|
|
||||||
|
|
||||||
Sets the second radio text: `RT2=Radio Nova - Best Hits around!`
|
|
||||||
|
|
||||||
### PTY
|
|
||||||
|
|
||||||
Sets the programme type flag: `PTY=11`
|
|
||||||
|
|
||||||
PTY values are diffrent for RDS and RDBS, look for them online
|
|
||||||
|
|
||||||
### ECC
|
|
||||||
|
|
||||||
Sets the extended country code: `ECC=E2`
|
|
||||||
*Note that the ECC is depended on the first letter of the PI, for example PI:3 and ECC:E2 is poland, but PI:1 would be the czech republic*
|
|
||||||
|
|
||||||
### RTP
|
|
||||||
|
|
||||||
TODO: RTP
|
|
||||||
|
|
||||||
### LPS
|
|
||||||
|
|
||||||
Sets the LPS: `LPS=NovaFM❤️`
|
|
||||||
*Note that LPS does UTF-8, while PS, RT don't*
|
|
||||||
|
|
||||||
### ERT
|
|
||||||
|
|
||||||
Sets the ERT: `ERT=Currently on air we're playing: Lady Gaga - Applause`
|
|
||||||
*Note that ERT is a 128-character version of RT with UTF-8 support*
|
|
||||||
|
|
||||||
### AFO
|
|
||||||
|
|
||||||
Sets the AF frequencies for the ODA 9-bit version which enables AF for 64.1-88 MHz: `AFO=69.8,95.0,225` (LowerFM,FM,LF not sure if this even works)
|
|
||||||
Clear the AFO: `AFO=`
|
|
||||||
|
|
||||||
### TEXT
|
|
||||||
|
|
||||||
Alias for [RT1](#rt1)
|
|
||||||
|
|
||||||
### PTYN
|
|
||||||
|
|
||||||
Sets the programme type name: `PTYN=Football`
|
|
||||||
|
|
||||||
### DPTY
|
|
||||||
|
|
||||||
*Formerly DI*
|
|
||||||
Sets the DPTY flag: `DPTY=1`
|
|
||||||
|
|
||||||
### SLCD
|
|
||||||
|
|
||||||
The 1A group where ECC is sent can also be used to send broadcaster data: `SLCD=FFF`
|
|
||||||
|
|
||||||
### ERTP
|
|
||||||
|
|
||||||
This only will work if ERT is no longer than 64 characters
|
|
||||||
See [RTP](#rtp)
|
|
||||||
|
|
||||||
### LINK
|
|
||||||
|
|
||||||
Toggles the linkage bit in 1A groups, enable this if you have EON about a station and that station has EON about you: `LINK=1`
|
|
||||||
|
|
||||||
### SITE
|
|
||||||
|
|
||||||
Sets up to 2 site addresses: `SITE=44,95`
|
|
||||||
|
|
||||||
### G
|
|
||||||
|
|
||||||
Sends a custom group to the next group available: `G=F100FFFFFFFF` or `G=00002000AAAAAAAA` for RDS2
|
|
||||||
|
|
||||||
### RT1EN
|
|
||||||
|
|
||||||
Enables RT 1: `RT1EN=1`
|
|
||||||
|
|
||||||
### RT2EN
|
|
||||||
|
|
||||||
Enables RT 2: `RT2EN=1`
|
|
||||||
|
|
||||||
### RTPER
|
|
||||||
|
|
||||||
RT Switching period, in minutes: `RTPER=5`
|
|
||||||
|
|
||||||
### LEVEL
|
|
||||||
|
|
||||||
Sets the RDS output level: `LEVEL=255`
|
|
||||||
|
|
||||||
### PTYNEN
|
|
||||||
|
|
||||||
Enables PTYN transmission: `PTYEN=1`
|
|
||||||
|
|
||||||
### RTPRUN
|
|
||||||
|
|
||||||
Sets the RTP Running bit, to signal if the RTP data is accurate: `RTPRUN=1`
|
|
||||||
|
|
||||||
You can also toggle the state: `RTPRUN=1,1`
|
|
||||||
|
|
||||||
### GRPSEQ
|
|
||||||
|
|
||||||
Sets the group sequence for stream0, available groups:
|
|
||||||
|
|
||||||
- 0: 4 PSs
|
|
||||||
- 1: ECC
|
|
||||||
- 2: RT
|
|
||||||
- A: PTYN
|
|
||||||
- E: EON
|
|
||||||
- X: UDG1
|
|
||||||
- Y: UDG2
|
|
||||||
- R: RT+
|
|
||||||
- P: eRT+
|
|
||||||
- S: ERT
|
|
||||||
- 3: ODA
|
|
||||||
- F: LPS
|
|
||||||
- T: Fast tuning info
|
|
||||||
- U: ODA AF
|
|
||||||
|
|
||||||
`GRPSEQ=002222`
|
|
||||||
|
|
||||||
### RTTYPE
|
|
||||||
|
|
||||||
Sets the RT1/RT2 types of A/B:
|
|
||||||
|
|
||||||
- 0: Set to A
|
|
||||||
- 1: RT1 is A, RT2 is B
|
|
||||||
- 2: Default, just toggle A/B
|
|
||||||
|
|
||||||
### PROGRAM
|
|
||||||
|
|
||||||
Switches the current program, so diffrent saves: `PROGRAM=1`
|
|
||||||
|
|
||||||
### RDS2MOD
|
|
||||||
|
|
||||||
Sets the RDS2 operation mode:
|
|
||||||
|
|
||||||
- 0: Default, full tunnelling of stream 0
|
|
||||||
- 1: Independent tunelling, RDS2 runs a seperate group sequence
|
|
||||||
|
|
||||||
### GRPSEQ2
|
|
||||||
|
|
||||||
The Group Sequence for the RDS2 independent tunnelling mode
|
|
||||||
See [GRPSEQ](#grpseq)
|
|
||||||
|
|
||||||
### DTTMOUT
|
|
||||||
|
|
||||||
Default text timeout, once runs out it sets the RT1 which is saved in memory: `DTTMOUT=60` (1 hour)
|
|
||||||
|
|
||||||
### ERTPRUN
|
|
||||||
|
|
||||||
See [RTPRUN](#rtprun)
|
|
||||||
|
|
||||||
### INIT
|
|
||||||
|
|
||||||
Resets program to default settings, no arguments: `INIT`
|
|
||||||
|
|
||||||
### VER
|
|
||||||
|
|
||||||
If you have output, then it shows the version of the encoder
|
|
||||||
|
|
||||||
### RESET
|
|
||||||
|
|
||||||
Resets the internal state: `RESET`
|
|
||||||
|
|
||||||
### EONxEN
|
|
||||||
|
|
||||||
Enables the EON of x: `EON1EN=1`
|
|
||||||
|
|
||||||
### EONxPI
|
|
||||||
|
|
||||||
Sets the PI of EON x: `EON1PI=30FE`
|
|
||||||
|
|
||||||
### EONxPS
|
|
||||||
|
|
||||||
Sets the PS of EON x: `EON1PS=AFERA`
|
|
||||||
|
|
||||||
### EONxPTY
|
|
||||||
|
|
||||||
Sets the PTY of EON x: `EON1PTY=11`
|
|
||||||
|
|
||||||
### EONxTA
|
|
||||||
|
|
||||||
Enables the TA of EON x: `EON1TA=1`
|
|
||||||
|
|
||||||
### EONxTP
|
|
||||||
|
|
||||||
Sets the TP of EON x: `EON1TP=1`
|
|
||||||
|
|
||||||
### EONxAF
|
|
||||||
|
|
||||||
Sets the AF of EON x: `EON1AF=98.6,95.0`
|
|
||||||
|
|
||||||
### EONxDT
|
|
||||||
|
|
||||||
Sets the broadcaster data of EON x: `EON1DT=F`
|
|
||||||
|
|
||||||
### UDG1
|
|
||||||
|
|
||||||
Sets the user defined group, max 8 groups: `UDG1=6000FFFFFFFF`
|
|
||||||
|
|
||||||
### UDG2
|
|
||||||
|
|
||||||
See [UDG1](#udg1)
|
|
||||||
|
|
||||||
### 2UDG1
|
|
||||||
|
|
||||||
Sets the UDG1 of RDS2, max 8 groups expects 4 blocks: `2UDG1=0000200020202020`
|
|
||||||
|
|
||||||
### 2UDG2
|
|
||||||
|
|
||||||
See [2UDG1](#2udg1)
|
|
||||||
|
|
||||||
### RDSGEN
|
|
||||||
|
|
||||||
Sets the rds generator level:
|
|
||||||
|
|
||||||
- 0: No streams
|
|
||||||
- 1: Stream 0 only
|
|
||||||
- 2: Stream 0 and 1
|
|
||||||
|
|
||||||
`RDSGEN=1`
|
|
||||||
|
|
||||||
### Don't like the commands?
|
|
||||||
Implement them yourself then smartass, go on, look into the command.lua file
|
|
||||||
|
|
||||||
## Disclaimer
|
## Disclaimer
|
||||||
|
|
||||||
RDS95 is based on [Anthony96922](https://github.com/Anthony96922/)'s [MiniRDS](https://github.com/Anthony96922/MiniRDS)
|
RDS95 is based on [Anthony96922](https://github.com/Anthony96922/)'s [MiniRDS](https://github.com/Anthony96922/MiniRDS)
|
||||||
|
|||||||
66
scripts/ert.lua
Normal file
66
scripts/ert.lua
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
_Ert_state = 0
|
||||||
|
_Ert_oda_id = nil
|
||||||
|
|
||||||
|
local function init_ert()
|
||||||
|
if _Ert_oda_id == nil then
|
||||||
|
_Ert_oda_id = register_oda(12, false, 0x6552, 1)
|
||||||
|
set_oda_handler(_Ert_oda_id, function ()
|
||||||
|
if string.byte(get_userdata_offset(257, 1)) == 1 then
|
||||||
|
local new_data = get_userdata_offset(0, 128)
|
||||||
|
local new_segments = string.byte(get_userdata_offset(128, 1))
|
||||||
|
set_userdata_offset(129, 128, new_data)
|
||||||
|
set_userdata_offset(257, 1, string.char(new_segments))
|
||||||
|
set_userdata_offset(258, 1, string.char(0))
|
||||||
|
_Ert_state = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
local segments = string.byte(get_userdata_offset(257, 1))
|
||||||
|
if segments == 0 then segments = 1 end
|
||||||
|
|
||||||
|
local b = _Ert_state & 31
|
||||||
|
local chunk = get_userdata_offset(129 + _Ert_state * 4, 4)
|
||||||
|
local c = (string.byte(chunk, 1) << 8) | string.byte(chunk, 2)
|
||||||
|
local d = (string.byte(chunk, 3) << 8) | string.byte(chunk, 4)
|
||||||
|
|
||||||
|
_Ert_state = (_Ert_state + 1) % segments
|
||||||
|
return b, c, d
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function set_rds_ert(ert)
|
||||||
|
if #ert == 0 then
|
||||||
|
set_userdata_offset(128, 1, string.char(0))
|
||||||
|
set_userdata_offset(258, 1, string.char(1))
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local data = ert .. "\r"
|
||||||
|
data = string.sub(data, 1, 128)
|
||||||
|
|
||||||
|
local padding = (4 - (#data % 4)) % 4
|
||||||
|
data = data .. string.rep("\0", padding)
|
||||||
|
|
||||||
|
set_userdata_offset(0, 128, data)
|
||||||
|
|
||||||
|
local segments = #data // 4
|
||||||
|
if segments > 32 then segments = 32 end
|
||||||
|
|
||||||
|
if string.byte(get_userdata_offset(257, 1)) == 0 then
|
||||||
|
init_ert()
|
||||||
|
set_userdata_offset(129, 128, data)
|
||||||
|
set_userdata_offset(257, 1, string.char(segments))
|
||||||
|
else set_userdata_offset(258, 1, string.char(1)) end
|
||||||
|
|
||||||
|
set_userdata_offset(128, 1, string.char(segments))
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_rds_ert()
|
||||||
|
local data = get_userdata_offset(0, 128)
|
||||||
|
if string.byte(get_userdata_offset(128, 1)) == 0 then return "" end
|
||||||
|
return data:match("^(.-)[\r%z]*") or ""
|
||||||
|
end
|
||||||
|
|
||||||
|
function on_state()
|
||||||
|
if string.byte(get_userdata_offset(257, 1)) ~= 0 then init_ert() end
|
||||||
|
end
|
||||||
@@ -311,9 +311,6 @@ STR_SETTER(rt2, set_rds_rt2)
|
|||||||
STR_RAW_SETTER(lps, set_rds_lps)
|
STR_RAW_SETTER(lps, set_rds_lps)
|
||||||
STR_RAW_GETTER(lps, LPS_LENGTH)
|
STR_RAW_GETTER(lps, LPS_LENGTH)
|
||||||
|
|
||||||
STR_RAW_SETTER(ert, set_rds_ert)
|
|
||||||
STR_RAW_GETTER(ert, ERT_LENGTH)
|
|
||||||
|
|
||||||
STR_RAW_SETTER(grp_sqc_rds2, set_rds_grpseq2)
|
STR_RAW_SETTER(grp_sqc_rds2, set_rds_grpseq2)
|
||||||
STR_RAW_GETTER(grp_sqc_rds2, 24)
|
STR_RAW_GETTER(grp_sqc_rds2, 24)
|
||||||
|
|
||||||
@@ -589,9 +586,6 @@ void init_lua(RDSModulator* rds_mod) {
|
|||||||
lua_register(L, "set_rds_lps", lua_set_rds_lps);
|
lua_register(L, "set_rds_lps", lua_set_rds_lps);
|
||||||
lua_register(L, "get_rds_lps", lua_get_rds_lps);
|
lua_register(L, "get_rds_lps", lua_get_rds_lps);
|
||||||
|
|
||||||
lua_register(L, "set_rds_ert", lua_set_rds_ert);
|
|
||||||
lua_register(L, "get_rds_ert", lua_get_rds_ert);
|
|
||||||
|
|
||||||
lua_register(L, "set_rds_rtplus_tags", lua_set_rds_rtplus_tags);
|
lua_register(L, "set_rds_rtplus_tags", lua_set_rds_rtplus_tags);
|
||||||
lua_register(L, "get_rds_rtplus_tags", lua_get_rds_rtplus_tags);
|
lua_register(L, "get_rds_rtplus_tags", lua_get_rds_rtplus_tags);
|
||||||
lua_register(L, "toggle_rds_rtp", lua_toggle_rds_rtp);
|
lua_register(L, "toggle_rds_rtp", lua_toggle_rds_rtp);
|
||||||
|
|||||||
11
src/rds.c
11
src/rds.c
@@ -14,7 +14,6 @@ void get_rds_fasttuning_group(RDSEncoder* enc, RDSGroup *group);
|
|||||||
void get_rds_rt_group(RDSEncoder* enc, RDSGroup *group);
|
void get_rds_rt_group(RDSEncoder* enc, RDSGroup *group);
|
||||||
void get_rdsp_rtp_oda_group(RDSGroup *group);
|
void get_rdsp_rtp_oda_group(RDSGroup *group);
|
||||||
void get_rdsp_ertp_oda_group(RDSGroup *group);
|
void get_rdsp_ertp_oda_group(RDSGroup *group);
|
||||||
void get_rdsp_ert_oda_group(RDSGroup *group);
|
|
||||||
void get_rdsp_oda_af_oda_group(RDSGroup *group);
|
void get_rdsp_oda_af_oda_group(RDSGroup *group);
|
||||||
void get_rds_oda_af_group(RDSEncoder* enc, RDSGroup *group);
|
void get_rds_oda_af_group(RDSEncoder* enc, RDSGroup *group);
|
||||||
void get_rdsp_ct_group(RDSGroup *group, time_t now);
|
void get_rdsp_ct_group(RDSGroup *group, time_t now);
|
||||||
@@ -25,7 +24,6 @@ void get_rds_ptyn_group(RDSEncoder* enc, RDSGroup *group);
|
|||||||
void get_rds_rtplus_group(RDSEncoder* enc, RDSGroup *group);
|
void get_rds_rtplus_group(RDSEncoder* enc, RDSGroup *group);
|
||||||
void get_rds_ertplus_group(RDSEncoder* enc, RDSGroup *group);
|
void get_rds_ertplus_group(RDSEncoder* enc, RDSGroup *group);
|
||||||
void get_rds_eon_group(RDSEncoder* enc, RDSGroup *group);
|
void get_rds_eon_group(RDSEncoder* enc, RDSGroup *group);
|
||||||
void get_rds_ert_group(RDSEncoder* enc, RDSGroup *group);
|
|
||||||
uint8_t get_rds_custom_groups(RDSEncoder* enc, RDSGroup *group);
|
uint8_t get_rds_custom_groups(RDSEncoder* enc, RDSGroup *group);
|
||||||
uint8_t get_rds_custom_groups2(RDSEncoder* enc, RDSGroup *group);
|
uint8_t get_rds_custom_groups2(RDSEncoder* enc, RDSGroup *group);
|
||||||
int get_rdsp_lua_group(RDSGroup *group);
|
int get_rdsp_lua_group(RDSGroup *group);
|
||||||
@@ -100,11 +98,6 @@ static void get_rds_sequence_group(RDSEncoder* enc, RDSGroup *group, char* grp,
|
|||||||
else get_rdsp_ertp_oda_group(group);
|
else get_rdsp_ertp_oda_group(group);
|
||||||
TOGGLE(enc->state[enc->program].ert_oda);
|
TOGGLE(enc->state[enc->program].ert_oda);
|
||||||
break;
|
break;
|
||||||
case 'S':
|
|
||||||
if(enc->state[enc->program].ert_oda == 0) get_rds_ert_group(enc, group);
|
|
||||||
else get_rdsp_ert_oda_group(group);
|
|
||||||
TOGGLE(enc->state[enc->program].ert_oda);
|
|
||||||
break;
|
|
||||||
case 'F':
|
case 'F':
|
||||||
get_rds_lps_group(enc, group);
|
get_rds_lps_group(enc, group);
|
||||||
break;
|
break;
|
||||||
@@ -145,8 +138,7 @@ static uint8_t check_rds_good_group(RDSEncoder* enc, char* grp) {
|
|||||||
if(*grp == 'X' && enc->data[enc->program].udg1_len != 0) good_group = 1;
|
if(*grp == 'X' && enc->data[enc->program].udg1_len != 0) good_group = 1;
|
||||||
if(*grp == 'Y' && enc->data[enc->program].udg2_len != 0) good_group = 1;
|
if(*grp == 'Y' && enc->data[enc->program].udg2_len != 0) good_group = 1;
|
||||||
if(*grp == 'R' && enc->rtpData[enc->program][0].enabled) good_group = 1;
|
if(*grp == 'R' && enc->rtpData[enc->program][0].enabled) good_group = 1;
|
||||||
if(*grp == 'P' && enc->rtpData[enc->program][1].enabled && (_strnlen(enc->data[enc->program].ert, 65) < 64)) good_group = 1;
|
if(*grp == 'P' && enc->rtpData[enc->program][1].enabled) good_group = 1;
|
||||||
if(*grp == 'S' && enc->data[enc->program].ert[0] != '\0') good_group = 1;
|
|
||||||
if(*grp == 'F' && enc->data[enc->program].lps[0] != '\0') good_group = 1;
|
if(*grp == 'F' && enc->data[enc->program].lps[0] != '\0') good_group = 1;
|
||||||
if(*grp == 'T') good_group = 1;
|
if(*grp == 'T') good_group = 1;
|
||||||
if(*grp == 'L') good_group = 1;
|
if(*grp == 'L') good_group = 1;
|
||||||
@@ -364,7 +356,6 @@ void reset_rds_state(RDSEncoder* enc, uint8_t program) {
|
|||||||
tempCoder.state[program].ptyn_ab = 1;
|
tempCoder.state[program].ptyn_ab = 1;
|
||||||
set_rds_rt1(&tempCoder, enc->data[program].rt1);
|
set_rds_rt1(&tempCoder, enc->data[program].rt1);
|
||||||
set_rds_rt2(&tempCoder, enc->data[program].rt2);
|
set_rds_rt2(&tempCoder, enc->data[program].rt2);
|
||||||
set_rds_ert(&tempCoder, enc->data[program].ert);
|
|
||||||
set_rds_ps(&tempCoder, enc->data[program].ps);
|
set_rds_ps(&tempCoder, enc->data[program].ps);
|
||||||
set_rds_tps(&tempCoder, enc->data[program].tps);
|
set_rds_tps(&tempCoder, enc->data[program].tps);
|
||||||
set_rds_ptyn(&tempCoder, enc->data[program].ptyn);
|
set_rds_ptyn(&tempCoder, enc->data[program].ptyn);
|
||||||
|
|||||||
14
src/rds.h
14
src/rds.h
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#define LUA_USER_DATA 512
|
#define LUA_USER_DATA 768
|
||||||
|
|
||||||
/* The RDS error-detection code generator polynomial is
|
/* The RDS error-detection code generator polynomial is
|
||||||
* x^10 + x^8 + x^7 + x^5 + x^4 + x^3 + x^0
|
* x^10 + x^8 + x^7 + x^5 + x^4 + x^3 + x^0
|
||||||
@@ -14,7 +14,6 @@
|
|||||||
#define RDS_SAMPLE_RATE 4750
|
#define RDS_SAMPLE_RATE 4750
|
||||||
|
|
||||||
#define RT_LENGTH 64
|
#define RT_LENGTH 64
|
||||||
#define ERT_LENGTH 128
|
|
||||||
#define PS_LENGTH 8
|
#define PS_LENGTH 8
|
||||||
#define PTYN_LENGTH 8
|
#define PTYN_LENGTH 8
|
||||||
#define LPS_LENGTH 32
|
#define LPS_LENGTH 32
|
||||||
@@ -30,7 +29,6 @@
|
|||||||
|
|
||||||
// List of ODAs: https://www.nrscstandards.org/committees/dsm/archive/rds-oda-aids.pdf
|
// List of ODAs: https://www.nrscstandards.org/committees/dsm/archive/rds-oda-aids.pdf
|
||||||
#define ODA_AID_RTPLUS 0x4bd7
|
#define ODA_AID_RTPLUS 0x4bd7
|
||||||
#define ODA_AID_ERT 0x6552
|
|
||||||
#define ODA_AID_ERTPLUS 0x4BD8
|
#define ODA_AID_ERTPLUS 0x4BD8
|
||||||
#define ODA_AID_ODAAF 0x6365
|
#define ODA_AID_ODAAF 0x6365
|
||||||
|
|
||||||
@@ -79,10 +77,6 @@ typedef struct {
|
|||||||
char default_rt[RT_LENGTH];
|
char default_rt[RT_LENGTH];
|
||||||
char rt2[RT_LENGTH];
|
char rt2[RT_LENGTH];
|
||||||
|
|
||||||
uint8_t ert_switching_period;
|
|
||||||
uint8_t orignal_ert_switching_period;
|
|
||||||
char ert[ERT_LENGTH];
|
|
||||||
|
|
||||||
uint8_t ptyn_enabled : 1;
|
uint8_t ptyn_enabled : 1;
|
||||||
char ptyn[PTYN_LENGTH];
|
char ptyn[PTYN_LENGTH];
|
||||||
|
|
||||||
@@ -144,11 +138,6 @@ typedef struct {
|
|||||||
uint8_t rt_segments : 5;
|
uint8_t rt_segments : 5;
|
||||||
uint8_t rt2_segments : 5;
|
uint8_t rt2_segments : 5;
|
||||||
|
|
||||||
char ert_text[ERT_LENGTH];
|
|
||||||
uint8_t ert_state : 6;
|
|
||||||
uint8_t ert_update : 1;
|
|
||||||
uint8_t ert_segments : 6;
|
|
||||||
|
|
||||||
char ptyn_text[PTYN_LENGTH];
|
char ptyn_text[PTYN_LENGTH];
|
||||||
uint8_t ptyn_state : 1;
|
uint8_t ptyn_state : 1;
|
||||||
uint8_t ptyn_update : 1;
|
uint8_t ptyn_update : 1;
|
||||||
@@ -254,7 +243,6 @@ void set_rds_rt2(RDSEncoder* enc, const char *rt2);
|
|||||||
void set_rds_ps(RDSEncoder* enc, const char *ps);
|
void set_rds_ps(RDSEncoder* enc, const char *ps);
|
||||||
void set_rds_tps(RDSEncoder* enc, const char *tps);
|
void set_rds_tps(RDSEncoder* enc, const char *tps);
|
||||||
void set_rds_lps(RDSEncoder* enc, const char *lps);
|
void set_rds_lps(RDSEncoder* enc, const char *lps);
|
||||||
void set_rds_ert(RDSEncoder *enc, const char *ert);
|
|
||||||
void set_rds_rtplus_tags(RDSEncoder *enc, uint8_t *tags);
|
void set_rds_rtplus_tags(RDSEncoder *enc, uint8_t *tags);
|
||||||
void set_rds_ertplus_tags(RDSEncoder *enc, uint8_t *tags);
|
void set_rds_ertplus_tags(RDSEncoder *enc, uint8_t *tags);
|
||||||
void set_rds_ptyn(RDSEncoder *enc, const char *ptyn);
|
void set_rds_ptyn(RDSEncoder *enc, const char *ptyn);
|
||||||
|
|||||||
@@ -148,13 +148,6 @@ void get_rdsp_ertp_oda_group(RDSGroup *group) {
|
|||||||
group->d = ODA_AID_ERTPLUS;
|
group->d = ODA_AID_ERTPLUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_rdsp_ert_oda_group(RDSGroup *group) {
|
|
||||||
group->b |= 3 << 12;
|
|
||||||
group->b |= 12 << 1;
|
|
||||||
group->c = 1; // UTF-8
|
|
||||||
group->d = ODA_AID_ERT;
|
|
||||||
}
|
|
||||||
|
|
||||||
void get_rdsp_oda_af_oda_group(RDSGroup *group) {
|
void get_rdsp_oda_af_oda_group(RDSGroup *group) {
|
||||||
group->b |= 3 << 12;
|
group->b |= 3 << 12;
|
||||||
group->b |= 7 << 1;
|
group->b |= 7 << 1;
|
||||||
@@ -326,22 +319,6 @@ void get_rds_eon_group(RDSEncoder* enc, RDSGroup *group) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_rds_ert_group(RDSEncoder* enc, RDSGroup *group) {
|
|
||||||
if (enc->state[enc->program].ert_state == 0 && enc->state[enc->program].ert_update) {
|
|
||||||
memcpy(enc->state[enc->program].ert_text, enc->data[enc->program].ert, ERT_LENGTH);
|
|
||||||
enc->state[enc->program].ert_update = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
group->b |= 12 << 12 | (enc->state[enc->program].ert_state & 31);
|
|
||||||
group->c = enc->state[enc->program].ert_text[enc->state[enc->program].ert_state * 4] << 8;
|
|
||||||
group->c |= enc->state[enc->program].ert_text[enc->state[enc->program].ert_state * 4 + 1];
|
|
||||||
group->d = enc->state[enc->program].ert_text[enc->state[enc->program].ert_state * 4 + 2] << 8;
|
|
||||||
group->d |= enc->state[enc->program].ert_text[enc->state[enc->program].ert_state * 4 + 3];
|
|
||||||
|
|
||||||
enc->state[enc->program].ert_state++;
|
|
||||||
if (enc->state[enc->program].ert_state >= enc->state[enc->program].ert_segments) enc->state[enc->program].ert_state = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t get_rds_custom_groups(RDSEncoder* enc, RDSGroup *group) {
|
uint8_t get_rds_custom_groups(RDSEncoder* enc, RDSGroup *group) {
|
||||||
if(enc->state[enc->program].custom_group[0] == 1) {
|
if(enc->state[enc->program].custom_group[0] == 1) {
|
||||||
enc->state[enc->program].custom_group[0] = 0;
|
enc->state[enc->program].custom_group[0] = 0;
|
||||||
|
|||||||
@@ -87,27 +87,6 @@ void set_rds_lps(RDSEncoder* enc, const char *lps) {
|
|||||||
if(enc->state[enc->program].lps_segments > 8) enc->state[enc->program].lps_segments = 8; //make sure
|
if(enc->state[enc->program].lps_segments > 8) enc->state[enc->program].lps_segments = 8; //make sure
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_rds_ert(RDSEncoder* enc, const char *ert) {
|
|
||||||
uint8_t i = 0, len = 0;
|
|
||||||
|
|
||||||
enc->state[enc->program].ert_update = 1;
|
|
||||||
|
|
||||||
memset(enc->data[enc->program].ert, ' ', ERT_LENGTH);
|
|
||||||
while (*ert != 0 && len < ERT_LENGTH) enc->data[enc->program].ert[len++] = *ert++;
|
|
||||||
|
|
||||||
while (len > 0 && enc->data[enc->program].ert[len - 1] == ' ') len--;
|
|
||||||
|
|
||||||
if (len < ERT_LENGTH) {
|
|
||||||
enc->state[enc->program].ert_segments = 0;
|
|
||||||
enc->data[enc->program].ert[len++] = '\r';
|
|
||||||
while (i < len) {
|
|
||||||
i += 4;
|
|
||||||
enc->state[enc->program].ert_segments++;
|
|
||||||
}
|
|
||||||
} else enc->state[enc->program].ert_segments = 32;
|
|
||||||
if(enc->state[enc->program].ert_segments > 32) enc->state[enc->program].ert_segments = 32; //make sure
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void set_rds_rtplus_tags(RDSEncoder* enc, uint8_t *tags) {
|
inline void set_rds_rtplus_tags(RDSEncoder* enc, uint8_t *tags) {
|
||||||
enc->rtpData[enc->program][0].type[0] = tags[0] & 0x3f;
|
enc->rtpData[enc->program][0].type[0] = tags[0] & 0x3f;
|
||||||
enc->rtpData[enc->program][0].start[0] = tags[1] & 0x3f;
|
enc->rtpData[enc->program][0].start[0] = tags[1] & 0x3f;
|
||||||
|
|||||||
Reference in New Issue
Block a user