Skip to content

Commit

Permalink
hooooo, boy, many changes:
Browse files Browse the repository at this point in the history
.buildconfig: bump kernel version
base/hooks: add logging when hooks get called
stdlib/package: add /usr/lib to the package path
base/thread: don't give userspace wrapped coroutines
base/tty: i have no idea
base/util: messed with pipes a bit
extra/sound: am currently rewriting it to be Better:tm:
extra/sound/*: see above
extra/sound_old*: old sound api
  • Loading branch information
Ocawesome101 committed Aug 19, 2021
1 parent 1be07ad commit 726a19b
Show file tree
Hide file tree
Showing 15 changed files with 232 additions and 139 deletions.
2 changes: 1 addition & 1 deletion .buildconfig
@@ -1,3 +1,3 @@
KMODS=extra/net/base,extra/getgpu,extra/sound
KRELEASE=1.30
KRELEASE=1.41
KCUSTOMNAME=default
4 changes: 2 additions & 2 deletions base/hooks.lua
Expand Up @@ -9,15 +9,15 @@ do
function k.hooks.add(name, func)
checkArg(1, name, "string")
checkArg(2, func, "function")

hooks[name] = hooks[name] or {}
table.insert(hooks[name], func)
end

function k.hooks.call(name, ...)
checkArg(1, name, "string")

k.log(k.loglevels.debug, "calling hook ", name)
k.logio:write(":: calling hook " .. name .. "\n")
if hooks[name] then
for k, v in ipairs(hooks[name]) do
v(...)
Expand Down
9 changes: 7 additions & 2 deletions base/load.lua
Expand Up @@ -94,6 +94,8 @@ if (not k.cmdline.no_force_yields) then
if not ok then
return nil, err
end

local ysq = {}
return function(...)
local last_yield = computer.uptime()
local old_iyield = env.__internal_yield
Expand All @@ -102,13 +104,16 @@ if (not k.cmdline.no_force_yields) then
env.__internal_yield = function()
if computer.uptime() - last_yield >= max_time then
last_yield = computer.uptime()
coroutine.yield(0.05)
local msg = table.pack(old_cyield(0.05))
if msg.n > 0 then ysq[#ysq+1] = msg end
end
end

env.coroutine.yield = function(...)
last_yield = computer.uptime()
coroutine.yield(...)
local msg = table.pack(old_cyield(...))
ysq[#ysq+1] = msg
return table.unpack(table.remove(ysq, 1))
end

local result = table.pack(ok(...))
Expand Down
2 changes: 1 addition & 1 deletion base/stdlib/package.lua
Expand Up @@ -17,7 +17,7 @@ do
}

package.loaded = loaded
package.path = "/lib/?.lua;/lib/lib?.lua;/lib/?/init.lua"
package.path = "/lib/?.lua;/lib/lib?.lua;/lib/?/init.lua;/usr/lib/?.lua;/usr/lib/lib?.lua;/usr/lib/?/init.lua"

local fs = k.fs.api

Expand Down
5 changes: 5 additions & 0 deletions base/thread.lua
Expand Up @@ -10,6 +10,11 @@ do
local old_coroutine = coroutine
local _coroutine = {}
_G.coroutine = _coroutine
-- [[
k.hooks.add("sandbox", function()
k.userspace.coroutine = old_coroutine
end)
--]]

function _coroutine.create(func)
checkArg(1, func, "function")
Expand Down
2 changes: 2 additions & 0 deletions base/tty.lua
Expand Up @@ -170,6 +170,8 @@ do
if n == 0 then
self.fg = colors[8]
self.bg = colors[1]
self.gpu.setForeground(self.fg)
self.gpu.setBackground(self.bg)
self.attributes.echo = true
elseif n == 8 then
self.attributes.echo = false
Expand Down
14 changes: 9 additions & 5 deletions base/util.lua
Expand Up @@ -134,11 +134,13 @@ do
if self.closed and #self.rb == 0 then
return nil
end
while #self.rb < n and not self.closed do
if self.from ~= 0 then
k.scheduler.info().data.self.resume_next = self.from
if not self.closed then
while #self.rb < n do
if self.from ~= 0 then
k.scheduler.info().data.self.resume_next = self.from
end
coroutine.yield()
end
coroutine.yield()
end
local data = self.rb:sub(1, n)
self.rb = self.rb:sub(n + 1)
Expand All @@ -163,11 +165,13 @@ do
end

function util.make_pipe()
return k.create_fstream(setmetatable({
local new = k.create_fstream(setmetatable({
from = 0, -- the process providing output
to = 0, -- the process reading input
rb = "",
}, {__index = _pipe}), "rw")
new.buffer_mode = "none"
return new
end

k.hooks.add("sandbox", function()
Expand Down
131 changes: 60 additions & 71 deletions extra/sound.lua
@@ -1,88 +1,77 @@
-- sound subsystem for Cynosure --
-- sound api v2: emulate the sound card for everything --

k.log(k.loglevels.info, "extra/sound")

do
k.log(k.loglevels.debug, "registering sound-related component detection")
local api = {}
local tiers = {
internal = 0,
beep = 1,
noise = 2,
sound = 3,
[0] = "internal",
"beep",
"noise",
"sound"
}

local api = {
MAX_CHANNELS = 1,
CARD_TYPE = "computer.beep", -- also beep, noise, sound
voice = {
SQUARE = "square",
SINE = "sine",
TRIANGLE = "triangle",
SAWTOOTH = "sawtooth",
NOISE = "noise",
}
local available = {
internal = 1,
beep = 0,
noise = 0,
sound = 0,
}

local component_cache = {}

-- all handlers must contain:
-- a table of supported voices
-- the maximum number of channels
-- a play(tab) function to play simultaneous notes
-- through { frequency, ms[, volume][, voice] } pairs contained in
-- `tab`
-- a mode(chan, voice) function to set the voice
-- for each channel
local card_handlers = {
["computer.beep"] = {
voices = { [api.voice.SINE] = true },
channels = 1,
play = function(tab)
local freq, dur = table.unpack(select(2, next(tab)))
dur = dur / 1000 -- ms -> s
computer.beep(freq, dur)
end
local proxies = {
internal = {
[computer.address()] = {
beep = function(tab)
return computer.beep(tab[1][1], tab[1][2])
end
}
},
--#include "extra/sound/beep.lua"
--#include "extra/sound/noise.lua"
--#include "extra/sound/sound.lua"
beep = {},
noise = {},
sound = {}
}

local current = "internal"
local caddr = computer.address()

function api.play(notes)
checkArg(1, notes, "table")
return card_handlers[api.CARD_TYPE].play(notes)
end

local chandler = function(s, add, typ)
s = s == "component_added"
if s then
if typ == "beep" or typ == "noise" or typ == "sound" then
local card = component_cache[typ] or add
if type(card) == "string" then
component_cache[typ] = component.proxy(card)
end
end
elseif component_cache[typ] and component_cache[typ].address == add then
component_cache[typ] = component.list(typ, true)()
if component_cache[typ] then
component_cache[typ] = component.proxy(component_cache[typ])
local function component_changed(sig, addr, ctype)
if sig == "component_added" then
if tiers[ctype] and tiers[ctype] > tiers[current] then
current = ctype
available[ctype] = math.max(1, available[ctype] + 1)
proxies[ctype][addr] = component.proxy(addr)
end
end
if component_cache.sound or component_cache.noise or
component_cache.beep then
api.MAX_CHANNELS = 8
else
api.MAX_CHANNELS = 1
end
if component_cache.sound then
api.CARD_TYPE = "sound"
elseif component_cache.noise then
api.CARD_TYPE = "noise"
elseif component_cache.beep then
api.CARD_TYPE = "beep"
else
api.CARD_TYPE = "computer.beep"
if tiers[ctype] then
available[ctype] = math.min(0, available[ctype] - 1)
proxies[ctype][addr] = nil
if caddr == addr then
for i=#tiers, 0, -1 do
if available[tiers[i]] > 0 then
current = tiers[i]
caddr = next(proxies[current])
end
end
end
end
end
end

local id = k.event.register("component_added", chandler)
k.event.register("component_removed", chandler)
k.event.register("component_added", component_changed)
k.event.register("component_removed", component_changed)

local handlers = {
internal = {play = select(2, next(proxies.internal)).beep},
--#include "extra/sound/beep.lua"
--#include "extra/sound/noise.lua"
--#include "extra/sound/sound.lua"
}

k.hooks.add("sandbox", function()
k.userspace.package.loaded.sound = package.protect(api)
end)
function api.play(notes)
return handlers[current].play(notes)
end
end
18 changes: 0 additions & 18 deletions extra/sound/beep.lua
@@ -1,18 +0,0 @@
beep = {
voices = { [api.voice.SINE] = true },
channels = 8,
play = function(tab)
local bcard = component_cache.beep
if bcard then
local o = tab
tab = {}
for i=1, #o, 1 do
tab[o[i][1]] = o[i][2] / 1000
end
bcard.play(tab)
else
return nil, "no beep card installed"
end
end,
mode = function() end
},
15 changes: 0 additions & 15 deletions extra/sound/noise.lua
@@ -1,15 +0,0 @@
noise = {
voices = { [api.voice.SQUARE] = true, [api.voice.SINE] = true,
[api.voice.TRIANGLE] = true, [api.voice.SAWTOOTH] = true },
channels = 8,
play = function(tab)
local card = component_cache.noise
if card then
for i=1, #tab, 1 do
if tab[i][4] then card.setMode(i, card.modes[tab[i][4]]) end
tab[i] = { tab[i][1], tab[i][2] / 100}
end
card.play(tab)
end
end,
},
24 changes: 0 additions & 24 deletions extra/sound/sound.lua
@@ -1,24 +0,0 @@
sound = {
voices = { [api.voice.SQUARE] = true, [api.voice.SINE] = true,
[api.voice.TRIANGLE] = true, [api.voice.SAWTOOTH] = true,
[api.voice.NOISE] = true },
channels = 8,
play = function(tab)
local card = component_cache.sound
if card then
local dur = 0
for i in pairs(tab) do
local freq, _dur, vol, voi = table.unpack(tab[i])
dur = math.max(dur, _dur)
card.open(i)
card.setFrequency(i, freq)
card.setADSR(i, 0, _dur, 0.25, _dur // 2)
if vol then card.setVolume(i, vol / 100) end
if voi then card.setWave(i, card.modes[voi]) end
end
card.delay(dur or 0)
for i=1, 10, 1 do card.process() end
for i=1, #tab, 1 do card.close(i) end
end
end,
},

0 comments on commit 726a19b

Please sign in to comment.