robathome

MC_jukebox - Speaker node

Oct 27th, 2025
335
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.49 KB | None | 0 0
  1. -- speaker_node.lua
  2. local MODE = "ui-mirror-v1"
  3.  
  4. -- open rednet
  5. local side=nil; for _,s in ipairs(rs.getSides()) do if peripheral.getType(s)=="modem" then side=s break end end
  6. assert(side, "wireless modem required"); if not rednet.isOpen(side) then rednet.open(side) end
  7.  
  8. -- find speakers
  9. local speakers = { peripheral.find("speaker") }
  10. assert(#speakers>0, "attach a speaker to this node")
  11.  
  12. -- hello as a speaker client
  13. rednet.broadcast({ op="HELLO", role="speaker" }, MODE)
  14.  
  15. local make_decoder = require("cc.audio.dfpwm").make_decoder
  16. local decoder = make_decoder()
  17. local volume = 1.0
  18.  
  19. local function playAll(pcm)
  20. local tasks={}
  21. for i,sp in ipairs(speakers) do
  22. tasks[i]=function()
  23. local name = peripheral.getName(sp)
  24. while not sp.playAudio(pcm, volume) do
  25. repeat until select(2, os.pullEvent("speaker_audio_empty")) == name
  26. end
  27. end
  28. end
  29. pcall(parallel.waitForAll, table.unpack(tasks))
  30. end
  31.  
  32. while true do
  33. local id,msg,proto = rednet.receive(MODE)
  34. if proto==MODE and type(msg)=="table" then
  35. if msg.op=="HELLO_ACK_SPK" then
  36. -- optional: print("linked to server "..id)
  37. elseif msg.op=="AUDIO_BEGIN" then
  38. decoder = make_decoder() -- reset stream state
  39. volume = tonumber(msg.vol) or volume
  40. elseif msg.op=="AUDIO_PART" and type(msg.data)=="string" then
  41. local pcm = decoder(msg.data) -- incremental decode
  42. playAll(pcm)
  43. elseif msg.op=="AUDIO_END" then
  44. -- no-op
  45. end
  46. end
  47. end
  48.  
Advertisement
Add Comment
Please, Sign In to add comment