Advertisement
TechManDylan

speaker.lua

Feb 24th, 2023
662
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. local aukit = require("aukit")
  2. local speaker = peripheral.find("speaker")
  3.  
  4. local file = fs.open("robots.wav", "rb")
  5. local data = file.readAll()
  6. file.close()
  7.  
  8. -- Create the filters
  9. local function makeBiquad(a0, a1, a2, b0, b1, b2)
  10.     local x1, x2, y1, y2 = 0, 0, 0, 0
  11.     return function(x0)
  12.         local y0 = (b0 / a0) * x0 + (b1 / a0) * x1 + (b2 / a0) * x2 - (a1 / a0) * y1 - (a2 / a0) * y2
  13.         x2, x1 = x1, x0
  14.         y2, y1 = y1, y0
  15.         return y0
  16.     end
  17. end
  18. local function make10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, b0, b1, b2, b3, b4 ,b5 ,b6, b7, b8, b9, b10)
  19.     local x1, x2, x3, x4, x5, x6, x7, x8, x9, x10 = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  20.     local y1, y2, y3, y4, y5, y6, y7, y8, y9, y10 = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  21.     return function (x0)
  22.         local y0 = (b0 / a0) * x0 + (b1 / a0) * x1 + (b2 / a0) * x2 + (b3 / a0) * x3 + (b4 / a0) * x4 + (b5 / a0) * x5 + (b6 / a0) * x6 + (b7 / a0) * x7 + (b8 / a0) * x8 + (b9 / a0) * x9 + (b10 / a0) * x10 - (a1 / a0) * y1 - (a2 / a0) * y2 - (a3 / a0) * y3 - (a4 / a0) * y4 - (a5 / a0) * y5 - (a6 / a0) * y6 - (a7 / a0) * y7 - (a8 / a0) * y8 - (a9 / a0) * y9 - (a10 / a0) * y10
  23.         x10, x9, x8, x7, x6, x5, x4, x3, x2, x1 = x9, x8, x7, x6, x5, x4, x3, x2, x1, x0
  24.         y10, y9, y8, y7, y6, y5, y4, y3, y2, y1 = y9, y8, y7, y6, y5, y4, y3, y2, y1, y0
  25.         return y0
  26.     end
  27. end
  28.  
  29. -- Parameters; highpass is a 2nd-order butterworth filter, yule is a yulewalk-designed filter based on the equal loudness contours by Robinson and Dadson
  30. local highpass = makeBiquad(
  31.     1,
  32.     -1.9722334,
  33.     0.9726137,
  34.     0.9862118,
  35.     -1.9724236,
  36.     0.9862118
  37. )
  38. local yule = make10(
  39.     1,
  40.     -3.846646,
  41.     7.8150167,
  42.     -11.341703,
  43.     13.055042,
  44.     -12.287599,
  45.     9.482938,
  46.     -5.8725786,
  47.     2.7546587,
  48.     -0.8698438,
  49.     0.13919315,
  50.     0.038575996,
  51.     -0.021603672,
  52.     -0.0012339532,
  53.     -9.291678E-5,
  54.     -0.016552603,
  55.     0.021615269,
  56.     -0.020740451,
  57.     0.0059429808,
  58.     0.0030642801,
  59.     1.2025322E-4,
  60.     0.0028846369
  61. )
  62.  
  63. -- whether to apply the effect or not
  64. local biquadEnabled = false
  65. for buffer, time in aukit.stream.wav(data, true) do
  66.     local mono = buffer[1]
  67.  
  68.     if biquadEnabled then
  69.         -- on each sample:
  70.         -- preAmp by approx 10db
  71.         -- apply yule
  72.         -- apply highpass
  73.         -- clamp to [-128, 127]
  74.         for i = 1, #buffer[1] do
  75.             mono[i] = math.max(math.min(127, highpass(yule(mono[i] * 3))), -128)
  76.         end
  77.     end
  78.  
  79.     -- play the modified buffer
  80.     while not speaker.playAudio(mono) do
  81.         os.pullEvent("speaker_audio_empty")
  82.     end
  83.  
  84.     -- process inputs if needed
  85.     local event = { os.pullEvent() }
  86.     if event[1] == "key" then
  87.         biquadEnabled = not biquadEnabled
  88.         print("Equal loudness effect enabled: " .. tostring(biquadEnabled))
  89.     end
  90. end
  91.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement