Advertisement
guitarplayer616

SheetReaderReworkWIP

Dec 16th, 2019
381
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.29 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. tempo = 120
  24. capo = 0
  25. signature = "4/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. Note.fromHexadecimal = {
  111.   ['A'] = 10,
  112.   ['B'] = 11,
  113.   ['C'] = 12,
  114.   ['D'] = 13,
  115.   ['E'] = 14,
  116.   ['F'] = 15,
  117. }
  118. Note.toHexadecimal = {
  119.   [10] = "A",
  120.   [11] = "B",
  121.   [12] = "C",
  122.   [13] = "D",
  123.   [14] = "E",
  124.   [15] = "F",
  125. }
  126.  
  127. function Note:new(ithStr,ithFret,fracNote)
  128.   o = {}
  129.   o.ithStr = tonumber(ithStr)
  130.   o.ithFret = tonumber(ithFret) or Note.fromHexadecimal[ithFret] or Note.lastNote[ithStr]
  131.   o.fracNote = fracNote
  132.   o.string = ithStr..ithFret..fracNote
  133.   setmetatable(o,self)
  134.   self.__index = self
  135.   --Note.lastNote[ithStr] = ithFret
  136.   return o
  137. end
  138.  
  139. function Note:getNote()
  140.   --requires access to tuning table
  141.   local strNote = tuning[self.ithStr]
  142.   io.write(strNote)
  143.   strNote = self:halfStep(strNote,self.ithFret)
  144.   io.write(",")
  145.   io.write(self.ithFret)
  146.   io.write("->")
  147.   print(strNote)
  148.   return strNote
  149. end
  150.  
  151. function Note:getFreq()
  152.   return freq[self:getNote()]
  153. end
  154.  
  155. function Note:getDuration()
  156.   local val = duration[self.fracNote]
  157.   if not val then
  158.     val = 1
  159.   end
  160.   return val*(60/tempo)
  161. end
  162.  
  163. function Note:halfStep(strNote,numReps)
  164.   --ie takes a strNote: "A#" and moves it up numReps: 4 half steps
  165.   if numReps == 0 then
  166.     return strNote
  167.   end
  168.   local letter = strNote:sub(1,#strNote-1)
  169.   local octave = strNote:sub(#strNote)
  170.   local key = table.getKey(self.alphabet,letter)
  171.   local index = key + numReps
  172.   local octave = tonumber(octave) + math.floor(index/#self.alphabet)
  173.   index = index%#self.alphabet
  174.   if index == 0 then
  175.     index = 12
  176.   end
  177.   return self.alphabet[index]..tostring(octave)
  178. end
  179.  
  180. function Note:capo(num)
  181.   for i = 1,#tuning do
  182.     tuning[i] = self:halfStep(tuning[i],num)
  183.   end
  184. end
  185.  
  186. function table:getKey(value) --GLOBAL
  187.   for k,v in pairs(self) do
  188.     if value == v then
  189.       return k
  190.     end
  191.   end
  192. end
  193.  
  194. function Batch:new(status)
  195.   o = {}
  196.   o.status = status
  197.   o.string = ""
  198.   o.duration = 0
  199.   setmetatable(o,self)
  200.   self.__index = self
  201.   return o
  202. end
  203.  
  204. function Batch:insert(strNote)
  205.   self.string = self.string..getExec(strNote)
  206. end
  207.  
  208. lastNote = {0,0,0,0,0,0}
  209.  
  210. function getExec(strNote)
  211.   local ithStr = strNote:sub(1,1)
  212.   local ithFret = strNote:sub(2,2)
  213.   local duration = strNote:sub(3,3)
  214.   local addDot = strNote:sub(4,4) == '.'
  215.   if addDot then
  216.     duration = duration..'.'
  217.   end
  218.  
  219.   local note = Note:new(ithStr,ithFret,duration)
  220.  
  221.   if ithStr == "0" then
  222.     return "os.sleep("..tostring(note:getDuration())..") "
  223.   else
  224.     return "computer.beep("..tostring(note:getFreq())..","..tostring(note:getDuration())..") "
  225.   end
  226. end
  227.  
  228. function getDuration(strNote)
  229.   local stop = 3
  230.   if strNote:sub(1,1) == '{' then
  231.     stop = stop + 1
  232.   end
  233.   if strNote:sub(stop+1,stop+1) == "." then
  234.     return (duration[strNote:sub(stop,stop+1)] or 1)*(60/tempo)
  235.   else
  236.     return (duration[strNote:sub(stop,stop)] or 1)*(60/tempo)
  237.   end
  238. end
  239.  
  240. function tabulateFile(filename)
  241.   local table = {}
  242.   local iter = 1
  243.   for line in io.lines(filename) do
  244.     table[iter] = line
  245.     iter = iter + 1
  246.   end
  247.   return table
  248. end
  249.  
  250. function findMeasure(sheet,num)
  251.   for i = num,#sheet do
  252.     local char = sheet[i]:sub(1,1)
  253.     if char == "E" or char == "|" or char == "-" or char == "e" then
  254.       return i-1
  255.     end
  256.   end
  257.   return false
  258. end
  259.  
  260. function findNote(sheet,durationLine)
  261.   local str = sheet[durationLine]
  262.   local searchFrom = 1
  263.   while true do
  264.     local start, stop = str:find("%g+",searchFrom)
  265.     if not start then
  266.         break
  267.     end
  268.     local charDuration = str:sub(start,stop)
  269.     local noteCount = 0
  270.     local strNote = ""
  271.     for i = 1,6 do
  272.       local charNum = sheet[durationLine+i]:sub(start,start)
  273.       if charNum ~= "-" then
  274.         --L handler
  275.         if charNum == "L" then
  276.           --charNum = Note.lastNote[i]
  277.           ithStr = 0
  278.         end
  279.         --double digit handler
  280.         if start > 1 and sheet[durationLine+i]:sub(start-1,start-1)~="-" then
  281.           io.write()
  282.           charNum = tostring(sheet[durationLine+i]:sub(start-1,start-1))..tostring(charNum)
  283.           charNum = Note.toHexadecimal[tonumber(charNum)]
  284.           print(charNum)
  285.         end
  286.        
  287.         strNote = strNote .. tostring(i) .. charNum ..charDuration.." "
  288.         Note.lastNote[i] = charNum
  289.         noteCount = noteCount + 1
  290.       end
  291.     end
  292.     local broadcast = ""
  293.     if noteCount > 1 then
  294.       for word in strNote:gmatch("%g+") do
  295.         --print(word)
  296.         print(strNote)
  297.         broadcast = broadcast .. getExec(word)
  298.       end
  299.     else
  300.       --print(strNote)
  301.       print(strNote)
  302.       broadcast = broadcast .. getExec(strNote)
  303.     end
  304.     print(broadcast)
  305.     m.broadcast(2412,broadcast)
  306.     print(getDuration(strNote))
  307.     os.sleep(getDuration(strNote))    
  308.     searchFrom = stop+1
  309.   end
  310. end
  311.  
  312. function main()
  313.   sheet = tabulateFile(args)
  314.   Note:capo(capo)
  315.  
  316.   local start = 1
  317.   while true do
  318.     local durationLine = findMeasure(sheet,start)
  319.     if not durationLine then
  320.       break
  321.     end
  322.     findNote(sheet,durationLine)
  323.     start = durationLine + 7
  324.   end
  325. end
  326.  
  327. --addGlobals()
  328. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement