cc-libs/packages/trapos-music/tests/libaudio.lua
2026-06-20 14:15:54 +02:00

94 lines
3.0 KiB
Lua

local createLibTest = require('/apis/libtest');
local createAudio = require('/apis/libaudio');
local testlib = createLibTest({ ... });
local function constant(value, n)
local buf = {};
for i = 1, n do buf[i] = value; end
return buf;
end
local function impulse(value, n)
local buf = constant(0, n);
buf[1] = value;
return buf;
end
local function allInRange(buf)
for i = 1, #buf do
if buf[i] < -128 or buf[i] > 127 or buf[i] ~= math.floor(buf[i]) then
return false;
end
end
return true;
end
testlib.test('low-pass passes DC and stays in range, rising toward the input', function()
local audio = createAudio();
local lp = audio.lowPass();
local out = lp.process(constant(127, 2000));
testlib.assertTrue(allInRange(out), 'samples must be valid 8-bit integers');
testlib.assertTrue(out[#out] > out[1], 'output should rise toward the DC level');
testlib.assertTrue(out[#out] <= 127, 'output must not exceed the DC level');
end);
testlib.test('high-pass blocks DC: a constant decays toward zero', function()
local audio = createAudio();
local hp = audio.highPass();
local out = hp.process(constant(100, 200));
testlib.assertTrue(allInRange(out), 'samples must be valid 8-bit integers');
testlib.assertTrue(math.abs(out[#out]) < math.abs(out[1]), 'DC component should decay');
testlib.assertTrue(math.abs(out[#out]) <= 1, 'DC should fall close to zero');
end);
testlib.test('set changes the response and reset clears state', function()
local audio = createAudio();
local lp = audio.lowPass();
lp.set(200);
local low = lp.process(constant(127, 1))[1];
lp.reset();
lp.set(5000);
local high = lp.process(constant(127, 1))[1];
testlib.assertTrue(low ~= high, 'different cutoffs should give a different first sample');
-- reset must make a repeated run identical
lp.reset();
local a = lp.process(constant(50, 16));
lp.reset();
local b = lp.process(constant(50, 16));
testlib.assertEquals(a[#a], b[#b]);
end);
testlib.test('set clamps the param to the spec range', function()
local audio = createAudio();
local rv = audio.reverb();
rv.set(10);
testlib.assertEquals(rv.get(), 0.9);
rv.set(-5);
testlib.assertEquals(rv.get(), 0);
end);
testlib.test('delay re-emits the dry signal after the ring length', function()
local audio = createAudio({ sampleRate = 8 });
local d = audio.delay(1000); -- 1000ms * 8/s = 8-sample ring
local out = d.process(impulse(100, 10));
testlib.assertTrue(allInRange(out), 'samples must be valid 8-bit integers');
testlib.assertEquals(out[1], 60); -- 100 * 0.6 dry
testlib.assertEquals(out[9], 40); -- 100 * 0.4 delayed by 8 samples
testlib.assertEquals(out[5], 0); -- nothing in between
end);
testlib.test('reverb stays bounded for a loud impulse', function()
local audio = createAudio();
local rv = audio.reverb(0.8);
local buf = constant(0, 4000);
for i = 1, 200 do buf[i] = 127; end
local out = rv.process(buf);
testlib.assertTrue(allInRange(out), 'reverb output must never clip past 8-bit range');
end);
testlib.run();