mirror of
https://github.com/radio95-rnt/rds95.git
synced 2026-02-26 12:32:05 +01:00
improvements (no way)
This commit is contained in:
10
plugin.lua
10
plugin.lua
@@ -304,6 +304,10 @@ function set_rds_af_oda(afs) end
|
||||
---@return integer oda_id
|
||||
function register_oda(group, group_version, aid, data) end
|
||||
|
||||
---Unregisters an ODA, this stops the handler or AID being called/sent
|
||||
---@param oda_id integer
|
||||
function unregister_oda(oda_id) end
|
||||
|
||||
---Sets the data for a existing ODA group
|
||||
---@param oda_id integer
|
||||
---@param data integer
|
||||
@@ -340,7 +344,7 @@ function get_userdata() end
|
||||
function get_userdata_offset(offset, size) end
|
||||
|
||||
---The callback function for an ODA handler
|
||||
---@alias RDS2_ODAHandler fun(): (boolean, integer, integer, integer, integer)
|
||||
---@alias RDS2_ODAHandler fun(integer): (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))
|
||||
@@ -360,6 +364,10 @@ function set_oda_id_data_rds2(oda_id, data) end
|
||||
---@return integer oda_id
|
||||
function register_oda_rds2(aid, data, file_related) end
|
||||
|
||||
---Unregisters an RDS 2 ODA, this stops the handler or AID being called/sent
|
||||
---@param oda_id integer
|
||||
function unregister_oda_rds2(oda_id) end
|
||||
|
||||
---This function is defined externally
|
||||
---Loads the file into RFT and initializes it if needed, note that this needs RDR2 mode 2
|
||||
---@param path string
|
||||
|
||||
@@ -21,15 +21,32 @@ 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)
|
||||
for i = 1, #_RDS_ODAs do
|
||||
if _RDS_ODAs[i] == false then
|
||||
_RDS_ODAs[i] = oda
|
||||
return i
|
||||
end
|
||||
end
|
||||
table.insert(_RDS_ODAs, oda)
|
||||
return #_RDS_ODAs
|
||||
end
|
||||
|
||||
---Unregisters an ODA, this stops the handler or AID being called/sent
|
||||
---@param oda_id integer
|
||||
function unregister_oda(oda_id)
|
||||
if oda_id < 1 or oda_id > #_RDS_ODAs or _RDS_ODAs[oda_id] == false then error("Invalid ODA ID: " .. tostring(oda_id), 2) end
|
||||
|
||||
_RDS_ODAs[oda_id] = false
|
||||
|
||||
if _RDS_ODA_pointer == oda_id then _RDS_ODA_pointer = (_RDS_ODA_pointer % #_RDS_ODAs) + 1 end
|
||||
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 < 1 or oda_id > #_RDS_ODAs then error("Invalid ODA ID: " .. tostring(oda_id), 2) end
|
||||
if oda_id < 1 or oda_id > #_RDS_ODAs or _RDS_ODAs[oda_id] == false then error("Invalid ODA ID: " .. tostring(oda_id), 2) end
|
||||
_RDS_ODAs[oda_id].data = data
|
||||
end
|
||||
|
||||
@@ -41,29 +58,40 @@ end
|
||||
---@param oda_id integer The ID returned by register_oda
|
||||
---@param fun ODAHandler
|
||||
function set_oda_handler(oda_id, fun)
|
||||
if oda_id < 1 or oda_id > #_RDS_ODAs then error("Invalid ODA ID: " .. tostring(oda_id), 2) end
|
||||
if oda_id < 1 or oda_id > #_RDS_ODAs or _RDS_ODAs[oda_id] == false then error("Invalid ODA ID: " .. tostring(oda_id), 2) end
|
||||
if _RDS_ODAs[oda_id].group == 3 then error("3A ODAs cannot have handlers.", 2) end
|
||||
_RDS_ODAs[oda_id].handler = fun
|
||||
end
|
||||
|
||||
local function get_aid()
|
||||
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
|
||||
local checked = 0
|
||||
|
||||
_RDS_ODA_pointer = (_RDS_ODA_pointer % #_RDS_ODAs) + 1
|
||||
while checked < #_RDS_ODAs do
|
||||
local oda = _RDS_ODAs[_RDS_ODA_pointer]
|
||||
|
||||
return b, data, aid
|
||||
if oda ~= false then
|
||||
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
|
||||
return b, data, aid
|
||||
end
|
||||
|
||||
_RDS_ODA_pointer = (_RDS_ODA_pointer % #_RDS_ODAs) + 1
|
||||
checked = checked + 1
|
||||
end
|
||||
|
||||
return false, 0, 0, 0
|
||||
end
|
||||
|
||||
|
||||
local function get_data()
|
||||
local checked_count = 0
|
||||
local total_odas = #_RDS_ODAs
|
||||
|
||||
while checked_count < total_odas do
|
||||
while checked_count < #_RDS_ODAs do
|
||||
local oda = _RDS_ODAs[_RDS_ODA_pointer]
|
||||
|
||||
if type(oda.handler) == "function" then
|
||||
if oda ~= false and type(oda.handler) == "function" then
|
||||
local generated, b, c, d = oda.handler()
|
||||
_RDS_ODA_pointer = (_RDS_ODA_pointer % #_RDS_ODAs) + 1
|
||||
b = b | oda.group << 12
|
||||
@@ -84,8 +112,7 @@ function group(group_type)
|
||||
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()
|
||||
return true, b, c, d
|
||||
return get_aid()
|
||||
elseif group_type == "K" then
|
||||
return get_data()
|
||||
end
|
||||
|
||||
@@ -17,15 +17,32 @@ _RDS2_ODA_pointer = 1
|
||||
---@return integer oda_id
|
||||
function register_oda_rds2(aid, data, file_related)
|
||||
local oda = _RDS2_ODA.new(aid, data, false, file_related)
|
||||
for i = 1, #_RDS2_ODAs do
|
||||
if _RDS2_ODAs[i] == false then
|
||||
_RDS2_ODAs[i] = oda
|
||||
return i
|
||||
end
|
||||
end
|
||||
table.insert(_RDS2_ODAs, oda)
|
||||
return #_RDS2_ODAs
|
||||
end
|
||||
|
||||
---Unregisters an RDS 2 ODA, this stops the handler or AID being called/sent
|
||||
---@param oda_id integer
|
||||
function unregister_oda_rds2(oda_id)
|
||||
if oda_id < 1 or oda_id > #_RDS2_ODAs or _RDS2_ODAs[oda_id] == false then error("Invalid ODA ID: " .. tostring(oda_id), 2) end
|
||||
|
||||
_RDS2_ODAs[oda_id] = false
|
||||
|
||||
if _RDS2_ODA_pointer == oda_id then _RDS2_ODA_pointer = _RDS2_ODA_pointer + 1 end
|
||||
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 < 1 or oda_id > #_RDS2_ODAs then error("Invalid ODA ID: " .. tostring(oda_id), 2) end
|
||||
if oda_id < 1 or oda_id > #_RDS2_ODAs or _RDS2_ODAs[oda_id] == false then error("Invalid ODA ID: " .. tostring(oda_id), 2) end
|
||||
_RDS2_ODAs[oda_id].data = data
|
||||
end
|
||||
|
||||
@@ -33,12 +50,22 @@ end
|
||||
---@param oda_id integer
|
||||
---@param func RDS2_ODAHandler
|
||||
function set_oda_handler_rds2(oda_id, func)
|
||||
if oda_id < 1 or oda_id > #_RDS2_ODAs then error("Invalid ODA ID: " .. tostring(oda_id), 2) end
|
||||
if oda_id < 1 or oda_id > #_RDS2_ODAs or _RDS2_ODAs[oda_id] == false then error("Invalid ODA ID: " .. tostring(oda_id), 2) end
|
||||
_RDS2_ODAs[oda_id].handler = func
|
||||
end
|
||||
|
||||
function rds2_group(stream)
|
||||
if #_RDS2_ODAs == 0 then return false, 0, 0, 0, 0 end
|
||||
|
||||
local checked = 0
|
||||
while checked < #_RDS2_ODAs and _RDS2_ODAs[_RDS2_ODA_pointer] == false do
|
||||
_RDS2_ODA_pointer = _RDS2_ODA_pointer + 1
|
||||
if _RDS2_ODA_pointer > #_RDS2_ODAs then _RDS2_ODA_pointer = 1 end
|
||||
checked = checked + 1
|
||||
end
|
||||
|
||||
if checked == #_RDS2_ODAs 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]
|
||||
|
||||
@@ -10,19 +10,19 @@ _Rft_crc = false
|
||||
_Rft_crc_full_file = 0
|
||||
_Rft_crc_mode = 0
|
||||
_Rft_crc_sent = false
|
||||
_Rft_aid = 0xFF7F
|
||||
_Rft_aid = 0
|
||||
|
||||
local function start_rft()
|
||||
if _Rft_oda_id == nil then
|
||||
if _Rft_oda_id == nil and _Rft_aid ~= 0 then
|
||||
_Rft_oda_id = register_oda_rds2(_Rft_aid, 0, true)
|
||||
set_oda_handler_rds2(_Rft_oda_id, function ()
|
||||
set_oda_handler_rds2(_Rft_oda_id, function (stream)
|
||||
if #_Rft_file == 0 then return false, 0, 0, 0, 0 end
|
||||
|
||||
local total_segments = math.ceil(#_Rft_file / 5)
|
||||
local seg = _Rft_file_segment
|
||||
local base = seg * 5 + 1
|
||||
|
||||
if not _Rft_crc_sent and _Rft_crc and (seg % 16 == 0) then
|
||||
if not _Rft_crc_sent and _Rft_crc and (seg % 16 == 0) and stream == 1 then
|
||||
_Rft_crc_sent = true
|
||||
local chunk_address = math.floor((_Rft_crc_segment - 1) / 2)
|
||||
local c = (1 << 12) | (_Rft_crc_mode & 7) << 9 | (chunk_address & 0x1ff)
|
||||
@@ -39,7 +39,7 @@ local function start_rft()
|
||||
|
||||
_Rft_crc_segment = _Rft_crc_segment + 2
|
||||
if _Rft_crc_segment > #_Rft_crc_data then _Rft_crc_segment = 1 end
|
||||
|
||||
|
||||
return true, (2 << 14), _Rft_aid, c, (high_byte << 8) | low_byte
|
||||
else
|
||||
_Rft_crc_sent = false
|
||||
@@ -60,12 +60,35 @@ local function start_rft()
|
||||
end
|
||||
end
|
||||
|
||||
local function stop_rft()
|
||||
if _Rft_oda_id ~= nil and _Rft_aid ~= 0 then
|
||||
unregister_oda_rds2(_Rft_oda_id)
|
||||
_Rft_oda_id = nil
|
||||
_Rft_aid = 0
|
||||
end
|
||||
|
||||
_Rft_file = ""
|
||||
_Rft_crc_data = ""
|
||||
_Rft_file_segment = 0
|
||||
_Rft_crc_segment = 0
|
||||
_Rft_toggle = false
|
||||
_Rft_last_id = -1
|
||||
_Rft_version = 0
|
||||
_Rft_crc = false
|
||||
_Rft_crc_full_file = 0
|
||||
_Rft_crc_mode = 0
|
||||
_Rft_crc_sent = false
|
||||
end
|
||||
|
||||
---This function is defined externally
|
||||
---Loads the file into RFT and initializes it if needed, note that this needs RDR2 mode 2
|
||||
---@param path string
|
||||
---@param id integer
|
||||
---@param crc integer|boolean
|
||||
---@param path string filesystem path on the os
|
||||
---@param id integer mostly use 0 here
|
||||
---@param crc integer|boolean false for disabled, true for mode 7, and an integer for any of the modes
|
||||
function load_station_logo(path, id, crc)
|
||||
if _Rft_aid ~= 0xFF7F then stop_rft() end
|
||||
_Rft_aid = 0xFF7F
|
||||
|
||||
local file = io.open(path, "rb")
|
||||
if not file then error("Could not open file") end
|
||||
_Rft_file = file:read("*a")
|
||||
@@ -78,72 +101,63 @@ function load_station_logo(path, id, crc)
|
||||
if _Rft_version > 7 then _Rft_version = 0 end
|
||||
end
|
||||
|
||||
_Rft_crc_data = "" -- Clear previous CRC data
|
||||
_Rft_crc_data = ""
|
||||
_Rft_crc = (crc ~= false)
|
||||
|
||||
local chunk_size = 0
|
||||
if crc and crc == 0 then
|
||||
_Rft_crc_mode = 0
|
||||
_Rft_crc_full_file = crc16(_Rft_file)
|
||||
elseif crc and crc == 1 and #_Rft_file <= 40960 then
|
||||
_Rft_crc_mode = 1
|
||||
local chunk_size = 5 * 16 -- 80 bytes
|
||||
for i = 1, #_Rft_file, chunk_size do
|
||||
local chunk = string.sub(_Rft_file, i, i + chunk_size - 1)
|
||||
local crc_val = crc16(chunk)
|
||||
_Rft_crc_data = _Rft_crc_data .. string.char(math.floor(crc_val / 256), crc_val % 256)
|
||||
end
|
||||
chunk_size = 5 * 16
|
||||
elseif crc and crc == 2 and #_Rft_file < 40960 and #_Rft_file >= 81920 then
|
||||
_Rft_crc_mode = 2
|
||||
local chunk_size = 5 * 32
|
||||
for i = 1, #_Rft_file, chunk_size do
|
||||
local chunk = string.sub(_Rft_file, i, i + chunk_size - 1)
|
||||
local crc_val = crc16(chunk)
|
||||
_Rft_crc_data = _Rft_crc_data .. string.char(math.floor(crc_val / 256), crc_val % 256)
|
||||
end
|
||||
chunk_size = 5 * 32
|
||||
elseif crc and crc == 3 and #_Rft_file > 81960 then
|
||||
_Rft_crc_mode = 3
|
||||
local chunk_size = 5 * 64
|
||||
for i = 1, #_Rft_file, chunk_size do
|
||||
local chunk = string.sub(_Rft_file, i, i + chunk_size - 1)
|
||||
local crc_val = crc16(chunk)
|
||||
_Rft_crc_data = _Rft_crc_data .. string.char(math.floor(crc_val / 256), crc_val % 256)
|
||||
end
|
||||
chunk_size = 5 * 64
|
||||
elseif crc and crc == 4 and #_Rft_file > 81960 then
|
||||
_Rft_crc_mode = 4
|
||||
local chunk_size = 5 * 128
|
||||
for i = 1, #_Rft_file, chunk_size do
|
||||
local chunk = string.sub(_Rft_file, i, i + chunk_size - 1)
|
||||
local crc_val = crc16(chunk)
|
||||
_Rft_crc_data = _Rft_crc_data .. string.char(math.floor(crc_val / 256), crc_val % 256)
|
||||
end
|
||||
chunk_size = 5 * 128
|
||||
elseif crc and crc == 5 and #_Rft_file > 81960 then
|
||||
_Rft_crc_mode = 5
|
||||
local chunk_size = 5 * 256
|
||||
for i = 1, #_Rft_file, chunk_size do
|
||||
local chunk = string.sub(_Rft_file, i, i + chunk_size - 1)
|
||||
local crc_val = crc16(chunk)
|
||||
_Rft_crc_data = _Rft_crc_data .. string.char(math.floor(crc_val / 256), crc_val % 256)
|
||||
end
|
||||
chunk_size = 5 * 256
|
||||
elseif crc and (crc == 7 or crc == true) then
|
||||
_Rft_crc_mode = 7
|
||||
local chunk_size = 0
|
||||
if #_Rft_file <= 40960 then chunk_size = 5*16
|
||||
elseif #_Rft_file > 40960 and #_Rft_file <= 81920 then chunk_size = 5*32
|
||||
elseif #_Rft_file > 81960 then chunk_size = 5*64 end
|
||||
if chunk_size ~= 0 then
|
||||
for i = 1, #_Rft_file, chunk_size do
|
||||
local chunk = string.sub(_Rft_file, i, i + chunk_size - 1)
|
||||
local crc_val = crc16(chunk)
|
||||
_Rft_crc_data = _Rft_crc_data .. string.char(math.floor(crc_val / 256), crc_val % 256)
|
||||
end
|
||||
if #_Rft_file <= 40960 then
|
||||
_Rft_crc_mode = 1
|
||||
chunk_size = 5*16
|
||||
elseif #_Rft_file > 40960 and #_Rft_file <= 81920 then
|
||||
_Rft_crc_mode = 2
|
||||
chunk_size = 5*32
|
||||
elseif #_Rft_file > 81960 then
|
||||
_Rft_crc_mode = 3
|
||||
chunk_size = 5*64
|
||||
end
|
||||
else
|
||||
_Rft_crc = false
|
||||
end
|
||||
|
||||
if _Rft_crc and chunk_size ~= 0 then
|
||||
for i = 1, #_Rft_file, chunk_size do
|
||||
local chunk = string.sub(_Rft_file, i, i + chunk_size - 1)
|
||||
local crc_val = crc16(chunk)
|
||||
_Rft_crc_data = _Rft_crc_data .. string.char(math.floor(crc_val / 256), crc_val % 256)
|
||||
end
|
||||
end
|
||||
|
||||
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 & 63) << 18 | (_Rft_version & 7) << 24 | (_Rft_crc and 1 or 0) << 27)
|
||||
_Rft_last_id = id
|
||||
end
|
||||
end
|
||||
|
||||
local _old_on_state_oda_rds2 = on_state
|
||||
function on_state()
|
||||
stop_rft()
|
||||
_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
|
||||
|
||||
Reference in New Issue
Block a user