0
1
mirror of https://github.com/radio95-rnt/rds95.git synced 2026-02-26 20:33:53 +01:00

some adjustments and smart detections

This commit is contained in:
2025-12-28 16:01:15 +01:00
parent c56e932c93
commit 6552d3dc9d
5 changed files with 86 additions and 47 deletions

View File

@@ -9,8 +9,8 @@ eon_count = 0
max_programs = 0
---@type integer
user_data_len = 0
---@type integer
oda_count = 0
--#region Functions implemented or used in C
---Starts the initialization sequence, also calls the on_init function
---@return nil
@@ -136,6 +136,9 @@ function get_rds2_mode() end
function set_rds_streams(streams) end
---@return integer
function get_rds_streams() end
---This function returns the absolute number of streams that can be output without restarting the core
---@return integer
function get_available_rds_streams() end
---@param level number
function set_rds_level(level) end
@@ -201,22 +204,6 @@ function set_rds_grpseq2(grpseq2) end
---@return string
function get_rds_grpseq2() end
-- RT Plus Tags
---Sets RT+ tags: type1, start1, len1, type2, start2, len2
---@param ertp boolean
---@param t1 integer
---@param s1 integer
---@param l1 integer
---@param t2 integer
---@param s2 integer
---@param l2 integer
function set_rds_rtplus_tags(ertp, t1, s1, l1, t2, s2, l2) end
---Gets RT+ tags: type1, start1, len1, type2, start2, len2
---@param ertp boolean
---@return integer type1, integer start1, integer len1, integer type2, integer start2, integer len2
function get_rds_rtplus_tags(ertp) end
---Puts in a RDS1 group in the buffer, note that block A is filled in always
---@param b integer
---@param c integer
@@ -230,28 +217,9 @@ function put_rds_custom_group(b, c, d) end
---@param d integer
function put_rds2_custom_group(a, b, c, d) end
---This is implemented externally
---Toggles RTP or ERTP's toggle switch
---@param ertp boolean
function toggle_rds_rtp(ertp) end
---This is implemented externally
---Sets the metadata of RTP or ERTP
---@param ertp boolean
---@param running boolean
function set_rds_rtp_meta(ertp, running) end
---This is implemented externally
---Gets the metadata of RTP and ERTP
---@param ertp boolean
---@return boolean running
function get_rds_rtp_meta(ertp) end
---Sets the AFs included in group 0
---@param afs table
function set_rds_af_group0(afs) end
---Sets the AFs included in the ODA
---@param afs table
function set_rds_af_oda(afs) end
---Sets data about the EON
---@param eon integer Index of the EON we are setting
@@ -286,7 +254,41 @@ function set_rds_udg(xy, groups) end
---@param groups table Table of tables, this should be up to 8 tables containing 4 integers
function set_rds_udg2(xy, groups) end
---This function is defined externally
--#endregion
-- RT Plus Tags
---Sets RT+ tags: type1, start1, len1, type2, start2, len2
---@param ertp boolean
---@param t1 integer
---@param s1 integer
---@param l1 integer
---@param t2 integer
---@param s2 integer
---@param l2 integer
function set_rds_rtplus_tags(ertp, t1, s1, l1, t2, s2, l2) end
---Gets RT+ tags: type1, start1, len1, type2, start2, len2
---@param ertp boolean
---@return integer type1, integer start1, integer len1, integer type2, integer start2, integer len2
function get_rds_rtplus_tags(ertp) end
---Toggles RTP or ERTP's toggle switch
---@param ertp boolean
function toggle_rds_rtp(ertp) end
---Sets the metadata of RTP or ERTP
---@param ertp boolean
---@param running boolean
function set_rds_rtp_meta(ertp, running) end
---Gets the metadata of RTP and ERTP
---@param ertp boolean
---@return boolean running
function get_rds_rtp_meta(ertp) end
---Sets the AFs included in the ODA
---@param afs table
function set_rds_af_oda(afs) end
---Registers an ODA to be used in the O of the group sequence. ODAs are stored as state data, thus running reset_rds will clear it
---Groups 14, 15, 2, 0 cannot be registered either version, groups 10, 4, 1 can be only registered as B, any other is free to take
---Group 3A will mean that there will be no group handler for this ODA, meaning it can only be interacted with via the 3A AID group, handler set is not possible with such groups
@@ -296,8 +298,8 @@ function set_rds_udg2(xy, groups) end
---@param data integer
---@return integer oda_id
function register_oda(group, group_version, aid, data) end
---This function is defined externally
---Sets the id_data for a existing ODA group
---Sets the data for a existing ODA group
---@param oda_id integer
---@param data integer
function set_oda_id_data(oda_id, data) end
@@ -308,13 +310,13 @@ function set_oda_id_data(oda_id, data) end
---Sets a function to handle the ODA data generation.
---The handler is called when the group sequence 'K' slot is processed.
---The function must return 3 integers representing RDS Blocks B, C, and D.
---Please note that you do not need to compute the block A to indentify the group and group version, that will be done for you and EVERY SINGLE group has PTY and TP inserted (and also PI if its a B)
---Please note that you do not need to compute the block B to indentify the group and group version, that will be done for you and EVERY SINGLE group has PTY and TP inserted (and also PI if its a B inside block C)
---You are asked to set groups B last 5 bits, leave rest 0
---@param oda_id integer The ID returned by register_oda
---@param fun ODAHandler
function set_oda_handler(oda_id, fun) end
---Data is allocated in each program's data for lua data (per program, diffrent program, diffrent data), note that this overwrites existing data
---Data is allocated in each program's data for lua data (per program, diffrent program, diffrent data), note that this overwrites existing data over the whole userdata string
---@param data string
function set_userdata(data) end
---Writes to the userdata at the offset, size does not have to match the length of the string, if the string is less than size then the rest of the string will be padded with zeroes until it is size
@@ -336,6 +338,7 @@ function get_userdata_offset(offset, size) end
---@alias RDS2_ODAHandler fun(): (boolean, integer, integer, integer, integer)
---This function is defined externally
---You are asked to not fill in the channel id in block A, however you are asked to fill in the function number (if you do not know what is that, just OR block A with (1 << 14))
---@param oda_id integer
---@param func RDS2_ODAHandler
function set_oda_handler_rds2(oda_id, func) end
@@ -356,4 +359,4 @@ function register_oda_rds2(aid, data, file_related) end
---Loads the file into RFT and initializes it if needed, note that this needs RDR2 mode 2
---@param path string
---@param id integer
function load_rft_file(path, id) end
function load_station_logo(path, id) end

View File

@@ -42,6 +42,7 @@ end
---@param fun ODAHandler
function set_oda_handler(oda_id, fun)
if oda_id > #_RDS_ODAs then return end
if _RDS_ODAs.group == 3 then error("3A ODAs cannot have handlers.") end
_RDS_ODAs[oda_id].handler = fun
end
@@ -91,3 +92,10 @@ function group(group_type)
end
return false, 0, 0, 0
end
local _old_on_state_oda = on_state
function on_state()
_RDS_ODAs = {}
_RDS_ODA_pointer = 1
if type(_old_on_state_oda) == "function" then _old_on_state_oda() end
end

View File

@@ -75,8 +75,23 @@ function rds2_group(stream)
if _RDS2_ODA_aid > 8 then _RDS2_ODA_aid = 0 end
if oda.handler then
local generated, a, b, c, d = oda.handler(stream)
return generated, (channel << 8) | a, b, c, d
local channel_bitshift = 8
local fid = (a & 0xC000) >> 14
local fn_msb = (a >> 15) & 1
if fid == 0 and fn_msb == 0 then return true, 0, b, c, d
elseif fid == 0 and fn_msb == 1 then channel = channel & 0xF
--FID = 1 means a normal ODA group
elseif fid == 2 and fn_msb == 0 then channel_bitshift = 0 end -- This is AID
return generated, (channel << channel_bitshift) | a, b, c, d
end
return true, (2 << 14) | channel, oda.aid, (oda.data >> 16) & 0xffff, oda.data & 0xffff
end
end
local _old_on_state_oda_rds2 = on_state
function on_state()
_RDS2_ODAs = {}
_RDS2_ODA_aid = 0
_RDS2_ODA_pointer = 1
if type(_old_on_state_oda_rds2) == "function" then _old_on_state_oda_rds2() end
end

View File

@@ -2,6 +2,8 @@ _Rft_oda_id = nil
_Rft_file = ""
_Rft_file_segment = 0
_Rft_toggle = false
_Rft_last_id = -1
_Rft_version = 0 -- TODO
local function start_rft()
if _Rft_oda_id == nil then
@@ -23,7 +25,6 @@ local function start_rft()
_Rft_file_segment = seg + 1
if _Rft_file_segment >= total_segments then
_Rft_file_segment = 0
_Rft_toggle = not _Rft_toggle
end
return true, (2 << 12) | word1, word2, word3, word4
@@ -35,7 +36,12 @@ end
---Loads the file into RFT and initializes it if needed, note that this needs RDR2 mode 2
---@param path string
---@param id integer
function load_rft_file(path, id)
function load_station_logo(path, id)
if id == _Rft_last_id then
_Rft_toggle = not _Rft_toggle
_Rft_version = _Rft_version + 1
if _Rft_version > 7 then _Rft_version = 0 end
end
local file = io.open(path, "rb")
if not file then error("Could not open file") end
_Rft_file = file:read("*a")
@@ -44,5 +50,6 @@ function load_rft_file(path, id)
if #_Rft_file > 262143 then error("The file is too large", 2) end
if _Rft_oda_id == nil then start_rft() end
---@diagnostic disable-next-line: param-type-mismatch
set_oda_id_data_rds2(_Rft_oda_id, #_Rft_file | id << 18)
set_oda_id_data_rds2(_Rft_oda_id, #_Rft_file | (id & 63) << 18 | (_Rft_version & 7) << 24 | 0 << 27)
_Rft_last_id = id
end

View File

@@ -401,6 +401,11 @@ int lua_set_rds_udg2(lua_State *localL) {
return 0;
}
int lua_get_available_rds_streams(lua_State *localL) {
lua_pushinteger(localL, mod->num_streams);
return 1
}
void init_lua(RDSModulator* rds_mod) {
static int mutex_initialized = 0;
mod = rds_mod;
@@ -470,6 +475,7 @@ void init_lua(RDSModulator* rds_mod) {
lua_register(L, "set_rds_streams", lua_set_rds_streams);
lua_register(L, "get_rds_streams", lua_get_rds_streams);
lua_register(L, "get_available_rds_streams", lua_get_available_rds_streams);
lua_register(L, "set_rds_grpseq", lua_set_rds_grp_sqc);
lua_register(L, "get_rds_grpseq", lua_get_rds_grp_sqc);