View difference between Paste ID: YcztrG9t and vsPsLci1
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