Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local args = ...
- filesystem = require("filesystem")
- component = require("component")
- computer = require("computer")
- m = component.proxy(component.list("modem")())
- m.open(2412)
- function addGlobals()
- Computer = {}
- Computer.beep = function(frequency,duration)
- print("Computer.beep("..tostring(frequency)..", "..tostring(duration)..")")
- end
- end
- function readfile(filename)
- local f = io.open(filename,'r')
- local str = f:read("*a")
- f:close()
- return str
- end
- tuning = {'E4','B3','G3','D3','A2','E2'}
- tempo = 120
- capo = 0
- signature = "4/4"
- Note = {}
- Batch = {}
- song = {}
- duration = {}
- duration.W = 4
- duration.H = 2
- duration.Q = 1
- duration.E = .5
- duration.S = .25
- duration.T = .33
- duration['W.'] = 6
- duration['H.'] = 3
- duration['Q.'] = 1.5
- duration['E.'] = .75
- duration['S.'] = .375
- duration['T.'] = .495
- freq = {} --GLOBAL
- freq['C2'] = 65.41
- freq['C#2'] = 69.30
- freq['D2'] = 73.42
- freq['D#2'] = 77.78
- freq['E2'] = 82.41
- freq['F2'] = 87.31
- freq['F#2'] = 92.50
- freq['G2'] = 98.00
- freq['G#2'] = 103.83
- freq['A2'] = 110.00
- freq['A#2'] = 116.54
- freq['B2'] = 123.47
- freq['C3'] = 130.81
- freq['C#3'] = 138.59
- freq['D3'] = 146.83
- freq['D#3'] = 155.56
- freq['E3'] = 164.81
- freq['F3'] = 174.61
- freq['F#3'] = 185.00
- freq['G3'] = 196.00
- freq['G#3'] = 207.65
- freq['A3'] = 220.00
- freq['A#3'] = 233.08
- freq['B3'] = 246.94
- freq['C4'] = 261.63
- freq['C#4'] = 277.18
- freq['D4'] = 293.66
- freq['D#4'] = 311.13
- freq['E4'] = 329.63
- freq['F4'] = 349.23
- freq['F#4'] = 369.99
- freq['G4'] = 392.00
- freq['G#4'] = 415.30
- freq['A4'] = 440.00
- freq['A#4'] = 466.16
- freq['B4'] = 493.88
- freq['C5'] = 523.25
- freq['C#5'] = 554.37
- freq['D5'] = 587.33
- freq['D#5'] = 622.25
- freq['E5'] = 659.25
- freq['F5'] = 698.46
- freq['F#5'] = 739.99
- freq['G5'] = 783.99
- freq['G#5'] = 830.61
- freq['A5'] = 880.00
- freq['A#5'] = 932.33
- freq['B5'] = 987.77
- freq['C6'] = 1046.50
- freq['C#6'] = 1108.73
- freq['D6'] = 1174.66
- freq['D#6'] = 1244.51
- freq['E6'] = 1318.51
- freq['F6'] = 1396.91
- freq['F#6'] = 1479.98
- freq['G6'] = 1567.98
- freq['G#6'] = 1661.22
- freq['A6'] = 1760.00
- freq['A#6'] = 1864.66
- freq['B6'] = 1975.53
- freq['C7'] = 2093.00
- Note.alphabet = {'C','C#','D','D#','E','F','F#','G','G#','A','A#','B'}
- Note.lastNote = {0,0,0,0,0,0}
- Note.fromHexadecimal = {
- ['A'] = 10,
- ['B'] = 11,
- ['C'] = 12,
- ['D'] = 13,
- ['E'] = 14,
- ['F'] = 15,
- }
- Note.toHexadecimal = {
- [10] = "A",
- [11] = "B",
- [12] = "C",
- [13] = "D",
- [14] = "E",
- [15] = "F",
- }
- function Note:new(ithStr,ithFret,fracNote)
- o = {}
- o.ithStr = tonumber(ithStr)
- o.ithFret = tonumber(ithFret) or Note.fromHexadecimal[ithFret] or Note.lastNote[ithStr]
- o.fracNote = fracNote
- o.string = ithStr..ithFret..fracNote
- setmetatable(o,self)
- self.__index = self
- --Note.lastNote[ithStr] = ithFret
- return o
- end
- function Note:getNote()
- --requires access to tuning table
- local strNote = tuning[self.ithStr]
- io.write(strNote)
- strNote = self:halfStep(strNote,self.ithFret)
- io.write(",")
- io.write(self.ithFret)
- io.write("->")
- print(strNote)
- return strNote
- end
- function Note:getFreq()
- return freq[self:getNote()]
- end
- function Note:getDuration()
- local val = duration[self.fracNote]
- if not val then
- val = 1
- end
- return val*(60/tempo)
- end
- function Note:halfStep(strNote,numReps)
- --ie takes a strNote: "A#" and moves it up numReps: 4 half steps
- if numReps == 0 then
- return strNote
- end
- local letter = strNote:sub(1,#strNote-1)
- local octave = strNote:sub(#strNote)
- local key = table.getKey(self.alphabet,letter)
- local index = key + numReps
- local octave = tonumber(octave) + math.floor(index/#self.alphabet)
- index = index%#self.alphabet
- if index == 0 then
- index = 12
- end
- return self.alphabet[index]..tostring(octave)
- end
- function Note:capo(num)
- for i = 1,#tuning do
- tuning[i] = self:halfStep(tuning[i],num)
- end
- end
- function table:getKey(value) --GLOBAL
- for k,v in pairs(self) do
- if value == v then
- return k
- end
- end
- end
- function Batch:new(status)
- o = {}
- o.status = status
- o.string = ""
- o.duration = 0
- setmetatable(o,self)
- self.__index = self
- return o
- end
- function Batch:insert(strNote)
- self.string = self.string..getExec(strNote)
- end
- lastNote = {0,0,0,0,0,0}
- function getExec(strNote)
- local ithStr = strNote:sub(1,1)
- local ithFret = strNote:sub(2,2)
- local duration = strNote:sub(3,3)
- local addDot = strNote:sub(4,4) == '.'
- if addDot then
- duration = duration..'.'
- end
- local note = Note:new(ithStr,ithFret,duration)
- if ithStr == "0" then
- return "os.sleep("..tostring(note:getDuration())..") "
- else
- return "computer.beep("..tostring(note:getFreq())..","..tostring(note:getDuration())..") "
- end
- end
- function getDuration(strNote)
- local stop = 3
- if strNote:sub(1,1) == '{' then
- stop = stop + 1
- end
- if strNote:sub(stop+1,stop+1) == "." then
- return (duration[strNote:sub(stop,stop+1)] or 1)*(60/tempo)
- else
- return (duration[strNote:sub(stop,stop)] or 1)*(60/tempo)
- end
- end
- function tabulateFile(filename)
- local table = {}
- local iter = 1
- for line in io.lines(filename) do
- table[iter] = line
- iter = iter + 1
- end
- return table
- end
- function findMeasure(sheet,num)
- for i = num,#sheet do
- local char = sheet[i]:sub(1,1)
- if char == "E" or char == "|" or char == "-" or char == "e" then
- return i-1
- end
- end
- return false
- end
- function findNote(sheet,durationLine)
- local str = sheet[durationLine]
- local searchFrom = 1
- while true do
- local start, stop = str:find("%g+",searchFrom)
- if not start then
- break
- end
- local charDuration = str:sub(start,stop)
- local noteCount = 0
- local strNote = ""
- for i = 1,6 do
- local charNum = sheet[durationLine+i]:sub(start,start)
- if charNum ~= "-" then
- --L handler
- if charNum == "L" then
- --charNum = Note.lastNote[i]
- ithStr = 0
- end
- --double digit handler
- if start > 1 and sheet[durationLine+i]:sub(start-1,start-1)~="-" then
- io.write()
- charNum = tostring(sheet[durationLine+i]:sub(start-1,start-1))..tostring(charNum)
- charNum = Note.toHexadecimal[tonumber(charNum)]
- print(charNum)
- end
- strNote = strNote .. tostring(i) .. charNum ..charDuration.." "
- Note.lastNote[i] = charNum
- noteCount = noteCount + 1
- end
- end
- local broadcast = ""
- if noteCount > 1 then
- for word in strNote:gmatch("%g+") do
- --print(word)
- print(strNote)
- broadcast = broadcast .. getExec(word)
- end
- else
- --print(strNote)
- print(strNote)
- broadcast = broadcast .. getExec(strNote)
- end
- print(broadcast)
- m.broadcast(2412,broadcast)
- print(getDuration(strNote))
- os.sleep(getDuration(strNote))
- searchFrom = stop+1
- end
- end
- function main()
- sheet = tabulateFile(args)
- Note:capo(capo)
- local start = 1
- while true do
- local durationLine = findMeasure(sheet,start)
- if not durationLine then
- break
- end
- findNote(sheet,durationLine)
- start = durationLine + 7
- end
- end
- --addGlobals()
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement