mirror of
https://github.com/radio95-rnt/rds95.git
synced 2026-02-26 20:33:53 +01:00
massive lua api refactor
This commit is contained in:
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@@ -30,5 +30,8 @@
|
|||||||
"ffi": "disable",
|
"ffi": "disable",
|
||||||
"package": "disable"
|
"package": "disable"
|
||||||
},
|
},
|
||||||
"C_Cpp.dimInactiveRegions": false
|
"C_Cpp.dimInactiveRegions": false,
|
||||||
|
"Lua.diagnostics.disable": [
|
||||||
|
"duplicate-set-field"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
196
plugin.lua
196
plugin.lua
@@ -3,48 +3,62 @@
|
|||||||
-- Global Variables
|
-- Global Variables
|
||||||
---@type string
|
---@type string
|
||||||
core_version = ""
|
core_version = ""
|
||||||
---@type integer
|
|
||||||
eon_count = 0
|
|
||||||
---@type integer
|
|
||||||
max_programs = 0
|
|
||||||
---@type integer
|
|
||||||
user_data_len = 0
|
|
||||||
|
|
||||||
--#region Functions implemented or used in C
|
--#region Functions implemented or used in C
|
||||||
|
|
||||||
---Executes a CRC-16 CCIIT
|
dp = {}
|
||||||
|
|
||||||
|
---@type integer
|
||||||
|
dp.max_programs = 0
|
||||||
|
|
||||||
|
---Executes a CRC-16 CCIIT on given data
|
||||||
---@param data string
|
---@param data string
|
||||||
---@return integer
|
---@return integer
|
||||||
function crc16(data) end
|
function dp.crc16(data) end
|
||||||
|
|
||||||
---Starts the initialization sequence, also calls the on_init function
|
---Starts the initialization sequence, also calls the on_init function
|
||||||
---@return nil
|
---@return nil
|
||||||
function set_rds_program_defaults() end
|
function dp.set_rds_program_defaults() end
|
||||||
|
|
||||||
---Saves, loads and resets the state of the data, you might as well restart the whole program
|
---Saves, loads and resets the state of the data, you might as well restart the whole program
|
||||||
---@return nil
|
---@return nil
|
||||||
function reset_rds() end
|
function dp.reset_rds() end
|
||||||
|
|
||||||
---Forces encoder and modulator data to be saved to disc
|
---Forces encoder and modulator data to be saved to disc
|
||||||
---@return nil
|
---@return nil
|
||||||
function force_save() end
|
function dp.force_save() end
|
||||||
|
|
||||||
|
---@param program_idx integer 0 to (max_programs - 1)
|
||||||
|
function dp.set_rds_program(program_idx) end
|
||||||
|
---@return integer
|
||||||
|
function dp.get_rds_program() end
|
||||||
|
|
||||||
---This function is called by the C core after we reset data, or have no data in general
|
---This function is called by the C core after we reset data, or have no data in general
|
||||||
---It should be defined by the user in the script.
|
---It should be defined by the user in the script.
|
||||||
---@return nil
|
---@return nil
|
||||||
function on_init() end
|
function on_init() end
|
||||||
|
on_inits = {}
|
||||||
|
|
||||||
---This function is called by the C core after we initialize the encoder (always, every start)
|
---This function is called by the C core after we initialize the encoder (always, every start)
|
||||||
---It should be defined by the user in the script.
|
---It should be defined by the user in the script.
|
||||||
---@return nil
|
---@return nil
|
||||||
function on_start() end
|
function on_start() end
|
||||||
|
on_starts = {}
|
||||||
|
|
||||||
---This function is called every time when the state resets, register your odas here
|
---This function is called every time when the state resets, register your odas here
|
||||||
---It should be defined by the user in the script.
|
---It should be defined by the user in the script.
|
||||||
---@return nil
|
---@return nil
|
||||||
function on_state() end
|
function on_state() end
|
||||||
|
on_states = {}
|
||||||
|
|
||||||
---This function is called every second
|
---This function is called every second
|
||||||
---It should be defined by the user in the script.
|
---It should be defined by the user in the script.
|
||||||
---@return nil
|
---@return nil
|
||||||
function tick() end
|
function tick() end
|
||||||
|
ticks = {}
|
||||||
|
|
||||||
|
-- Every function with with the s suffixed table means that other versions of that function can be in that list-table, and each one will be called
|
||||||
|
|
||||||
---This function is called in order to handle UDP data
|
---This function is called in order to handle UDP data
|
||||||
---It should be defined by the user in the script.
|
---It should be defined by the user in the script.
|
||||||
---@param data string
|
---@param data string
|
||||||
@@ -70,72 +84,77 @@ function group(group) end
|
|||||||
---@return integer d
|
---@return integer d
|
||||||
function rds2_group(stream) end
|
function rds2_group(stream) end
|
||||||
|
|
||||||
|
rds = {}
|
||||||
|
|
||||||
|
---@type integer
|
||||||
|
rds.eon_count = 0
|
||||||
|
|
||||||
---@param pi integer
|
---@param pi integer
|
||||||
function set_rds_pi(pi) end
|
function rds.set_pi(pi) end
|
||||||
---@return integer
|
---@return integer
|
||||||
function get_rds_pi() end
|
function rds.get_pi() end
|
||||||
|
|
||||||
---@param pty integer
|
---@param pty integer
|
||||||
function set_rds_pty(pty) end
|
function rds.set_pty(pty) end
|
||||||
---@return integer
|
---@return integer
|
||||||
function get_rds_pty() end
|
function rds.get_pty() end
|
||||||
|
|
||||||
---@param ecc integer
|
---@param ecc integer
|
||||||
function set_rds_ecc(ecc) end
|
function rds.set_ecc(ecc) end
|
||||||
---@return integer
|
---@return integer
|
||||||
function get_rds_ecc() end
|
function rds.get_ecc() end
|
||||||
|
|
||||||
---@param slc_data integer
|
---@param slc_data integer
|
||||||
function set_rds_slc_data(slc_data) end
|
function rds.set_slc_data(slc_data) end
|
||||||
---@return integer
|
---@return integer
|
||||||
function get_rds_slc_data() end
|
function rds.get_slc_data() end
|
||||||
|
|
||||||
---@param ct boolean
|
---@param ct boolean
|
||||||
function set_rds_ct(ct) end
|
function rds.set_ct(ct) end
|
||||||
---@return boolean
|
---@return boolean
|
||||||
function get_rds_ct() end
|
function rds.get_ct() end
|
||||||
|
|
||||||
---@param dpty boolean
|
---@param dpty boolean
|
||||||
function set_rds_dpty(dpty) end
|
function rds.set_dpty(dpty) end
|
||||||
---@return boolean
|
---@return boolean
|
||||||
function get_rds_dpty() end
|
function rds.get_dpty() end
|
||||||
|
|
||||||
---@param tp boolean
|
---@param tp boolean
|
||||||
function set_rds_tp(tp) end
|
function rds.set_tp(tp) end
|
||||||
---@return boolean
|
---@return boolean
|
||||||
function get_rds_tp() end
|
function rds.get_tp() end
|
||||||
|
|
||||||
---@param ta boolean
|
---@param ta boolean
|
||||||
function set_rds_ta(ta) end
|
function rds.set_ta(ta) end
|
||||||
---@return boolean
|
---@return boolean
|
||||||
function get_rds_ta() end
|
function rds.get_ta() end
|
||||||
|
|
||||||
-- Feature Flags
|
-- Feature Flags
|
||||||
---@param enabled boolean
|
---@param enabled boolean
|
||||||
function set_rds_rt1_enabled(enabled) end
|
function rds.set_rt1_enabled(enabled) end
|
||||||
---@return boolean
|
---@return boolean
|
||||||
function get_rds_rt1_enabled() end
|
function rds.get_rt1_enabled() end
|
||||||
|
|
||||||
---@param enabled boolean
|
---@param enabled boolean
|
||||||
function set_rds_rt2_enabled(enabled) end
|
function rds.set_rt2_enabled(enabled) end
|
||||||
---@return boolean
|
---@return boolean
|
||||||
function get_rds_rt2_enabled() end
|
function rds.get_rt2_enabled() end
|
||||||
|
|
||||||
---@param enabled boolean
|
---@param enabled boolean
|
||||||
function set_rds_ptyn_enabled(enabled) end
|
function rds.set_ptyn_enabled(enabled) end
|
||||||
---@return boolean
|
---@return boolean
|
||||||
function get_rds_ptyn_enabled() end
|
function rds.get_ptyn_enabled() end
|
||||||
|
|
||||||
---@param rt_type integer
|
---@param rt_type integer
|
||||||
function set_rds_rt_type(rt_type) end
|
function rds.set_rt_type(rt_type) end
|
||||||
---@return integer
|
---@return integer
|
||||||
function get_rds_rt_type() end
|
function rds.get_rt_type() end
|
||||||
|
|
||||||
-- Modulation & Generation
|
-- Modulation & Generation
|
||||||
---@param mode integer
|
---@param mode integer
|
||||||
function set_rds2_mode(mode) end
|
function rds.set_rds2_mode(mode) end
|
||||||
---@return integer
|
---@return integer
|
||||||
function get_rds2_mode() end
|
function rds.get_rds2_mode() end
|
||||||
|
|
||||||
---@param streams integer
|
---@param streams integer
|
||||||
function set_rds_streams(streams) end
|
function set_rds_streams(streams) end
|
||||||
@@ -152,72 +171,67 @@ function get_rds_level() end
|
|||||||
|
|
||||||
-- Program & Linking
|
-- Program & Linking
|
||||||
---@param linkage boolean
|
---@param linkage boolean
|
||||||
function set_rds_link(linkage) end
|
function rds.set_link(linkage) end
|
||||||
---@return boolean
|
---@return boolean
|
||||||
function get_rds_link() end
|
function rds.get_link() end
|
||||||
|
|
||||||
---@param program_idx integer 0 to (max_programs - 1)
|
|
||||||
function set_rds_program(program_idx) end
|
|
||||||
---@return integer
|
|
||||||
function get_rds_program() end
|
|
||||||
|
|
||||||
-- Timeouts and Periods
|
-- Timeouts and Periods
|
||||||
---@param period integer in seconds
|
---@param period integer in seconds
|
||||||
function set_rds_rt_switching_period(period) end
|
function rds.set_rt_switching_period(period) end
|
||||||
---@return integer
|
---@return integer
|
||||||
function get_rds_rt_switching_period() end
|
function rds.get_rt_switching_period() end
|
||||||
|
|
||||||
---For a RT1, this sets the timeout period before setting RT1 into "Default RT" (not literally)
|
---For a RT1, this sets the timeout period before setting RT1 into "Default RT" (not literally)
|
||||||
---@param timeout integer in seconds
|
---@param timeout integer in seconds
|
||||||
function set_rds_rt_text_timeout(timeout) end
|
function rds.set_rt_text_timeout(timeout) end
|
||||||
---@return integer
|
---@return integer
|
||||||
function get_rds_rt_text_timeout() end
|
function rds.get_rt_text_timeout() end
|
||||||
|
|
||||||
-- String Setters (Charset converted)
|
-- String Setters (Charset converted)
|
||||||
---@param ptyn string Program Type Name (max 8 chars)
|
---@param ptyn string Program Type Name (max 8 chars)
|
||||||
function set_rds_ptyn(ptyn) end
|
function rds.set_ptyn(ptyn) end
|
||||||
---@param ps string Program Service (8 chars)
|
---@param ps string Program Service (8 chars)
|
||||||
function set_rds_ps(ps) end
|
function rds.set_ps(ps) end
|
||||||
---@param tps string Traffic PS
|
---@param tps string Traffic PS
|
||||||
function set_rds_tps(tps) end
|
function rds.set_tps(tps) end
|
||||||
---@param rt1 string Radio Text 1 (max 64 chars)
|
---@param rt1 string Radio Text 1 (max 64 chars)
|
||||||
function set_rds_rt1(rt1) end
|
function rds.set_rt1(rt1) end
|
||||||
---@param rt2 string Radio Text 2 (max 64 chars)
|
---@param rt2 string Radio Text 2 (max 64 chars)
|
||||||
function set_rds_rt2(rt2) end
|
function rds.set_rt2(rt2) end
|
||||||
---@param rt string Default radio text - max 64 characters
|
---@param rt string Default radio text - max 64 characters
|
||||||
function set_rds_default_rt(rt) end
|
function rds.set_default_rt(rt) end
|
||||||
|
|
||||||
---@param lps string
|
---@param lps string
|
||||||
function set_rds_lps(lps) end
|
function rds.set_lps(lps) end
|
||||||
---@return string
|
---@return string
|
||||||
function get_rds_lps() end
|
function rds.get_lps() end
|
||||||
|
|
||||||
---@param grpseq string
|
---@param grpseq string
|
||||||
function set_rds_grpseq(grpseq) end
|
function rds.set_grpseq(grpseq) end
|
||||||
---@return string
|
---@return string
|
||||||
function get_rds_grpseq() end
|
function rds.get_grpseq() end
|
||||||
|
|
||||||
---@param grpseq2 string
|
---@param grpseq2 string
|
||||||
function set_rds_grpseq2(grpseq2) end
|
function rds.set_grpseq2(grpseq2) end
|
||||||
---@return string
|
---@return string
|
||||||
function get_rds_grpseq2() end
|
function rds.get_grpseq2() end
|
||||||
|
|
||||||
---Puts in a RDS1 group in the buffer, note that block A is filled in always
|
---Puts in a RDS1 group in the buffer, note that block A is filled in always
|
||||||
---@param b integer
|
---@param b integer
|
||||||
---@param c integer
|
---@param c integer
|
||||||
---@param d integer
|
---@param d integer
|
||||||
function put_rds_custom_group(b, c, d) end
|
function rds.put_custom_group(b, c, d) end
|
||||||
|
|
||||||
---Puts in a RDS2 group in the buffer
|
---Puts in a RDS2 group in the buffer
|
||||||
---@param a integer
|
---@param a integer
|
||||||
---@param b integer
|
---@param b integer
|
||||||
---@param c integer
|
---@param c integer
|
||||||
---@param d integer
|
---@param d integer
|
||||||
function put_rds2_custom_group(a, b, c, d) end
|
function rds.put_rds2_custom_group(a, b, c, d) end
|
||||||
|
|
||||||
---Sets the AFs included in group 0
|
---Sets the AFs included in group 0
|
||||||
---@param afs table
|
---@param afs table
|
||||||
function set_rds_af_group0(afs) end
|
function rds.set_af(afs) end
|
||||||
|
|
||||||
---Sets data about the EON
|
---Sets data about the EON
|
||||||
---@param eon integer Index of the EON we are setting
|
---@param eon integer Index of the EON we are setting
|
||||||
@@ -229,7 +243,7 @@ function set_rds_af_group0(afs) end
|
|||||||
---@param ps string
|
---@param ps string
|
||||||
---@param afs table
|
---@param afs table
|
||||||
---@param data integer
|
---@param data integer
|
||||||
function set_rds_eon(eon, enabled, pi, tp, ta, pty, ps, afs, data) end
|
function rds.set_eon(eon, enabled, pi, tp, ta, pty, ps, afs, data) end
|
||||||
|
|
||||||
---Gets the same data set_rds_eon sets, yes this returns 8 arguments
|
---Gets the same data set_rds_eon sets, yes this returns 8 arguments
|
||||||
---@param eon integer
|
---@param eon integer
|
||||||
@@ -241,37 +255,45 @@ function set_rds_eon(eon, enabled, pi, tp, ta, pty, ps, afs, data) end
|
|||||||
---@return string ps
|
---@return string ps
|
||||||
---@return table _ this is empty, getting afs is not supported yet
|
---@return table _ this is empty, getting afs is not supported yet
|
||||||
---@return integer data
|
---@return integer data
|
||||||
function get_rds_eon(eon) end
|
function rds.get_eon(eon) end
|
||||||
|
|
||||||
---Sets the X/Y of the UDG
|
---Sets the X/Y of the UDG
|
||||||
---@param xy boolean
|
---@param xy boolean
|
||||||
---@param groups table Table of tables, this should be up to 8 tables containing 3 integers
|
---@param groups table Table of tables, this should be up to 8 tables containing 3 integers
|
||||||
function set_rds_udg(xy, groups) end
|
function rds.set_udg(xy, groups) end
|
||||||
---Sets the X/Y of the UDG for RDS2
|
---Sets the X/Y of the UDG for RDS2
|
||||||
---@param xy boolean
|
---@param xy boolean
|
||||||
---@param groups table Table of tables, this should be up to 8 tables containing 4 integers
|
---@param groups table Table of tables, this should be up to 8 tables containing 4 integers
|
||||||
function set_rds_udg2(xy, groups) end
|
function rds.set_udg2(xy, groups) end
|
||||||
|
|
||||||
|
userdata = {}
|
||||||
|
|
||||||
|
---@type integer
|
||||||
|
userdata.len = 0
|
||||||
|
|
||||||
---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
|
---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
|
---@param data string
|
||||||
function set_userdata(data) end
|
function userdata.set(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
|
---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
|
||||||
---@param offset integer
|
---@param offset integer
|
||||||
---@param size integer
|
---@param size integer
|
||||||
---@param data string
|
---@param data string
|
||||||
function set_userdata_offset(offset, size, data) end
|
function userdata.set_offset(offset, size, data) end
|
||||||
|
|
||||||
---Returns all of the data saved as user data
|
---Returns all of the data saved as user data
|
||||||
---@return string
|
---@return string
|
||||||
function get_userdata() end
|
function userdata.get() end
|
||||||
---Gets data from userdata but at the specified offset
|
---Gets data from userdata but at the specified offset
|
||||||
---@param offset integer
|
---@param offset integer
|
||||||
---@param size integer
|
---@param size integer
|
||||||
---@return string
|
---@return string
|
||||||
function get_userdata_offset(offset, size) end
|
function userdata.get_offset(offset, size) end
|
||||||
|
|
||||||
--#endregion
|
--#endregion
|
||||||
|
|
||||||
|
ext = {}
|
||||||
|
rds.ext = {}
|
||||||
|
|
||||||
-- RT Plus Tags
|
-- RT Plus Tags
|
||||||
---Sets RT+ tags: type1, start1, len1, type2, start2, len2
|
---Sets RT+ tags: type1, start1, len1, type2, start2, len2
|
||||||
---@param ertp boolean
|
---@param ertp boolean
|
||||||
@@ -281,29 +303,29 @@ function get_userdata_offset(offset, size) end
|
|||||||
---@param t2 integer
|
---@param t2 integer
|
||||||
---@param s2 integer
|
---@param s2 integer
|
||||||
---@param l2 integer
|
---@param l2 integer
|
||||||
function set_rds_rtplus_tags(ertp, t1, s1, l1, t2, s2, l2) end
|
function rds.ext.set_rtplus_tags(ertp, t1, s1, l1, t2, s2, l2) end
|
||||||
|
|
||||||
---Gets RT+ tags: type1, start1, len1, type2, start2, len2
|
---Gets RT+ tags: type1, start1, len1, type2, start2, len2
|
||||||
---@param ertp boolean
|
---@param ertp boolean
|
||||||
---@return integer type1, integer start1, integer len1, integer type2, integer start2, integer len2
|
---@return integer type1, integer start1, integer len1, integer type2, integer start2, integer len2
|
||||||
function get_rds_rtplus_tags(ertp) end
|
function rds.ext.get_rtplus_tags(ertp) end
|
||||||
|
|
||||||
---Toggles RTP or ERTP's toggle switch
|
---Toggles RTP or ERTP's toggle switch
|
||||||
---@param ertp boolean
|
---@param ertp boolean
|
||||||
function toggle_rds_rtp(ertp) end
|
function rds.ext.toggle_rtp(ertp) end
|
||||||
|
|
||||||
---Sets the metadata of RTP or ERTP
|
---Sets the metadata of RTP or ERTP
|
||||||
---@param ertp boolean
|
---@param ertp boolean
|
||||||
---@param running boolean
|
---@param running boolean
|
||||||
function set_rds_rtp_meta(ertp, running) end
|
function rds.ext.set_rtp_meta(ertp, running) end
|
||||||
---Gets the metadata of RTP and ERTP
|
---Gets the metadata of RTP and ERTP
|
||||||
---@param ertp boolean
|
---@param ertp boolean
|
||||||
---@return boolean running
|
---@return boolean running
|
||||||
function get_rds_rtp_meta(ertp) end
|
function rds.ext.get_rtp_meta(ertp) end
|
||||||
|
|
||||||
---Sets the AFs included in the ODA
|
---Sets the AFs included in the ODA
|
||||||
---@param afs table
|
---@param afs table
|
||||||
function set_rds_af_oda(afs) end
|
function rds.ext.set_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
|
---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
|
---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
|
||||||
@@ -313,16 +335,16 @@ function set_rds_af_oda(afs) end
|
|||||||
---@param aid integer
|
---@param aid integer
|
||||||
---@param data integer
|
---@param data integer
|
||||||
---@return integer oda_id
|
---@return integer oda_id
|
||||||
function register_oda(group, group_version, aid, data) end
|
function ext.register_oda(group, group_version, aid, data) end
|
||||||
|
|
||||||
---Unregisters an ODA, this stops the handler or AID being called/sent
|
---Unregisters an ODA, this stops the handler or AID being called/sent
|
||||||
---@param oda_id integer
|
---@param oda_id integer
|
||||||
function unregister_oda(oda_id) end
|
function ext.unregister_oda(oda_id) end
|
||||||
|
|
||||||
---Sets the data for a existing ODA group
|
---Sets the data for a existing ODA group
|
||||||
---@param oda_id integer
|
---@param oda_id integer
|
||||||
---@param data integer
|
---@param data integer
|
||||||
function set_oda_id_data(oda_id, data) end
|
function ext.set_oda_id_data(oda_id, data) end
|
||||||
|
|
||||||
---The callback function for an ODA handler
|
---The callback function for an ODA handler
|
||||||
---@alias ODAHandler fun(): (boolean, integer, integer, integer)
|
---@alias ODAHandler fun(): (boolean, integer, integer, integer)
|
||||||
@@ -334,7 +356,7 @@ function set_oda_id_data(oda_id, data) end
|
|||||||
---You are asked to set groups B last 5 bits, leave rest 0
|
---You are asked to set groups B last 5 bits, leave rest 0
|
||||||
---@param oda_id integer The ID returned by register_oda
|
---@param oda_id integer The ID returned by register_oda
|
||||||
---@param fun ODAHandler
|
---@param fun ODAHandler
|
||||||
function set_oda_handler(oda_id, fun) end
|
function ext.set_oda_handler(oda_id, fun) end
|
||||||
|
|
||||||
---The callback function for an ODA handler
|
---The callback function for an ODA handler
|
||||||
---@alias RDS2_ODAHandler fun(integer): (boolean, integer, integer, integer, integer)
|
---@alias RDS2_ODAHandler fun(integer): (boolean, integer, integer, integer, integer)
|
||||||
@@ -342,23 +364,23 @@ function set_oda_handler(oda_id, fun) end
|
|||||||
---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))
|
---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 oda_id integer
|
||||||
---@param func RDS2_ODAHandler
|
---@param func RDS2_ODAHandler
|
||||||
function set_oda_handler_rds2(oda_id, func) end
|
function ext.set_oda_handler_rds2(oda_id, func) end
|
||||||
|
|
||||||
---@param oda_id integer
|
---@param oda_id integer
|
||||||
---@param data integer
|
---@param data integer
|
||||||
function set_oda_id_data_rds2(oda_id, data) end
|
function ext.set_oda_id_data_rds2(oda_id, data) end
|
||||||
|
|
||||||
---@param aid integer
|
---@param aid integer
|
||||||
---@param data integer
|
---@param data integer
|
||||||
---@param file_related boolean
|
---@param file_related boolean
|
||||||
---@return integer oda_id
|
---@return integer oda_id
|
||||||
function register_oda_rds2(aid, data, file_related) end
|
function ext.register_oda_rds2(aid, data, file_related) end
|
||||||
|
|
||||||
---Unregisters an RDS 2 ODA, this stops the handler or AID being called/sent
|
---Unregisters an RDS 2 ODA, this stops the handler or AID being called/sent
|
||||||
---@param oda_id integer
|
---@param oda_id integer
|
||||||
function unregister_oda_rds2(oda_id) end
|
function ext.unregister_oda_rds2(oda_id) end
|
||||||
|
|
||||||
---@param ert string
|
---@param ert string
|
||||||
function set_rds_ert(ert) end
|
function rds.ext.set_ert(ert) end
|
||||||
---@return string
|
---@return string
|
||||||
function get_rds_ert() end
|
function rds.ext.get_ert() end
|
||||||
@@ -17,7 +17,7 @@ local _RDS_ODA_pointer = 1
|
|||||||
---@param aid integer
|
---@param aid integer
|
||||||
---@param data integer
|
---@param data integer
|
||||||
---@return integer oda_id
|
---@return integer oda_id
|
||||||
function register_oda(group, group_version, aid, data)
|
function ext.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 == 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
|
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)
|
local oda = _ODA.new(group, group_version, aid, data, false)
|
||||||
@@ -33,7 +33,7 @@ end
|
|||||||
|
|
||||||
---Unregisters an ODA, this stops the handler or AID being called/sent
|
---Unregisters an ODA, this stops the handler or AID being called/sent
|
||||||
---@param oda_id integer
|
---@param oda_id integer
|
||||||
function unregister_oda(oda_id)
|
function ext.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
|
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
|
_RDS_ODAs[oda_id] = false
|
||||||
@@ -45,7 +45,7 @@ end
|
|||||||
---Sets the id_data for a existing ODA group
|
---Sets the id_data for a existing ODA group
|
||||||
---@param oda_id integer
|
---@param oda_id integer
|
||||||
---@param data integer
|
---@param data integer
|
||||||
function set_oda_id_data(oda_id, data)
|
function ext.set_oda_id_data(oda_id, data)
|
||||||
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 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
|
_RDS_ODAs[oda_id].data = data
|
||||||
end
|
end
|
||||||
@@ -57,7 +57,7 @@ end
|
|||||||
---You are asked to set groups B last 5 bits, leave rest 0
|
---You are asked to set groups B last 5 bits, leave rest 0
|
||||||
---@param oda_id integer The ID returned by register_oda
|
---@param oda_id integer The ID returned by register_oda
|
||||||
---@param fun ODAHandler
|
---@param fun ODAHandler
|
||||||
function set_oda_handler(oda_id, fun)
|
function ext.set_oda_handler(oda_id, fun)
|
||||||
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 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
|
if _RDS_ODAs[oda_id].group == 3 then error("3A ODAs cannot have handlers.", 2) end
|
||||||
_RDS_ODAs[oda_id].handler = fun
|
_RDS_ODAs[oda_id].handler = fun
|
||||||
@@ -113,18 +113,13 @@ function group(group_type)
|
|||||||
if #_RDS_ODAs == 0 then return false, 0, 0, 0 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 _RDS_ODA_pointer > #_RDS_ODAs or _RDS_ODA_pointer < 1 then _RDS_ODA_pointer = 1 end
|
||||||
|
|
||||||
if group_type == "O" then
|
if group_type == "O" then return get_aid()
|
||||||
return get_aid()
|
elseif group_type == "K" then return get_data() end
|
||||||
elseif group_type == "K" then
|
|
||||||
return get_data()
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
return false, 0, 0, 0
|
return false, 0, 0, 0
|
||||||
end
|
end
|
||||||
|
|
||||||
local _old_on_state_oda = on_state
|
table.insert(on_states, function ()
|
||||||
function on_state()
|
|
||||||
_RDS_ODAs = {}
|
_RDS_ODAs = {}
|
||||||
_RDS_ODA_pointer = 1
|
_RDS_ODA_pointer = 1
|
||||||
if type(_old_on_state_oda) == "function" then _old_on_state_oda() end
|
end)
|
||||||
end
|
|
||||||
@@ -14,7 +14,7 @@ _RDS2_ODA_pointer = 1
|
|||||||
---@param data integer
|
---@param data integer
|
||||||
---@param file_related boolean
|
---@param file_related boolean
|
||||||
---@return integer oda_id
|
---@return integer oda_id
|
||||||
function register_oda_rds2(aid, data, file_related)
|
function ext.register_oda_rds2(aid, data, file_related)
|
||||||
local oda = _RDS2_ODA.new(aid, data, false, file_related)
|
local oda = _RDS2_ODA.new(aid, data, false, file_related)
|
||||||
for i = 1, #_RDS2_ODAs do
|
for i = 1, #_RDS2_ODAs do
|
||||||
if _RDS2_ODAs[i] == false then
|
if _RDS2_ODAs[i] == false then
|
||||||
@@ -28,7 +28,7 @@ end
|
|||||||
|
|
||||||
---Unregisters an RDS 2 ODA, this stops the handler or AID being called/sent
|
---Unregisters an RDS 2 ODA, this stops the handler or AID being called/sent
|
||||||
---@param oda_id integer
|
---@param oda_id integer
|
||||||
function unregister_oda_rds2(oda_id)
|
function ext.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
|
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
|
_RDS2_ODAs[oda_id] = false
|
||||||
@@ -39,14 +39,14 @@ end
|
|||||||
|
|
||||||
---@param oda_id integer
|
---@param oda_id integer
|
||||||
---@param data integer
|
---@param data integer
|
||||||
function set_oda_id_data_rds2(oda_id, data)
|
function ext.set_oda_id_data_rds2(oda_id, data)
|
||||||
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
|
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
|
_RDS2_ODAs[oda_id].data = data
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param oda_id integer
|
---@param oda_id integer
|
||||||
---@param func RDS2_ODAHandler
|
---@param func RDS2_ODAHandler
|
||||||
function set_oda_handler_rds2(oda_id, func)
|
function ext.set_oda_handler_rds2(oda_id, func)
|
||||||
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
|
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
|
_RDS2_ODAs[oda_id].handler = func
|
||||||
end
|
end
|
||||||
@@ -125,10 +125,8 @@ function rds2_group(stream)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local _old_on_state_oda_rds2 = on_state
|
table.insert(on_states, function ()
|
||||||
function on_state()
|
|
||||||
_RDS2_ODAs = {}
|
_RDS2_ODAs = {}
|
||||||
_RDS2_ODA_aid = 0
|
_RDS2_ODA_aid = 0
|
||||||
_RDS2_ODA_pointer = 1
|
_RDS2_ODA_pointer = 1
|
||||||
if type(_old_on_state_oda_rds2) == "function" then _old_on_state_oda_rds2() end
|
end)
|
||||||
end
|
|
||||||
@@ -55,8 +55,8 @@ end
|
|||||||
|
|
||||||
local function init_af_oda()
|
local function init_af_oda()
|
||||||
if _Af_Oda_id == nil then
|
if _Af_Oda_id == nil then
|
||||||
_Af_Oda_id = register_oda(7, false, 0x6365, 0)
|
_Af_Oda_id = ext.register_oda(7, false, 0x6365, 0)
|
||||||
set_oda_handler(_Af_Oda_id, function()
|
ext.set_oda_handler(_Af_Oda_id, function()
|
||||||
local b, c, d = get_next_af_oda_group()
|
local b, c, d = get_next_af_oda_group()
|
||||||
return true, b, c, d
|
return true, b, c, d
|
||||||
end)
|
end)
|
||||||
@@ -69,7 +69,7 @@ local function save_af_to_userdata(afs)
|
|||||||
|
|
||||||
local payload = string.pack("B", count)
|
local payload = string.pack("B", count)
|
||||||
for i = 1, count do payload = payload .. string.pack("f", afs[i]) end
|
for i = 1, count do payload = payload .. string.pack("f", afs[i]) end
|
||||||
set_userdata_offset(USERDATA_ODA_OFFSET, #payload, payload)
|
userdata.set_offset(USERDATA_ODA_OFFSET, #payload, payload)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function _process_af_list(afs)
|
local function _process_af_list(afs)
|
||||||
@@ -86,13 +86,13 @@ local function _process_af_list(afs)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function load_af_from_userdata()
|
local function load_af_from_userdata()
|
||||||
local header = get_userdata_offset(USERDATA_ODA_OFFSET, 1)
|
local header = userdata.get_offset(USERDATA_ODA_OFFSET, 1)
|
||||||
if header == "" or header == nil then return end
|
if header == "" or header == nil then return end
|
||||||
|
|
||||||
local count = string.unpack("B", header)
|
local count = string.unpack("B", header)
|
||||||
if count == 0 or count > 25 then return end
|
if count == 0 or count > 25 then return end
|
||||||
|
|
||||||
local data = get_userdata_offset(USERDATA_ODA_OFFSET + 1, count * 4)
|
local data = userdata.get_offset(USERDATA_ODA_OFFSET + 1, count * 4)
|
||||||
if #data < (count * 4) then return end
|
if #data < (count * 4) then return end
|
||||||
|
|
||||||
local afs = {}
|
local afs = {}
|
||||||
@@ -106,14 +106,12 @@ end
|
|||||||
|
|
||||||
---Sets the AFs included in the ODA and saves them
|
---Sets the AFs included in the ODA and saves them
|
||||||
---@param afs table List of numbers (e.g., {98.1, 102.5})
|
---@param afs table List of numbers (e.g., {98.1, 102.5})
|
||||||
function set_rds_af_oda(afs)
|
function rds.ext.set_af_oda(afs)
|
||||||
_process_af_list(afs)
|
_process_af_list(afs)
|
||||||
save_af_to_userdata(afs)
|
save_af_to_userdata(afs)
|
||||||
end
|
end
|
||||||
|
|
||||||
local _old_on_state_af = on_state
|
table.insert(on_states, function ()
|
||||||
function on_state()
|
|
||||||
load_af_from_userdata()
|
load_af_from_userdata()
|
||||||
if _Af_Oda_len ~= 0 then init_af_oda() end
|
if _Af_Oda_len ~= 0 then init_af_oda() end
|
||||||
if type(_old_on_state_af) == "function" then _old_on_state_af() end
|
end)
|
||||||
end
|
|
||||||
@@ -6,25 +6,25 @@ local USERDATA_ERT_OFFSET = 0
|
|||||||
|
|
||||||
local function init_ert()
|
local function init_ert()
|
||||||
if _Ert_oda_id == nil then
|
if _Ert_oda_id == nil then
|
||||||
_Ert_oda_id = register_oda(13, false, 0x6552, 1)
|
_Ert_oda_id = ext.register_oda(13, false, 0x6552, 1)
|
||||||
set_oda_handler(_Ert_oda_id, function ()
|
ext.set_oda_handler(_Ert_oda_id, function ()
|
||||||
if string.byte(get_userdata_offset(USERDATA_ERT_OFFSET+258, 1)) == 1 then
|
if string.byte(userdata.get_offset(USERDATA_ERT_OFFSET+258, 1)) == 1 then
|
||||||
local new_data = get_userdata_offset(USERDATA_ERT_OFFSET, 128)
|
local new_data = userdata.get_offset(USERDATA_ERT_OFFSET, 128)
|
||||||
local new_segments = string.byte(get_userdata_offset(USERDATA_ERT_OFFSET+128, 1))
|
local new_segments = string.byte(userdata.get_offset(USERDATA_ERT_OFFSET+128, 1))
|
||||||
set_userdata_offset(USERDATA_ERT_OFFSET+129, 128, new_data)
|
userdata.set_offset(USERDATA_ERT_OFFSET+129, 128, new_data)
|
||||||
set_userdata_offset(USERDATA_ERT_OFFSET+257, 1, string.char(new_segments))
|
userdata.set_offset(USERDATA_ERT_OFFSET+257, 1, string.char(new_segments))
|
||||||
set_userdata_offset(USERDATA_ERT_OFFSET+258, 1, string.char(0))
|
userdata.set_offset(USERDATA_ERT_OFFSET+258, 1, string.char(0))
|
||||||
_Ert_state = 0
|
_Ert_state = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
local segments = string.byte(get_userdata_offset(USERDATA_ERT_OFFSET+257, 1))
|
local segments = string.byte(userdata.get_offset(USERDATA_ERT_OFFSET+257, 1))
|
||||||
|
|
||||||
if segments == 0 then return false, 0, 0, 0 end
|
if segments == 0 then return false, 0, 0, 0 end
|
||||||
|
|
||||||
if _Ert_state >= segments then _Ert_state = 0 end
|
if _Ert_state >= segments then _Ert_state = 0 end
|
||||||
|
|
||||||
local b = _Ert_state & 31
|
local b = _Ert_state & 31
|
||||||
local chunk = get_userdata_offset(USERDATA_ERT_OFFSET + 129 + _Ert_state * 4, 4)
|
local chunk = userdata.get_offset(USERDATA_ERT_OFFSET + 129 + _Ert_state * 4, 4)
|
||||||
local c = (string.byte(chunk, 1) << 8) | string.byte(chunk, 2)
|
local c = (string.byte(chunk, 1) << 8) | string.byte(chunk, 2)
|
||||||
local d = (string.byte(chunk, 3) << 8) | string.byte(chunk, 4)
|
local d = (string.byte(chunk, 3) << 8) | string.byte(chunk, 4)
|
||||||
|
|
||||||
@@ -36,16 +36,16 @@ end
|
|||||||
|
|
||||||
function unregister_ert()
|
function unregister_ert()
|
||||||
if _Ert_oda_id ~= nil then
|
if _Ert_oda_id ~= nil then
|
||||||
unregister_oda(_Ert_oda_id)
|
ext.unregister_oda(_Ert_oda_id)
|
||||||
_Ert_oda_id = nil
|
_Ert_oda_id = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function set_rds_ert(ert)
|
function rds.ext.set_ert(ert)
|
||||||
if #ert == 0 then
|
if #ert == 0 then
|
||||||
set_userdata_offset(USERDATA_ERT_OFFSET, 128, "")
|
userdata.set_offset(USERDATA_ERT_OFFSET, 128, "")
|
||||||
set_userdata_offset(USERDATA_ERT_OFFSET+128, 1, string.char(0))
|
userdata.set_offset(USERDATA_ERT_OFFSET+128, 1, string.char(0))
|
||||||
set_userdata_offset(USERDATA_ERT_OFFSET+258, 1, string.char(1))
|
userdata.set_offset(USERDATA_ERT_OFFSET+258, 1, string.char(1))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -55,33 +55,31 @@ function set_rds_ert(ert)
|
|||||||
local padding = (4 - (#data % 4)) % 4
|
local padding = (4 - (#data % 4)) % 4
|
||||||
data = data .. string.rep("\0", padding)
|
data = data .. string.rep("\0", padding)
|
||||||
|
|
||||||
set_userdata_offset(USERDATA_ERT_OFFSET, 128, data)
|
userdata.set_offset(USERDATA_ERT_OFFSET, 128, data)
|
||||||
|
|
||||||
local segments = #data // 4
|
local segments = #data // 4
|
||||||
if segments > 32 then segments = 32 end
|
if segments > 32 then segments = 32 end
|
||||||
|
|
||||||
set_userdata_offset(USERDATA_ERT_OFFSET+128, 1, string.char(segments))
|
userdata.set_offset(USERDATA_ERT_OFFSET+128, 1, string.char(segments))
|
||||||
|
|
||||||
if string.byte(get_userdata_offset(USERDATA_ERT_OFFSET+257, 1)) == 0 then
|
if string.byte(userdata.get_offset(USERDATA_ERT_OFFSET+257, 1)) == 0 then
|
||||||
init_ert()
|
init_ert()
|
||||||
set_userdata_offset(USERDATA_ERT_OFFSET+129, 128, data)
|
userdata.set_offset(USERDATA_ERT_OFFSET+129, 128, data)
|
||||||
set_userdata_offset(USERDATA_ERT_OFFSET+257, 1, string.char(segments))
|
userdata.set_offset(USERDATA_ERT_OFFSET+257, 1, string.char(segments))
|
||||||
_Ert_state = 0
|
_Ert_state = 0
|
||||||
else set_userdata_offset(USERDATA_ERT_OFFSET+258, 1, string.char(1)) end
|
else userdata.set_offset(USERDATA_ERT_OFFSET+258, 1, string.char(1)) end
|
||||||
|
|
||||||
if _Ert_oda_id == nil then init_ert() end
|
if _Ert_oda_id == nil then init_ert() end
|
||||||
end
|
end
|
||||||
|
|
||||||
function get_rds_ert()
|
function rds.ext.get_ert()
|
||||||
local segments = string.byte(get_userdata_offset(USERDATA_ERT_OFFSET+128, 1))
|
local segments = string.byte(userdata.get_offset(USERDATA_ERT_OFFSET+128, 1))
|
||||||
if segments == 0 then return "" end
|
if segments == 0 then return "" end
|
||||||
|
|
||||||
local data = get_userdata_offset(USERDATA_ERT_OFFSET, 128)
|
local data = userdata.get_offset(USERDATA_ERT_OFFSET, 128)
|
||||||
return data:match("^(.-)[\r%z]*") or ""
|
return data:match("^(.-)[\r%z]*") or ""
|
||||||
end
|
end
|
||||||
|
|
||||||
local _old_on_state_ert = on_state
|
table.insert(on_states, function ()
|
||||||
function on_state()
|
if string.byte(userdata.get_offset(USERDATA_ERT_OFFSET+257, 1)) ~= 0 then init_ert() end
|
||||||
if string.byte(get_userdata_offset(USERDATA_ERT_OFFSET+257, 1)) ~= 0 then init_ert() end
|
end)
|
||||||
if type(_old_on_state_ert) == "function" then _old_on_state_ert() end
|
|
||||||
end
|
|
||||||
@@ -43,7 +43,7 @@ end
|
|||||||
|
|
||||||
function RftInstance:stop()
|
function RftInstance:stop()
|
||||||
if self.oda_id ~= nil and self.aid ~= 0 then
|
if self.oda_id ~= nil and self.aid ~= 0 then
|
||||||
unregister_oda_rds2(self.oda_id)
|
ext.unregister_oda_rds2(self.oda_id)
|
||||||
self.oda_id = nil
|
self.oda_id = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -59,9 +59,9 @@ end
|
|||||||
---@private
|
---@private
|
||||||
function RftInstance:start()
|
function RftInstance:start()
|
||||||
if self.oda_id == nil and self.aid ~= 0 then
|
if self.oda_id == nil and self.aid ~= 0 then
|
||||||
self.oda_id = register_oda_rds2(self.aid, 0, true)
|
self.oda_id = ext.register_oda_rds2(self.aid, 0, true)
|
||||||
|
|
||||||
set_oda_handler_rds2(self.oda_id, function(stream)
|
ext.set_oda_handler_rds2(self.oda_id, function(stream)
|
||||||
if #self.file_data == 0 or self.paused then
|
if #self.file_data == 0 or self.paused then
|
||||||
return false, 0, 0, 0, 0
|
return false, 0, 0, 0, 0
|
||||||
end
|
end
|
||||||
@@ -138,7 +138,7 @@ function RftInstance:sendFile(aid, path, id, crc, once)
|
|||||||
local f_size = #self.file_data
|
local f_size = #self.file_data
|
||||||
if crc == 0 then
|
if crc == 0 then
|
||||||
self.crc_mode = 0
|
self.crc_mode = 0
|
||||||
self.crc_full_file = crc16(self.file_data)
|
self.crc_full_file = dp.crc16(self.file_data)
|
||||||
elseif crc == true or crc == 7 then
|
elseif crc == true or crc == 7 then
|
||||||
if f_size <= 40960 then self.crc_mode = 1
|
if f_size <= 40960 then self.crc_mode = 1
|
||||||
elseif f_size > 40960 and f_size <= 81920 then self.crc_mode = 2
|
elseif f_size > 40960 and f_size <= 81920 then self.crc_mode = 2
|
||||||
@@ -153,7 +153,7 @@ function RftInstance:sendFile(aid, path, id, crc, once)
|
|||||||
local chunk_size = 5 * multiplier
|
local chunk_size = 5 * multiplier
|
||||||
for i = 1, f_size, chunk_size do
|
for i = 1, f_size, chunk_size do
|
||||||
local chunk = string.sub(self.file_data, i, i + chunk_size - 1)
|
local chunk = string.sub(self.file_data, i, i + chunk_size - 1)
|
||||||
local v = crc16(chunk)
|
local v = dp.crc16(chunk)
|
||||||
self.crc_data = self.crc_data .. string.char(v >> 8, v & 0xff)
|
self.crc_data = self.crc_data .. string.char(v >> 8, v & 0xff)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -161,7 +161,7 @@ function RftInstance:sendFile(aid, path, id, crc, once)
|
|||||||
if f_size > (0x3ffff * 5) then error("File too large") end
|
if f_size > (0x3ffff * 5) then error("File too large") end
|
||||||
if self.oda_id == nil then self:start() end
|
if self.oda_id == nil then self:start() end
|
||||||
|
|
||||||
set_oda_id_data_rds2(self.oda_id, f_size | (id & 63) << 18 | (self.version & 7) << 24 | (self.crc_enabled and 1 or 0) << 27)
|
ext.set_oda_id_data_rds2(self.oda_id, f_size | (id & 63) << 18 | (self.version & 7) << 24 | (self.crc_enabled and 1 or 0) << 27)
|
||||||
self.last_id = id
|
self.last_id = id
|
||||||
self.paused = false
|
self.paused = false
|
||||||
return interrupted
|
return interrupted
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ local USERDATA_RTP_OFFSET = 259
|
|||||||
|
|
||||||
local function init_rtp()
|
local function init_rtp()
|
||||||
if _Rtp_oda_id == nil then
|
if _Rtp_oda_id == nil then
|
||||||
_Rtp_oda_id = register_oda(11, false, 0x4BD7, 0)
|
_Rtp_oda_id = ext.register_oda(11, false, 0x4BD7, 0)
|
||||||
set_oda_handler(_Rtp_oda_id, function ()
|
ext.set_oda_handler(_Rtp_oda_id, function ()
|
||||||
local b = (_Rtp_toggle and 1 or 0) << 4 | string.byte(get_userdata_offset(USERDATA_RTP_OFFSET, 1)) << 3
|
local b = (_Rtp_toggle and 1 or 0) << 4 | string.byte(userdata.get_offset(USERDATA_RTP_OFFSET, 1)) << 3
|
||||||
local data_0 = get_userdata_offset(USERDATA_RTP_OFFSET+1, 3)
|
local data_0 = userdata.get_offset(USERDATA_RTP_OFFSET+1, 3)
|
||||||
local data_1 = get_userdata_offset(USERDATA_RTP_OFFSET+4, 3)
|
local data_1 = userdata.get_offset(USERDATA_RTP_OFFSET+4, 3)
|
||||||
b = b | (string.byte(data_0, 1) & 0xf8) >> 3
|
b = b | (string.byte(data_0, 1) & 0xf8) >> 3
|
||||||
|
|
||||||
local c = (string.byte(data_0, 1) & 0x7) << 13
|
local c = (string.byte(data_0, 1) & 0x7) << 13
|
||||||
@@ -31,11 +31,11 @@ end
|
|||||||
|
|
||||||
local function init_ertp()
|
local function init_ertp()
|
||||||
if _Ertp_oda_id == nil then
|
if _Ertp_oda_id == nil then
|
||||||
_Ertp_oda_id = register_oda(12, false, 0x4BD8, 0)
|
_Ertp_oda_id = ext.register_oda(12, false, 0x4BD8, 0)
|
||||||
set_oda_handler(_Ertp_oda_id, function ()
|
ext.set_oda_handler(_Ertp_oda_id, function ()
|
||||||
local b = (_Ertp_toggle and 1 or 0) << 4 | string.byte(get_userdata_offset(USERDATA_RTP_OFFSET+7, 1)) << 3
|
local b = (_Ertp_toggle and 1 or 0) << 4 | string.byte(userdata.get_offset(USERDATA_RTP_OFFSET+7, 1)) << 3
|
||||||
local data_0 = get_userdata_offset(USERDATA_RTP_OFFSET+8, 3)
|
local data_0 = userdata.get_offset(USERDATA_RTP_OFFSET+8, 3)
|
||||||
local data_1 = get_userdata_offset(USERDATA_RTP_OFFSET+11, 3)
|
local data_1 = userdata.get_offset(USERDATA_RTP_OFFSET+11, 3)
|
||||||
b = b | (string.byte(data_0, 1) & 0xf8) >> 3
|
b = b | (string.byte(data_0, 1) & 0xf8) >> 3
|
||||||
|
|
||||||
local c = (string.byte(data_0, 1) & 0x7) << 13
|
local c = (string.byte(data_0, 1) & 0x7) << 13
|
||||||
@@ -52,46 +52,44 @@ local function init_ertp()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function set_rds_rtp_meta(ertp, running)
|
function rds.ext.set_rtp_meta(ertp, running)
|
||||||
if ertp then
|
if ertp then
|
||||||
if running and _Ertp_oda_id == nil then init_ertp() end
|
if running and _Ertp_oda_id == nil then init_ertp() end
|
||||||
set_userdata_offset(USERDATA_RTP_OFFSET+7, 1, string.char(running and 1 or 0))
|
userdata.set_offset(USERDATA_RTP_OFFSET+7, 1, string.char(running and 1 or 0))
|
||||||
else
|
else
|
||||||
if running and _Rtp_oda_id == nil then init_rtp() end
|
if running and _Rtp_oda_id == nil then init_rtp() end
|
||||||
set_userdata_offset(USERDATA_RTP_OFFSET, 1, string.char(running and 1 or 0))
|
userdata.set_offset(USERDATA_RTP_OFFSET, 1, string.char(running and 1 or 0))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function get_rds_rtp_meta(ertp)
|
function rds.ext.get_rtp_meta(ertp)
|
||||||
local offset = ertp and (USERDATA_RTP_OFFSET+7) or USERDATA_RTP_OFFSET
|
local offset = ertp and (USERDATA_RTP_OFFSET+7) or USERDATA_RTP_OFFSET
|
||||||
return string.byte(get_userdata_offset(offset, 1)) ~= 0
|
return string.byte(userdata.get_offset(offset, 1)) ~= 0
|
||||||
end
|
end
|
||||||
function toggle_rds_rtp(ertp)
|
function rds.ext.toggle_rtp(ertp)
|
||||||
if ertp then _Ertp_toggle = not _Ertp_toggle
|
if ertp then _Ertp_toggle = not _Ertp_toggle
|
||||||
else _Rtp_toggle = not _Rtp_toggle end
|
else _Rtp_toggle = not _Rtp_toggle end
|
||||||
end
|
end
|
||||||
|
|
||||||
function set_rds_rtplus_tags(ertp, t1, s1, l1, t2, s2, l2)
|
function rds.ext.set_rtplus_tags(ertp, t1, s1, l1, t2, s2, l2)
|
||||||
set_rds_rtp_meta(ertp, true)
|
rds.ext.set_rds_rtp_meta(ertp, true)
|
||||||
toggle_rds_rtp(ertp)
|
rds.ext.toggle_rds_rtp(ertp)
|
||||||
set_userdata_offset(ertp and (USERDATA_RTP_OFFSET+8) or (USERDATA_RTP_OFFSET+1), 6, string.char(t1, s1, l1, t2, s2, l2))
|
userdata.set_offset(ertp and (USERDATA_RTP_OFFSET+8) or (USERDATA_RTP_OFFSET+1), 6, string.char(t1, s1, l1, t2, s2, l2))
|
||||||
end
|
end
|
||||||
function get_rds_rtplus_tags(ertp)
|
function rds.ext.get_rtplus_tags(ertp)
|
||||||
return string.byte(get_userdata_offset(ertp and (USERDATA_RTP_OFFSET+8) or (USERDATA_RTP_OFFSET+1), 6), 1, 6)
|
return string.byte(userdata.get_offset(ertp and (USERDATA_RTP_OFFSET+8) or (USERDATA_RTP_OFFSET+1), 6), 1, 6)
|
||||||
end
|
end
|
||||||
|
|
||||||
function unregister_rtp(ertp)
|
function unregister_rtp(ertp)
|
||||||
if ertp and _Ertp_oda_id ~= nil then
|
if ertp and _Ertp_oda_id ~= nil then
|
||||||
unregister_oda(_Ertp_oda_id)
|
ext.unregister_oda(_Ertp_oda_id)
|
||||||
_Ertp_oda_id = nil
|
_Ertp_oda_id = nil
|
||||||
elseif _Rtp_oda_id ~= nil then
|
elseif _Rtp_oda_id ~= nil then
|
||||||
unregister_oda(_Rtp_oda_id)
|
ext.unregister_oda(_Rtp_oda_id)
|
||||||
_Rtp_oda_id = nil
|
_Rtp_oda_id = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local _old_on_state_rtp = on_state
|
table.insert(on_states, function ()
|
||||||
function on_state()
|
if rds.ext.get_rtp_meta(false) then init_rtp() end
|
||||||
if get_rds_rtp_meta(false) then init_rtp() end
|
if rds.ext.get_rtp_meta(true) then init_ertp() end
|
||||||
if get_rds_rtp_meta(true) then init_ertp() end
|
end)
|
||||||
if type(_old_on_state_rtp) == "function" then _old_on_state_rtp() end
|
|
||||||
end
|
|
||||||
@@ -40,52 +40,52 @@ function data_handle(data)
|
|||||||
data = data:lower()
|
data = data:lower()
|
||||||
if data == "ver" then return string.format("rds95 core v. %s - (C) 2025 radio95 - lua parser\r\n", core_version)
|
if data == "ver" then return string.format("rds95 core v. %s - (C) 2025 radio95 - lua parser\r\n", core_version)
|
||||||
elseif data == "init" then
|
elseif data == "init" then
|
||||||
set_rds_program_defaults()
|
dp.set_rds_program_defaults()
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif data == "reset" then
|
elseif data == "reset" then
|
||||||
reset_rds()
|
dp.reset_rds()
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif data == "pi" then return string.format("PI=%s\r\n", string.format("%x", get_rds_pi()))
|
elseif data == "pi" then return string.format("PI=%s\r\n", string.format("%x", rds.get_pi()))
|
||||||
elseif data == "pty" then return string.format("PTY=%s\r\n", string.format("%d", get_rds_pty()))
|
elseif data == "pty" then return string.format("PTY=%s\r\n", string.format("%d", rds.get_pty()))
|
||||||
elseif data == "ecc" then return string.format("ECC=%s\r\n", string.format("%x", get_rds_ecc()))
|
elseif data == "ecc" then return string.format("ECC=%s\r\n", string.format("%x", rds.get_ecc()))
|
||||||
elseif data == "slcd" then return string.format("SLCD=%s\r\n", string.format("%x", get_rds_slc_data()))
|
elseif data == "slcd" then return string.format("SLCD=%s\r\n", string.format("%x", rds.get_slc_data()))
|
||||||
elseif data == "ct" then return string.format("CT=%s\r\n", string.format("%d", (get_rds_ct() and 1 or 0)))
|
elseif data == "ct" then return string.format("CT=%s\r\n", string.format("%d", (rds.get_ct() and 1 or 0)))
|
||||||
elseif data == "dpty" then return string.format("DPTY=%s\r\n", string.format("%d", (get_rds_dpty() and 1 or 0)))
|
elseif data == "dpty" then return string.format("DPTY=%s\r\n", string.format("%d", (rds.get_dpty() and 1 or 0)))
|
||||||
elseif data == "tp" then return string.format("TP=%s\r\n", string.format("%d", (get_rds_tp() and 1 or 0)))
|
elseif data == "tp" then return string.format("TP=%s\r\n", string.format("%d", (rds.get_tp() and 1 or 0)))
|
||||||
elseif data == "ta" then return string.format("TA=%s\r\n", string.format("%d", (get_rds_ta() and 1 or 0)))
|
elseif data == "ta" then return string.format("TA=%s\r\n", string.format("%d", (rds.get_ta() and 1 or 0)))
|
||||||
elseif data == "rt1en" then return string.format("RT1EN=%s\r\n", string.format("%d", (get_rds_rt1_enabled() and 1 or 0)))
|
elseif data == "rt1en" then return string.format("RT1EN=%s\r\n", string.format("%d", (rds.get_rt1_enabled() and 1 or 0)))
|
||||||
elseif data == "rt2en" then return string.format("RT2EN=%s\r\n", string.format("%d", (get_rds_rt2_enabled() and 1 or 0)))
|
elseif data == "rt2en" then return string.format("RT2EN=%s\r\n", string.format("%d", (rds.get_rt2_enabled() and 1 or 0)))
|
||||||
elseif data == "ptynen" then return string.format("PTYNEN=%s\r\n", string.format("%d", (get_rds_ptyn_enabled() and 1 or 0)))
|
elseif data == "ptynen" then return string.format("PTYNEN=%s\r\n", string.format("%d", (rds.get_ptyn_enabled() and 1 or 0)))
|
||||||
elseif data == "rttype" then return string.format("RTTYPE=%s\r\n", string.format("%d", get_rds_rt_type()))
|
elseif data == "rttype" then return string.format("RTTYPE=%s\r\n", string.format("%d", rds.get_rt_type()))
|
||||||
elseif data == "rds2mod" then return string.format("RDS2MOD=%s\r\n", string.format("%d", get_rds2_mode()))
|
elseif data == "rds2mod" then return string.format("RDS2MOD=%s\r\n", string.format("%d", rds.get_rds2_mode()))
|
||||||
elseif data == "rdsgen" then return string.format("RDSGEN=%s\r\n", string.format("%d", get_rds_streams()))
|
elseif data == "rdsgen" then return string.format("RDSGEN=%s\r\n", string.format("%d", get_rds_streams()))
|
||||||
elseif data == "level" then return string.format("LEVEL=%s\r\n", string.format("%d", get_rds_level() * 255))
|
elseif data == "level" then return string.format("LEVEL=%s\r\n", string.format("%d", get_rds_level() * 255))
|
||||||
elseif data == "link" then return string.format("LINK=%s\r\n", string.format("%d", (get_rds_link() and 1 or 0)))
|
elseif data == "link" then return string.format("LINK=%s\r\n", string.format("%d", (rds.get_link() and 1 or 0)))
|
||||||
elseif data == "rtp" then
|
elseif data == "rtp" then
|
||||||
local t1, s1, l1, t2, s2, l2 = get_rds_rtplus_tags(false)
|
local t1, s1, l1, t2, s2, l2 = rds.ext.get_rtplus_tags(false)
|
||||||
return string.format("RTP=%d,%d,%d,%d,%d,%d\r\n", t1, s1, l1, t2, s2, l2)
|
return string.format("RTP=%d,%d,%d,%d,%d,%d\r\n", t1, s1, l1, t2, s2, l2)
|
||||||
elseif data == "ertp" then
|
elseif data == "ertp" then
|
||||||
local t1, s1, l1, t2, s2, l2 = get_rds_rtplus_tags(true)
|
local t1, s1, l1, t2, s2, l2 = rds.ext.get_rtplus_tags(true)
|
||||||
return string.format("ERTP=%d,%d,%d,%d,%d,%d\r\n", t1, s1, l1, t2, s2, l2)
|
return string.format("ERTP=%d,%d,%d,%d,%d,%d\r\n", t1, s1, l1, t2, s2, l2)
|
||||||
elseif data == "rtprun" then
|
elseif data == "rtprun" then
|
||||||
local running = get_rds_rtp_meta(false)
|
local running = rds.ext.get_rtp_meta(false)
|
||||||
local f1 = 2 or (running and 1 or 0)
|
local f1 = 2 or (running and 1 or 0)
|
||||||
return string.format("RTPRUN=%d\r\n", f1)
|
return string.format("RTPRUN=%d\r\n", f1)
|
||||||
elseif data == "ertprun" then
|
elseif data == "ertprun" then
|
||||||
local running = get_rds_rtp_meta(true)
|
local running = rds.ext.get_rtp_meta(true)
|
||||||
local f1 = 2 or (running and 1 or 0)
|
local f1 = 2 or (running and 1 or 0)
|
||||||
return string.format("ERTPRUN=%d\r\n", f1)
|
return string.format("ERTPRUN=%d\r\n", f1)
|
||||||
elseif data == "lps" then return string.format("LPS=%s\r\n", get_rds_lps())
|
elseif data == "lps" then return string.format("LPS=%s\r\n", rds.get_lps())
|
||||||
elseif data == "ert" then return string.format("ERT=%s\r\n", get_rds_ert())
|
elseif data == "ert" then return string.format("ERT=%s\r\n", rds.ext.get_ert())
|
||||||
elseif data == "grpseq" then return string.format("GRPSEQ=%s\r\n", get_rds_grpseq())
|
elseif data == "grpseq" then return string.format("GRPSEQ=%s\r\n", rds.get_grpseq())
|
||||||
elseif data == "grpseq2" then return string.format("GRPSEQ2=%s\r\n", get_rds_grpseq2())
|
elseif data == "grpseq2" then return string.format("GRPSEQ2=%s\r\n", rds.get_grpseq2())
|
||||||
else
|
else
|
||||||
local eon_cmd, eon_num = data:match("^eon(%d+)([a-z]+)$")
|
local eon_cmd, eon_num = data:match("^eon(%d+)([a-z]+)$")
|
||||||
if eon_cmd then
|
if eon_cmd then
|
||||||
local eon_idx = tonumber(eon_cmd)
|
local eon_idx = tonumber(eon_cmd)
|
||||||
if not eon_idx or eon_idx < 1 or eon_idx > eon_count then return "?\r\n" end
|
if not eon_idx or eon_idx < 1 or eon_idx > rds.eon_count then return "?\r\n" end
|
||||||
eon_idx = eon_idx - 1
|
eon_idx = eon_idx - 1
|
||||||
local enabled, pi, tp, ta, pty, ps, afs, data_val = get_rds_eon(eon_idx)
|
local enabled, pi, tp, ta, pty, ps, afs, data_val = rds.get_eon(eon_idx)
|
||||||
|
|
||||||
if eon_num == "en" then return string.format("EON%dEN=%d\r\n", eon_idx + 1, enabled and 1 or 0)
|
if eon_num == "en" then return string.format("EON%dEN=%d\r\n", eon_idx + 1, enabled and 1 or 0)
|
||||||
elseif eon_num == "pi" then return string.format("EON%dPI=%x\r\n", eon_idx + 1, pi)
|
elseif eon_num == "pi" then return string.format("EON%dPI=%x\r\n", eon_idx + 1, pi)
|
||||||
@@ -106,48 +106,48 @@ function data_handle(data)
|
|||||||
local eon_num, eon_type = cmd:match("^eon(%d+)([a-z]+)$")
|
local eon_num, eon_type = cmd:match("^eon(%d+)([a-z]+)$")
|
||||||
if eon_num then
|
if eon_num then
|
||||||
local eon_idx = tonumber(eon_num)
|
local eon_idx = tonumber(eon_num)
|
||||||
if not eon_idx or eon_idx < 1 or eon_idx > eon_count then return "?\r\n" end
|
if not eon_idx or eon_idx < 1 or eon_idx > rds.eon_count then return "?\r\n" end
|
||||||
eon_idx = eon_idx - 1
|
eon_idx = eon_idx - 1
|
||||||
|
|
||||||
local enabled, pi, tp, ta, pty, ps, afs, data_val = get_rds_eon(eon_idx)
|
local enabled, pi, tp, ta, pty, ps, afs, data_val = rds.get_eon(eon_idx)
|
||||||
if eon_type == "en" then
|
if eon_type == "en" then
|
||||||
local en_val = tonumber(value)
|
local en_val = tonumber(value)
|
||||||
if not en_val then return "-\r\n" end
|
if not en_val then return "-\r\n" end
|
||||||
enabled = (en_val ~= 0)
|
enabled = (en_val ~= 0)
|
||||||
set_rds_eon(eon_idx, enabled, pi, tp, ta, pty, ps, afs, data_val)
|
rds.set_eon(eon_idx, enabled, pi, tp, ta, pty, ps, afs, data_val)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif eon_type == "pi" then
|
elseif eon_type == "pi" then
|
||||||
local pi_val = tonumber(value, 16)
|
local pi_val = tonumber(value, 16)
|
||||||
if not pi_val then return "-\r\n" end
|
if not pi_val then return "-\r\n" end
|
||||||
set_rds_eon(eon_idx, enabled, pi_val, tp, ta, pty, ps, afs, data_val)
|
rds.set_eon(eon_idx, enabled, pi_val, tp, ta, pty, ps, afs, data_val)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif eon_type == "ps" then
|
elseif eon_type == "ps" then
|
||||||
local ps_val = value:sub(1, 24)
|
local ps_val = value:sub(1, 24)
|
||||||
set_rds_eon(eon_idx, enabled, pi, tp, ta, pty, ps_val, afs, data_val)
|
rds.set_eon(eon_idx, enabled, pi, tp, ta, pty, ps_val, afs, data_val)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif eon_type == "pty" then
|
elseif eon_type == "pty" then
|
||||||
local pty_val = tonumber(value)
|
local pty_val = tonumber(value)
|
||||||
if not pty_val then return "-\r\n" end
|
if not pty_val then return "-\r\n" end
|
||||||
set_rds_eon(eon_idx, enabled, pi, tp, ta, pty_val, ps, afs, data_val)
|
rds.set_eon(eon_idx, enabled, pi, tp, ta, pty_val, ps, afs, data_val)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif eon_type == "ta" then
|
elseif eon_type == "ta" then
|
||||||
if not enabled or not tp then return "-\r\n" end
|
if not enabled or not tp then return "-\r\n" end
|
||||||
local ta_val = tonumber(value)
|
local ta_val = tonumber(value)
|
||||||
if not ta_val then return "-\r\n" end
|
if not ta_val then return "-\r\n" end
|
||||||
ta = (ta_val ~= 0)
|
ta = (ta_val ~= 0)
|
||||||
set_rds_eon(eon_idx, enabled, pi, tp, ta, pty, ps, afs, data_val)
|
rds.set_eon(eon_idx, enabled, pi, tp, ta, pty, ps, afs, data_val)
|
||||||
if ta then set_rds_ta(true) end
|
if ta then rds.set_ta(true) end
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif eon_type == "tp" then
|
elseif eon_type == "tp" then
|
||||||
local tp_val = tonumber(value)
|
local tp_val = tonumber(value)
|
||||||
if not tp_val then return "-\r\n" end
|
if not tp_val then return "-\r\n" end
|
||||||
tp = (tp_val ~= 0)
|
tp = (tp_val ~= 0)
|
||||||
set_rds_eon(eon_idx, enabled, pi, tp, ta, pty, ps, afs, data_val)
|
rds.set_eon(eon_idx, enabled, pi, tp, ta, pty, ps, afs, data_val)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif eon_type == "af" then
|
elseif eon_type == "af" then
|
||||||
local af_table = {}
|
local af_table = {}
|
||||||
if value == "" or value == "0" then
|
if value == "" or value == "0" then
|
||||||
set_rds_eon(eon_idx, enabled, pi, tp, ta, pty, ps, {}, data_val)
|
rds.set_eon(eon_idx, enabled, pi, tp, ta, pty, ps, {}, data_val)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
end
|
end
|
||||||
for freq_str in value:gmatch("([^,]+)") do
|
for freq_str in value:gmatch("([^,]+)") do
|
||||||
@@ -156,12 +156,12 @@ function data_handle(data)
|
|||||||
else return "-\r\n" end
|
else return "-\r\n" end
|
||||||
end
|
end
|
||||||
if #af_table > 25 then return "-\r\n" end
|
if #af_table > 25 then return "-\r\n" end
|
||||||
set_rds_eon(eon_idx, enabled, pi, tp, ta, pty, ps, af_table, data_val)
|
rds.set_eon(eon_idx, enabled, pi, tp, ta, pty, ps, af_table, data_val)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif eon_type == "dt" then
|
elseif eon_type == "dt" then
|
||||||
local dt_val = tonumber(value, 16)
|
local dt_val = tonumber(value, 16)
|
||||||
if not dt_val then return "-\r\n" end
|
if not dt_val then return "-\r\n" end
|
||||||
set_rds_eon(eon_idx, enabled, pi, tp, ta, pty, ps, afs, dt_val)
|
rds.set_eon(eon_idx, enabled, pi, tp, ta, pty, ps, afs, dt_val)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
else return "?\r\n" end
|
else return "?\r\n" end
|
||||||
end
|
end
|
||||||
@@ -179,7 +179,7 @@ function data_handle(data)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if #groups > 8 or #groups == 0 then return "-\r\n" end
|
if #groups > 8 or #groups == 0 then return "-\r\n" end
|
||||||
set_rds_udg(xy, groups)
|
rds.set_udg(xy, groups)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
end
|
end
|
||||||
if udg2_num then
|
if udg2_num then
|
||||||
@@ -193,7 +193,7 @@ function data_handle(data)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if #groups > 8 or #groups == 0 then return "-" end
|
if #groups > 8 or #groups == 0 then return "-" end
|
||||||
set_rds_udg2(xy, groups)
|
rds.set_udg2(xy, groups)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -201,67 +201,67 @@ function data_handle(data)
|
|||||||
local pi = tonumber(value, 16)
|
local pi = tonumber(value, 16)
|
||||||
if not pi then return "-\r\n" end
|
if not pi then return "-\r\n" end
|
||||||
if (pi & 0xF000) == 0 then return "-\r\n" end
|
if (pi & 0xF000) == 0 then return "-\r\n" end
|
||||||
set_rds_pi(pi)
|
rds.set_pi(pi)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "ecc" then
|
elseif cmd == "ecc" then
|
||||||
local ecc = tonumber(value, 16)
|
local ecc = tonumber(value, 16)
|
||||||
if not ecc then return "-\r\n" end
|
if not ecc then return "-\r\n" end
|
||||||
set_rds_ecc(ecc)
|
rds.set_ecc(ecc)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "pty" then
|
elseif cmd == "pty" then
|
||||||
local pty = tonumber(value)
|
local pty = tonumber(value)
|
||||||
if not pty then return "-\r\n" end
|
if not pty then return "-\r\n" end
|
||||||
set_rds_pty(pty)
|
rds.set_pty(pty)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "slcd" then
|
elseif cmd == "slcd" then
|
||||||
local slc_data = tonumber(value, 16)
|
local slc_data = tonumber(value, 16)
|
||||||
if not slc_data then return "-\r\n" end
|
if not slc_data then return "-\r\n" end
|
||||||
set_rds_slc_data(slc_data)
|
rds.set_slc_data(slc_data)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "ct" then
|
elseif cmd == "ct" then
|
||||||
local ct = tonumber(value)
|
local ct = tonumber(value)
|
||||||
if not ct then return "-\r\n" end
|
if not ct then return "-\r\n" end
|
||||||
set_rds_ct(ct ~= 0)
|
rds.set_ct(ct ~= 0)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "dpty" then
|
elseif cmd == "dpty" then
|
||||||
local dpty = tonumber(value)
|
local dpty = tonumber(value)
|
||||||
if not dpty then return "-\r\n" end
|
if not dpty then return "-\r\n" end
|
||||||
set_rds_dpty(dpty ~= 0)
|
rds.set_dpty(dpty ~= 0)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "tp" then
|
elseif cmd == "tp" then
|
||||||
local tp = tonumber(value)
|
local tp = tonumber(value)
|
||||||
if not tp then return "-\r\n" end
|
if not tp then return "-\r\n" end
|
||||||
set_rds_tp(tp ~= 0)
|
rds.set_tp(tp ~= 0)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "ta" then
|
elseif cmd == "ta" then
|
||||||
local ta = tonumber(value)
|
local ta = tonumber(value)
|
||||||
if not ta then return "-\r\n" end
|
if not ta then return "-\r\n" end
|
||||||
set_rds_ta(ta ~= 0)
|
rds.set_ta(ta ~= 0)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "rt1en" then
|
elseif cmd == "rt1en" then
|
||||||
local en = tonumber(value)
|
local en = tonumber(value)
|
||||||
if not en then return "-\r\n" end
|
if not en then return "-\r\n" end
|
||||||
set_rds_rt1_enabled(en ~= 0)
|
rds.set_rt1_enabled(en ~= 0)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "rt2en" then
|
elseif cmd == "rt2en" then
|
||||||
local en = tonumber(value)
|
local en = tonumber(value)
|
||||||
if not en then return "-\r\n" end
|
if not en then return "-\r\n" end
|
||||||
set_rds_rt2_enabled(en ~= 0)
|
rds.set_rt2_enabled(en ~= 0)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "ptynen" then
|
elseif cmd == "ptynen" then
|
||||||
local en = tonumber(value)
|
local en = tonumber(value)
|
||||||
if not en then return "-\r\n" end
|
if not en then return "-\r\n" end
|
||||||
set_rds_ptyn_enabled(en ~= 0)
|
rds.set_ptyn_enabled(en ~= 0)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "rttype" then
|
elseif cmd == "rttype" then
|
||||||
local type = tonumber(value)
|
local type = tonumber(value)
|
||||||
if not type then return "-\r\n" end
|
if not type then return "-\r\n" end
|
||||||
set_rds_rt_type(type)
|
rds.set_rt_type(type)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "rds2mod" then
|
elseif cmd == "rds2mod" then
|
||||||
local type = tonumber(value)
|
local type = tonumber(value)
|
||||||
if not type then return "-\r\n" end
|
if not type then return "-\r\n" end
|
||||||
set_rds2_mode(type)
|
rds.set_rds2_mode(type)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "rdsgen" then
|
elseif cmd == "rdsgen" then
|
||||||
local type = tonumber(value)
|
local type = tonumber(value)
|
||||||
@@ -269,42 +269,42 @@ function data_handle(data)
|
|||||||
set_rds_streams(type)
|
set_rds_streams(type)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "ptyn" then
|
elseif cmd == "ptyn" then
|
||||||
set_rds_ptyn(value)
|
rds.set_ptyn(value)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "ps" then
|
elseif cmd == "ps" then
|
||||||
set_rds_ps(value)
|
rds.set_ps(value)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "tps" then
|
elseif cmd == "tps" then
|
||||||
set_rds_tps(value)
|
rds.set_tps(value)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "rt1" or cmd == "text" then
|
elseif cmd == "rt1" or cmd == "text" then
|
||||||
set_rds_rt1(value)
|
rds.set_rt1(value)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "rt2" then
|
elseif cmd == "rt2" then
|
||||||
set_rds_rt2(value)
|
rds.set_rt2(value)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "lps" then
|
elseif cmd == "lps" then
|
||||||
set_rds_lps(value)
|
rds.set_lps(value)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "ert" then
|
elseif cmd == "ert" then
|
||||||
set_rds_ert(value)
|
rds.ext.set_ert(value)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "link" then
|
elseif cmd == "link" then
|
||||||
local link = tonumber(value)
|
local link = tonumber(value)
|
||||||
if not link then return "-\r\n" end
|
if not link then return "-\r\n" end
|
||||||
set_rds_link(link ~= 0)
|
rds.set_link(link ~= 0)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "rtper" then
|
elseif cmd == "rtper" then
|
||||||
local period = tonumber(value)
|
local period = tonumber(value)
|
||||||
if not period then return "-\r\n" end
|
if not period then return "-\r\n" end
|
||||||
set_rds_rt_switching_period(period*60)
|
rds.set_rt_switching_period(period*60)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "program" then
|
elseif cmd == "program" then
|
||||||
local program = tonumber(value)
|
local program = tonumber(value)
|
||||||
if not program then return "-\r\n" end
|
if not program then return "-\r\n" end
|
||||||
if program < 1 or program > max_programs then return "-\r\n" end
|
if program < 1 or program > dp.max_programs then return "-\r\n" end
|
||||||
set_rds_program(program-1)
|
dp.set_rds_program(program-1)
|
||||||
set_rds_ta(false)
|
rds.set_ta(false)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "level" then
|
elseif cmd == "level" then
|
||||||
local level = tonumber(value)
|
local level = tonumber(value)
|
||||||
@@ -314,20 +314,20 @@ function data_handle(data)
|
|||||||
elseif cmd == "dttmout" then
|
elseif cmd == "dttmout" then
|
||||||
local timeout = tonumber(value)
|
local timeout = tonumber(value)
|
||||||
if not timeout then return "-\r\n" end
|
if not timeout then return "-\r\n" end
|
||||||
set_rds_rt_text_timeout(timeout*60)
|
rds.set_rt_text_timeout(timeout*60)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "grpseq" then
|
elseif cmd == "grpseq" then
|
||||||
set_rds_grpseq(value)
|
rds.set_grpseq(value)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "grpseq2" then
|
elseif cmd == "grpseq2" then
|
||||||
set_rds_grpseq2(value)
|
rds.set_grpseq2(value)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "rtp" or cmd == "ertp" then
|
elseif cmd == "rtp" or cmd == "ertp" then
|
||||||
local is_ertp = (cmd == "ertp")
|
local is_ertp = (cmd == "ertp")
|
||||||
local t1, s1, l1, t2, s2, l2 = value:match("(%d+),(%d+),(%d+),(%d+),(%d+),(%d+)")
|
local t1, s1, l1, t2, s2, l2 = value:match("(%d+),(%d+),(%d+),(%d+),(%d+),(%d+)")
|
||||||
|
|
||||||
if not l2 then return "-\r\n" end
|
if not l2 then return "-\r\n" end
|
||||||
set_rds_rtplus_tags(
|
rds.ext.set_rtplus_tags(
|
||||||
is_ertp,
|
is_ertp,
|
||||||
---@diagnostic disable-next-line: param-type-mismatch
|
---@diagnostic disable-next-line: param-type-mismatch
|
||||||
tonumber(t1), tonumber(s1), tonumber(l1), tonumber(t2), tonumber(s2), tonumber(l2)
|
tonumber(t1), tonumber(s1), tonumber(l1), tonumber(t2), tonumber(s2), tonumber(l2)
|
||||||
@@ -336,13 +336,13 @@ function data_handle(data)
|
|||||||
elseif cmd == "g" then
|
elseif cmd == "g" then
|
||||||
local a, b, c, d = value:match("^(%x%x%x%x)(%x%x%x%x)(%x%x%x%x)(%x%x%x%x)$")
|
local a, b, c, d = value:match("^(%x%x%x%x)(%x%x%x%x)(%x%x%x%x)(%x%x%x%x)$")
|
||||||
if a and b and c and d then
|
if a and b and c and d then
|
||||||
put_rds2_custom_group(tonumber(a, 16), tonumber(b, 16), tonumber(c, 16), tonumber(d, 16))
|
rds.put_rds2_custom_group(tonumber(a, 16), tonumber(b, 16), tonumber(c, 16), tonumber(d, 16))
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
local b1, c1, d1 = value:match("^(%x%x%x%x)(%x%x%x%x)(%x%x%x%x)$")
|
local b1, c1, d1 = value:match("^(%x%x%x%x)(%x%x%x%x)(%x%x%x%x)$")
|
||||||
if b1 and c1 and d1 then
|
if b1 and c1 and d1 then
|
||||||
put_rds_custom_group(tonumber(b1, 16), tonumber(c1, 16), tonumber(d1, 16))
|
rds.put_custom_group(tonumber(b1, 16), tonumber(c1, 16), tonumber(d1, 16))
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -357,14 +357,14 @@ function data_handle(data)
|
|||||||
local f2 = tonumber(f2_str) or 0
|
local f2 = tonumber(f2_str) or 0
|
||||||
local running = (f1 & 1) ~= 0
|
local running = (f1 & 1) ~= 0
|
||||||
|
|
||||||
set_rds_rtp_meta(is_ertp, running)
|
rds.ext.set_rtp_meta(is_ertp, running)
|
||||||
if f2 ~= 0 then toggle_rds_rtp(is_ertp) end
|
if f2 ~= 0 then rds.ext.toggle_rtp(is_ertp) end
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "af" then
|
elseif cmd == "af" then
|
||||||
local af_table = {}
|
local af_table = {}
|
||||||
|
|
||||||
if value == "" or value == "0" then
|
if value == "" or value == "0" then
|
||||||
set_rds_af_group0({})
|
rds.set_af({})
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -376,13 +376,13 @@ function data_handle(data)
|
|||||||
|
|
||||||
if #af_table > 25 then return "-\r\n" end
|
if #af_table > 25 then return "-\r\n" end
|
||||||
|
|
||||||
set_rds_af_group0(af_table)
|
rds.set_af(af_table)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
elseif cmd == "afo" then
|
elseif cmd == "afo" then
|
||||||
local af_table = {}
|
local af_table = {}
|
||||||
|
|
||||||
if value == "" or value == "0" then
|
if value == "" or value == "0" then
|
||||||
set_rds_af_oda({})
|
rds.ext.set_af_oda({})
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -394,7 +394,7 @@ function data_handle(data)
|
|||||||
|
|
||||||
if #af_table > 25 then return "-\r\n" end
|
if #af_table > 25 then return "-\r\n" end
|
||||||
|
|
||||||
set_rds_af_oda(af_table)
|
rds.ext.set_af_oda(af_table)
|
||||||
return "+\r\n"
|
return "+\r\n"
|
||||||
else
|
else
|
||||||
return "?\r\n"
|
return "?\r\n"
|
||||||
|
|||||||
425
src/lua_api.c
Normal file
425
src/lua_api.c
Normal file
@@ -0,0 +1,425 @@
|
|||||||
|
#include "lua_api.h"
|
||||||
|
#include "lua_rds.h"
|
||||||
|
|
||||||
|
static int in_set_defaults = 0;
|
||||||
|
|
||||||
|
extern lua_State *L;
|
||||||
|
extern RDSModulator* mod;
|
||||||
|
extern uint8_t unload_refs[33];
|
||||||
|
|
||||||
|
int lua_get_userdata(lua_State *localL) {
|
||||||
|
lua_pushlstring(localL, (const char*)&mod->enc->data[mod->enc->program].lua_data, LUA_USER_DATA);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
int lua_get_userdata_offset(lua_State *localL) {
|
||||||
|
uint16_t offset = luaL_checkinteger(localL, 1);
|
||||||
|
uint16_t size = luaL_checkinteger(localL, 2);
|
||||||
|
if((offset+size) > LUA_USER_DATA) return luaL_error(localL, "data exceeds limit");
|
||||||
|
lua_pushlstring(localL, (const char*)&mod->enc->data[mod->enc->program].lua_data[offset], size);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
int lua_set_userdata(lua_State *localL) {
|
||||||
|
size_t len;
|
||||||
|
const char *data = luaL_checklstring(localL, 1, &len);
|
||||||
|
if(len > LUA_USER_DATA) return luaL_error(localL, "data exceeds limit");
|
||||||
|
memset(mod->enc->data[mod->enc->program].lua_data, 0, LUA_USER_DATA);
|
||||||
|
memcpy(mod->enc->data[mod->enc->program].lua_data, data, len);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int lua_set_userdata_offset(lua_State *localL) {
|
||||||
|
uint16_t offset = luaL_checkinteger(localL, 1);
|
||||||
|
uint16_t size = luaL_checkinteger(localL, 2);
|
||||||
|
|
||||||
|
size_t len;
|
||||||
|
const char *data = luaL_checklstring(localL, 3, &len);
|
||||||
|
if(len > size || (offset + size) > LUA_USER_DATA) return luaL_error(localL, "data exceeds limit");
|
||||||
|
memset(mod->enc->data[mod->enc->program].lua_data + offset, 0, size);
|
||||||
|
memcpy(mod->enc->data[mod->enc->program].lua_data + offset, data, len);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua_force_save(lua_State *localL) {
|
||||||
|
(void)localL;
|
||||||
|
encoder_saveToFile(mod->enc);
|
||||||
|
Modulator_saveToFile(&mod->params);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua_set_rds_program_defaults(lua_State *localL) {
|
||||||
|
(void)localL;
|
||||||
|
if (in_set_defaults) {
|
||||||
|
fprintf(stderr, "Warning: Recursive call to lua_set_rds_program_defaults blocked\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
in_set_defaults = 1;
|
||||||
|
for (int i = 1; i < *unload_refs; i++) luaL_unref(L, LUA_REGISTRYINDEX, unload_refs[i]);
|
||||||
|
unload_refs[0] = 1;
|
||||||
|
set_rds_defaults(mod->enc, mod->enc->program);
|
||||||
|
lua_call_tfunction_nolock("on_init");
|
||||||
|
lua_call_tfunction_nolock("on_state");
|
||||||
|
in_set_defaults = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua_reset_rds(lua_State *localL) {
|
||||||
|
(void)localL;
|
||||||
|
for (int i = 1; i < *unload_refs; i++) luaL_unref(L, LUA_REGISTRYINDEX, unload_refs[i]);
|
||||||
|
unload_refs[0] = 1;
|
||||||
|
encoder_saveToFile(mod->enc);
|
||||||
|
Modulator_saveToFile(&mod->params);
|
||||||
|
|
||||||
|
encoder_loadFromFile(mod->enc);
|
||||||
|
for(int i = 0; i < PROGRAMS; i++) reset_rds_state(mod->enc, i);
|
||||||
|
Modulator_loadFromFile(&mod->params);
|
||||||
|
lua_call_tfunction_nolock("on_state");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BOOL_SETTER(name) \
|
||||||
|
int lua_set_rds_##name(lua_State *localL) { \
|
||||||
|
if (!lua_isboolean(localL, 1)) return luaL_error(localL, "boolean expected, got %s", luaL_typename(localL, 1)); \
|
||||||
|
mod->enc->data[mod->enc->program].name = lua_toboolean(localL, 1); \
|
||||||
|
return 0; \
|
||||||
|
}
|
||||||
|
#define INT_SETTER(name) \
|
||||||
|
int lua_set_rds_##name(lua_State *localL) { \
|
||||||
|
mod->enc->data[mod->enc->program].name = luaL_checkinteger(localL, 1); \
|
||||||
|
return 0; \
|
||||||
|
}
|
||||||
|
#define STR_SETTER(name, function) \
|
||||||
|
int lua_set_rds_##name(lua_State *localL) { \
|
||||||
|
const char* str = luaL_checklstring(localL, 1, NULL); \
|
||||||
|
function(mod->enc, convert_to_rdscharset(str)); \
|
||||||
|
return 0; \
|
||||||
|
}
|
||||||
|
#define STR_RAW_SETTER(name, function) \
|
||||||
|
int lua_set_rds_##name(lua_State *localL) { \
|
||||||
|
const char* str = luaL_checklstring(localL, 1, NULL); \
|
||||||
|
function(mod->enc, str); \
|
||||||
|
return 0; \
|
||||||
|
}
|
||||||
|
#define AF_SETTER(name, af_field, af_struct, add_func) \
|
||||||
|
int lua_set_rds_##name(lua_State *localL) { \
|
||||||
|
luaL_checktype(localL, 1, LUA_TTABLE); \
|
||||||
|
\
|
||||||
|
int n = lua_rawlen(localL, 1); \
|
||||||
|
if (n == 0) { \
|
||||||
|
memset(&(mod->enc->data[mod->enc->program].af_field), 0, sizeof(af_struct)); \
|
||||||
|
return 0; \
|
||||||
|
} \
|
||||||
|
if(n > 25) return luaL_error(localL, "table length over 25"); \
|
||||||
|
\
|
||||||
|
af_struct new_af; \
|
||||||
|
memset(&new_af, 0, sizeof(af_struct)); \
|
||||||
|
\
|
||||||
|
for (int i = 1; i <= n; i++) { \
|
||||||
|
lua_rawgeti(localL, 1, i); \
|
||||||
|
if (lua_isnumber(localL, -1)) add_func(&new_af, lua_tonumber(localL, -1)); \
|
||||||
|
else return luaL_error(localL, "number expected, got %s", luaL_typename(localL, -1)); \
|
||||||
|
lua_pop(localL, 1); \
|
||||||
|
} \
|
||||||
|
memcpy(&(mod->enc->data[mod->enc->program].af_field), &new_af, sizeof(new_af)); \
|
||||||
|
\
|
||||||
|
return 0; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define INT_GETTER(name) \
|
||||||
|
int lua_get_rds_##name(lua_State *localL) { \
|
||||||
|
lua_pushinteger(localL, mod->enc->data[mod->enc->program].name); \
|
||||||
|
return 1; \
|
||||||
|
}
|
||||||
|
#define BOOL_GETTER(name) \
|
||||||
|
int lua_get_rds_##name(lua_State *localL) { \
|
||||||
|
lua_pushboolean(localL, mod->enc->data[mod->enc->program].name); \
|
||||||
|
return 1; \
|
||||||
|
}
|
||||||
|
#define STR_RAW_GETTER(name, length) \
|
||||||
|
int lua_get_rds_##name(lua_State *localL) { \
|
||||||
|
lua_pushlstring(localL, mod->enc->data[mod->enc->program].name, length); \
|
||||||
|
return 1; \
|
||||||
|
}
|
||||||
|
INT_SETTER(pi)
|
||||||
|
INT_GETTER(pi)
|
||||||
|
|
||||||
|
INT_SETTER(pty)
|
||||||
|
INT_GETTER(pty)
|
||||||
|
|
||||||
|
INT_SETTER(ecc)
|
||||||
|
INT_GETTER(ecc)
|
||||||
|
|
||||||
|
INT_SETTER(slc_data)
|
||||||
|
INT_GETTER(slc_data)
|
||||||
|
|
||||||
|
BOOL_SETTER(ct)
|
||||||
|
BOOL_GETTER(ct)
|
||||||
|
|
||||||
|
BOOL_SETTER(dpty)
|
||||||
|
BOOL_GETTER(dpty)
|
||||||
|
|
||||||
|
BOOL_SETTER(tp)
|
||||||
|
BOOL_GETTER(tp)
|
||||||
|
|
||||||
|
BOOL_SETTER(ta)
|
||||||
|
BOOL_GETTER(ta)
|
||||||
|
|
||||||
|
BOOL_SETTER(rt1_enabled)
|
||||||
|
BOOL_GETTER(rt1_enabled)
|
||||||
|
|
||||||
|
BOOL_SETTER(rt2_enabled)
|
||||||
|
BOOL_GETTER(rt2_enabled)
|
||||||
|
|
||||||
|
BOOL_SETTER(ptyn_enabled)
|
||||||
|
BOOL_GETTER(ptyn_enabled)
|
||||||
|
|
||||||
|
INT_SETTER(rt_type)
|
||||||
|
INT_GETTER(rt_type)
|
||||||
|
|
||||||
|
int lua_set_rds2_mode(lua_State *localL) {
|
||||||
|
mod->enc->encoder_data.rds2_mode = luaL_checkinteger(localL, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua_get_rds2_mode(lua_State *localL) {
|
||||||
|
lua_pushinteger(localL, mod->enc->encoder_data.rds2_mode);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua_set_rds_streams(lua_State *localL) {
|
||||||
|
mod->params.rdsgen = luaL_checkinteger(localL, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua_get_rds_streams(lua_State *localL) {
|
||||||
|
lua_pushinteger(localL, mod->params.rdsgen);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua_set_rds_link(lua_State *localL) {
|
||||||
|
if (!lua_isboolean(localL, 1)) return luaL_error(localL, "boolean expected, got %s", luaL_typename(localL, 1));
|
||||||
|
mod->enc->state[mod->enc->program].eon_linkage = lua_toboolean(localL, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua_get_rds_link(lua_State *localL) {
|
||||||
|
lua_pushboolean(localL, mod->enc->state[mod->enc->program].eon_linkage);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua_set_rds_program(lua_State *localL) {
|
||||||
|
int program = luaL_checkinteger(localL, 1);
|
||||||
|
if(program >= PROGRAMS) program = (PROGRAMS-1);
|
||||||
|
if(program < 0) program = 0;
|
||||||
|
|
||||||
|
if(mod->enc->program == program) return 0;
|
||||||
|
|
||||||
|
mod->enc->data[mod->enc->program].ta = 0;
|
||||||
|
mod->enc->data[(uint8_t)program].ta = 0;
|
||||||
|
mod->enc->program = (uint8_t)program;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua_get_rds_program(lua_State *localL) {
|
||||||
|
lua_pushinteger(localL, mod->enc->program);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua_set_rds_rt_switching_period(lua_State *localL) {
|
||||||
|
mod->enc->data[mod->enc->program].rt_switching_period = luaL_checkinteger(localL, 1);
|
||||||
|
mod->enc->state[mod->enc->program].rt_switching_period_state = mod->enc->data[mod->enc->program].rt_switching_period;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
INT_GETTER(rt_switching_period)
|
||||||
|
|
||||||
|
int lua_set_rds_rt_text_timeout(lua_State *localL) {
|
||||||
|
mod->enc->data[mod->enc->program].rt_text_timeout = luaL_checkinteger(localL, 1);
|
||||||
|
mod->enc->state[mod->enc->program].rt_text_timeout_state = mod->enc->data[mod->enc->program].rt_text_timeout;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
INT_GETTER(rt_text_timeout)
|
||||||
|
|
||||||
|
int lua_set_rds_level(lua_State *localL) {
|
||||||
|
mod->params.level = luaL_checknumber(localL, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua_get_rds_level(lua_State *localL) {
|
||||||
|
lua_pushnumber(localL, mod->params.level);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua_put_rds_custom_group(lua_State *localL) {
|
||||||
|
mod->enc->state[mod->enc->program].custom_group[0] = 1;
|
||||||
|
mod->enc->state[mod->enc->program].custom_group[1] = luaL_checkinteger(localL, 1);
|
||||||
|
mod->enc->state[mod->enc->program].custom_group[2] = luaL_checkinteger(localL, 2);
|
||||||
|
mod->enc->state[mod->enc->program].custom_group[3] = luaL_checkinteger(localL, 3);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua_put_rds2_custom_group(lua_State *localL) {
|
||||||
|
mod->enc->state[mod->enc->program].custom_group2[0] = 1;
|
||||||
|
mod->enc->state[mod->enc->program].custom_group2[1] = luaL_checkinteger(localL, 1);
|
||||||
|
mod->enc->state[mod->enc->program].custom_group2[2] = luaL_checkinteger(localL, 2);
|
||||||
|
mod->enc->state[mod->enc->program].custom_group2[3] = luaL_checkinteger(localL, 3);
|
||||||
|
mod->enc->state[mod->enc->program].custom_group2[4] = luaL_checkinteger(localL, 4);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
STR_SETTER(ptyn, set_rds_ptyn)
|
||||||
|
STR_SETTER(ps, set_rds_ps)
|
||||||
|
STR_SETTER(tps, set_rds_tps)
|
||||||
|
STR_SETTER(rt1, set_rds_rt1)
|
||||||
|
STR_SETTER(rt2, set_rds_rt2)
|
||||||
|
STR_SETTER(default_rt, set_rds_default_rt)
|
||||||
|
|
||||||
|
STR_RAW_SETTER(lps, set_rds_lps)
|
||||||
|
STR_RAW_GETTER(lps, LPS_LENGTH)
|
||||||
|
|
||||||
|
STR_RAW_SETTER(grp_sqc_rds2, set_rds_grpseq2)
|
||||||
|
STR_RAW_GETTER(grp_sqc_rds2, 32)
|
||||||
|
|
||||||
|
int lua_set_rds_grp_sqc(lua_State *localL) {
|
||||||
|
const char* str = luaL_checklstring(localL, 1, NULL);
|
||||||
|
if(_strnlen(str, 2) < 1) set_rds_grpseq(mod->enc, DEFAULT_GRPSQC);
|
||||||
|
else set_rds_grpseq(mod->enc, str);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
STR_RAW_GETTER(grp_sqc, 32)
|
||||||
|
|
||||||
|
AF_SETTER(af_group0, af, RDSAFs, add_rds_af)
|
||||||
|
|
||||||
|
int lua_set_rds_eon(lua_State *localL) {
|
||||||
|
int eon = luaL_checkinteger(localL, 1);
|
||||||
|
if(eon >= EONs) return luaL_error(localL, "eon index exceeded");
|
||||||
|
if (!lua_isboolean(localL, 2)) return luaL_error(localL, "boolean expected, got %s", luaL_typename(localL, 2));
|
||||||
|
if (!lua_isboolean(localL, 4)) return luaL_error(localL, "boolean expected, got %s", luaL_typename(localL, 4));
|
||||||
|
if (!lua_isboolean(localL, 5)) return luaL_error(localL, "boolean expected, got %s", luaL_typename(localL, 5));
|
||||||
|
luaL_checktype(localL, 8, LUA_TTABLE);
|
||||||
|
mod->enc->data[mod->enc->program].eon[eon].enabled = lua_toboolean(localL, 2);
|
||||||
|
mod->enc->data[mod->enc->program].eon[eon].pi = luaL_checkinteger(localL, 3);
|
||||||
|
mod->enc->data[mod->enc->program].eon[eon].tp = lua_toboolean(localL, 4);
|
||||||
|
mod->enc->data[mod->enc->program].eon[eon].ta = lua_toboolean(localL, 5);
|
||||||
|
mod->enc->data[mod->enc->program].eon[eon].pty = luaL_checkinteger(localL, 6);
|
||||||
|
_strncpy(mod->enc->data[mod->enc->program].eon[eon].ps, luaL_checklstring(localL, 7, NULL), 8);
|
||||||
|
|
||||||
|
int n = lua_rawlen(localL, 8);
|
||||||
|
if (n == 0) {
|
||||||
|
memset(&(mod->enc->data[mod->enc->program].eon[eon].af), 0, sizeof(RDSAFs));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(n > 25) return luaL_error(localL, "table length over 25");
|
||||||
|
|
||||||
|
RDSAFs new_af;
|
||||||
|
memset(&new_af, 0, sizeof(RDSAFs));
|
||||||
|
|
||||||
|
for (int i = 1; i <= n; i++) {
|
||||||
|
lua_rawgeti(localL, 8, i);
|
||||||
|
if (lua_isnumber(localL, -1)) add_rds_af(&new_af, lua_tonumber(localL, -1));
|
||||||
|
else return luaL_error(localL, "number expected, got %s", luaL_typename(localL, -1));
|
||||||
|
lua_pop(localL, 1);
|
||||||
|
}
|
||||||
|
memcpy(&(mod->enc->data[mod->enc->program].eon[eon].af), &new_af, sizeof(new_af));
|
||||||
|
|
||||||
|
mod->enc->data[mod->enc->program].eon[eon].data = luaL_checkinteger(localL, 9);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua_get_rds_eon(lua_State *localL) {
|
||||||
|
int eon = luaL_checkinteger(localL, 1);
|
||||||
|
if(eon >= EONs) return luaL_error(localL, "eon index exceeded");
|
||||||
|
lua_pushboolean(localL, mod->enc->data[mod->enc->program].eon[eon].enabled);
|
||||||
|
lua_pushinteger(localL, mod->enc->data[mod->enc->program].eon[eon].pi);
|
||||||
|
lua_pushboolean(localL, mod->enc->data[mod->enc->program].eon[eon].tp);
|
||||||
|
lua_pushboolean(localL, mod->enc->data[mod->enc->program].eon[eon].ta);
|
||||||
|
lua_pushinteger(localL, mod->enc->data[mod->enc->program].eon[eon].pty);
|
||||||
|
lua_pushlstring(localL, mod->enc->data[mod->enc->program].eon[eon].ps, 8);
|
||||||
|
lua_createtable(localL, 0, 0); // don't have decoding for AF, so just return empty table
|
||||||
|
lua_pushinteger(localL, mod->enc->data[mod->enc->program].eon[eon].data);
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua_set_rds_udg(lua_State *localL) {
|
||||||
|
if (!lua_isboolean(localL, 1)) return luaL_error(localL, "boolean expected, got %s", luaL_typename(localL, 1));
|
||||||
|
int xy = lua_toboolean(localL, 1);
|
||||||
|
luaL_checktype(localL, 2, LUA_TTABLE);
|
||||||
|
int n = lua_rawlen(localL, 2);
|
||||||
|
if(n > 8) return luaL_error(localL, "table length over 8");
|
||||||
|
|
||||||
|
uint16_t blocks[8][3] = {0};
|
||||||
|
|
||||||
|
for (int i = 1; i <= n; i++) {
|
||||||
|
lua_rawgeti(localL, 2, i);
|
||||||
|
if(lua_istable(localL, -1)) {
|
||||||
|
int n2 = lua_rawlen(localL, -1);
|
||||||
|
if(n2 > 3) return luaL_error(localL, "table length over 3");
|
||||||
|
for(int j = 1; j <= n2; j++) {
|
||||||
|
lua_rawgeti(localL, -1, j);
|
||||||
|
if (lua_isinteger(localL, -1)) blocks[i-1][j-1] = lua_tointeger(localL, -1);
|
||||||
|
else return luaL_error(localL, "integer expected, got %s", luaL_typename(localL, -1));
|
||||||
|
lua_pop(localL, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else return luaL_error(localL, "table expected, got %s", luaL_typename(localL, -1));
|
||||||
|
lua_pop(localL, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(xy) {
|
||||||
|
memcpy(&(mod->enc->data[mod->enc->program].udg2), blocks, n * sizeof(uint16_t[3]));
|
||||||
|
mod->enc->data[mod->enc->program].udg2_len = n;
|
||||||
|
} else {
|
||||||
|
memcpy(&(mod->enc->data[mod->enc->program].udg1), blocks, n * sizeof(uint16_t[3]));
|
||||||
|
mod->enc->data[mod->enc->program].udg1_len = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua_set_rds_udg2(lua_State *localL) {
|
||||||
|
if (!lua_isboolean(localL, 1)) return luaL_error(localL, "boolean expected, got %s", luaL_typename(localL, 1));
|
||||||
|
int xy = lua_toboolean(localL, 1);
|
||||||
|
luaL_checktype(localL, 2, LUA_TTABLE);
|
||||||
|
int n = lua_rawlen(localL, 2);
|
||||||
|
if(n > 8) return luaL_error(localL, "table length over 8");
|
||||||
|
|
||||||
|
uint16_t blocks[8][4] = {0};
|
||||||
|
|
||||||
|
for (int i = 1; i <= n; i++) {
|
||||||
|
lua_rawgeti(localL, 2, i);
|
||||||
|
if(lua_istable(localL, -1)) {
|
||||||
|
int n2 = lua_rawlen(localL, -1);
|
||||||
|
if(n2 > 4) return luaL_error(localL, "table length over 4");
|
||||||
|
for(int j = 1; j <= n2; j++) {
|
||||||
|
lua_rawgeti(localL, -1, j);
|
||||||
|
if (lua_isinteger(localL, -1)) blocks[i-1][j-1] = lua_tointeger(localL, -1);
|
||||||
|
else return luaL_error(localL, "integer expected, got %s", luaL_typename(localL, -1));
|
||||||
|
lua_pop(localL, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else return luaL_error(localL, "table expected, got %s", luaL_typename(localL, -1));
|
||||||
|
lua_pop(localL, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(xy) {
|
||||||
|
memcpy(&(mod->enc->data[mod->enc->program].udg2_rds2), blocks, n * sizeof(uint16_t[4]));
|
||||||
|
mod->enc->data[mod->enc->program].udg2_len_rds2 = n;
|
||||||
|
} else {
|
||||||
|
memcpy(&(mod->enc->data[mod->enc->program].udg1_rds2), blocks, n * sizeof(uint16_t[4]));
|
||||||
|
mod->enc->data[mod->enc->program].udg1_len_rds2 = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua_get_available_rds_streams(lua_State *localL) {
|
||||||
|
lua_pushinteger(localL, mod->num_streams);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua_crc16(lua_State *localL) {
|
||||||
|
size_t len;
|
||||||
|
const char* data = luaL_checklstring(localL, 1, &len);
|
||||||
|
lua_pushinteger(localL, crc16_ccitt(data, len));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
101
src/lua_api.h
Normal file
101
src/lua_api.h
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <lua.h>
|
||||||
|
#include <lualib.h>
|
||||||
|
#include <lauxlib.h>
|
||||||
|
#include "rds.h"
|
||||||
|
#include "fs.h"
|
||||||
|
#include "modulator.h"
|
||||||
|
|
||||||
|
int lua_get_userdata(lua_State *localL);
|
||||||
|
int lua_get_userdata_offset(lua_State *localL);
|
||||||
|
int lua_set_userdata(lua_State *localL);
|
||||||
|
int lua_set_userdata_offset(lua_State *localL);
|
||||||
|
int lua_force_save(lua_State *localL);
|
||||||
|
int lua_set_rds_program_defaults(lua_State *localL);
|
||||||
|
int lua_reset_rds(lua_State *localL);
|
||||||
|
|
||||||
|
int lua_set_rds_pi(lua_State *localL);
|
||||||
|
int lua_get_rds_pi(lua_State *localL);
|
||||||
|
|
||||||
|
int lua_set_rds_pty(lua_State *localL);
|
||||||
|
int lua_get_rds_pty(lua_State *localL);
|
||||||
|
|
||||||
|
int lua_set_rds_ecc(lua_State *localL);
|
||||||
|
int lua_get_rds_ecc(lua_State *localL);
|
||||||
|
|
||||||
|
int lua_set_rds_slc_data(lua_State *localL);
|
||||||
|
int lua_get_rds_slc_data(lua_State *localL);
|
||||||
|
|
||||||
|
int lua_set_rds_ct(lua_State *localL);
|
||||||
|
int lua_get_rds_ct(lua_State *localL);
|
||||||
|
|
||||||
|
int lua_set_rds_dpty(lua_State *localL);
|
||||||
|
int lua_get_rds_dpty(lua_State *localL);
|
||||||
|
|
||||||
|
int lua_set_rds_tp(lua_State *localL);
|
||||||
|
int lua_get_rds_tp(lua_State *localL);
|
||||||
|
|
||||||
|
int lua_set_rds_ta(lua_State *localL);
|
||||||
|
int lua_get_rds_ta(lua_State *localL);
|
||||||
|
|
||||||
|
int lua_set_rds_rt1_enabled(lua_State *localL);
|
||||||
|
int lua_get_rds_rt1_enabled(lua_State *localL);
|
||||||
|
|
||||||
|
int lua_set_rds_rt2_enabled(lua_State *localL);
|
||||||
|
int lua_get_rds_rt2_enabled(lua_State *localL);
|
||||||
|
|
||||||
|
int lua_set_rds_ptyn_enabled(lua_State *localL);
|
||||||
|
int lua_get_rds_ptyn_enabled(lua_State *localL);
|
||||||
|
|
||||||
|
int lua_set_rds_rt_type(lua_State *localL);
|
||||||
|
int lua_get_rds_rt_type(lua_State *localL);
|
||||||
|
|
||||||
|
int lua_set_rds2_mode(lua_State *localL);
|
||||||
|
int lua_get_rds2_mode(lua_State *localL);
|
||||||
|
|
||||||
|
int lua_set_rds_streams(lua_State *localL);
|
||||||
|
int lua_get_rds_streams(lua_State *localL);
|
||||||
|
int lua_get_available_rds_streams(lua_State *localL);
|
||||||
|
|
||||||
|
int lua_set_rds_grp_sqc(lua_State *localL);
|
||||||
|
int lua_get_rds_grp_sqc(lua_State *localL);
|
||||||
|
|
||||||
|
int lua_set_rds_grp_sqc_rds2(lua_State *localL);
|
||||||
|
int lua_get_rds_grp_sqc_rds2(lua_State *localL);
|
||||||
|
|
||||||
|
int lua_set_rds_link(lua_State *localL);
|
||||||
|
int lua_get_rds_link(lua_State *localL);
|
||||||
|
|
||||||
|
int lua_set_rds_program(lua_State *localL);
|
||||||
|
int lua_get_rds_program(lua_State *localL);
|
||||||
|
|
||||||
|
int lua_set_rds_rt_switching_period(lua_State *localL);
|
||||||
|
int lua_get_rds_rt_switching_period(lua_State *localL);
|
||||||
|
|
||||||
|
int lua_set_rds_rt_text_timeout(lua_State *localL);
|
||||||
|
int lua_get_rds_rt_text_timeout(lua_State *localL);
|
||||||
|
|
||||||
|
int lua_set_rds_level(lua_State *localL);
|
||||||
|
int lua_get_rds_level(lua_State *localL);
|
||||||
|
|
||||||
|
int lua_put_rds_custom_group(lua_State *localL);
|
||||||
|
int lua_put_rds2_custom_group(lua_State *localL);
|
||||||
|
|
||||||
|
int lua_set_rds_lps(lua_State *localL);
|
||||||
|
int lua_get_rds_lps(lua_State *localL);
|
||||||
|
int lua_set_rds_af_group0(lua_State *localL);
|
||||||
|
int lua_set_rds_default_rt(lua_State *localL);
|
||||||
|
int lua_set_rds_rt2(lua_State *localL);
|
||||||
|
int lua_set_rds_rt1(lua_State *localL);
|
||||||
|
int lua_set_rds_tps(lua_State *localL);
|
||||||
|
int lua_set_rds_ps(lua_State *localL);
|
||||||
|
int lua_set_rds_ptyn(lua_State *localL);
|
||||||
|
int lua_set_rds_grp_sqc(lua_State *localL);
|
||||||
|
|
||||||
|
int lua_set_rds_eon(lua_State *localL);
|
||||||
|
int lua_get_rds_eon(lua_State *localL);
|
||||||
|
int lua_set_rds_udg(lua_State *localL);
|
||||||
|
int lua_set_rds_udg2(lua_State *localL);
|
||||||
|
|
||||||
|
int lua_crc16(lua_State *localL);
|
||||||
651
src/lua_rds.c
651
src/lua_rds.c
@@ -1,418 +1,13 @@
|
|||||||
#include "lua_rds.h"
|
#include "lua_rds.h"
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include "lua_api.h"
|
||||||
|
|
||||||
static RDSModulator* mod = NULL;
|
RDSModulator* mod = NULL;
|
||||||
static lua_State *L = NULL;
|
lua_State *L = NULL;
|
||||||
static pthread_mutex_t lua_mutex;
|
static pthread_mutex_t lua_mutex;
|
||||||
static uint8_t unload_refs[33] = {LUA_REFNIL};
|
uint8_t unload_refs[33] = {LUA_REFNIL};
|
||||||
static int in_set_defaults = 0;
|
|
||||||
|
|
||||||
int lua_get_userdata(lua_State *localL) {
|
|
||||||
lua_pushlstring(localL, (const char*)&mod->enc->data[mod->enc->program].lua_data, LUA_USER_DATA);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
int lua_get_userdata_offset(lua_State *localL) {
|
|
||||||
uint16_t offset = luaL_checkinteger(localL, 1);
|
|
||||||
uint16_t size = luaL_checkinteger(localL, 2);
|
|
||||||
if((offset+size) > LUA_USER_DATA) return luaL_error(localL, "data exceeds limit");
|
|
||||||
lua_pushlstring(localL, (const char*)&mod->enc->data[mod->enc->program].lua_data[offset], size);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
int lua_set_userdata(lua_State *localL) {
|
|
||||||
size_t len;
|
|
||||||
const char *data = luaL_checklstring(localL, 1, &len);
|
|
||||||
if(len > LUA_USER_DATA) return luaL_error(localL, "data exceeds limit");
|
|
||||||
memset(mod->enc->data[mod->enc->program].lua_data, 0, LUA_USER_DATA);
|
|
||||||
memcpy(mod->enc->data[mod->enc->program].lua_data, data, len);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int lua_set_userdata_offset(lua_State *localL) {
|
|
||||||
uint16_t offset = luaL_checkinteger(localL, 1);
|
|
||||||
uint16_t size = luaL_checkinteger(localL, 2);
|
|
||||||
|
|
||||||
size_t len;
|
|
||||||
const char *data = luaL_checklstring(localL, 3, &len);
|
|
||||||
if(len > size || (offset + size) > LUA_USER_DATA) return luaL_error(localL, "data exceeds limit");
|
|
||||||
memset(mod->enc->data[mod->enc->program].lua_data + offset, 0, size);
|
|
||||||
memcpy(mod->enc->data[mod->enc->program].lua_data + offset, data, len);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lua_force_save(lua_State *localL) {
|
|
||||||
(void)localL;
|
|
||||||
encoder_saveToFile(mod->enc);
|
|
||||||
Modulator_saveToFile(&mod->params);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lua_set_rds_program_defaults(lua_State *localL) {
|
|
||||||
(void)localL;
|
|
||||||
if (in_set_defaults) {
|
|
||||||
fprintf(stderr, "Warning: Recursive call to lua_set_rds_program_defaults blocked\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
in_set_defaults = 1;
|
|
||||||
for (int i = 1; i < *unload_refs; i++) luaL_unref(L, LUA_REGISTRYINDEX, unload_refs[i]);
|
|
||||||
unload_refs[0] = 1;
|
|
||||||
set_rds_defaults(mod->enc, mod->enc->program);
|
|
||||||
lua_call_function_nolock("on_init");
|
|
||||||
lua_call_function_nolock("on_state");
|
|
||||||
in_set_defaults = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lua_reset_rds(lua_State *localL) {
|
|
||||||
(void)localL;
|
|
||||||
for (int i = 1; i < *unload_refs; i++) luaL_unref(L, LUA_REGISTRYINDEX, unload_refs[i]);
|
|
||||||
unload_refs[0] = 1;
|
|
||||||
encoder_saveToFile(mod->enc);
|
|
||||||
Modulator_saveToFile(&mod->params);
|
|
||||||
|
|
||||||
encoder_loadFromFile(mod->enc);
|
|
||||||
for(int i = 0; i < PROGRAMS; i++) reset_rds_state(mod->enc, i);
|
|
||||||
Modulator_loadFromFile(&mod->params);
|
|
||||||
lua_call_function_nolock("on_state");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BOOL_SETTER(name) \
|
|
||||||
int lua_set_rds_##name(lua_State *localL) { \
|
|
||||||
if (!lua_isboolean(localL, 1)) return luaL_error(localL, "boolean expected, got %s", luaL_typename(localL, 1)); \
|
|
||||||
mod->enc->data[mod->enc->program].name = lua_toboolean(localL, 1); \
|
|
||||||
return 0; \
|
|
||||||
}
|
|
||||||
#define INT_SETTER(name) \
|
|
||||||
int lua_set_rds_##name(lua_State *localL) { \
|
|
||||||
mod->enc->data[mod->enc->program].name = luaL_checkinteger(localL, 1); \
|
|
||||||
return 0; \
|
|
||||||
}
|
|
||||||
#define STR_SETTER(name, function) \
|
|
||||||
int lua_set_rds_##name(lua_State *localL) { \
|
|
||||||
const char* str = luaL_checklstring(localL, 1, NULL); \
|
|
||||||
function(mod->enc, convert_to_rdscharset(str)); \
|
|
||||||
return 0; \
|
|
||||||
}
|
|
||||||
#define STR_RAW_SETTER(name, function) \
|
|
||||||
int lua_set_rds_##name(lua_State *localL) { \
|
|
||||||
const char* str = luaL_checklstring(localL, 1, NULL); \
|
|
||||||
function(mod->enc, str); \
|
|
||||||
return 0; \
|
|
||||||
}
|
|
||||||
#define AF_SETTER(name, af_field, af_struct, add_func) \
|
|
||||||
int lua_set_rds_##name(lua_State *localL) { \
|
|
||||||
luaL_checktype(localL, 1, LUA_TTABLE); \
|
|
||||||
\
|
|
||||||
int n = lua_rawlen(localL, 1); \
|
|
||||||
if (n == 0) { \
|
|
||||||
memset(&(mod->enc->data[mod->enc->program].af_field), 0, sizeof(af_struct)); \
|
|
||||||
return 0; \
|
|
||||||
} \
|
|
||||||
if(n > 25) return luaL_error(localL, "table length over 25"); \
|
|
||||||
\
|
|
||||||
af_struct new_af; \
|
|
||||||
memset(&new_af, 0, sizeof(af_struct)); \
|
|
||||||
\
|
|
||||||
for (int i = 1; i <= n; i++) { \
|
|
||||||
lua_rawgeti(localL, 1, i); \
|
|
||||||
if (lua_isnumber(localL, -1)) add_func(&new_af, lua_tonumber(localL, -1)); \
|
|
||||||
else return luaL_error(localL, "number expected, got %s", luaL_typename(localL, -1)); \
|
|
||||||
lua_pop(localL, 1); \
|
|
||||||
} \
|
|
||||||
memcpy(&(mod->enc->data[mod->enc->program].af_field), &new_af, sizeof(new_af)); \
|
|
||||||
\
|
|
||||||
return 0; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define INT_GETTER(name) \
|
|
||||||
int lua_get_rds_##name(lua_State *localL) { \
|
|
||||||
lua_pushinteger(localL, mod->enc->data[mod->enc->program].name); \
|
|
||||||
return 1; \
|
|
||||||
}
|
|
||||||
#define BOOL_GETTER(name) \
|
|
||||||
int lua_get_rds_##name(lua_State *localL) { \
|
|
||||||
lua_pushboolean(localL, mod->enc->data[mod->enc->program].name); \
|
|
||||||
return 1; \
|
|
||||||
}
|
|
||||||
#define STR_RAW_GETTER(name, length) \
|
|
||||||
int lua_get_rds_##name(lua_State *localL) { \
|
|
||||||
lua_pushlstring(localL, mod->enc->data[mod->enc->program].name, length); \
|
|
||||||
return 1; \
|
|
||||||
}
|
|
||||||
INT_SETTER(pi)
|
|
||||||
INT_GETTER(pi)
|
|
||||||
|
|
||||||
INT_SETTER(pty)
|
|
||||||
INT_GETTER(pty)
|
|
||||||
|
|
||||||
INT_SETTER(ecc)
|
|
||||||
INT_GETTER(ecc)
|
|
||||||
|
|
||||||
INT_SETTER(slc_data)
|
|
||||||
INT_GETTER(slc_data)
|
|
||||||
|
|
||||||
BOOL_SETTER(ct)
|
|
||||||
BOOL_GETTER(ct)
|
|
||||||
|
|
||||||
BOOL_SETTER(dpty)
|
|
||||||
BOOL_GETTER(dpty)
|
|
||||||
|
|
||||||
BOOL_SETTER(tp)
|
|
||||||
BOOL_GETTER(tp)
|
|
||||||
|
|
||||||
BOOL_SETTER(ta)
|
|
||||||
BOOL_GETTER(ta)
|
|
||||||
|
|
||||||
BOOL_SETTER(rt1_enabled)
|
|
||||||
BOOL_GETTER(rt1_enabled)
|
|
||||||
|
|
||||||
BOOL_SETTER(rt2_enabled)
|
|
||||||
BOOL_GETTER(rt2_enabled)
|
|
||||||
|
|
||||||
BOOL_SETTER(ptyn_enabled)
|
|
||||||
BOOL_GETTER(ptyn_enabled)
|
|
||||||
|
|
||||||
INT_SETTER(rt_type)
|
|
||||||
INT_GETTER(rt_type)
|
|
||||||
|
|
||||||
int lua_set_rds2_mode(lua_State *localL) {
|
|
||||||
mod->enc->encoder_data.rds2_mode = luaL_checkinteger(localL, 1);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int lua_get_rds2_mode(lua_State *localL) {
|
|
||||||
lua_pushinteger(localL, mod->enc->encoder_data.rds2_mode);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
int lua_set_rds_streams(lua_State *localL) {
|
|
||||||
mod->params.rdsgen = luaL_checkinteger(localL, 1);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int lua_get_rds_streams(lua_State *localL) {
|
|
||||||
lua_pushinteger(localL, mod->params.rdsgen);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lua_set_rds_link(lua_State *localL) {
|
|
||||||
if (!lua_isboolean(localL, 1)) return luaL_error(localL, "boolean expected, got %s", luaL_typename(localL, 1));
|
|
||||||
mod->enc->state[mod->enc->program].eon_linkage = lua_toboolean(localL, 1);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int lua_get_rds_link(lua_State *localL) {
|
|
||||||
lua_pushboolean(localL, mod->enc->state[mod->enc->program].eon_linkage);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lua_set_rds_program(lua_State *localL) {
|
|
||||||
int program = luaL_checkinteger(localL, 1);
|
|
||||||
if(program >= PROGRAMS) program = (PROGRAMS-1);
|
|
||||||
if(program < 0) program = 0;
|
|
||||||
|
|
||||||
if(mod->enc->program == program) return 0;
|
|
||||||
|
|
||||||
mod->enc->data[mod->enc->program].ta = 0;
|
|
||||||
mod->enc->data[(uint8_t)program].ta = 0;
|
|
||||||
mod->enc->program = (uint8_t)program;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int lua_get_rds_program(lua_State *localL) {
|
|
||||||
lua_pushinteger(localL, mod->enc->program);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lua_set_rds_rt_switching_period(lua_State *localL) {
|
|
||||||
mod->enc->data[mod->enc->program].rt_switching_period = luaL_checkinteger(localL, 1);
|
|
||||||
mod->enc->state[mod->enc->program].rt_switching_period_state = mod->enc->data[mod->enc->program].rt_switching_period;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
INT_GETTER(rt_switching_period)
|
|
||||||
int lua_set_rds_rt_text_timeout(lua_State *localL) {
|
|
||||||
mod->enc->data[mod->enc->program].rt_text_timeout = luaL_checkinteger(localL, 1);
|
|
||||||
mod->enc->state[mod->enc->program].rt_text_timeout_state = mod->enc->data[mod->enc->program].rt_text_timeout;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
INT_GETTER(rt_text_timeout)
|
|
||||||
|
|
||||||
int lua_set_rds_level(lua_State *localL) {
|
|
||||||
mod->params.level = luaL_checknumber(localL, 1);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int lua_get_rds_level(lua_State *localL) {
|
|
||||||
lua_pushnumber(localL, mod->params.level);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lua_put_rds_custom_group(lua_State *localL) {
|
|
||||||
mod->enc->state[mod->enc->program].custom_group[0] = 1;
|
|
||||||
mod->enc->state[mod->enc->program].custom_group[1] = luaL_checkinteger(localL, 1);
|
|
||||||
mod->enc->state[mod->enc->program].custom_group[2] = luaL_checkinteger(localL, 2);
|
|
||||||
mod->enc->state[mod->enc->program].custom_group[3] = luaL_checkinteger(localL, 3);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int lua_put_rds2_custom_group(lua_State *localL) {
|
|
||||||
mod->enc->state[mod->enc->program].custom_group2[0] = 1;
|
|
||||||
mod->enc->state[mod->enc->program].custom_group2[1] = luaL_checkinteger(localL, 1);
|
|
||||||
mod->enc->state[mod->enc->program].custom_group2[2] = luaL_checkinteger(localL, 2);
|
|
||||||
mod->enc->state[mod->enc->program].custom_group2[3] = luaL_checkinteger(localL, 3);
|
|
||||||
mod->enc->state[mod->enc->program].custom_group2[4] = luaL_checkinteger(localL, 4);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
STR_SETTER(ptyn, set_rds_ptyn)
|
|
||||||
STR_SETTER(ps, set_rds_ps)
|
|
||||||
STR_SETTER(tps, set_rds_tps)
|
|
||||||
STR_SETTER(rt1, set_rds_rt1)
|
|
||||||
STR_SETTER(rt2, set_rds_rt2)
|
|
||||||
STR_SETTER(default_rt, set_rds_default_rt)
|
|
||||||
|
|
||||||
STR_RAW_SETTER(lps, set_rds_lps)
|
|
||||||
STR_RAW_GETTER(lps, LPS_LENGTH)
|
|
||||||
|
|
||||||
STR_RAW_SETTER(grp_sqc_rds2, set_rds_grpseq2)
|
|
||||||
STR_RAW_GETTER(grp_sqc_rds2, 32)
|
|
||||||
|
|
||||||
int lua_set_rds_grp_sqc(lua_State *localL) {
|
|
||||||
const char* str = luaL_checklstring(localL, 1, NULL);
|
|
||||||
if(_strnlen(str, 2) < 1) set_rds_grpseq(mod->enc, DEFAULT_GRPSQC);
|
|
||||||
else set_rds_grpseq(mod->enc, str);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
STR_RAW_GETTER(grp_sqc, 32)
|
|
||||||
|
|
||||||
AF_SETTER(af_group0, af, RDSAFs, add_rds_af)
|
|
||||||
|
|
||||||
int lua_set_rds_eon(lua_State *localL) {
|
|
||||||
int eon = luaL_checkinteger(localL, 1);
|
|
||||||
if(eon >= EONs) return luaL_error(localL, "eon index exceeded");
|
|
||||||
if (!lua_isboolean(localL, 2)) return luaL_error(localL, "boolean expected, got %s", luaL_typename(localL, 2));
|
|
||||||
if (!lua_isboolean(localL, 4)) return luaL_error(localL, "boolean expected, got %s", luaL_typename(localL, 4));
|
|
||||||
if (!lua_isboolean(localL, 5)) return luaL_error(localL, "boolean expected, got %s", luaL_typename(localL, 5));
|
|
||||||
luaL_checktype(localL, 8, LUA_TTABLE);
|
|
||||||
mod->enc->data[mod->enc->program].eon[eon].enabled = lua_toboolean(localL, 2);
|
|
||||||
mod->enc->data[mod->enc->program].eon[eon].pi = luaL_checkinteger(localL, 3);
|
|
||||||
mod->enc->data[mod->enc->program].eon[eon].tp = lua_toboolean(localL, 4);
|
|
||||||
mod->enc->data[mod->enc->program].eon[eon].ta = lua_toboolean(localL, 5);
|
|
||||||
mod->enc->data[mod->enc->program].eon[eon].pty = luaL_checkinteger(localL, 6);
|
|
||||||
_strncpy(mod->enc->data[mod->enc->program].eon[eon].ps, luaL_checklstring(localL, 7, NULL), 8);
|
|
||||||
|
|
||||||
int n = lua_rawlen(localL, 8);
|
|
||||||
if (n == 0) {
|
|
||||||
memset(&(mod->enc->data[mod->enc->program].eon[eon].af), 0, sizeof(RDSAFs));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if(n > 25) return luaL_error(localL, "table length over 25");
|
|
||||||
|
|
||||||
RDSAFs new_af;
|
|
||||||
memset(&new_af, 0, sizeof(RDSAFs));
|
|
||||||
|
|
||||||
for (int i = 1; i <= n; i++) {
|
|
||||||
lua_rawgeti(localL, 8, i);
|
|
||||||
if (lua_isnumber(localL, -1)) add_rds_af(&new_af, lua_tonumber(localL, -1));
|
|
||||||
else return luaL_error(localL, "number expected, got %s", luaL_typename(localL, -1));
|
|
||||||
lua_pop(localL, 1);
|
|
||||||
}
|
|
||||||
memcpy(&(mod->enc->data[mod->enc->program].eon[eon].af), &new_af, sizeof(new_af));
|
|
||||||
|
|
||||||
mod->enc->data[mod->enc->program].eon[eon].data = luaL_checkinteger(localL, 9);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int lua_get_rds_eon(lua_State *localL) {
|
|
||||||
int eon = luaL_checkinteger(localL, 1);
|
|
||||||
if(eon >= EONs) return luaL_error(localL, "eon index exceeded");
|
|
||||||
lua_pushboolean(localL, mod->enc->data[mod->enc->program].eon[eon].enabled);
|
|
||||||
lua_pushinteger(localL, mod->enc->data[mod->enc->program].eon[eon].pi);
|
|
||||||
lua_pushboolean(localL, mod->enc->data[mod->enc->program].eon[eon].tp);
|
|
||||||
lua_pushboolean(localL, mod->enc->data[mod->enc->program].eon[eon].ta);
|
|
||||||
lua_pushinteger(localL, mod->enc->data[mod->enc->program].eon[eon].pty);
|
|
||||||
lua_pushlstring(localL, mod->enc->data[mod->enc->program].eon[eon].ps, 8);
|
|
||||||
lua_createtable(localL, 0, 0); // don't have decoding for AF, so just return empty table
|
|
||||||
lua_pushinteger(localL, mod->enc->data[mod->enc->program].eon[eon].data);
|
|
||||||
return 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lua_set_rds_udg(lua_State *localL) {
|
|
||||||
if (!lua_isboolean(localL, 1)) return luaL_error(localL, "boolean expected, got %s", luaL_typename(localL, 1));
|
|
||||||
int xy = lua_toboolean(localL, 1);
|
|
||||||
luaL_checktype(localL, 2, LUA_TTABLE);
|
|
||||||
int n = lua_rawlen(localL, 2);
|
|
||||||
if(n > 8) return luaL_error(localL, "table length over 8");
|
|
||||||
|
|
||||||
uint16_t blocks[8][3] = {0};
|
|
||||||
|
|
||||||
for (int i = 1; i <= n; i++) {
|
|
||||||
lua_rawgeti(localL, 2, i);
|
|
||||||
if(lua_istable(localL, -1)) {
|
|
||||||
int n2 = lua_rawlen(localL, -1);
|
|
||||||
if(n2 > 3) return luaL_error(localL, "table length over 3");
|
|
||||||
for(int j = 1; j <= n2; j++) {
|
|
||||||
lua_rawgeti(localL, -1, j);
|
|
||||||
if (lua_isinteger(localL, -1)) blocks[i-1][j-1] = lua_tointeger(localL, -1);
|
|
||||||
else return luaL_error(localL, "integer expected, got %s", luaL_typename(localL, -1));
|
|
||||||
lua_pop(localL, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else return luaL_error(localL, "table expected, got %s", luaL_typename(localL, -1));
|
|
||||||
lua_pop(localL, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(xy) {
|
|
||||||
memcpy(&(mod->enc->data[mod->enc->program].udg2), blocks, n * sizeof(uint16_t[3]));
|
|
||||||
mod->enc->data[mod->enc->program].udg2_len = n;
|
|
||||||
} else {
|
|
||||||
memcpy(&(mod->enc->data[mod->enc->program].udg1), blocks, n * sizeof(uint16_t[3]));
|
|
||||||
mod->enc->data[mod->enc->program].udg1_len = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int lua_set_rds_udg2(lua_State *localL) {
|
|
||||||
if (!lua_isboolean(localL, 1)) return luaL_error(localL, "boolean expected, got %s", luaL_typename(localL, 1));
|
|
||||||
int xy = lua_toboolean(localL, 1);
|
|
||||||
luaL_checktype(localL, 2, LUA_TTABLE);
|
|
||||||
int n = lua_rawlen(localL, 2);
|
|
||||||
if(n > 8) return luaL_error(localL, "table length over 8");
|
|
||||||
|
|
||||||
uint16_t blocks[8][4] = {0};
|
|
||||||
|
|
||||||
for (int i = 1; i <= n; i++) {
|
|
||||||
lua_rawgeti(localL, 2, i);
|
|
||||||
if(lua_istable(localL, -1)) {
|
|
||||||
int n2 = lua_rawlen(localL, -1);
|
|
||||||
if(n2 > 4) return luaL_error(localL, "table length over 4");
|
|
||||||
for(int j = 1; j <= n2; j++) {
|
|
||||||
lua_rawgeti(localL, -1, j);
|
|
||||||
if (lua_isinteger(localL, -1)) blocks[i-1][j-1] = lua_tointeger(localL, -1);
|
|
||||||
else return luaL_error(localL, "integer expected, got %s", luaL_typename(localL, -1));
|
|
||||||
lua_pop(localL, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else return luaL_error(localL, "table expected, got %s", luaL_typename(localL, -1));
|
|
||||||
lua_pop(localL, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(xy) {
|
|
||||||
memcpy(&(mod->enc->data[mod->enc->program].udg2_rds2), blocks, n * sizeof(uint16_t[4]));
|
|
||||||
mod->enc->data[mod->enc->program].udg2_len_rds2 = n;
|
|
||||||
} else {
|
|
||||||
memcpy(&(mod->enc->data[mod->enc->program].udg1_rds2), blocks, n * sizeof(uint16_t[4]));
|
|
||||||
mod->enc->data[mod->enc->program].udg1_len_rds2 = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lua_get_available_rds_streams(lua_State *localL) {
|
|
||||||
lua_pushinteger(localL, mod->num_streams);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lua_crc16(lua_State *localL) {
|
|
||||||
size_t len;
|
|
||||||
const char* data = luaL_checklstring(localL, 1, &len);
|
|
||||||
lua_pushinteger(localL, crc16_ccitt(data, len));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#define lua_registertotable(L,n,f) (lua_pushcfunction(L, (f)), lua_setfield(L, -2, (n)))
|
||||||
void init_lua(RDSModulator* rds_mod) {
|
void init_lua(RDSModulator* rds_mod) {
|
||||||
static int mutex_initialized = 0;
|
static int mutex_initialized = 0;
|
||||||
mod = rds_mod;
|
mod = rds_mod;
|
||||||
@@ -430,109 +25,131 @@ void init_lua(RDSModulator* rds_mod) {
|
|||||||
|
|
||||||
lua_pushstring(L, VERSION);
|
lua_pushstring(L, VERSION);
|
||||||
lua_setglobal(L, "core_version");
|
lua_setglobal(L, "core_version");
|
||||||
lua_pushinteger(L, PROGRAMS);
|
|
||||||
lua_setglobal(L, "max_programs");
|
lua_newtable(L);
|
||||||
lua_pushinteger(L, EONs);
|
lua_setglobal(L, "ext");
|
||||||
lua_setglobal(L, "eon_count");
|
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_setglobal(L, "on_inits");
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_setglobal(L, "on_starts");
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_setglobal(L, "on_states");
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_setglobal(L, "ticks");
|
||||||
|
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_registertotable(L, "get", lua_get_userdata);
|
||||||
|
lua_registertotable(L, "get_offset", lua_get_userdata_offset);
|
||||||
|
lua_registertotable(L, "set", lua_set_userdata);
|
||||||
|
lua_registertotable(L, "set_offset", lua_set_userdata_offset);
|
||||||
lua_pushinteger(L, LUA_USER_DATA);
|
lua_pushinteger(L, LUA_USER_DATA);
|
||||||
lua_setglobal(L, "user_data_len");
|
lua_setfield(L, -2, "len");
|
||||||
|
lua_setglobal(L, "userdata");
|
||||||
|
|
||||||
lua_register(L, "set_rds_program_defaults", lua_set_rds_program_defaults);
|
lua_newtable(L);
|
||||||
lua_register(L, "reset_rds", lua_reset_rds);
|
lua_registertotable(L, "crc16", lua_crc16);
|
||||||
lua_register(L, "force_save", lua_force_save);
|
lua_registertotable(L, "force_save", lua_force_save);
|
||||||
|
lua_registertotable(L, "reset_rds", lua_reset_rds);
|
||||||
|
lua_registertotable(L, "set_rds_program_defaults", lua_set_rds_program_defaults);
|
||||||
|
lua_pushinteger(L, PROGRAMS);
|
||||||
|
lua_setfield(L, -2, "max_programs");
|
||||||
|
lua_registertotable(L, "set_rds_program", lua_set_rds_program);
|
||||||
|
lua_registertotable(L, "get_rds_program", lua_get_rds_program);
|
||||||
|
lua_setglobal(L, "dp");
|
||||||
|
|
||||||
lua_register(L, "set_rds_pi", lua_set_rds_pi);
|
lua_newtable(L);
|
||||||
lua_register(L, "get_rds_pi", lua_get_rds_pi);
|
|
||||||
|
|
||||||
lua_register(L, "set_rds_pty", lua_set_rds_pty);
|
lua_newtable(L);
|
||||||
lua_register(L, "get_rds_pty", lua_get_rds_pty);
|
lua_setfield(L, -2, "ext");
|
||||||
|
|
||||||
lua_register(L, "set_rds_ecc", lua_set_rds_ecc);
|
lua_pushinteger(L, EONs);
|
||||||
lua_register(L, "get_rds_ecc", lua_get_rds_ecc);
|
lua_setfield(L, -2, "eon_count");
|
||||||
|
|
||||||
lua_register(L, "set_rds_slc_data", lua_set_rds_slc_data);
|
lua_registertotable(L, "set_pi", lua_set_rds_pi);
|
||||||
lua_register(L, "get_rds_slc_data", lua_get_rds_slc_data);
|
lua_registertotable(L, "get_pi", lua_get_rds_pi);
|
||||||
|
|
||||||
lua_register(L, "set_rds_ct", lua_set_rds_ct);
|
lua_registertotable(L, "set_pty", lua_set_rds_pty);
|
||||||
lua_register(L, "get_rds_ct", lua_get_rds_ct);
|
lua_registertotable(L, "get_pty", lua_get_rds_pty);
|
||||||
|
|
||||||
lua_register(L, "set_rds_dpty", lua_set_rds_dpty);
|
lua_registertotable(L, "set_ecc", lua_set_rds_ecc);
|
||||||
lua_register(L, "get_rds_dpty", lua_get_rds_dpty);
|
lua_registertotable(L, "get_ecc", lua_get_rds_ecc);
|
||||||
|
|
||||||
lua_register(L, "set_rds_tp", lua_set_rds_tp);
|
lua_registertotable(L, "set_slc_data", lua_set_rds_slc_data);
|
||||||
lua_register(L, "get_rds_tp", lua_get_rds_tp);
|
lua_registertotable(L, "get_slc_data", lua_get_rds_slc_data);
|
||||||
|
|
||||||
lua_register(L, "set_rds_ta", lua_set_rds_ta);
|
lua_registertotable(L, "set_ct", lua_set_rds_ct);
|
||||||
lua_register(L, "get_rds_ta", lua_get_rds_ta);
|
lua_registertotable(L, "get_ct", lua_get_rds_ct);
|
||||||
|
|
||||||
lua_register(L, "set_rds_rt1_enabled", lua_set_rds_rt1_enabled);
|
lua_registertotable(L, "set_dpty", lua_set_rds_dpty);
|
||||||
lua_register(L, "get_rds_rt1_enabled", lua_get_rds_rt1_enabled);
|
lua_registertotable(L, "get_dpty", lua_get_rds_dpty);
|
||||||
|
|
||||||
lua_register(L, "set_rds_rt2_enabled", lua_set_rds_rt2_enabled);
|
lua_registertotable(L, "set_tp", lua_set_rds_tp);
|
||||||
lua_register(L, "get_rds_rt2_enabled", lua_get_rds_rt2_enabled);
|
lua_registertotable(L, "get_tp", lua_get_rds_tp);
|
||||||
|
|
||||||
lua_register(L, "set_rds_ptyn_enabled", lua_set_rds_ptyn_enabled);
|
lua_registertotable(L, "set_ta", lua_set_rds_ta);
|
||||||
lua_register(L, "get_rds_ptyn_enabled", lua_get_rds_ptyn_enabled);
|
lua_registertotable(L, "get_ta", lua_get_rds_ta);
|
||||||
|
|
||||||
lua_register(L, "set_rds_rt_type", lua_set_rds_rt_type);
|
lua_registertotable(L, "set_rt1_enabled", lua_set_rds_rt1_enabled);
|
||||||
lua_register(L, "get_rds_rt_type", lua_get_rds_rt_type);
|
lua_registertotable(L, "get_rt1_enabled", lua_get_rds_rt1_enabled);
|
||||||
|
|
||||||
lua_register(L, "set_rds2_mode", lua_set_rds2_mode);
|
lua_registertotable(L, "set_rt2_enabled", lua_set_rds_rt2_enabled);
|
||||||
lua_register(L, "get_rds2_mode", lua_get_rds2_mode);
|
lua_registertotable(L, "get_rt2_enabled", lua_get_rds_rt2_enabled);
|
||||||
|
|
||||||
|
lua_registertotable(L, "set_ptyn_enabled", lua_set_rds_ptyn_enabled);
|
||||||
|
lua_registertotable(L, "get_ptyn_enabled", lua_get_rds_ptyn_enabled);
|
||||||
|
|
||||||
|
lua_registertotable(L, "set_rt_type", lua_set_rds_rt_type);
|
||||||
|
lua_registertotable(L, "get_rt_type", lua_get_rds_rt_type);
|
||||||
|
|
||||||
|
lua_registertotable(L, "set_rds2_mode", lua_set_rds2_mode);
|
||||||
|
lua_registertotable(L, "get_rds2_mode", lua_get_rds2_mode);
|
||||||
|
|
||||||
|
lua_registertotable(L, "set_link", lua_set_rds_link);
|
||||||
|
lua_registertotable(L, "get_link", lua_get_rds_link);
|
||||||
|
|
||||||
|
lua_registertotable(L, "set_rt_switching_period", lua_set_rds_rt_switching_period);
|
||||||
|
lua_registertotable(L, "get_rt_switching_period", lua_get_rds_rt_switching_period);
|
||||||
|
|
||||||
|
lua_registertotable(L, "set_rt_text_timeout", lua_set_rds_rt_text_timeout);
|
||||||
|
lua_registertotable(L, "get_rt_text_timeout", lua_get_rds_rt_text_timeout);
|
||||||
|
|
||||||
|
lua_registertotable(L, "set_ptyn", lua_set_rds_ptyn);
|
||||||
|
lua_registertotable(L, "set_ps", lua_set_rds_ps);
|
||||||
|
lua_registertotable(L, "set_tps", lua_set_rds_tps);
|
||||||
|
lua_registertotable(L, "set_rt1", lua_set_rds_rt1);
|
||||||
|
lua_registertotable(L, "set_rt2", lua_set_rds_rt2);
|
||||||
|
lua_registertotable(L, "set_default_rt", lua_set_rds_default_rt);
|
||||||
|
|
||||||
|
lua_registertotable(L, "set_lps", lua_set_rds_lps);
|
||||||
|
lua_registertotable(L, "get_lps", lua_get_rds_lps);
|
||||||
|
|
||||||
|
lua_registertotable(L, "set_grpseq", lua_set_rds_grp_sqc);
|
||||||
|
lua_registertotable(L, "get_grpseq", lua_get_rds_grp_sqc);
|
||||||
|
|
||||||
|
lua_registertotable(L, "set_grpseq2", lua_set_rds_grp_sqc_rds2);
|
||||||
|
lua_registertotable(L, "get_grpseq2", lua_get_rds_grp_sqc_rds2);
|
||||||
|
|
||||||
|
lua_registertotable(L, "put_custom_group", lua_put_rds_custom_group);
|
||||||
|
lua_registertotable(L, "put_rds2_custom_group", lua_put_rds2_custom_group);
|
||||||
|
|
||||||
|
lua_registertotable(L, "set_af", lua_set_rds_af_group0);
|
||||||
|
|
||||||
|
lua_registertotable(L, "set_eon", lua_set_rds_eon);
|
||||||
|
lua_registertotable(L, "get_eon", lua_get_rds_eon);
|
||||||
|
|
||||||
|
lua_registertotable(L, "set_udg", lua_set_rds_udg);
|
||||||
|
lua_registertotable(L, "set_udg2", lua_set_rds_udg2);
|
||||||
|
|
||||||
|
lua_setglobal(L, "rds");
|
||||||
|
|
||||||
lua_register(L, "set_rds_streams", lua_set_rds_streams);
|
lua_register(L, "set_rds_streams", lua_set_rds_streams);
|
||||||
lua_register(L, "get_rds_streams", lua_get_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, "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);
|
|
||||||
|
|
||||||
lua_register(L, "set_rds_grpseq2", lua_set_rds_grp_sqc_rds2);
|
|
||||||
lua_register(L, "get_rds_grpseq2", lua_get_rds_grp_sqc_rds2);
|
|
||||||
|
|
||||||
lua_register(L, "set_rds_link", lua_set_rds_link);
|
|
||||||
lua_register(L, "get_rds_link", lua_get_rds_link);
|
|
||||||
|
|
||||||
lua_register(L, "set_rds_program", lua_set_rds_program);
|
|
||||||
lua_register(L, "get_rds_program", lua_get_rds_program);
|
|
||||||
|
|
||||||
lua_register(L, "set_rds_rt_switching_period", lua_set_rds_rt_switching_period);
|
|
||||||
lua_register(L, "get_rds_rt_switching_period", lua_get_rds_rt_switching_period);
|
|
||||||
|
|
||||||
lua_register(L, "set_rds_rt_text_timeout", lua_set_rds_rt_text_timeout);
|
|
||||||
lua_register(L, "get_rds_rt_text_timeout", lua_get_rds_rt_text_timeout);
|
|
||||||
|
|
||||||
lua_register(L, "set_rds_level", lua_set_rds_level);
|
lua_register(L, "set_rds_level", lua_set_rds_level);
|
||||||
lua_register(L, "get_rds_level", lua_get_rds_level);
|
lua_register(L, "get_rds_level", lua_get_rds_level);
|
||||||
|
|
||||||
lua_register(L, "set_rds_ptyn", lua_set_rds_ptyn);
|
|
||||||
lua_register(L, "set_rds_ps", lua_set_rds_ps);
|
|
||||||
lua_register(L, "set_rds_tps", lua_set_rds_tps);
|
|
||||||
lua_register(L, "set_rds_rt1", lua_set_rds_rt1);
|
|
||||||
lua_register(L, "set_rds_rt2", lua_set_rds_rt2);
|
|
||||||
lua_register(L, "set_rds_default_rt", lua_set_rds_default_rt);
|
|
||||||
|
|
||||||
lua_register(L, "set_rds_lps", lua_set_rds_lps);
|
|
||||||
lua_register(L, "get_rds_lps", lua_get_rds_lps);
|
|
||||||
|
|
||||||
lua_register(L, "put_rds_custom_group", lua_put_rds_custom_group);
|
|
||||||
lua_register(L, "put_rds2_custom_group", lua_put_rds2_custom_group);
|
|
||||||
|
|
||||||
lua_register(L, "set_rds_af_group0", lua_set_rds_af_group0);
|
|
||||||
|
|
||||||
lua_register(L, "set_rds_eon", lua_set_rds_eon);
|
|
||||||
lua_register(L, "get_rds_eon", lua_get_rds_eon);
|
|
||||||
|
|
||||||
lua_register(L, "set_rds_udg", lua_set_rds_udg);
|
|
||||||
lua_register(L, "set_rds_udg2", lua_set_rds_udg2);
|
|
||||||
|
|
||||||
lua_register(L, "set_userdata", lua_set_userdata);
|
|
||||||
lua_register(L, "set_userdata_offset", lua_set_userdata_offset);
|
|
||||||
lua_register(L, "get_userdata", lua_get_userdata);
|
|
||||||
lua_register(L, "get_userdata_offset", lua_get_userdata_offset);
|
|
||||||
|
|
||||||
lua_register(L, "crc16", lua_crc16);
|
|
||||||
|
|
||||||
if (luaL_loadfile(L, "/etc/rds95.lua") != LUA_OK) {
|
if (luaL_loadfile(L, "/etc/rds95.lua") != LUA_OK) {
|
||||||
fprintf(stderr, "Lua error loading file: %s\n", lua_tostring(L, -1));
|
fprintf(stderr, "Lua error loading file: %s\n", lua_tostring(L, -1));
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
@@ -562,6 +179,7 @@ void run_lua(char *str, char *cmd_output, size_t* out_len) {
|
|||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
pthread_mutex_unlock(&lua_mutex);
|
pthread_mutex_unlock(&lua_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
int lua_group(RDSGroup* group, const char grp) {
|
int lua_group(RDSGroup* group, const char grp) {
|
||||||
pthread_mutex_lock(&lua_mutex);
|
pthread_mutex_lock(&lua_mutex);
|
||||||
lua_getglobal(L, "group");
|
lua_getglobal(L, "group");
|
||||||
@@ -703,7 +321,58 @@ void lua_call_function(const char* function) {
|
|||||||
pthread_mutex_unlock(&lua_mutex);
|
pthread_mutex_unlock(&lua_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy_lua(void) {
|
void lua_call_table_nolock(const char *table_name) {
|
||||||
|
lua_getglobal(L, table_name);
|
||||||
|
|
||||||
|
if (!lua_istable(L, -1)) {
|
||||||
|
lua_pop(L, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_Integer len = lua_rawlen(L, -1);
|
||||||
|
for (lua_Integer i = 1; i <= len; i++) {
|
||||||
|
lua_rawgeti(L, -1, i);
|
||||||
|
if (lua_isfunction(L, -1)) {
|
||||||
|
if (lua_pcall(L, 0, 0, 0) != LUA_OK) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Lua error: %s at '%s[%lld]'\n",
|
||||||
|
lua_tostring(L, -1),
|
||||||
|
table_name,
|
||||||
|
(long long)i);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
} else lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
lua_pop(L, 1); // pop table
|
||||||
|
}
|
||||||
|
void lua_call_table(const char* function) {
|
||||||
|
int need_lock = (pthread_mutex_trylock(&lua_mutex) == 0);
|
||||||
|
if (!need_lock) {
|
||||||
|
fprintf(stderr, "Warning: lua_mutex already locked when table calling %s\n", function);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lua_call_table_nolock(function);
|
||||||
|
pthread_mutex_unlock(&lua_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lua_call_tfunction_nolock(const char* name) {
|
||||||
|
char table_name[256];
|
||||||
|
lua_call_function_nolock(name);
|
||||||
|
snprintf(table_name, sizeof(table_name), "%ss", name);
|
||||||
|
lua_call_table_nolock(table_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lua_call_tfunction(const char* name) {
|
||||||
|
int need_lock = (pthread_mutex_trylock(&lua_mutex) == 0);
|
||||||
|
if (!need_lock) {
|
||||||
|
fprintf(stderr, "Warning: lua_mutex already locked when table tcalling %s\n", name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lua_call_tfunction_nolock(name);
|
||||||
|
pthread_mutex_unlock(&lua_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy_lua() {
|
||||||
if (L) {
|
if (L) {
|
||||||
for (int i = 1; i < *unload_refs; i++) luaL_unref(L, LUA_REGISTRYINDEX, unload_refs[i]);
|
for (int i = 1; i < *unload_refs; i++) luaL_unref(L, LUA_REGISTRYINDEX, unload_refs[i]);
|
||||||
*unload_refs = 1;
|
*unload_refs = 1;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "common.h"
|
||||||
|
#include "rds.h"
|
||||||
|
#include "modulator.h"
|
||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
#include <lualib.h>
|
#include <lualib.h>
|
||||||
#include <lauxlib.h>
|
#include <lauxlib.h>
|
||||||
#include "rds.h"
|
|
||||||
#include "fs.h"
|
|
||||||
#include "modulator.h"
|
|
||||||
|
|
||||||
void init_lua(RDSModulator* rds_mod);
|
void init_lua(RDSModulator* rds_mod);
|
||||||
void run_lua(char *str, char *cmd_output, size_t* out_len);
|
void run_lua(char *str, char *cmd_output, size_t* out_len);
|
||||||
@@ -12,5 +12,9 @@ int lua_group(RDSGroup* group, const char grp);
|
|||||||
int lua_rds2_group(RDSGroup* group, int stream);
|
int lua_rds2_group(RDSGroup* group, int stream);
|
||||||
void lua_call_function_nolock(const char* function);
|
void lua_call_function_nolock(const char* function);
|
||||||
void lua_call_function(const char* function);
|
void lua_call_function(const char* function);
|
||||||
|
void lua_call_table_nolock(const char *table_name);
|
||||||
|
void lua_call_table(const char* function);
|
||||||
|
void lua_call_tfunction_nolock(const char* name);
|
||||||
|
void lua_call_tfunction(const char* name);
|
||||||
void lua_group_ref(RDSGroup* group, int ref);
|
void lua_group_ref(RDSGroup* group, int ref);
|
||||||
void destroy_lua();
|
void destroy_lua();
|
||||||
@@ -155,7 +155,7 @@ void get_rds_group(RDSEncoder* enc, RDSGroup *group, uint8_t stream) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_call_function("tick");
|
lua_call_tfunction("tick");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (utc->tm_min != enc->state[enc->program].last_minute) {
|
if (utc->tm_min != enc->state[enc->program].last_minute) {
|
||||||
@@ -378,10 +378,10 @@ void init_rds_encoder(RDSEncoder* enc) {
|
|||||||
|
|
||||||
if (encoder_loadFromFile(enc)) {
|
if (encoder_loadFromFile(enc)) {
|
||||||
printf("Encoder file will be reinitialized.\n");
|
printf("Encoder file will be reinitialized.\n");
|
||||||
lua_call_function("on_init");
|
lua_call_tfunction("on_init");
|
||||||
}
|
}
|
||||||
for(int i = 0; i < PROGRAMS; i++) reset_rds_state(enc, i);
|
for(int i = 0; i < PROGRAMS; i++) reset_rds_state(enc, i);
|
||||||
lua_call_function("on_start");
|
lua_call_tfunction("on_start");
|
||||||
lua_call_function("on_state");
|
lua_call_tfunction("on_state");
|
||||||
encoder_saveToFile(enc);
|
encoder_saveToFile(enc);
|
||||||
}
|
}
|
||||||
23
src/rds95.c
23
src/rds95.c
@@ -101,12 +101,12 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
const char *short_opt = "c:ah";
|
const char *short_opt = "c:ah";
|
||||||
|
|
||||||
struct option long_opt[] =
|
struct option long_opt[] =
|
||||||
{
|
{
|
||||||
{"config", required_argument, NULL, 'c'},
|
{"config", required_argument, NULL, 'c'},
|
||||||
{"asciig", no_argument, NULL, 'a'},
|
{"asciig", no_argument, NULL, 'a'},
|
||||||
{"help", no_argument, NULL, 'h'},
|
{"help", no_argument, NULL, 'h'},
|
||||||
{ 0, 0, 0, 0 }
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
int opt;
|
int opt;
|
||||||
@@ -144,7 +144,6 @@ int main(int argc, char **argv) {
|
|||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
|
|
||||||
struct sigaction sa_stop;
|
struct sigaction sa_stop;
|
||||||
|
|
||||||
sa_stop.sa_handler = stop;
|
sa_stop.sa_handler = stop;
|
||||||
sigemptyset(&sa_stop.sa_mask);
|
sigemptyset(&sa_stop.sa_mask);
|
||||||
sa_stop.sa_flags = 0;
|
sa_stop.sa_flags = 0;
|
||||||
@@ -160,17 +159,7 @@ int main(int argc, char **argv) {
|
|||||||
buffer.tlength = buffer.maxlength = NUM_MPX_FRAMES * config.num_streams;
|
buffer.tlength = buffer.maxlength = NUM_MPX_FRAMES * config.num_streams;
|
||||||
|
|
||||||
if(config.asciig == 0) {
|
if(config.asciig == 0) {
|
||||||
rds_device = pa_simple_new(
|
rds_device = pa_simple_new(NULL, "rds95", PA_STREAM_PLAYBACK, config.rds_device_name, "RDS Generator", &format, NULL, &buffer, NULL);
|
||||||
NULL,
|
|
||||||
"rds95",
|
|
||||||
PA_STREAM_PLAYBACK,
|
|
||||||
config.rds_device_name,
|
|
||||||
"RDS Generator",
|
|
||||||
&format,
|
|
||||||
NULL,
|
|
||||||
&buffer,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
if (rds_device == NULL) {
|
if (rds_device == NULL) {
|
||||||
fprintf(stderr, "Error: cannot open sound device.\n");
|
fprintf(stderr, "Error: cannot open sound device.\n");
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|||||||
Reference in New Issue
Block a user