Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function readBool(bin, i)
- bool = string.byte(bin,i) == 1
- return i+1, bool
- end
- function readInt(bin, i, prog)
- buffer = 0
- for j=1,prog do
- -- print(buffer)
- buffer = string.byte(bin,i+j-1)*math.pow(16,2*(j-1)) + buffer
- end
- -- print(i..": Int("..buffer..")")
- return i+prog, buffer
- end
- function readByte(bin, i, prog)
- for j=1,prog do
- -- print(buffer)
- buffer = buffer .. " " .. string.byte(bin,i+j-1)
- end
- return i+prog, buffer
- end
- function readStr(bin, i)
- i, prog = readInt(bin, i, 4)
- buffer = ""
- -- print(i..": "..prog)
- -- print(prog)
- for j=1,prog do
- buffer = buffer .. "" .. string.char(string.byte(bin,i+j-1))
- end
- return i+prog, buffer
- end
- function skip(bin, i, prog)
- return i+prog
- end
- function readHeader(bin, i)
- i = skip(bin, i, 2)
- i, ver = readInt(bin, i, 1)
- -- print("NBS Version: " .. ver)
- i, vanInst = readInt(bin, i, 1)
- -- print("Number of Vanilla Instruments: " .. vanInst)
- i, tikLen = readInt(bin, i, 2)
- -- print("Length in Ticks: " .. tikLen)
- i, lyr = readInt(bin, i, 2)
- -- print("Number of Layers (inaccurate): " .. lyr)
- -- print("SNAME")
- i, sName = readStr(bin, i)
- -- print("Song Name: " .. sName)
- -- print("ANAME")
- i, authName = readStr(bin, i)
- -- print("Author: " .. authName)
- -- print("OGANAME")
- i, ogAuthName = readStr(bin, i)
- -- print("Original Author: " .. ogAuthName)
- -- print("DESC")
- i, desc = readStr(bin, i)
- -- print("Description: " .. desc)
- i, tempo = readInt(bin, i, 2)
- -- print("Tempo (Ticks/Sec)*100: " .. tempo)
- i, aSave = readBool(bin, i)
- -- print("Auto-Save?: " .. (aSave and "Yes" or "No"))
- i, aSaveT = readInt(bin, i, 1)
- -- print("Auto-Save Time: " .. aSaveT)
- i, tSign = readInt(bin, i, 1)
- -- print("Time Signature:0 "..tSign.."/4")
- i, minSpent = readInt(bin, i, 4)
- -- print("Minutes Spent On Project: " .. minSpent)
- i, lClick = readInt(bin, i, 4)
- -- print("Left Clicks: " .. lClick)
- i, rClick = readInt(bin, i, 4)
- -- print("Right Clicks: " .. rClick)
- i, nbAdd = readInt(bin, i, 4)
- -- print("Noteblocks Added: " .. nbAdd)
- i, nbRem = readInt(bin, i, 4)
- -- print("Noteblocks Removed: " .. nbRem)
- -- print("PORT")
- i, port = readStr(bin, i)
- -- print("Imported MIDI / Scematic File: " .. port)
- i, loop = readBool(bin, i)
- -- print("Looping?: " .. (loop and "Yes" or "No"))
- i, mLoop = readInt(bin, i, 1)
- -- print("Max Times Looped: " .. mLoop)
- i, loopIdx = readInt(bin, i, 2)
- -- print("Loop Start Tick: " .. loopIdx)
- songHead = {version=ver, vInstruments=vanInst, tLength=tikLen,layerCount=lyr, songName=sName, chartAuthor=authName, songAuthor=ogAuthName, description=desc, tempo=tempo,autoSave=aSave,saveTime=aSaveT,timeSignature=tSign, minutesSpent=minSpent, leftClicks=lClick, rightClicks=rClick,notesAdded=nbAdd,notesRemoved=nbRem, importedFile=port, isLooping=loop,maxLoops=mLoop,loopStart=loopIdx}
- return i, songHead
- end
- function readNote(bin, i, cft, idx, reps)
- jumpNT = nil
- if cft then
- i, jumpNT = readInt(bin, i, 2)
- -- print("Wait " .. jumpNT .. " Ticks")
- if jumpNT == 0 then
- return i, nil, false, idx
- end
- end
- i, jumpNL = readInt(bin, i, 2)
- if jumpNL == 0 and not cft then
- -- print("prepare for pause")
- return readNote(bin,i,true,idx,reps)
- end
- -- print(jumpNL .. " Jumps From Last Layer")
- i, inst = readInt(bin, i, 1)
- -- print("Instrument: " .. (inst < 16 and band[inst] or "Custom?"))
- i, nKey = readInt(bin, i, 1)
- -- print("Key: "..nKey)
- i, vol = readInt(bin, i, 1)
- -- print("Volume: "..vol .. "%")
- i, stere = readInt(bin, i, 1)
- -- print("Stereo Position: "..stere)
- i, pit = readInt(bin, i, 2)
- -- print("Pitch: "..pit)
- note = {jumpTNNote = jumpNT, jumpTNLayer = jumpNL, instrument = inst, noteKey = nKey, volume = vol, stereo = stere, pitch = pit}
- if reps > 1 then
- return readNote(bin,i,false,idx+1,reps-1)
- else
- return i, note, false, idx+1
- end
- end
- function dec2hex(size, num)
- hnum = string.format("%x",num)
- op = hnum
- if #hnum < size*2 then
- for i=1, size*2-#hnum do
- op = "0"..op
- end
- end
- return op
- end-- REDUNDANT
- function readBinaryNote(bin, i, cft, idx, reps)
- jumpNT = nil
- if cft then
- i, jumpNT = readInt(bin, i, 2)
- print(dec2hex(2,jumpNT) .. " Jumps From Last Note")
- end
- i, jumpNL = readInt(bin, i, 2)
- if jumpNL == 0 and not cft then
- print("prepare for pause")
- return readBinaryNote(bin,i,true,idx,reps)
- end
- print(dec2hex(2,jumpNL) .. " Jumps From Last Layer")
- i, inst = readInt(bin, i, 1)
- print("Instrument: " .. dec2hex(1,inst))
- i, nKey = readInt(bin, i, 1)
- print("Key: "..dec2hex(1,nKey))
- i, vol = readInt(bin, i, 1)
- print("Volume: "..dec2hex(1,vol))
- i, stere = readInt(bin, i, 1)
- print("Stereo Position: "..dec2hex(1,stere))
- i, pit = readInt(bin, i, 2)
- print("Pitch: "..dec2hex(2,pit))
- note = {jumpTNNote = jumpNT, jumpTNLayer = jumpNL, instrument = inst, noteKey = nKey, volume = vol, stereo = stere, pitch = pit}
- if reps > 1 then
- return readBinaryNote(bin,i,false,idx+1,reps-1)
- else
- return i, note, false, idx+1
- end
- end-- REDUNDANT
- function skipNotes(bin, i, cft, count, idx)
- jumpNT = nil
- if cft then
- i, jumpNT = readInt(bin, i, 2)
- if jumpNT == 0 then
- -- print("ENDING")
- -- print(idx)
- return i, count, idx
- else
- -- print("JUMPED")
- idx = idx + jumpNT
- end
- end
- i, jumpNL = readInt(bin, i, 2)
- if jumpNL == 0 and not cft then
- return skipNotes(bin, i, true, count, idx)
- end
- i = skip(bin,i,6)
- return skipNotes(bin, i, false, count+1, idx)
- end
- function readLayer(bin, i, lIdex, reps)
- i, lName = readStr(bin, i)
- -- print(lName .. " layer")
- i, lock = readBool(bin, i)
- -- print((lock and "Layer locked" or "Layer Unlocked"))
- i, vol = readInt(bin,i,1)
- -- print("Layer Volume: " .. vol .. "%")
- i, stere = readInt(bin,i,1)
- -- print("Stereo Position: "..stere)
- layer = {layerName=lName,isLocked=lock,volume=vol,stereo=stere}
- if reps > 1 then
- return readLayer(bin,i,lIdex+1,reps-1)
- end
- return i, layer, lIdex+1
- end
- function skipLayers(bin, i, lIdex, count)
- -- print(lIdex)
- -- print("SKIPPING")
- -- print(i)
- -- print(readInt(bin,i, 4))
- i = readStr(bin, i)
- i = skip(bin, i, 3)
- if lIdex+1 < header.layerCount then
- return skipLayers(bin,i,lIdex+1,count+1)
- end
- return i, count+1, lIdex+1
- end
- function readCustom(bin, i, cIdex, reps)
- i, cName = readStr(bin, i)
- -- print("Instrument: " .. cName)
- i, cFile = readStr(bin, i)
- -- print("Path: " .. cFile)
- i, key = readInt(bin,i,1)
- -- print("Default Key: " .. key)
- i, vis = readBool(bin, i)
- -- print((vis and "Visuallise" or "Don't Visuallise"))
- custom = {CustomName=lName,filePath=cFile,defaultKey=key,isvisuallised=vis}
- if reps > 1 then
- return readCustom(bin,i,cIdex+1,reps-1)
- end
- return i, custom, cIdex+1
- end
- function YNPrompt(str)
- print(str)
- ans=read()
- if ans=="y" or ans =="Y" then
- return true
- elseif ans=="n" or ans=="N" then
- return false
- else
- print("Invalid input")
- return YNPrompt(str)
- end
- end-- REDUNDANT
- function validateFile(bin)
- -- print("VALIDATING")
- i, header = readHeader(bin, 1)
- lyStart = skipNotes(bin, i, true, 0, 0)
- -- print("lyStart: "..lyStart)
- cuStart = skipLayers(bin, lyStart, 0, 0)
- _, cInsts = readInt(bin, cuStart, 1)
- if cInsts < 0 then
- printError("Song Contains Custom Instruments (Unsupported)")
- return nil, nil, nil
- end
- -- print("HEADER VALID")
- j=i
- cft = true
- nIdx = 0
- while j<lyStart do
- -- print(j.."/"..lyStart)
- j, note, cft, nIdx = readNote(bin, j, cft, nIdx, 1)
- if note then
- if note.noteKey > 57 or note.noteKey < 33 then
- printError("Notes are Keyed Outside of 2 Octave Spectrum at ".. nIdx .. " pitch " .. note.noteKey)
- -- printError(j.."/"..lyStart)
- return nil, nil, nil
- end
- if not note.stereo == 100 then
- printError("Stereo Unsupported")
- return nil, nil, nil
- end
- if not note.pitch == 0 then
- printError("Notes are Fine Pitched (Unsupported)")
- return nil, nil, nil
- end
- end
- end
- -- print("NOTES VALID")
- -- print("scanning from byte: "..j.."/"..#bin)
- layers = {}
- lIdx = 1
- while j<cuStart do
- j, layers[lIdx], tlIdx = readLayer(bin,j, lIdx, 1)
- if not layers[lIdx].stereo == 100 then
- printError("Stereo Unsupported")
- return nil, nil, nil
- end
- lIdx = tlIdx
- end
- -- print("VALIDATED")
- return i, header, layers
- end
- function findSpeak()
- spk = nil
- for k,v in pairs(peripheral.getNames()) do
- if peripheral.getType(v) == "speaker" and not spk then
- spk = peripheral.wrap(v)
- end
- end
- return spk
- end
- local tArgs = { ... }
- bin = nil
- -- print("RUNNING")
- if #tArgs<1 then
- if fs.exists("/disk") then
- flist = fs.list("/disk")
- for k,v in pairs(flist) do
- if string.find(v,".nbs") then
- -- print(v)
- bin = fs.open("/disk/"..v,"rb").readAll()
- end
- end
- if not bin then
- print("No File Specified or on Disk")
- return
- end
- end
- -- print("No File")
- -- return
- elseif not fs.exists(tArgs[1]) or (fs.exists(tArgs[1]) and fs.isDir(tArgs[1])) then
- print("Not a File Bozo")
- return
- else
- -- print(fs.getName(tArgs[1]) .. " Exists!")
- bin = fs.open(tArgs[1],"rb").readAll()
- end
- -- print(#bin .. "b")
- i=1
- i, header, layers= validateFile(bin)
- if not i then
- return
- end
- -- print("Notes start at offset " .. i)
- speak = findSpeak()
- if not speak then
- printError("No Speaker Found")
- return
- end
- notStart = i
- idex = 0
- mtnt = true
- lyStart = skipNotes(bin, i, mtnt, 0, 0)
- lIdex = 0
- -- cuStart = skipLayers(bin, lyStart, 0, 0)
- -- cIdex = 0
- -- cuStart, cInsts = readInt(bin, cuStart, 1)
- -- print(cInsts .. " Custom Instruments")
- print("Now Playing " .. header.songName .. " by " .. header.songAuthor)
- -- tick = true
- band = {[0]="harp", "bass", "basedrum", "snare", "hat", "guitar", "flute", "bell", "chime", "xylophone", "iron_xylophone", "cow_bell", "didgeridoo", "bit", "banjo", "pling"}
- -- print(layers[2].volume)
- -- print(7.5*(100/header.tempo))
- while i < lyStart do
- i, note, mtnt, idex = readNote(bin, i, mtnt, idex, 1)
- if note then
- if note.jumpTNNote then
- sleep((note.jumpTNNote)*(100/header.tempo))
- lIdex = 0
- -- print((tick and "tick" or "tock"))
- -- tick = not tick
- end
- lIdex = lIdex + note.jumpTNLayer
- -- print(lIdex)
- vol = ((layers[lIdex].volume * note.volume)/10000)*3
- speak.playNote(band[note.instrument],vol,note.noteKey-33)
- end
- end
- print("Joever")
- -- print(bin.read())
- -- print(bin.readLine(true))
- -- bin.close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement