initialize

This commit is contained in:
Andrew-71 2024-03-10 23:45:44 +03:00
commit 5b23ea99fd
43 changed files with 2336 additions and 0 deletions

View file

@ -0,0 +1,98 @@
--[[
Class to manage ComputerCraft (CC) audio tracks on different disks
Written by Andrew_7_1
]]
local audio_manager = {}
audio_manager.init = function (dirs_file)
local self = {}
-- Load audio directories from file where directories are seperated by newlines"
local function load_audio_dirs(file_location)
local audio_dirs = {}
local file = io.open(file_location, 'r')
if file then
for line in file:lines() do
table.insert(audio_dirs, line)
end
file:close()
end
return audio_dirs
end
local audio_dirs = load_audio_dirs(dirs_file or 'audio_dirs.txt')
--[[
Iterate over all audio directories and load all audio files into a catalogue.
Audio files have extensions of .dfpwm and rarely .wav
Save them to a table of tables like this:
{
["filepath"] = absolute file path
["length"] = file size / 6000
["title"] = file name without extension and path, e.g. "title.dfpwm" -> "title"
["extension"] = file extension, e.g. "dfpwm"
}
]]
local function load_audio_catalogue()
local audio_catalogue = {}
for _, dir in pairs(audio_dirs) do
for _, file in pairs(fs.list(dir)) do
if file:find('.dfpwm') or file:find('.wav') then
local file_path = dir .. '/' .. file
local file_size = fs.getSize(file_path)
local file_title = file:sub(1, #file - #file:match('.*%.(.*)$'))
local file_extension = file:match('.*%.(.*)$')
table.insert(audio_catalogue, {
["filepath"] = file_path,
["length"] = file_size / 6000,
["title"] = file_title,
["extension"] = file_extension
})
end
end
end
return audio_catalogue
end
self.audio_catalogue = load_audio_catalogue()
-- Update audio catalogue
function self.update_catalogue()
self.audio_catalogue = load_audio_catalogue()
end
function self.get_catalogue()
return self.audio_catalogue
end
-- Get part of an audio file in the catalogue
function self.get_track_chunk(index, starting_second, length)
if index > #self.audio_catalogue then
return false
end
local track = self.audio_catalogue[index]
local file = io.open(track.filepath, 'rb')
if not file then
return false
end
file:seek('set', starting_second * 6000)
local chunk = file:read(length * 6000)
file:close()
return chunk
end
-- More convenient way to get track info than using entire catalogue
function self.get_track_details(index)
if index > #self.audio_catalogue then
return false
end
return self.audio_catalogue[index]
end
return self
end
return audio_manager

View file

@ -0,0 +1,60 @@
local logger = {}
logger.init = function(monitor_wrap, scale)
local self = {}
local monitor = monitor_wrap or peripheral.find("monitor")
if not monitor then
monitor = term
else monitor.setTextScale(scale or 0.5)
end
local log_colours = {
['log'] = colours.white,
['info'] = colours.lightBlue,
['warn'] = colours.yellow,
['err'] = colours.red,
['success'] = colours.lime
}
local function move_line()
monitor.setCursorPos(1, select(2, monitor.getCursorPos()) + 1)
if select(2, monitor.getCursorPos()) >= select(2, monitor.getSize()) then
monitor.scroll(1)
monitor.setCursorPos(1, select(2, monitor.getCursorPos()) - 1)
end
end
local function write_msg(message, msg_colour)
local time_str = os.date('%Y-%b-%d %H:%M:%S')
local msg_formatted = "[" .. time_str .. "] " .. message
monitor.setTextColour(msg_colour)
monitor.write(msg_formatted)
move_line()
end
function self.log(msg)
write_msg(msg, log_colours['log'])
end
function self.info(msg)
write_msg('INFO: ' .. msg, log_colours['info'])
end
function self.warning(msg)
write_msg('WARNING: ' .. msg, log_colours['warn'])
end
function self.error(msg)
write_msg('ERROR: ' .. msg, log_colours['err'])
end
function self.success(msg)
write_msg('SUCCESS: ' .. msg, log_colours['success'])
end
return self
end
return logger

View file

@ -0,0 +1,60 @@
--[[
Audio server for ComputerCraft (CC)
Written by Andrew_7_1
]]
local server = {}
server.init = function (port, audio_dir)
local self = {}
local logger = require('logger').init()
local audio_manager = require('audio_manager').init(audio_dir or 'audio_dirs.txt')
local port = port or 7101
local modem = peripheral.find('modem')
if not modem then error('No modem found') end
modem.open(port)
logger.info('Audio server started on port ' .. port .. ' with audio directories from ' .. audio_dir)
local message_types = {
query = function (replyChannel, msg)
modem.transmit(replyChannel, port, {code = 200, audio_catalogue = audio_manager.get_catalogue()})
logger.success('Query sent')
end,
refresh = function (replyChannel, msg)
audio_manager.update_catalogue()
modem.transmit(replyChannel, port, {code = 200})
logger.success('Catalogue updated')
end,
track_info = function (replyChannel, msg)
local track = audio_manager.get_track_details(msg.index)
if not track then
modem.transmit(replyChannel, port, {code = 404})
logger.error('Track not found (id: ' .. msg.index .. ')')
else
modem.transmit(replyChannel, port, {code = 200, track = track})
logger.success('Track details sent (id: ' .. msg.index .. ')')
end
end,
track_chunk = function (replyChannel, msg)
local track = audio_manager.get_track_chunk(msg.index, msg.starting_second, msg.length)
if not track then
modem.transmit(replyChannel, port, {code = 404})
logger.error('Track not found (id: ' .. msg.index .. ')')
else
modem.transmit(replyChannel, port, {code = 200, track = track})
logger.success('Part of a track sent (id: ' .. msg.index .. ', part:' .. msg.starting_second .. '-' .. msg.starting_second + msg.length .. ')')
end
end
}
function self.process_transmission(event, side, channel, replyChannel, message, distance)
message_types[message.type](replyChannel, message)
end
return self
end
return server

View file

@ -0,0 +1,14 @@
local config = {
port = 7101,
audio_dir = 'audio_dirs.txt'
}
local server = require("server").init(config.port, config.audio_dir)
local modem = peripheral.find("modem")
if not modem then error("No modem found") end
modem.open(config.port)
while true do
local event, side, channel, replyChannel, message, distance = os.pullEvent("modem_message")
server.process_transmission(event, side, channel, replyChannel, message, distance)
end