0
1
mirror of https://github.com/radio95-rnt/rds95.git synced 2026-02-26 12:32:05 +01:00

on god, i can send 48 bits?

This commit is contained in:
2025-12-27 15:03:23 +01:00
parent 2a2a8713b3
commit e32558ecf5
6 changed files with 87 additions and 49 deletions

View File

@@ -24,7 +24,6 @@
},
"Lua.runtime.plugin": "plugin.lua",
"Lua.runtime.builtin": {
"io": "disable",
"debug": "disable",
"os": "disable",
"jit": "disable",

View File

@@ -286,6 +286,7 @@ 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
---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
@@ -295,6 +296,7 @@ function set_rds_udg2(xy, groups) end
---@param id_data integer
---@return integer oda_id
function register_oda(group, group_version, id, id_data) end
---This function is defined externally
---Sets the id_data for a existing ODA group
---@param oda_id integer
---@param data integer
@@ -346,5 +348,6 @@ function set_oda_id_data_rds2(oda_id, data) end
---This function is defined externally
---@param aid integer
---@param data integer
---@param file_related boolean
---@return integer oda_id
function register_oda_rds2(aid, data) end
function register_oda_rds2(aid, data, file_related) end

View File

@@ -1,13 +1,13 @@
local ODA = { group = 0, group_version = false, aid = 0, data = 0, handler = false }
local _ODA = { group = 0, group_version = false, aid = 0, data = 0, handler = false }
function ODA.new(group, group_version, aid, data, handler)
function _ODA.new(group, group_version, aid, data, handler)
local instance = { group = group or 0, group_version = group_version or false, aid = aid or 0, data = data or 0, handler = handler or false }
setmetatable(instance, { __index = ODA })
setmetatable(instance, { __index = _ODA })
return instance
end
local RDS_ODAs = {}
local RDS_ODA_pointer = 1
local _RDS_ODAs = {}
local _RDS_ODA_pointer = 1
---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
@@ -20,17 +20,17 @@ local RDS_ODA_pointer = 1
function register_oda(group, group_version, aid, data)
if group == 14 or group == 15 or group == 2 or group == 0 then error("Group is incorrect", 2) end
if (group == 10 or group == 4 or group == 1) and group_version then error("Group is incorrect", 2) end
local oda = ODA.new(group, group_version, aid, data, false)
table.insert(RDS_ODAs, oda)
return #RDS_ODAs
local oda = _ODA.new(group, group_version, aid, data, false)
table.insert(_RDS_ODAs, oda)
return #_RDS_ODAs
end
---Sets the id_data for a existing ODA group
---@param oda_id integer
---@param data integer
function set_oda_id_data(oda_id, data)
if oda_id > #RDS_ODAs then return end
RDS_ODAs[oda_id].data = data
if oda_id > #_RDS_ODAs then return end
_RDS_ODAs[oda_id].data = data
end
---Sets a function to handle the ODA data generation.
@@ -41,36 +41,36 @@ end
---@param oda_id integer The ID returned by register_oda
---@param fun ODAHandler
function set_oda_handler(oda_id, fun)
if oda_id > #RDS_ODAs then return end
RDS_ODAs[oda_id].handler = fun
if oda_id > #_RDS_ODAs then return end
_RDS_ODAs[oda_id].handler = fun
end
local function get_aid()
local oda = RDS_ODAs[RDS_ODA_pointer]
local oda = _RDS_ODAs[_RDS_ODA_pointer]
local b = 3 << 12 | oda.group << 1 | (oda.group_version and 1 or 0)
local data, aid = oda.data, oda.aid
RDS_ODA_pointer = (RDS_ODA_pointer % #RDS_ODAs) + 1
_RDS_ODA_pointer = (_RDS_ODA_pointer % #_RDS_ODAs) + 1
return b, data, aid
end
local function get_data()
local checked_count = 0
local total_odas = #RDS_ODAs
local total_odas = #_RDS_ODAs
while checked_count < total_odas do
local oda = RDS_ODAs[RDS_ODA_pointer]
local oda = _RDS_ODAs[_RDS_ODA_pointer]
if type(oda.handler) == "function" then
local generated, b, c, d = oda.handler()
RDS_ODA_pointer = (RDS_ODA_pointer % #RDS_ODAs) + 1
_RDS_ODA_pointer = (_RDS_ODA_pointer % #_RDS_ODAs) + 1
b = b | oda.group << 12
b = b | (oda.group_version and 1 or 0) << 11
return generated, b, c, d
end
RDS_ODA_pointer = (RDS_ODA_pointer % #RDS_ODAs) + 1
_RDS_ODA_pointer = (_RDS_ODA_pointer % #_RDS_ODAs) + 1
checked_count = checked_count + 1
end
@@ -79,8 +79,8 @@ end
function group(group_type)
if group_type == "O" or group_type == "K" then
if #RDS_ODAs == 0 then return false, 0, 0, 0 end
if RDS_ODA_pointer > #RDS_ODAs or RDS_ODA_pointer < 1 then RDS_ODA_pointer = 1 end
if #_RDS_ODAs == 0 then return false, 0, 0, 0 end
if _RDS_ODA_pointer > #_RDS_ODAs or _RDS_ODA_pointer < 1 then _RDS_ODA_pointer = 1 end
if group_type == "O" then
local b, c, d = get_aid()

View File

@@ -1,57 +1,82 @@
local RDS2_ODA = { aid = 0, data = 0, handler = false }
_RDS2_ODA = { aid = 0, data = 0, handler = false, file_related = false }
function RDS2_ODA.new(aid, data, handler)
local instance = { aid = aid or 0, data = data or 0, handler = handler or false }
setmetatable(instance, { __index = RDS2_ODA })
function _RDS2_ODA.new(aid, data, handler, file_related)
local instance = { aid = aid or 0, data = data or 0, handler = handler or false, file_related = file_related or false }
setmetatable(instance, { __index = _RDS2_ODA })
return instance
end
local RDS2_ODAs = {}
local RDS2_ODA_aid = true
local RDS2_ODA_pointer = 1
_RDS2_ODAs = {}
_RDS2_ODA_aid = 0
_RDS2_ODA_pointer = 1
---This function is defined externally
---@param aid integer
---@param data integer
---@param file_related boolean
---@return integer oda_id
function register_oda_rds2(aid, data)
local oda = RDS2_ODA.new(aid, data, false)
table.insert(RDS2_ODAs, oda)
return #RDS2_ODAs
function register_oda_rds2(aid, data, file_related)
local oda = _RDS2_ODA.new(aid, data, false, file_related)
table.insert(_RDS2_ODAs, oda)
return #_RDS2_ODAs
end
---This function is defined externally
---@param oda_id integer
---@param data integer
function set_oda_id_data_rds2(oda_id, data)
if oda_id > #RDS2_ODAs then return end
RDS2_ODAs[oda_id].data = data
if oda_id > #_RDS2_ODAs then return end
_RDS2_ODAs[oda_id].data = data
end
---This function is defined externally
---@param oda_id integer
---@param func RDS2_ODAHandler
function set_oda_handler_rds2(oda_id, func)
if oda_id > #RDS2_ODAs then return end
RDS2_ODAs[oda_id].handler = func
if oda_id > #_RDS2_ODAs then return end
_RDS2_ODAs[oda_id].handler = func
end
function rds2_group(stream)
if #RDS2_ODAs == 0 then return false, 0, 0, 0, 0 end
if RDS2_ODA_pointer > #RDS2_ODAs then RDS2_ODA_pointer = 1 end
local oda = RDS2_ODAs[RDS2_ODA_pointer]
local channel = (RDS2_ODA_pointer & 0x40) << 8
RDS2_ODA_pointer = RDS2_ODA_pointer + 1
if RDS2_ODA_aid then
-- TODO: add support for the multi aid thing (page 49)
RDS2_ODA_aid = not RDS2_ODA_aid
return true, 1 << 15 | channel, oda.aid, (oda.data & 0xffff0000) >> 16, (oda.data & 0xffff)
if #_RDS2_ODAs == 0 then return false, 0, 0, 0, 0 end
if _RDS2_ODA_pointer > #_RDS2_ODAs then _RDS2_ODA_pointer = 1 end
local oda = _RDS2_ODAs[_RDS2_ODA_pointer]
local channel_offset = 16 * (oda.file_related and 1 or 0)
local channel = ((_RDS2_ODA_pointer - 1 + channel_offset) & 0x3F)
_RDS2_ODA_pointer = _RDS2_ODA_pointer + 1
local next_oda = nil
if _RDS2_ODA_pointer <= #_RDS2_ODAs then next_oda = _RDS2_ODAs[_RDS2_ODA_pointer] end
if _RDS2_ODA_aid == 0 then
_RDS2_ODA_aid = 1
local block1_base = (1 << 15) | channel
if next_oda ~= nil and next_oda.data ~= 0 and oda.data <= 0xffff then
_RDS2_ODA_pointer = _RDS2_ODA_pointer + 1
return true, block1_base | (1 << 6), oda.aid, oda.data, next_oda.aid
elseif next_oda ~= nil and oda.data == 0 and next_oda.data <= 0xffff and next_oda.data ~= 0 then
_RDS2_ODA_pointer = _RDS2_ODA_pointer + 1
return true, block1_base | (2 << 6), oda.aid, next_oda.aid, next_oda.data
elseif next_oda ~= nil and oda.data == 0 and next_oda.data == 0 then
_RDS2_ODA_pointer = _RDS2_ODA_pointer + 1
if _RDS2_ODA_pointer <= #_RDS2_ODAs then
local third_oda = _RDS2_ODAs[_RDS2_ODA_pointer]
_RDS2_ODA_pointer = _RDS2_ODA_pointer + 1
return true, block1_base | (3 << 6), oda.aid, next_oda.aid, third_oda.aid
else return true, block1_base, oda.aid, (oda.data >> 16) & 0xffff, oda.data & 0xffff end
end
return true, block1_base, oda.aid, (oda.data >> 16) & 0xffff, oda.data & 0xffff
else
RDS2_ODA_aid = not RDS2_ODA_aid
_RDS2_ODA_aid = _RDS2_ODA_aid + 1
if _RDS2_ODA_aid > 2 then _RDS2_ODA_aid = 0 end
if oda.handler then
local generated, a, b, c, d = oda.handler(stream)
return generated, 1 << 14 | channel | a, b, c, d
return generated, (1 << 14) | (channel << 8) | a, b, c, d
end
return true, 1 << 15 | channel, oda.aid, (oda.data & 0xffff0000) >> 16, (oda.data & 0xffff)
return true, (1 << 15) | channel, oda.aid, (oda.data >> 16) & 0xffff, oda.data & 0xffff
end
end

View File

@@ -0,0 +1,10 @@
local _rds2_test_counter = 0
local function rds2_oda_test()
local id = register_oda_rds2(0xfffe, 0xfffff, false)
set_oda_handler_rds2(id, function ()
_rds2_test_counter = _rds2_test_counter + 1
if _rds2_test_counter > 0xffffffffffff then _rds2_test_counter = 0 end
return true, 0, (_rds2_test_counter & 0xffff00000000) >> 32, (_rds2_test_counter & 0xffff0000) >> 16, _rds2_test_counter & 0xffff
end)
end

View File

@@ -414,6 +414,7 @@ void init_lua(RDSModulator* rds_mod) {
luaL_requiref(L, LUA_UTF8LIBNAME, luaopen_utf8, 1);
luaL_requiref(L, LUA_COLIBNAME, luaopen_coroutine, 1);
luaL_requiref(L, LUA_MATHLIBNAME, luaopen_math, 1);
luaL_requiref(L, LUA_IOLIBNAME, luaopen_io, 1);
lua_pop(L, 6);
lua_pushstring(L, VERSION);