Advertisement
Alakazard12

MID Columna1

Mar 1st, 2014
178
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.65 KB | None | 0 0
  1. local function mread(amm)
  2. local str = ""
  3. for i = 1, amm do
  4. str = str .. string.char(file:read())
  5. end
  6. return str
  7. end
  8.  
  9. function readVarLen()
  10. value = 0
  11. c = 0
  12.  
  13. value = string.byte(mread(1))
  14. totalRead = totalRead + 1
  15. if math.floor(value / 2 ^ 7) == 1 then
  16. value = value - 128
  17. repeat
  18. c1 = string.byte(mread(1))
  19. totalRead = totalRead + 1
  20. c = math.floor( c1 / 2 ^ 7)
  21. if c == 1 then c1 = c1 -128 end
  22. value = value * 2 ^ 7 + c1
  23. until c == 0
  24. end
  25. return value
  26. end
  27.  
  28. function round(num, idp)
  29. local mult = 10^(idp or 0)
  30. return math.floor(num * mult + 0.5) / mult
  31. end
  32.  
  33. function readEvent()
  34. totalRead = totalRead + 1
  35. data = string.byte(mread(1))
  36. if data ~= 0xFF then
  37. event = math.floor(data / 2 ^ 4)
  38. channel = data - event * 2 ^ 4
  39. else
  40. event = 0xFF
  41. channel = -1
  42. end
  43. return event,channel
  44. end
  45.  
  46. function readMetaEvent(deltaTime)
  47. --for now we only care about set tempo events
  48. eventType = string.byte(mread(1))
  49. totalRead = totalRead + 1
  50. if eventType == 81 then -- Tempo type event
  51. local length = string.byte(mread(1))
  52. Mpqn = readShortInt()
  53. MpM = 60000000
  54. totalRead = totalRead + 1
  55. miliseconds_Per_quarter_note = MpM / currentTempo
  56. microseconds_per_deltaUnit = math.floor(Mpqn / timeDev)
  57. --print("before BPM: "..currentTempo)
  58. currentTempo = math.floor(MpM / Mpqn)
  59. --print("after BPM: "..currentTempo)
  60. --print("microseconds from last event "..deltaTime * microseconds_per_deltaUnit)
  61. --print("seconds from last event "..(deltaTime * microseconds_per_deltaUnit)/ 1000000)
  62. --print("microseconds_per_deltaUnit "..microseconds_per_deltaUnit)
  63. --print("microseconds_Per_quarter_note "..Mpqn)
  64. --use total delta time and then when reading the notes from file
  65. --use the table to expand notes to seconds time
  66. --the table will store how long a delta unit will last in microseconds
  67. if not tempo[0] then tempo[1] = microseconds_per_deltaUnit end
  68. for i = 1,deltaTime do
  69. tempo[i+deltaTimeTempo] = microseconds_per_deltaUnit
  70. end
  71. deltaTimeTempo = deltaTimeTempo + deltaTime
  72. --print("deltaTime: "..deltaTimeTempo)
  73. else
  74. local length = readVarLen()
  75. --print("skipping: "..eventType.." by: "..length)
  76. mread(length)
  77. totalRead = totalRead + length
  78. end
  79. end
  80.  
  81. function readNormEvent(dt, channel)
  82. if event == 9 then
  83. --note on event 2 bytes
  84. time = 0
  85. for i = 1,dt do
  86. if #tempo > i+totalTime then
  87. time = time + tempo[i+totalTime]/1000000-- if there is a value for it add it
  88. else
  89. time = time + tempo[#tempo]/1000000-- else add the last value (for after the last tempo event)
  90. end
  91. end
  92. local note = string.byte(mread(1))
  93. local velocity = string.byte(mread(1))
  94. totalRead = totalRead + 2
  95. totalRealTime = totalRealTime + time
  96. --print("starts at: "..totalRealTime)
  97. --print("deltaTime: "..totalTime)
  98. curnotes[note] = {totalRealTime,velocity}
  99. --print("Note on "..note.." velocity "..velocity)
  100. elseif event == 8 then
  101. time = 0
  102. for i = 1,dt do
  103. if #tempo > i+totalTime then
  104. time = time + tempo[i+totalTime]/1000000-- if there is a value for it add it
  105. else
  106. time = time + tempo[#tempo]/1000000-- else add the last value (for after the last tempo event)
  107. end
  108. end
  109. totalRealTime = totalRealTime + time
  110. ----print the time the note has lasted
  111. local note = string.byte(mread(1))
  112. local velocity = string.byte(mread(1))
  113. if curnotes[note] then
  114. if type(curnotes[note]) == "table" then
  115. --print("time lasted: "..totalRealTime - curnotes[note][1])--this also should be where the notes are added to the table for display
  116. notes[#notes+1] = {curnotes[note][1],totalRealTime,note,curnotes[note][2],CurTrack,channel}
  117. curnotes[note] = nil
  118. end
  119. end
  120. totalRead = totalRead + 2
  121. elseif event == 12 or event == 13 then
  122. time = 0
  123. for i = 1,dt do
  124. if #tempo > i+totalTime then
  125. time = time + tempo[i+totalTime]/1000000-- if there is a value for it add it
  126. else
  127. time = time + tempo[#tempo]/1000000-- else add the last value (for after the last tempo event)
  128. end
  129. end
  130. totalRealTime = totalRealTime + time
  131. --ignore by reading 1 byte
  132. mread(1)
  133. totalRead = totalRead + 1
  134. else
  135. time = 0
  136. for i = 1,dt do
  137. if #tempo > i+totalTime then
  138. time = time + tempo[i+totalTime]/1000000-- if there is a value for it add it
  139. else
  140. time = time + tempo[#tempo]/1000000-- else add the last value (for after the last tempo event)
  141. end
  142. end
  143. totalRealTime = totalRealTime + time
  144. mread(2)
  145. totalRead = totalRead + 2
  146. end
  147. end
  148.  
  149. function bytes_to_int(a,b,c,d)--big Endian
  150. sum = 0
  151. sum = sum + a * 2 ^ 24
  152. sum = sum + b * 2 ^ 16
  153. sum = sum + c * 2 ^ 8
  154. sum = sum + d
  155. return sum
  156. end
  157.  
  158. function readInt()
  159. e = string.byte(mread(1))
  160. f = string.byte(mread(1))
  161. g = string.byte(mread(1))
  162. h = string.byte(mread(1))
  163. totalRead = totalRead + 4
  164. return bytes_to_int(e,f,g,h)
  165. end
  166.  
  167. function readShortInt()
  168. f = string.byte(mread(1))
  169. g = string.byte(mread(1))
  170. h = string.byte(mread(1))
  171. e = 0
  172. totalRead = totalRead + 3
  173. return bytes_to_int(e,f,g,h)
  174. end
  175.  
  176. function readShort()
  177. g = string.byte(mread(1))
  178. h = string.byte(mread(1))
  179. e = 0
  180. f = 0
  181. totalRead = totalRead + 2
  182. return bytes_to_int(e,f,g,h)
  183. end
  184.  
  185.  
  186. function load()
  187. currentTempo = 120 -- BPM
  188. totalRead = 0
  189. totalTime = 0
  190. totalRealTime = 0
  191. deltaTimeTempo = 0
  192. curnotes = {}
  193. notes = {}
  194. num = 2
  195. CurTrack = 1
  196. TrackColors = {}
  197. for i = 0,127 do
  198. curnotes[i] = 0-- this will be the time that the midi note started
  199. end
  200. music = {}--table of note on/off events with ms delta time
  201. file = io.open("ar.mid","rb")
  202. readHeader()
  203. tempo = {500000/timeDev}
  204. for i = 1,tracks do
  205. TrackColors[i] = {math.random(0,255),math.random(0,255),math.random(0,255)}
  206. CurTrack = i
  207. readTrack(i)
  208. end
  209. timeTable = {}
  210. findTimeTable()
  211. --[[
  212. for i,k in pairs(timeTable) do
  213. print(i)
  214. for l,m in pairs(k) do
  215. print (l,m)
  216. end
  217. end
  218. ]]
  219. for j = 1,1000 do
  220. i = (j*0.005)
  221. print(i)
  222. if timeTable[i] then
  223. for l,m in pairs(timeTable[i]) do
  224. print (l,m)
  225. end
  226. end
  227. end
  228. --print(timeDev)
  229. --love.event.push("quit")
  230. timeElapsed = 0
  231. --print(notes[1][1],notes[1][2])
  232.  
  233. local d = fs.open("/new", "w")
  234. d.write(textutils.serialize(notes))
  235. d.close()
  236. end
  237.  
  238. function comp(a,b)
  239.  
  240. end
  241.  
  242. function draw()
  243. local scalar = 2/100
  244. for i = 1,#notes do
  245. love.graphics.setColor(TrackColors[notes[i][5]][1],TrackColors[notes[i][5]][2],TrackColors[notes[i][5]][3])
  246. if notes[i][1] < timeElapsed and notes[i][2] > timeElapsed then
  247. --love.graphics.rectangle("fill",0,(love.graphics.getHeight()/120)*notes[i][3],notes[i][4],math.floor(love.graphics.getHeight()/120))
  248. local FadeAmmount = notes[i][2] - notes[i][1]
  249. local faded = math.abs((timeElapsed - notes[i][2]) / FadeAmmount)
  250. --if notes[i][3] % 10 == 0 then --print(faded,notes[i][3]) end
  251. love.graphics.circle("fill",400,(love.graphics.getHeight()/120)*(120-notes[i][3]),(notes[i][4]/5)*faded,30)--(timeElapsed-notes[i][2])*50,30)
  252. end
  253. for j = 1,100 do
  254. if notes[i][1] < timeElapsed+(scalar*j) and notes[i][2] > timeElapsed+(scalar*j) then
  255. love.graphics.rectangle("fill",j*4+400,(love.graphics.getHeight()/120)*(120-notes[i][3]),4,math.floor(love.graphics.getHeight()/120))
  256. end
  257. end
  258. end
  259. --[[
  260. start = round(timeElapsed,2)
  261. if start > timeElapsed then
  262. start = start - 0.005
  263. elseif start < timeElapsed then
  264. start = start + 0.005
  265. end
  266. for i = 1,400 do
  267. --print(start+(0.005*i))
  268. if timeTable[start+(0.005*i)] then
  269. for j = 1,#timeTable[start+(0.005*i)] do
  270. --print("note: "..start+(0.005*i))
  271. --if start > 23 and start < 27 then print(start,timeTable[start+(0.005*i)][1],timeTable[start+(0.005*i)][2],timeTable[start+(0.005*i)][3],timeTable[start+(0.005*i)][4]) ; print("hi") end
  272. love.graphics.rectangle("fill",400+i,(love.graphics.getHeight()/120)*(120-timeTable[start+(0.005*i)][j]),1,600/120)
  273. end
  274. if start > 24.5 and start < 26 then print(start+(0.005*i),timeTable[start+(0.005*i)][1],timeTable[start+(0.005*i)][2],timeTable[start+(0.005*i)][3],timeTable[start+(0.005*i)][4]) ; print("hi") end
  275. end
  276. end
  277. ]]
  278. love.graphics.setColor(255,255,255,255)
  279. --peering into the futurbe
  280. --[[
  281. local scalar = 5/400
  282. for j = 1,400 do
  283. for i = 1,#notes do
  284. if notes[i][1] < timeElapsed+(scalar*j) and notes[i][2] > timeElapsed+(scalar*j) then
  285. love.graphics.rectangle("fill",j+400,(love.graphics.getHeight()/120)*notes[i][3],1,math.floor(love.graphics.getHeight()/120))
  286. end
  287. end
  288. end
  289. ]]
  290. love.graphics.print(timeElapsed,0,0)
  291. love.graphics.print("FPS: "..love.timer.getFPS(),200,0)
  292. end
  293.  
  294. function update(timChange)
  295. timeElapsed = timeElapsed + timChange
  296. end
  297.  
  298. function keypressed(key)
  299. if key == " " then
  300. bgm = love.audio.newSource("Ximares - Cohens Masterpiece Transcription.wav", "stream")
  301. love.audio.play(bgm)
  302. timeElapsed = 0
  303. elseif key == "backspace" then
  304. love.audio.stop()
  305. end
  306. end
  307.  
  308. function readHeader()
  309. local Test = mread(4)
  310. if Test ~= "MThd" then error("Not a valid midi file") end
  311. local size = readInt()-- always gonna be 6
  312. format = readShort()
  313. --print("format "..format)
  314. tracks = readShort()
  315. --print("tracks "..tracks)
  316. timeDev = readShort()
  317. end
  318.  
  319. function readTrack(tra)
  320. local evenType = mread(4)
  321. ----print(type)
  322. deltaTimeTempo = 0
  323. totalRealTime = 0
  324. totalRead = 0
  325. totalTime = 0
  326. --print("first four "..evenType)
  327. if evenType ~= "MTrk" then
  328. if mread(4) ~= "MTrk" then
  329. error("Missing or corrupted track")
  330. end
  331. end
  332. local size = readInt()
  333. while size > totalRead do
  334. local dt = readVarLen()
  335. ----print(dt)
  336. ----print(totalRead+ 0x16)
  337. local event,channel = readEvent()
  338. --print(event,channel)
  339. ----print(totalRead+ 0x16)
  340. if event == 255 then
  341. readMetaEvent(dt)
  342. else --its a normal event read it accordingly
  343. readNormEvent(dt, channel)--nothing yet
  344. end
  345. totalTime = totalTime + dt
  346. --print(totalTime)
  347. end
  348. --garbage = mread(size)
  349. end
  350.  
  351. function findTimeTable()
  352. timeTable = {}
  353. for i = 1,#notes do
  354. start = round(notes[i][1],2)
  355. if start > notes[i][1] then
  356. start = start - 0.005
  357. elseif start < notes[i][1] then
  358. start = start + 0.005
  359. end
  360. --print(notes[i][1],notes[i][2])
  361. k = 0
  362. --print(start,notes[i][1],notes[i][3])
  363. for j = start,notes[i][2],0.005 do
  364. --print("j: "..j.." N: "..i)
  365. if not timeTable[j] then
  366. timeTable[j] = {notes[i][3]}
  367. --print("Insterted: "..notes[i][3].." into: "..j)
  368. else
  369. timeTable[j][#timeTable[j]+1] = notes[i][3]
  370. end
  371. k = k + 1
  372. --print(j)
  373. end
  374. pr = false
  375. --print(k.." "..notes[i][2])
  376. end
  377. end
  378.  
  379. load()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement