103 lines
2.3 KiB
Lua
103 lines
2.3 KiB
Lua
-- @include constants.txt
|
|
-- @include track.txt
|
|
-- @include /koptilnya/libs/utils.txt
|
|
require("track.txt")
|
|
require("/koptilnya/libs/utils.txt")
|
|
|
|
local CONSTANTS = require("constants.txt")
|
|
|
|
function byteToHex(byte)
|
|
return tostring(byte)
|
|
end
|
|
|
|
MidiPlayer = class("MidiPlayer")
|
|
|
|
function MidiPlayer:initialize()
|
|
self._startTime = 0
|
|
self._buffer = nil
|
|
self._midiChunksByteLength = nil
|
|
self._division = 0
|
|
self._format = nil
|
|
self._setIntervalId = false
|
|
self._tracks = {}
|
|
self._instruments = {}
|
|
self._defaultTempo = 120
|
|
self._tempo = null
|
|
self._startTick = 0
|
|
self._tick = 0
|
|
self._lastTick = null
|
|
self._inLoop = false
|
|
self._totalTicks = 0
|
|
self._events = {}
|
|
self._totalEvents = 0
|
|
self._eventListeners = {}
|
|
end
|
|
|
|
function MidiPlayer:loadURL(link)
|
|
if not http.canRequest() then
|
|
return
|
|
end
|
|
|
|
http.get(link, function(data, len)
|
|
self._buffer = data
|
|
|
|
self:_fileLoaded()
|
|
end)
|
|
end
|
|
|
|
function MidiPlayer:_fileLoaded()
|
|
if not self:isValid() then
|
|
throw("Invalid MIDI file; should start with MThd")
|
|
end
|
|
|
|
self:setTempo(self._defaultTempo)
|
|
self:_parseDivision()
|
|
self:_parseFormat()
|
|
self:_parseTracks()
|
|
end
|
|
|
|
function MidiPlayer:isValid()
|
|
return string.char(unpack(byteTable(self._buffer, 1, 4))) == "MThd"
|
|
end
|
|
|
|
function MidiPlayer:setTempo(tempo)
|
|
self._tempo = tempo
|
|
end
|
|
|
|
function MidiPlayer:_parseDivision()
|
|
self._division = tonumber(bytesToHex(byteTable(self._buffer, 13, 2)))
|
|
end
|
|
|
|
function MidiPlayer:_parseFormat()
|
|
self._format = tonumber(bytesToHex(byteTable(self._buffer, 9, 2)))
|
|
end
|
|
|
|
function MidiPlayer:_parseTracks()
|
|
self._tracks = {}
|
|
|
|
local offset = 1
|
|
|
|
while offset < #self._buffer do
|
|
local length = tonumber(bytesToHex(byteTable(self._buffer, offset + 4, 4)))
|
|
|
|
if string.char(unpack(byteTable(self._buffer, offset, 4))) == "MTrk" then
|
|
table.insert(self._tracks, MidiTrack:new(#self._tracks + 1, string.sub(self._buffer, offset + 8, offset + 8 + length)))
|
|
end
|
|
|
|
offset = offset + length + 8
|
|
end
|
|
end
|
|
|
|
function MidiPlayer:resetTracks()
|
|
for _, v in pairs(self._tracks) do
|
|
v:reset()
|
|
end
|
|
end
|
|
|
|
function MidiPlayer:enableTrack(id)
|
|
self._tracks[id]:enable()
|
|
end
|
|
|
|
function MidiPlayer:disableTrack(id)
|
|
self._tracks[id]:disable()
|
|
end |