Advertisement
guitarplayer616

SheetReader

Dec 14th, 2019
442
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.69 KB | None | 0 0
  1. local args = ...
  2. filesystem = require("filesystem")
  3. component = require("component")
  4. computer = require("computer")
  5. m = component.proxy(component.list("modem")())
  6. m.open(2412)
  7.  
  8. function addGlobals()
  9.   Computer = {}
  10.   Computer.beep = function(frequency,duration)
  11.     print("Computer.beep("..tostring(frequency)..", "..tostring(duration)..")")
  12.   end
  13. end
  14.  
  15. function readfile(filename)
  16.   local f = io.open(filename,'r')
  17.   local str = f:read("*a")
  18.   f:close()
  19.   return str
  20. end
  21.  
  22. tuning = {'E4','B3','G3','D3','A2','E2'}
  23. capo = 0
  24. tempo = 90
  25. signature = "3/4"
  26.  
  27. Note = {}
  28. Batch = {}
  29. song = {}
  30.  
  31. duration = {}
  32. duration.W = 4
  33. duration.H = 2
  34. duration.Q = 1
  35. duration.E = .5
  36. duration.S = .25
  37. duration.T = .33
  38. duration['W.'] = 6
  39. duration['H.'] = 3
  40. duration['Q.'] = 1.5
  41. duration['E.'] = .75
  42. duration['S.'] = .375
  43. duration['T.'] = .495
  44.  
  45. freq = {} --GLOBAL
  46. freq['C2'] = 65.41
  47. freq['C#2'] = 69.30
  48. freq['D2'] = 73.42
  49. freq['D#2'] = 77.78
  50. freq['E2'] = 82.41
  51. freq['F2'] = 87.31
  52. freq['F#2'] = 92.50
  53. freq['G2'] = 98.00
  54. freq['G#2'] = 103.83
  55. freq['A2'] = 110.00
  56. freq['A#2'] = 116.54
  57. freq['B2'] = 123.47
  58. freq['C3'] = 130.81
  59. freq['C#3'] = 138.59
  60. freq['D3'] = 146.83
  61. freq['D#3'] = 155.56
  62. freq['E3'] = 164.81
  63. freq['F3'] = 174.61
  64. freq['F#3'] = 185.00
  65. freq['G3'] = 196.00
  66. freq['G#3'] = 207.65
  67. freq['A3'] = 220.00
  68. freq['A#3'] = 233.08
  69. freq['B3'] = 246.94
  70. freq['C4'] = 261.63
  71. freq['C#4'] = 277.18
  72. freq['D4'] = 293.66
  73. freq['D#4'] = 311.13
  74. freq['E4'] = 329.63
  75. freq['F4'] = 349.23
  76. freq['F#4'] = 369.99
  77. freq['G4'] = 392.00
  78. freq['G#4'] = 415.30
  79. freq['A4'] = 440.00
  80. freq['A#4'] = 466.16
  81. freq['B4'] = 493.88
  82. freq['C5'] = 523.25
  83. freq['C#5'] = 554.37
  84. freq['D5'] = 587.33
  85. freq['D#5'] = 622.25
  86. freq['E5'] = 659.25
  87. freq['F5'] = 698.46
  88. freq['F#5'] = 739.99
  89. freq['G5'] = 783.99
  90. freq['G#5'] = 830.61
  91. freq['A5'] = 880.00
  92. freq['A#5'] = 932.33
  93. freq['B5'] = 987.77
  94. freq['C6'] = 1046.50
  95. freq['C#6'] = 1108.73
  96. freq['D6'] = 1174.66
  97. freq['D#6'] = 1244.51
  98. freq['E6'] = 1318.51
  99. freq['F6'] = 1396.91
  100. freq['F#6'] = 1479.98
  101. freq['G6'] = 1567.98
  102. freq['G#6'] = 1661.22
  103. freq['A6'] = 1760.00
  104. freq['A#6'] = 1864.66
  105. freq['B6'] = 1975.53
  106. freq['C7'] = 2093.00
  107.  
  108. Note.alphabet = {'C','C#','D','D#','E','F','F#','G','G#','A','A#','B'}
  109. Note.lastNote = {0,0,0,0,0,0}
  110.  
  111. function Note:new(ithStr,ithFret,fracNote)
  112.   o = {}
  113.   o.ithStr = tonumber(ithStr)
  114.   o.ithFret = tonumber(ithFret) or Note.lastNote[ithStr] or 0
  115.   o.fracNote = fracNote
  116.   o.string = ithStr..ithFret..fracNote
  117.   setmetatable(o,self)
  118.   self.__index = self
  119.   --Note.lastNote[ithStr] = ithFret
  120.   return o
  121. end
  122.  
  123. function Note:getNote()
  124.   --requires access to tuning table
  125.   local strNote = tuning[self.ithStr]
  126.   strNote = self:halfStep(strNote,self.ithFret)
  127.   return strNote
  128. end
  129.  
  130. function Note:getFreq()
  131.   return freq[self:getNote()]
  132. end
  133.  
  134. function Note:getDuration()
  135.   local val = duration[self.fracNote]
  136.   if not val then
  137.     val = 1
  138.   end
  139.   return val*(60/tempo)
  140. end
  141.  
  142. function Note:halfStep(strNote,numReps)
  143.   --ie takes a strNote: "A#" and moves it up numReps: 4 half steps
  144.   if numReps == 0 then
  145.     return strNote
  146.   end
  147.   local letter = strNote:sub(1,#strNote-1)
  148.   local octave = strNote:sub(#strNote)
  149.   local key = table.getKey(self.alphabet,letter)
  150.   local index = key + numReps
  151.   local octave = tonumber(octave) + math.floor(index/#self.alphabet)
  152.   index = index%#self.alphabet
  153.   if index == 0 then
  154.     index = 12
  155.   end
  156.   return self.alphabet[index]..tostring(octave)
  157. end
  158.  
  159. function Note:capo(num)
  160.   for i = 1,#tuning do
  161.     tuning[i] = self:halfStep(tuning[i],num)
  162.   end
  163. end
  164.  
  165. function table:getKey(value) --GLOBAL
  166.   for k,v in pairs(self) do
  167.     if value == v then
  168.       return k
  169.     end
  170.   end
  171. end
  172.  
  173. function Batch:new(status)
  174.   o = {}
  175.   o.status = status
  176.   o.string = ""
  177.   o.duration = 0
  178.   setmetatable(o,self)
  179.   self.__index = self
  180.   return o
  181. end
  182.  
  183. function Batch:insert(strNote)
  184.   self.string = self.string..getExec(strNote)
  185. end
  186.  
  187. lastNote = {0,0,0,0,0,0}
  188.  
  189. function getExec(strNote)
  190.   local ithStr = strNote:sub(1,1) or 0
  191.   local ithFret = strNote:sub(2,2) or 0
  192.   local duration = strNote:sub(3,3)
  193.   local addDot = strNote:sub(4,4) == '.'
  194.   if addDot then
  195.     duration = duration..'.'
  196.   end
  197.  
  198.   local note = Note:new(ithStr,ithFret,duration)
  199.  
  200.   if ithStr == "0" then
  201.     return "os.sleep("..tostring(note:getDuration()-0.05)..") "
  202.   else
  203.     return "computer.beep("..tostring(note:getFreq())..","..tostring(note:getDuration()-0.05)..") "
  204.   end
  205. end
  206.  
  207. function getDuration(strNote)
  208.   local stop = 3
  209.   if strNote:sub(1,1) == '{' then
  210.     stop = stop + 1
  211.   end
  212.   if strNote:sub(stop+1,stop+1) == "." then
  213.     return (duration[strNote:sub(stop,stop+1)] or 1)*(60/tempo)
  214.   else
  215.     return (duration[strNote:sub(stop,stop)] or 1)*(60/tempo)
  216.   end
  217. end
  218.  
  219. function tabulateFile(filename)
  220.   local table = {}
  221.   local iter = 1
  222.   for line in io.lines(filename) do
  223.     table[iter] = line
  224.     iter = iter + 1
  225.   end
  226.   return table
  227. end
  228.  
  229. function findMeasure(sheet,num)
  230.   for i = num,#sheet do
  231.     local char = sheet[i]:sub(1,1)
  232.     if char == "E" or char == "|" or char == "-" or char == "e" then
  233.       return i-1
  234.     end
  235.   end
  236.   return false
  237. end
  238.  
  239. function findNote(sheet,durationLine)
  240.   local str = sheet[durationLine]
  241.   local searchFrom = 1
  242.   while true do
  243.     local start, stop = str:find("%g+",searchFrom)
  244.     if not start then
  245.         break
  246.     end
  247.     local charDuration = str:sub(start,stop)
  248.     local noteCount = 0
  249.     local strNote = ""
  250.     for i = 1,6 do
  251.       local charNum = sheet[durationLine+i]:sub(start,start)
  252.       if charNum ~= "-" and charNum ~= "x" then
  253.         --L exception
  254.         if charNum == "L" then
  255.           --L's not played for now
  256.           strNote = 0
  257.           --charNum = Note.lastNote[i]
  258.         end
  259.         strNote = strNote .. tostring(i) .. charNum ..charDuration.." "
  260.         Note.lastNote[i] = charNum
  261.         noteCount = noteCount + 1
  262.       end
  263.     end
  264.     local broadcast = ""
  265.     if noteCount > 1 then
  266.       for word in strNote:gmatch("%g+") do
  267.         --print(strNote)
  268.         broadcast = broadcast .. getExec(strNote)
  269.       end
  270.     else
  271.       --print(strNote)
  272.       broadcast = broadcast .. getExec(strNote)
  273.     end
  274.     --print(broadcast)
  275.     m.broadcast(2412,broadcast)
  276.     --print(getDuration(strNote))
  277.     os.sleep(getDuration(strNote))    
  278.     searchFrom = stop+1
  279.   end
  280. end
  281.  
  282. function main()
  283.   sheet = tabulateFile(args)
  284.   Note:capo(capo)
  285.  
  286.   local start = 1
  287.   while true do
  288.     local durationLine = findMeasure(sheet,start)
  289.     if not durationLine then
  290.       break
  291.     end
  292.     for i=0,7 do
  293.         print(sheet[durationLine+i])
  294.     end
  295.     findNote(sheet,durationLine)
  296.     start = durationLine + 7
  297.   end
  298. end
  299.  
  300. --addGlobals()
  301. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement