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 |