2022-12-04 18:59:10 +00:00
|
|
|
--
|
|
|
|
-- Alarm Sounder
|
|
|
|
--
|
|
|
|
|
2023-07-27 00:48:11 +00:00
|
|
|
local audio = require("scada-common.audio")
|
2023-02-03 04:07:09 +00:00
|
|
|
local log = require("scada-common.log")
|
2022-12-04 18:59:10 +00:00
|
|
|
|
|
|
|
---@class sounder
|
|
|
|
local sounder = {}
|
|
|
|
|
|
|
|
local alarm_ctl = {
|
|
|
|
speaker = nil,
|
|
|
|
volume = 0.5,
|
2023-07-27 00:48:11 +00:00
|
|
|
stream = audio.new_stream()
|
2022-12-04 18:59:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
-- start audio or continue audio on buffer empty
|
|
|
|
---@return boolean success successfully added buffer to audio output
|
|
|
|
local function play()
|
|
|
|
if not alarm_ctl.playing then
|
|
|
|
alarm_ctl.playing = true
|
|
|
|
return sounder.continue()
|
2023-07-27 00:48:11 +00:00
|
|
|
else return true end
|
2022-12-04 18:59:10 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
-- initialize the annunciator alarm system
|
|
|
|
---@param speaker table speaker peripheral
|
2022-12-04 19:29:39 +00:00
|
|
|
---@param volume number speaker volume
|
|
|
|
function sounder.init(speaker, volume)
|
2022-12-04 18:59:10 +00:00
|
|
|
alarm_ctl.speaker = speaker
|
|
|
|
alarm_ctl.speaker.stop()
|
2022-12-04 19:29:39 +00:00
|
|
|
alarm_ctl.volume = volume
|
2023-07-27 00:48:11 +00:00
|
|
|
alarm_ctl.stream.stop()
|
2022-12-04 18:59:10 +00:00
|
|
|
|
2023-07-27 00:48:11 +00:00
|
|
|
audio.generate_tones()
|
2022-12-04 18:59:10 +00:00
|
|
|
end
|
|
|
|
|
2022-12-04 19:36:29 +00:00
|
|
|
-- reconnect the speaker peripheral
|
|
|
|
---@param speaker table speaker peripheral
|
|
|
|
function sounder.reconnect(speaker)
|
|
|
|
alarm_ctl.speaker = speaker
|
|
|
|
alarm_ctl.playing = false
|
2023-07-27 00:48:11 +00:00
|
|
|
alarm_ctl.stream.stop()
|
2022-12-04 19:36:29 +00:00
|
|
|
end
|
|
|
|
|
2023-07-27 00:48:11 +00:00
|
|
|
-- set alarm tones
|
|
|
|
---@param states table alarm tone commands from supervisor
|
|
|
|
function sounder.set(states)
|
|
|
|
-- set tone states
|
|
|
|
for id = 1, #states do alarm_ctl.stream.set_active(id, states[id]) end
|
2022-12-04 18:59:10 +00:00
|
|
|
|
2023-07-27 00:48:11 +00:00
|
|
|
-- re-compute output if needed, then play audio if available
|
|
|
|
if alarm_ctl.stream.is_recompute_needed() then alarm_ctl.stream.compute_buffer() end
|
2023-08-26 23:01:22 +00:00
|
|
|
if alarm_ctl.stream.any_active() then play() else sounder.stop() end
|
2022-12-04 18:59:10 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
-- stop all audio and clear output buffer
|
|
|
|
function sounder.stop()
|
|
|
|
alarm_ctl.playing = false
|
|
|
|
alarm_ctl.speaker.stop()
|
2023-07-27 00:48:11 +00:00
|
|
|
alarm_ctl.stream.stop()
|
2022-12-04 18:59:10 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
-- continue audio on buffer empty
|
|
|
|
---@return boolean success successfully added buffer to audio output
|
|
|
|
function sounder.continue()
|
2023-07-27 00:48:11 +00:00
|
|
|
local success = false
|
2022-12-04 18:59:10 +00:00
|
|
|
|
2023-07-27 00:48:11 +00:00
|
|
|
if alarm_ctl.playing then
|
|
|
|
if alarm_ctl.speaker ~= nil and alarm_ctl.stream.has_next_block() then
|
|
|
|
success = alarm_ctl.speaker.playAudio(alarm_ctl.stream.get_next_block(), alarm_ctl.volume)
|
|
|
|
if not success then log.error("SOUNDER: error playing audio") end
|
2022-12-04 18:59:10 +00:00
|
|
|
end
|
|
|
|
end
|
2023-07-27 00:48:11 +00:00
|
|
|
|
|
|
|
return success
|
2022-12-04 18:59:10 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
return sounder
|