127 lines
4.1 KiB
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")
|