SHOW:
|
|
- or go back to the newest paste.
| 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 |