mirror of
https://github.com/grumpycoders/pcsx-redux.git
synced 2025-04-02 10:41:54 -04:00
149 lines
4.7 KiB
Lua
149 lines
4.7 KiB
Lua
-- Copyright (C) 2024 PCSX-Redux authors
|
|
--
|
|
-- This program is free software; you can redistribute it and/or modify
|
|
-- it under the terms of the GNU General Public License as published by
|
|
-- the Free Software Foundation; either version 2 of the License, or
|
|
-- (at your option) any later version.
|
|
--
|
|
-- This program is distributed in the hope that it will be useful,
|
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
-- GNU General Public License for more details.
|
|
--
|
|
-- You should have received a copy of the GNU General Public License
|
|
-- along with this program; if not, write to the
|
|
-- Free Software Foundation, Inc.,
|
|
-- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
local lu = require 'luaunit'
|
|
local ffi = require 'ffi'
|
|
|
|
TestAdpcm = {}
|
|
|
|
local function swapEndian32(x)
|
|
return bit.bor(
|
|
bit.lshift(bit.band(x, 0x000000FF), 24),
|
|
bit.lshift(bit.band(x, 0x0000FF00), 8),
|
|
bit.rshift(bit.band(x, 0x00FF0000), 8),
|
|
bit.rshift(bit.band(x, 0xFF000000), 24)
|
|
)
|
|
end
|
|
|
|
local function generateToneSample(frequency, sampleRate, t)
|
|
return math.sin(2 * math.pi * frequency * t / sampleRate)
|
|
end
|
|
|
|
local function generateDTMF(frequency1, frequency2, sampleRate, t)
|
|
return generateToneSample(frequency1, sampleRate, t) + generateToneSample(frequency2, sampleRate, t)
|
|
end
|
|
|
|
local DTMFFrequencies = {
|
|
{ 697, 1209 },
|
|
{ 697, 1336 },
|
|
{ 697, 1477 },
|
|
{ 697, 1633 },
|
|
{ 770, 1209 },
|
|
{ 770, 1336 },
|
|
{ 770, 1477 },
|
|
{ 770, 1633 },
|
|
{ 852, 1209 },
|
|
{ 852, 1336 },
|
|
{ 852, 1477 },
|
|
{ 852, 1633 },
|
|
{ 941, 1209 },
|
|
{ 941, 1336 },
|
|
{ 941, 1477 },
|
|
{ 941, 1633 },
|
|
}
|
|
|
|
local function generateMonoWaveform(frequency1, frequency2, sampleRate, duration)
|
|
local size = duration * sampleRate
|
|
local samples = ffi.new('int16_t[?]', size)
|
|
for t = 0, duration * sampleRate - 1 do
|
|
samples[t] = 10000 * generateDTMF(frequency1, frequency2, sampleRate, t)
|
|
end
|
|
return samples, size
|
|
end
|
|
|
|
local function generateStereoWaveform(frequency1, frequency2, frequency3, frequency4, sampleRate, duration)
|
|
local size = duration * sampleRate
|
|
local samples = ffi.new('int16_t[?]', size * 2)
|
|
for t = 0, duration * sampleRate - 1 do
|
|
samples[2 * t + 0] = 10000 * generateDTMF(frequency1, frequency2, sampleRate, t)
|
|
samples[2 * t + 1] = 10000 * generateDTMF(frequency3, frequency4, sampleRate, t)
|
|
end
|
|
return samples, size
|
|
end
|
|
|
|
local function generateDTMF1(sampleRate, duration)
|
|
local samples, size = generateMonoWaveform(DTMFFrequencies[1][1], DTMFFrequencies[1][2], sampleRate, duration)
|
|
lu.assertEquals(size % 28, 0)
|
|
return samples, size
|
|
end
|
|
|
|
local function generateDTMFStereo(sampleRate, duration)
|
|
local samples, size = generateStereoWaveform(DTMFFrequencies[1][1], DTMFFrequencies[1][2], DTMFFrequencies[6][1], DTMFFrequencies[6][2], sampleRate, duration)
|
|
lu.assertEquals(size % 28, 0)
|
|
return samples, size
|
|
end
|
|
|
|
function TestAdpcm:test_simpleSPU()
|
|
local sampleRate = 44100
|
|
local duration = 1
|
|
local samples, size = generateDTMF1(sampleRate, duration)
|
|
local e = PCSX.Adpcm.NewEncoder()
|
|
e:reset 'Normal'
|
|
local blockCount = size / 28
|
|
local ptr = ffi.cast('int16_t *', samples)
|
|
local file = Support.File.buffer()
|
|
file:write('VAGp')
|
|
file:writeU32(0)
|
|
file:writeU32(0)
|
|
file:writeU32(swapEndian32((blockCount + 4) * 16))
|
|
file:writeU32(swapEndian32(sampleRate))
|
|
for i = 1, 11 do
|
|
file:writeU32(0)
|
|
end
|
|
local out = Support.NewLuaBuffer(16)
|
|
for i = 1, blockCount do
|
|
e:processSPUBlock(ptr, out, i == blockCount and 'OneShotEnd' or 'OneShot')
|
|
ptr = ptr + 28
|
|
file:write(out)
|
|
end
|
|
e:finishSPU(out)
|
|
file:write(out)
|
|
file:close()
|
|
end
|
|
|
|
function TestAdpcm:test_simpleXA()
|
|
local sampleRate = 37800
|
|
local duration = 20
|
|
local samples, size = generateDTMFStereo(sampleRate, duration)
|
|
local e = PCSX.Adpcm.NewEncoder()
|
|
e:reset 'XA'
|
|
local blockCount = size / 112
|
|
local ptr = ffi.cast('int16_t *', samples)
|
|
local file = Support.File.buffer()
|
|
local out = Support.NewLuaBuffer(128)
|
|
for i = 1, blockCount do
|
|
if (i % 18) == 1 then
|
|
file:writeU8(0)
|
|
file:writeU32(0xffffffff)
|
|
file:writeU32(0xffffffff)
|
|
file:writeU16(0xffff)
|
|
file:writeU32(0)
|
|
file:writeU8(2)
|
|
file:writeU32(0x01640001)
|
|
file:writeU32(0x01640001)
|
|
end
|
|
e:processXABlock(ptr, out, 'XAFourBits', 2)
|
|
ptr = ptr + 112 * 2
|
|
file:write(out)
|
|
if (i % 18) == 0 then
|
|
for j = 1, 6 do
|
|
file:writeU32(0)
|
|
end
|
|
end
|
|
end
|
|
file:close()
|
|
end
|