Advertisement
guitarplayer616

OpenMusicDuo

Dec 13th, 2019
395
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.84 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")()) --GLOBAL
  6. m.open(2412)
  7.  
  8. function readfile(filename)
  9.     local f = io.open(filename,'r')
  10.     local str = f:read("*a")
  11.     f:close()
  12.     return str
  13. end
  14.  
  15. sheet = readfile(args) --GLOBAL
  16.  
  17. tuning = {'E4','B3','G3','D3','A2','E2'} --GLOBAL
  18. tempo = 95 --GLOBAL
  19. signature = "8/4" --GLOBAL
  20.  
  21. Note = {} --GLOBAL
  22. Batch = {} --GLOBAL
  23. song = {} --GLOBAL
  24.  
  25. duration = {} --GLOBAL
  26. duration.W = 4
  27. duration.H = 2
  28. duration.Q = 1
  29. duration.E = .5
  30. duration.S = .25
  31. duration.T = .334
  32.  
  33. freq = {} --GLOBAL
  34. freq['C2'] = 65.41
  35. freq['C#2'] = 69.30
  36. freq['D2'] = 73.42
  37. freq['D#2'] = 77.78
  38. freq['E2'] = 82.41
  39. freq['F2'] = 87.31
  40. freq['F#2'] = 92.50
  41. freq['G2'] = 98.00
  42. freq['G#2'] = 103.83
  43. freq['A2'] = 110.00
  44. freq['A#2'] = 116.54
  45. freq['B2'] = 123.47
  46. freq['C3'] = 130.81
  47. freq['C#3'] = 138.59
  48. freq['D3'] = 146.83
  49. freq['D#3'] = 155.56
  50. freq['E3'] = 164.81
  51. freq['F3'] = 174.61
  52. freq['F#3'] = 185.00
  53. freq['G3'] = 196.00
  54. freq['G#3'] = 207.65
  55. freq['A3'] = 220.00
  56. freq['A#3'] = 233.08
  57. freq['B3'] = 246.94
  58. freq['C4'] = 261.63
  59. freq['C#4'] = 277.18
  60. freq['D4'] = 293.66
  61. freq['D#4'] = 311.13
  62. freq['E4'] = 329.63
  63. freq['F4'] = 349.23
  64. freq['F#4'] = 369.99
  65. freq['G4'] = 392.00
  66. freq['G#4'] = 415.30
  67. freq['A4'] = 440.00
  68. freq['A#4'] = 466.16
  69. freq['B4'] = 493.88
  70. freq['C5'] = 523.25
  71. freq['C#5'] = 554.37
  72. freq['D5'] = 587.33
  73. freq['D#5'] = 622.25
  74. freq['E5'] = 659.25
  75. freq['F5'] = 698.46
  76. freq['F#5'] = 739.99
  77. freq['G5'] = 783.99
  78. freq['G#5'] = 830.61
  79. freq['A5'] = 880.00
  80. freq['A#5'] = 932.33
  81. freq['B5'] = 987.77
  82. freq['C6'] = 1046.50
  83. freq['C#6'] = 1108.73
  84. freq['D6'] = 1174.66
  85. freq['D#6'] = 1244.51
  86. freq['E6'] = 1318.51
  87. freq['F6'] = 1396.91
  88. freq['F#6'] = 1479.98
  89. freq['G6'] = 1567.98
  90. freq['G#6'] = 1661.22
  91. freq['A6'] = 1760.00
  92. freq['A#6'] = 1864.66
  93. freq['B6'] = 1975.53
  94. freq['C7'] = 2093.00
  95.  
  96. Note.alphabet = {'C','C#','D','D#','E','F','F#','G','G#','A','A#','B'}
  97. Note.hexadecimal = {['A'] = 10, ['B'] = 11, ['C'] = 12, ['D'] = 13, ['E'] = 14, ['F'] = 15}
  98.  
  99. function Note:new(ithStr,ithFret,fracNote)
  100.     o = {}
  101.     o.ithStr = tonumber(ithStr)
  102.     o.ithFret = tonumber(ithFret) or self.hexadecimal[ithFret]
  103.     o.fracNote = fracNote
  104.     o.string = ithStr..ithFret..fracNote
  105.     setmetatable(o,self)
  106.     self.__index = self
  107.     return o
  108. end
  109.  
  110. function Note:getNote()
  111.     --requires access to tuning table
  112.     local strNote = tuning[self.ithStr]
  113.     strNote = self:halfStep(strNote,self.ithFret)
  114.     return strNote
  115. end
  116.  
  117. function Note:getFreq()
  118.     return freq[self:getNote()]
  119. end
  120.  
  121. function Note:getDuration()
  122.     return duration[self.fracNote]*(60/tempo)
  123. end
  124.  
  125. function Note:halfStep(strNote,numReps)
  126.     if numReps == 0 then
  127.         return strNote
  128.     end
  129.     local letter = strNote:sub(1,#strNote-1)
  130.     local octave = strNote:sub(#strNote)
  131.     local key = table.getKey(self.alphabet,letter)
  132.     local index = key + numReps
  133.     local octave = octave + math.floor(index/#self.alphabet)
  134.     index = index%#self.alphabet
  135.     if index == 0 then
  136.         index = 12
  137.     end
  138.     return self.alphabet[index]..octave
  139. end
  140.  
  141. function table:getKey(value) --GLOBAL
  142.     for k,v in pairs(self) do
  143.         if value == v then
  144.             return k
  145.         end
  146.     end
  147. end
  148.  
  149. function Batch:new(status)
  150.     o = {}
  151.     o.status = status
  152.     o.string = ""
  153.     o.duration = 0
  154.     setmetatable(o,self)
  155.     self.__index = self
  156.     return o
  157. end
  158.  
  159. function Batch:insert(strNote)
  160.     self.string = self.string..getExec(strNote)
  161. end
  162.  
  163. function getExec(strNote) --GLOBAL
  164.     local note = Note:new(strNote:sub(1,1),strNote:sub(2,2),strNote:sub(3,3))
  165.     if strNote:sub(1,1) == "0" then
  166.         return "os.sleep("..tostring(note:getDuration())..") "
  167.     else
  168.         return "computer.beep("..tostring(note:getFreq())..","..tostring(note:getDuration())..") "
  169.     end
  170. end
  171.  
  172. function main() --GLOBAL
  173.     local measure = 0
  174.     local batch = Batch:new(false)
  175.     local measureTime = tonumber(signature:sub(1,1)) * (4/tonumber(signature:sub(#signature)))
  176.     for word in string.gmatch(sheet,'%g+') do
  177.         if word:sub(1,1)=="{" then
  178.             batch.status = true
  179.             batch.duration = duration[word:sub(#word)]
  180.             batch:insert(word:sub(2))
  181.            
  182.         elseif word:sub(#word)=="}" then
  183.             batch:insert(word:sub(1,#word-1))
  184.             m.broadcast(2412,batch.string)
  185.             print(batch.string)
  186.             batch.status = false
  187.             batch.string = ""
  188.             measure = measure + batch.duration
  189.             os.sleep(batch.duration*(60/tempo))
  190.            
  191.         elseif word == "|" then
  192.             if (measureTime-measure)>0 then
  193.                 m.broadcast(2412,"os.sleep("..tostring((measureTime-measure)*(60/tempo))..")")
  194.                 print(measureTime-measure)
  195.                 os.sleep((measureTime-measure)*(60/tempo))
  196.             end
  197.             measure = 0
  198.         else
  199.             if batch.status then
  200.                 batch:insert(word)
  201.             else
  202.                 print(getExec(word))
  203.                 measure = measure + duration[word:sub(3,3)]
  204.                 m.broadcast(2412,getExec(word))
  205.                 os.sleep(duration[word:sub(3,3)]*(60/tempo))
  206.             end
  207.         end
  208.     end
  209. end
  210.  
  211. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement