Mesen-X/GUI.NET/Dependencies/LuaScripts/DmcCapture.lua

127 lines
4.1 KiB
Lua

-----------------------
-- Name: DMC Capture
-- Author: upsilandre
-----------------------
-- Displays information about the DMC samples: [Sample Address] [Sample Size (bytes)] [Sample Frequency]
-- Every new sample encountered will be logged in the script's log window.
-- Right-clicking on the screen turns on DMC sample recording. While recording, any sample played
-- will be recorded on the disk in .wav format in the LuaScriptData folder
-----------------------
function Main()
dmc = emu.getState().apu.dmc
SelectRecord()
if dmc.bytesRemaining > 0 then
freq = math.floor(dmc.sampleRate)
new = true
if nbSample > 0 then
for i = 1,nbSample do
if (dmc.sampleAddr == sample.addr[i] and dmc.sampleLength == sample.length[i] and dmc.period == sample.period[i]) then
new = false
break
end
end
end
if new then
nbSample = nbSample + 1
sample.addr[nbSample] = dmc.sampleAddr
sample.length[nbSample] = dmc.sampleLength
sample.period[nbSample] = dmc.period
emu.log(nbSample.." >> $"..string.format("%X ", dmc.sampleAddr)..string.format("%4d bytes ",dmc.sampleLength)..string.format("%5d hertz ",freq)..stringR)
if record then
SampleRecord(dmc.sampleAddr, dmc.sampleLength, freq)
end
end
if dmc.sampleAddr ~= lastSampleAddr or dmc.sampleLength ~= lastSampleLength or dmc.period ~= lastSamplePeriod then
lastSampleAddr = dmc.sampleAddr
lastSampleLength = dmc.sampleLength
lastSamplePeriod = dmc.period
emu.drawString(4, 7, " $"..string.format("%X ", dmc.sampleAddr)..string.format("%4d bytes ",dmc.sampleLength)..string.format("%5d hertz ",freq), 0xffffff, 0x40ffffff, 2)
else
emu.drawString(4, 7, " $"..string.format("%X ", dmc.sampleAddr)..string.format("%4d bytes ",dmc.sampleLength)..string.format("%5d hertz ",freq), 0xc0c0c0, 0x40202020, 1)
end
end
end
function SelectRecord()
if emu.getMouseState().right then
if not hold then
hold = true
record = not record
nbSample = 0
emu.log("______________________________________________________________________\n")
if record then
emu.log("File path = "..emu.getScriptDataFolder().."\\\n")
end
end
else
hold = false
end
if record then
stringR = " recorded"
emu.drawRectangle(193, 5, 42, 11, 0x404040, true, 1)
emu.drawRectangle(192, 4, 44, 13, 0x808080, false, 1)
emu.drawString(196, 7, "RECORD", 0xFF0000, 0xFF000000, 1)
else
stringR = ""
end
end
function SampleRecord(addr, length, freq)
dataLen = length * 8 + 1
header[5] = (dataLen + 36) & 255
header[6] = (dataLen + 36) >> 8
header[25] = freq & 255
header[26] = freq >> 8
header[29] = header[25]
header[30] = header[26]
header[41] = dataLen & 255
header[42] = dataLen >> 8
header[45] = 0x80
fileName = string.sub(emu.getRomInfo().name, 1, #emu.getRomInfo().name - 4)..string.format("_$%X_", addr)..length.."b_"..freq.."hz.wav"
fileOutput = io.open(emu.getScriptDataFolder().."\\"..fileName, "w+b")
for k = 1,45 do
fileOutput:write(string.char(header[k]))
end
lastSample = 0x80
for i = 0, length - 1 do
bitMask = 1
byte = emu.read(addr + i, emu.memType.cpuDebug)
for j = 1,8 do
if byte & bitMask > 0 then
newSample = lastSample + 4
if newSample == 256 then
newSample = 252
end
else
newSample = lastSample - 4
if newSample == -4 then
newSample = 0
end
end
fileOutput:write(string.char(newSample))
lastSample = newSample
bitMask = bitMask << 1
end
end
fileOutput:close()
end
sample = {}
sample.addr = {}
sample.length = {}
sample.period = {}
nbSample = 0
record = false
hold = false
header = {0x52,0x49,0x46,0x46,0x00,0x00,0x00,0x00,
0x57,0x41,0x56,0x45,0x66,0x6D,0x74,0x20,
0x10,0x00,0x00,0x00,0x01,0x00,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x01,0x00,0x08,0x00,0x64,0x61,0x74,0x61,
0x00,0x00,0x00,0x00}
emu.addEventCallback(Main, emu.eventType.endFrame);
emu.displayMessage("Script", "DMC Capture")