-- speaker_node.lua local MODE = "ui-mirror-v1" -- open rednet local side=nil; for _,s in ipairs(rs.getSides()) do if peripheral.getType(s)=="modem" then side=s break end end assert(side, "wireless modem required"); if not rednet.isOpen(side) then rednet.open(side) end -- find speakers local speakers = { peripheral.find("speaker") } assert(#speakers>0, "attach a speaker to this node") -- hello as a speaker client rednet.broadcast({ op="HELLO", role="speaker" }, MODE) local make_decoder = require("cc.audio.dfpwm").make_decoder local decoder = make_decoder() local volume = 1.0 local function playAll(pcm) local tasks={} for i,sp in ipairs(speakers) do tasks[i]=function() local name = peripheral.getName(sp) while not sp.playAudio(pcm, volume) do repeat until select(2, os.pullEvent("speaker_audio_empty")) == name end end end pcall(parallel.waitForAll, table.unpack(tasks)) end while true do local id,msg,proto = rednet.receive(MODE) if proto==MODE and type(msg)=="table" then if msg.op=="HELLO_ACK_SPK" then -- optional: print("linked to server "..id) elseif msg.op=="AUDIO_BEGIN" then decoder = make_decoder() -- reset stream state volume = tonumber(msg.vol) or volume elseif msg.op=="AUDIO_PART" and type(msg.data)=="string" then local pcm = decoder(msg.data) -- incremental decode playAll(pcm) elseif msg.op=="AUDIO_END" then -- no-op end end end