From 6552d3dc9d8733f1bd0cc031377a0cbc2edd9308 Mon Sep 17 00:00:00 2001 From: KubaPro010 Date: Sun, 28 Dec 2025 16:01:15 +0100 Subject: [PATCH] some adjustments and smart detections --- plugin.lua | 89 ++++++++++++++++++++++-------------------- scripts/0-oda.lua | 8 ++++ scripts/0-rds2_oda.lua | 17 +++++++- scripts/1-rft.lua | 13 ++++-- src/lua_rds.c | 6 +++ 5 files changed, 86 insertions(+), 47 deletions(-) diff --git a/plugin.lua b/plugin.lua index 9d4684d..60b5835 100644 --- a/plugin.lua +++ b/plugin.lua @@ -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 diff --git a/scripts/0-oda.lua b/scripts/0-oda.lua index b56e60e..925ca70 100644 --- a/scripts/0-oda.lua +++ b/scripts/0-oda.lua @@ -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 @@ -90,4 +91,11 @@ function group(group_type) end 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 \ No newline at end of file diff --git a/scripts/0-rds2_oda.lua b/scripts/0-rds2_oda.lua index b09fcbf..abe08bc 100644 --- a/scripts/0-rds2_oda.lua +++ b/scripts/0-rds2_oda.lua @@ -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 \ No newline at end of file diff --git a/scripts/1-rft.lua b/scripts/1-rft.lua index 06e3577..b003d91 100644 --- a/scripts/1-rft.lua +++ b/scripts/1-rft.lua @@ -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 \ No newline at end of file diff --git a/src/lua_rds.c b/src/lua_rds.c index 051090f..9287d86 100644 --- a/src/lua_rds.c +++ b/src/lua_rds.c @@ -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);