Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local computer = require("computer")
- local fs = require("filesystem")
- local serial = require("serialization")
- local term = require("term")
- local event = require("event")
- local component = require("component")
- local gpu = component.gpu
- local note = component.note_block
- a = {...}
- filename = "c/songs/"..a[1]
- timeSig = tonumber(a[2])
- detail = tonumber(a[3])
- currentBar = 1
- bpm = 120
- if not fs.isDirectory("c/songs") then fs.makeDirectory("c/songs") end
- if timeSig == nil then timeSig = 4 end
- if bpm == nil then bpm = 120 end
- if detail == nil then detail = 4 end
- if detail == nil then detail = 4 end
- function newScore()
- score = nil
- score = {}
- score.bpm = bpm
- barCount = 0
- end
- function loadScore(filepath)
- file = io.open(filepath, "r")
- score = serial.unserialize(file:read("*all"))
- file:close()
- barCount = score.barCount
- bpm = score.bpm
- end
- function saveScore()
- score.barCount = barCount
- score.bpm = bpm
- file = io.open(filename, "w")
- file:write(serial.serialize(score))
- file:close()
- end
- function fixTempo(beats)
- tempo = 60 / beats
- tempo = tempo / detail
- gpu.setBackground(0x000000)
- gpu.setForeground(0xFFFFFF)
- gpu.set(1, y, currentBar.."/"..barCount.." "..bpm.." BPM")
- end
- function addBar(beats)
- barCount = barCount + 1
- score[barCount] = {}
- for i = 1, beats * detail do
- score[barCount][i] = "rest"
- end
- end
- function playNote(note)
- note.trigger(note)
- end
- function noteCaller()
- octCount = 0
- noteCount = 0
- noteString = "A1BC2D3EF4G5"
- notePos = 0
- noteTab = {}
- for i = 1, 25 do
- notePos = notePos + 1
- noteCount = noteCount + 1
- noteVal = string.sub(noteString, notePos, notePos)
- if noteVal == "1" then
- noteVal = "A#"
- elseif noteVal == "2" then
- noteVal = "C#"
- elseif noteVal == "3" then
- noteVal = "D#"
- elseif noteVal == "4" then
- noteVal = "F#"
- elseif noteVal == "5" then
- noteVal = "G#"
- end
- label = noteVal..octCount
- noteTab[noteCount] = {}
- noteTab[noteCount]["label"] = label
- noteTab[noteCount]["note"] = i
- if noteVal == "G#" then
- notePos = 0
- octCount = octCount + 1
- end
- end
- end
- function addButton(label, bType, xPos, yPos, w, h, col1, col2, retVal, retVal2)
- if buttonTab == nil then
- buttonTab = {}
- buttonCount = 0
- end
- buttonCount = buttonCount + 1
- buttonTab[buttonCount] = {
- label = label,
- bType = bType,
- xPos = xPos,
- yPos = yPos,
- width = w,
- height = h,
- colour = col1,
- pCol = col1,
- tCol = col2,
- retVal = retVal,
- retVal2 = retVal2,
- active = false,
- }
- end
- function initKeys()
- x, y = gpu.getResolution()
- bWidth = 4
- yStart = y - 15
- for i = 1, #noteTab do
- if string.sub(noteTab[i]["label"], 2, 2) == "#" then
- col = 0x000000
- tCol = 0xFFFFFF
- pCol = 0xFF0000
- bCol = 0x0000FF
- pTCol = 0x000000
- else
- col = 0xFFFFFF
- tCol = 0x000000
- pCol = 0xFF6666
- bCol = 0x6666FF
- pTCol = 0x000000
- end
- addButton(noteTab[i]["label"], "note", 1, yStart - i, 10, 1, col, tCol, noteTab[i]["note"])
- for j = 1, timeSig * detail do
- if j % detail == 1 then
- addButton("[<>]", "pad", 11 + (bWidth), yStart - i, 3, 1, bCol, pTCol, j, noteTab[i]["note"])
- else
- addButton("[<>]", "pad", 11 + (bWidth), yStart - i, 3, 1, pCol, pTCol, j, noteTab[i]["note"])
- end
- if j == timeSig * detail then
- bWidth = 4
- else
- bWidth = bWidth + 4
- end
- end
- end
- end
- function drawScreen(bar)
- gpu.setBackground(0x000000)
- term.clear()
- for i = 1, #buttonTab do
- gpu.setBackground(buttonTab[i]["colour"])
- gpu.setForeground(buttonTab[i]["tCol"])
- if buttonTab[i]["bType"] ~= "pad" then
- gpu.fill(buttonTab[i]["xPos"], buttonTab[i]["yPos"], buttonTab[i]["width"], buttonTab[i]["height"], " ")
- offset = math.floor((buttonTab[i]["width"] - #buttonTab[i]["label"]) / 2)
- if buttonTab[i]["height"] > 1 then
- yOffset = math.floor((buttonTab[i]["height"] /2))
- gpu.set(buttonTab[i]["xPos"] + offset, buttonTab[i]["yPos"] + yOffset, buttonTab[i]["label"])
- else
- gpu.set(buttonTab[i]["xPos"] + offset, buttonTab[i]["yPos"], buttonTab[i]["label"])
- end
- else
- if score[bar][buttonTab[i]["retVal"]] == buttonTab[i]["retVal2"] then
- buttonTab[i]["label"] = "[><]"
- buttonTab[i]["active"] = true
- buttonTab[i]["colour"] = 0x66FF66
- else
- buttonTab[i]["label"] = "[<>]"
- buttonTab[i]["active"] = true
- buttonTab[i]["colour"] = buttonTab[i]["pCol"]
- end
- gpu.setBackground(buttonTab[i]["colour"])
- gpu.set(buttonTab[i]["xPos"], buttonTab[i]["yPos"], buttonTab[i]["label"])
- end
- end
- gpu.setBackground(0x000000)
- gpu.setForeground(0xFFFFFF)
- gpu.set(1, y, currentBar.."/"..barCount.." "..bpm.." BPM")
- end
- function play()
- for j = 1, #score do
- for k = 1, #score[j] do
- if score[j][k] ~= "rest" then
- note.trigger(score[j][k])
- end
- ev = event.pull(tempo, _, ev)
- if ev == "touch" then
- return true
- end
- end
- end
- end
- function run()
- ev, sa, p1, p2, p3, p4 = event.pull(.1, _, ev, sa, p1, p2, p3, p4)
- if ev == "key_down" then
- running = false
- return
- elseif ev == "touch" or ev =="drag" then
- for i = 1, #buttonTab do
- if p1 >= buttonTab[i]["xPos"] and p1 <= buttonTab[i]["xPos"] + buttonTab[i]["width"] then
- if p2 >= buttonTab[i]["yPos"] and p2 <= buttonTab[i]["yPos"] + (buttonTab[i]["height"] - 1) then
- if buttonTab[i]["bType"] == "note" then
- gpu.setBackground(0x66FF66)
- gpu.fill(buttonTab[i]["xPos"], buttonTab[i]["yPos"], buttonTab[i]["width"], buttonTab[i]["height"], " ")
- note.trigger(buttonTab[i]["retVal"])
- gpu.setBackground(buttonTab[i]["colour"])
- gpu.setForeground(buttonTab[i]["tCol"])
- gpu.fill(buttonTab[i]["xPos"], buttonTab[i]["yPos"], buttonTab[i]["width"], buttonTab[i]["height"], " ")
- offset = math.floor((buttonTab[i]["width"] - #buttonTab[i]["label"]) / 2)
- gpu.set(buttonTab[i]["xPos"] + offset, buttonTab[i]["yPos"], buttonTab[i]["label"])
- return
- elseif buttonTab[i]["bType"] == "pad" then
- buttonTab[i]["active"] = not buttonTab[i]["active"]
- if buttonTab[i]["active"] then
- buttonTab[i]["colour"] = 0x66FF66
- buttonTab[i]["label"] = "[><]"
- score[currentBar][buttonTab[i]["retVal"]] = buttonTab[i]["retVal2"]
- note.trigger(buttonTab[i]["retVal2"])
- else
- buttonTab[i]["colour"] = buttonTab[i]["pCol"]
- buttonTab[i]["label"] = "[<>]"
- score[currentBar][buttonTab[i]["retVal"]] = "rest"
- end
- gpu.setBackground(buttonTab[i]["colour"])
- gpu.setForeground(buttonTab[i]["tCol"])
- gpu.set(buttonTab[i]["xPos"], buttonTab[i]["yPos"], buttonTab[i]["label"])
- elseif buttonTab[i]["bType"] == "save" then
- saveScore()
- elseif buttonTab[i]["bType"] == "loop" then
- if buttonTab[i]["active"] then
- loopBool = false
- buttonTab[i]["active"] = false
- else
- loopBool = true
- buttonTab[i]["active"] = true
- end
- elseif buttonTab[i]["bType"] == "play" then
- if loopBool then
- while true do
- if play() then return end
- end
- else
- play()
- end
- elseif buttonTab[i]["bType"] == "<<" then
- if currentBar > 1 then currentBar = currentBar - 1 end
- drawScreen(currentBar)
- elseif buttonTab[i]["bType"] == ">>" then
- if currentBar < barCount then
- currentBar = currentBar + 1
- drawScreen(currentBar)
- else
- addBar(timeSig)
- currentBar = currentBar + 1
- drawScreen(currentBar)
- end
- elseif buttonTab[i]["bType"] == "^" then
- bpm = bpm + 1
- fixTempo(bpm)
- elseif buttonTab[i]["bType"] == "v" then
- bpm = bpm - 1
- fixTempo(bpm)
- end
- end
- end
- end
- end
- end
- noteCaller()
- initKeys()
- if fs.exists(filename) then
- loadScore(filename)
- else
- newScore()
- end
- addBar(timeSig)
- currentBar = 1
- fixTempo(bpm)
- addButton("Save", "save", 1, 1, 10, 3, 0xFFFFFF, 0x000000)
- addButton("Loop", "loop", 21, 1, 10, 3, 0x00FFFF, 0x000000)
- addButton("Play", "play", 31, 1, 10, 3, 0x66FF66, 0x000000)
- addButton("<<", "<<", 41, 1, 10, 3, 0x6666FF, 0x000000)
- addButton(">>", ">>", 51, 1, 10, 3, 0x6666FF, 0x000000)
- addButton("^", "^", 61, 1, 10, 3, 0x66FF66, 0x000000)
- addButton("v", "v", 71, 1, 10, 3, 0x66FF66, 0x000000)
- drawScreen(currentBar)
- running = true
- while running do
- run()
- end
- gpu.setBackground(0x000000)
- gpu.setForeground(0xFFFFFF)
- term.clear()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement