Need help with NBS format binary parsing (erroring)

Started by pjals_but_noisy, Oct 22, 2021, 02:30 pm

Previous topic - Next topic

pjals_but_noisy

Oct 22, 2021, 02:30 pm Last Edit: Oct 22, 2021, 02:33 pm by pjals_but_noisy
im making a nbs implementation for CC/Pure Lua and its erroring, why is this happening?
here is the library i used (bitbuffer), https://github.com/Dekkonot/bitbuffer

the output goes like:
Code Select
> it4.nbs (test nbs)
< 5
< aaaa
< 256
< 0 256
<! opennbs.lua:72: attempt to index field '?' (a nil value)

and here is the code:
Code Select
local bitbuffer = require("bitbuffer")
local pretty = require("cc.pretty")

local function readStr(buffer)
local size = buffer.readInt32()
return buffer.readSetLengthString(size)
end

local function parseNbs(path)
local handle = fs.open(path, "rb")
handle.read(2)
local buffer = bitbuffer(handle.readAll())
handle.close()
local info, layers = {}, {}
info.version = buffer.readByte()
info.layers = {}
info.author = {}
info.clicks = {}
info.noteblocks = {}
print(info.version)
if info.version == 5 then
-- Header / Metadata
info.vic = buffer.readByte()
info.length = buffer.readInt16()
info.layers = buffer.readInt16()
info.name = readStr(buffer)
info.author.nbs = readStr(buffer)
info.author.original = readStr(buffer)
info.desc = readStr(buffer)
info.tempo = buffer.readInt16() / 100 -- ticks*100 -> ticks
info.autoSave = buffer.readByte()
info.asInterval = buffer.readByte()
info.ts = buffer.readByte()
info.timeSpent = buffer.readInt32() * 60 -- minutes -> seconds
info.clicks.left = buffer.readInt32()
info.clicks.right = buffer.readInt32()
info.noteblocks.added = buffer.readInt32()
info.noteblocks.removed = buffer.readInt32()
info.realname = readStr(buffer)
info.loop = buffer.readByte()
info.loopCount = buffer.readByte()
info.loopStart = buffer.readInt16()
-- Notes
local tick = 0
while true do
local jumps = buffer.readInt16()
if jumps == 0 then
print("a")
break
end
tick = tick + jumps
local layer = 0
layers[layer] = {}
layers[layer].notes = {}
print("aaaa")
while true do
local lJumps = buffer.readInt16()
if lJumps == 0 then
print(lJumps)
break
end
print(lJumps)
print(layer, layer + lJumps)
layer = layer + lJumps

local instrument = buffer.readByte()
local key = buffer.readByte()
local velocity = buffer.readByte()
local panning = buffer.readByte()
local pitch = buffer.readInt16()

layers[layer].notes[tick] = {}
layers[layer].notes[tick].instrument = instrument
layers[layer].notes[tick].key = key
layers[layer].notes[tick].velocity = velocity
layers[layer].notes[tick].panning = panning
layers[layer].notes[tick].pitch = pitch
print(layer, "a")
end
end
--Layers
for i = 1, info.layers do
pretty.print(pretty.pretty(layers))
print(i)
layers[i].name = readStr(buffer)
layers[i].lock = buffer.readByte()
layers[i].volume = buffer.readByte()
layers[i].pan = buffer.readByte()
end

return { ["info"] = info, ["layers"] = layers }
else
error("NBS file is outdated. Required version: 5. (got " .. info.version .. ")")
end
end

pretty.print(pretty.pretty(parseNbs(read())))
a

Lupus590

Oct 22, 2021, 06:05 pm #1 Last Edit: Oct 22, 2021, 06:11 pm by Lupus590
The error message is telling you that you are trying to use something as a table that is not a table. It could be that the table is not ready yet.

Looking at you code line 72 (the line number that the error is blaming) is this line

Code Select
layers[layer].notes[tick] = {}
That's quite the nested table and any of those could be not actually a table.

I would check that the table exists before trying to use it, and if it doesn't then make it, you have to do this for each level of the nesting of the table.

Code Select
if not layers then
  layers = {}
end
if not layers[layer] then
  layers[layer] = {}
end
if not layers[layer].notes then
  layers[layer].notes = {}
end

pjals_but_noisy

Oct 22, 2021, 09:15 pm #2 Last Edit: Oct 22, 2021, 09:17 pm by pjals_but_noisy
Quote from: Lupus590 on Oct 22, 2021, 06:05 pmThe error message is telling you that you are trying to use something as a table that is not a table. It could be that the table is not ready yet.

Looking at you code line 72 (the line number that the error is blaming) is this line

Code Select
layers[layer].notes[tick] = {}
That's quite the nested table and any of those could be not actually a table.

I would check that the table exists before trying to use it, and if it doesn't then make it, you have to do this for each level of the nesting of the table.

Code Select
if not layers then
  layers = {}
end
if not layers[layer] then
  layers[layer] = {}
end
if not layers[layer].notes then
  layers[layer].notes = {}
end
im pretty sure thats half the problem, since its normally not supposed to return 256 for everything
(and great, now its reading past the bounds)
a

pjals_but_noisy

Oct 22, 2021, 09:20 pm #3 Last Edit: Oct 22, 2021, 09:29 pm by pjals_but_noisy
oh look, i got it working, great.... nevermind, it thinks all notes are on layer 256? man binary is confusing
a