Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- Exposes a single function, playNote(instrument,note)
- where instrument is 0 for piano, 1 for bass drum, 2 for snare, 3 for clicks or 4 for bass guitar,
- and note is 0-24 in number of right-clicks.
- ]]--
- diskSide="left"
- mon = peripheral.wrap("top")
- nb = peripheral.wrap("right")
- version = "v1.0"
- mon.setTextScale(0.5)
- w,h = mon.getSize() -- 57,10
- wPos=0
- hPos=0
- char1=nil
- char2=nil
- instrument = nil
- piano={}
- drum={}
- snare={}
- clicks={}
- guitar={}
- tempo=5
- function printC(ph,text)
- tw,th = term.getSize()
- term.setCursorPos((tw/2)-(#text/2),ph)
- write(text)
- end
- function welcomeScreen()
- term.setTextColour(colours.yellow)
- printC(2,"Music Maker "..version)
- printC(3,"by fredthead")
- term.setTextColour(colours.white)
- printC(5,"Instructions")
- print("") print("")
- print("The 5 lines on the monitor control the different")
- print("instruments. From top to bottom: Piano, Bass Drum")
- print("Snare, Clicks and Bass Guitar.")
- print("")
- print("Right click on the small coloured boxes to")
- print("activate individual notes. Keep right clicking")
- print("to change the pitch. You can go up to 24.")
- print("")
- print("When you have composed a tune, click on play. You")
- print("can also adjust the tempo. It is advisable not to")
- print("make it too low or too high though.")
- end
- function greenNote(x,y,text1,text2)
- mon.setBackgroundColour(colours.green)
- mon.setCursorPos(x,y)
- mon.write(text1)
- mon.setCursorPos(x,y+1)
- mon.write(text2)
- mon.setBackgroundColour(colours.black)
- end
- function limeNote(x,y,text1,text2)
- mon.setBackgroundColour(colours.lime)
- mon.setCursorPos(x,y)
- mon.write(text1)
- mon.setCursorPos(x,y+1)
- mon.write(text2)
- mon.setBackgroundColour(colours.black)
- end
- function blueNote(x,y,text1,text2)
- mon.setBackgroundColour(colours.blue)
- mon.setCursorPos(x,y)
- mon.write(text1)
- mon.setCursorPos(x,y+1)
- mon.write(text2)
- mon.setBackgroundColour(colours.black)
- end
- function cyanNote(x,y,text1,text2)
- mon.setBackgroundColour(colours.cyan)
- mon.setCursorPos(x,y)
- mon.write(text1)
- mon.setCursorPos(x,y+1)
- mon.write(text2)
- mon.setBackgroundColour(colours.black)
- end
- function orangeNote(x,y,text1,text2)
- mon.setBackgroundColour(colours.orange)
- mon.setCursorPos(x,y)
- mon.write(text1)
- mon.setCursorPos(x,y+1)
- mon.write(text2)
- mon.setBackgroundColour(colours.black)
- end
- function redNote(x,y,text1,text2)
- mon.setBackgroundColour(colours.red)
- mon.setCursorPos(x,y)
- mon.write(text1)
- mon.setCursorPos(x,y+1)
- mon.write(text2)
- mon.setBackgroundColour(colours.black)
- end
- function greyNote(x,y,text1,text2)
- mon.setBackgroundColour(colours.grey)
- mon.setCursorPos(x,y)
- mon.write(text1)
- mon.setCursorPos(x,y+1)
- mon.write(text2)
- mon.setBackgroundColour(colours.black)
- end
- function lightGreyNote(x,y,text1,text2)
- mon.setBackgroundColour(colours.lightGrey)
- mon.setCursorPos(x,y)
- mon.write(text1)
- mon.setCursorPos(x,y+1)
- mon.write(text2)
- mon.setBackgroundColour(colours.black)
- end
- function purpleNote(x,y,text1,text2)
- mon.setBackgroundColour(colours.purple)
- mon.setCursorPos(x,y)
- mon.write(text1)
- mon.setCursorPos(x,y+1)
- mon.write(text2)
- mon.setBackgroundColour(colours.black)
- end
- function pinkNote(x,y,text1,text2)
- mon.setBackgroundColour(colours.pink)
- mon.setCursorPos(x,y)
- mon.write(text1)
- mon.setCursorPos(x,y+1)
- mon.write(text2)
- mon.setBackgroundColour(colours.black)
- end
- function drawNotes()
- --mon.clear()
- place=1
- for i=1,28 do
- if place==1 then
- char1="P" char2="N"
- else
- decodeTable(piano,place-1)
- end
- greenNote(place,1,char1,char2)
- place=place+2
- end
- place=2
- for i=1,28 do
- decodeTable(piano,place-1)
- limeNote(place,1,char1,char2)
- place=place+2
- end
- place=1
- for i=1,25 do
- if place==1 then
- char1="D" char2="M"
- else
- decodeTable(drum,place-1)
- end
- blueNote(place,3,char1,char2)
- place=place+2
- end
- place=2
- for i=1,25 do
- decodeTable(drum,place-1)
- cyanNote(place,3,char1,char2)
- place=place+2
- end
- place=1
- for i=1,25 do
- if place==1 then
- char1="S" char2="R"
- else
- decodeTable(snare,place-1)
- end
- redNote(place,5,char1,char2)
- place=place+2
- end
- place=2
- for i=1,25 do
- decodeTable(snare,place-1)
- orangeNote(place,5,char1,char2)
- place=place+2
- end
- place=1
- for i=1,25 do
- if place==1 then
- char1="C" char2="K"
- else
- decodeTable(clicks,place-1)
- end
- greyNote(place,7,char1,char2)
- place=place+2
- end
- place=2
- for i=1,25 do
- decodeTable(clicks,place-1)
- lightGreyNote(place,7,char1,char2)
- place=place+2
- end
- place=1
- for i=1,25 do
- if place==1 then
- char1="G" char2="T"
- else
- decodeTable(guitar,place-1)
- end
- purpleNote(place,9,char1,char2)
- place=place+2
- end
- place=2
- for i=1,25 do
- decodeTable(guitar,place-1)
- pinkNote(place,9,char1,char2)
- place=place+2
- end
- for i=1,10 do
- mon.setBackgroundColour(colours.black)
- mon.setCursorPos(50,i)
- mon.write(" ")
- end
- mon.setBackgroundColour(colours.orange)
- mon.setTextColour(colours.black)
- mon.setCursorPos(51,4)
- mon.write(" ")
- mon.setCursorPos(51,5)
- mon.write(" PLAY ")
- mon.setCursorPos(51,6)
- mon.write(" ")
- mon.setBackgroundColour(colours.yellow)
- mon.setCursorPos(51,1)
- mon.write(" ")
- mon.setCursorPos(51,2)
- mon.write(" TEMPO")
- mon.setCursorPos(51,3)
- mon.write(" UP DN")
- mon.setCursorPos(51,9)
- mon.write(" ")
- mon.setCursorPos(51,10)
- mon.write(" MENU ")
- mon.setBackgroundColour(colours.black)
- mon.setTextColour(colours.white)
- end
- function resetMusic()
- tempo=5
- piano = {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25}
- drum = {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25}
- snare = {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25}
- clicks = {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25}
- guitar = {25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25}
- end
- function decodeTable(tab,pos)
- local val = tab[pos]
- if val == nil then
- char1=" " char2=" "
- elseif val>=0 and val <= 9 then
- char1=tostring(0) char2=tostring(val)
- elseif val>=10 and val <= 19 then
- char1=tostring(1) char2=tostring(val-10)
- elseif val>=20 and val <= 24 then
- char1=tostring(2) char2=tostring(val-20)
- elseif val==25 then
- char1=" " char2=" "
- end
- end
- function addClick()
- local val= instrument[wPos-1]
- val= val+1
- if val == 26 then val = 0 end
- table.remove(instrument,wPos-1)
- table.insert(instrument,wPos-1,val)
- tempSave()
- return listen()
- end
- function drawTempo()
- mon.setTextColour(colours.orange)
- mon.setBackgroundColour(colours.yellow)
- mon.setCursorPos(51,1)
- mon.write(" ")
- mon.setCursorPos(54,1)
- if type(tempo)~="number" then
- for i,v in pairs(tempo) do
- tempo = v
- end
- end
- mon.write(tostring(tempo))
- mon.setBackgroundColour(colours.black)
- mon.setTextColour(colours.white)
- end
- function tempSave()
- local saveTable={{piano},{drum},{snare},{clicks},{guitar},tempo}
- dataToSave= textutils.serialize(saveTable)
- fs.delete("temp")
- fs.makeDir("temp")
- print(dataToSave)
- handle = fs.open("temp/tempFile","w")
- handle.write(dataToSave)
- handle.close()
- end
- function tempLoad()
- handle=fs.open("temp/tempFile","r")
- local fileLoadedTable = handle.readAll()
- handle.close()
- fileLoadedTable=textutils.unserialize(fileLoadedTable)
- piano =fileLoadedTable[1][1]
- drum =fileLoadedTable[2][1]
- snare =fileLoadedTable[3][1]
- clicks=fileLoadedTable[4][1]
- guitar=fileLoadedTable[5][1]
- tempo= fileLoadedTable[6]
- listen()
- end
- function overwrite()
- mon.setBackgroundColour(colours.yellow)
- mon.setTextColour(colours.black)
- mon.setCursorPos(20,4)
- mon.write(" ")
- mon.setCursorPos(20,5)
- mon.write(" OK NO ")
- mon.setCursorPos(20,6)
- mon.write(" ")
- mon.setBackgroundColour(colours.black)
- mon.setTextColour(colours.white)
- for i=4,6 do
- mon.setCursorPos(28,i) mon.write(" ")
- end
- while true do
- local event,p1,p2,p3 = os.pullEvent()
- if event=="monitor_touch" and p3 >=4 and p3 <= 6 then
- if p2 >=20 and p2 <= 27 then
- local saveTable={{piano},{drum},{snare},{clicks},{guitar},{tempo}}
- dataToSave= textutils.serialize(saveTable)
- if disk.isPresent(diskSide)==false then
- diskOps()
- end
- handle = fs.open("disk/saves/"..input,"w")
- handle.write(dataToSave)
- handle.close()
- mon.clear()
- mon.setCursorPos(16,2)
- mon.write("Music has been saved to disk")
- sleep(1)
- listen()
- elseif p2 >=31 and p2 <= 38 then
- save()
- end
- end
- end
- end
- function loadTheFile()
- if disk.isPresent(diskSide)==false then
- diskOps()
- end
- handle=fs.open("disk/saves/"..chooseFile,"r")
- local fileLoadedTable = handle.readAll()
- handle.close()
- fileLoadedTable=textutils.unserialize(fileLoadedTable)
- piano =fileLoadedTable[1][1]
- drum =fileLoadedTable[2][1]
- snare =fileLoadedTable[3][1]
- clicks=fileLoadedTable[4][1]
- guitar=fileLoadedTable[5][1]
- tempo= fileLoadedTable[6]
- for i = 9,19 do
- term.setCursorPos(1,i)
- write(string.rep(" ",w))
- end
- printC(9,chooseFile.." loaded")
- sleep(1)
- listen()
- end
- function load()
- mon.clear()
- if fs.exists("disk/saves")==false then
- mon.setCursorPos(16,2)
- mon.write("No save files on this disk")
- sleep(1.5)
- listen()
- else
- loadTab= fs.list("disk/saves")
- if #loadTab==0 or #loadTab=="nil" then
- mon.clear()
- mon.setCursorPos(16,2)
- mon.write("No save files on this disk")
- sleep(1.5)
- listen()
- else
- term.clear()
- term.setTextColour(colours.yellow)
- printC(2,"Music Maker "..version)
- printC(3,"by fredthead")
- term.setTextColour(colours.white)
- printC(5,"Enter a filename or type refresh or cancel")
- for i,v in pairs(loadTab) do
- if #loadTab <=10 then
- printC(i+8,v)
- elseif #loadTab >1 and #loadTab <= 20 and i <= 10 then
- term.setCursorPos(14,i+8)
- write(v)
- elseif #loadTab >10 and #loadTab <=20 and i > 10 then
- term.setCursorPos(30,i-2)
- write(v)
- elseif #loadTab >20 and #loadTab <=30 and i<=10 then
- term.setCursorPos(8,i+8)
- write(v)
- elseif #loadTab >20 and #loadTab <=30 and i > 10 and i<=20 then
- term.setCursorPos(22,i-2)
- write(v)
- elseif #loadTab >20 and #loadTab <=30 and i > 20 and i<=30 then
- term.setCursorPos(37,i-12)
- write(v)
- end
- end
- term.setCursorPos(19,7)
- write("> ")
- chooseFile=io.read()
- if chooseFile==string.lower("refresh") then load() end
- if chooseFile==string.lower("cancel") then
- listen()
- else
- for i=1,#loadTab do
- --print(loadTab[i])
- if chooseFile==loadTab[i] then
- loadTheFile()
- end
- end
- print("Unknown filename")
- sleep(1)
- load()
- end
- end
- end
- end
- function max30PerDisk()
- term.clear()
- printC(5,"Sorry, only 30 tracks per disk")
- sleep(1)
- menu()
- end
- function save()
- mon.clear()
- if fs.exists("disk/saves")==false then
- fs.makeDir("disk/saves")
- end
- saveNum = fs.list("disk/saves")
- if #saveNum > 29 then
- max30PerDisk()
- end
- mon.setCursorPos(16,2)
- mon.write("Enter a name for your music on")
- mon.setCursorPos(16,3)
- mon.write(" the terminal below")
- input = ""
- local count = 0
- local inputEntered=false
- term.clear()
- while inputEntered == false do
- term.setCursorPos(10,4)
- printC(4,"Please enter a filename")
- local event,p1,p2,p3 = os.pullEvent()
- if event=="char" and count < 11 then
- term.setCursorPos(20,6)
- input = input..p1
- count=count+1
- term.write(input)
- elseif event == "key" and p1==14 and count>0 then
- input=string.sub(input,1,(string.len(input)-1))
- term.setCursorPos(20,6)
- count=count-1
- term.write(input.." ")
- elseif event == "key" and p1==28 and input ~= "" then
- inputEntered=true
- term.clear()
- term.setCursorPos(20,4)
- print("Thank you")
- end
- end
- if fs.exists("disk/saves/"..input) == true then
- mon.clear()
- mon.setCursorPos(18,2)
- mon.write("File exists. Overwrite?")
- overwrite()
- else
- local saveTable={{piano},{drum},{snare},{clicks},{guitar},tempo}
- dataToSave= textutils.serialize(saveTable)
- if disk.isPresent(diskSide)==false then
- diskOps()
- end
- handle = fs.open("disk/saves/"..input,"w")
- handle.write(dataToSave)
- handle.close()
- mon.clear()
- mon.setCursorPos(16,2)
- mon.write("Music has been saved to disk")
- sleep(1)
- listen()
- end
- end
- function menu()
- mon.clear()
- mon.setBackgroundColour(colours.yellow)
- mon.setTextColour(colours.black)
- mon.setCursorPos(15,4)
- mon.write(" ")
- mon.setCursorPos(15,5)
- mon.write(" LOAD SAVE NEW ")
- mon.setCursorPos(15,6)
- mon.write(" ")
- mon.setCursorPos(51,9)
- mon.write(" ")
- mon.setCursorPos(51,10)
- mon.write(" BACK ")
- mon.setBackgroundColour(colours.black)
- mon.setTextColour(colours.white)
- for i=4,6 do
- mon.setCursorPos(23,i) mon.write(" ")
- end
- for i=4,6 do
- mon.setCursorPos(34,i) mon.write(" ")
- end
- while true do
- local event,p1,p2,p3 = os.pullEvent()
- if event=="monitor_touch" and p3 >=4 and p3 <= 6 then
- if p2 >=15 and p2 <= 22 then
- state="load"
- diskOps()
- --load()
- elseif p2 >=26 and p2 <= 33 then
- state="save"
- diskOps()
- --save()
- elseif p2 >=37 and p2 <=44 then
- --are you sure
- mon.clear()
- mon.setBackgroundColour(colours.yellow)
- mon.setTextColour(colours.black)
- mon.setCursorPos(20,4)
- mon.write(" ")
- mon.setCursorPos(20,5)
- mon.write(" OK NO ")
- mon.setCursorPos(20,6)
- mon.write(" ")
- mon.setBackgroundColour(colours.black)
- mon.setTextColour(colours.white)
- for i=4,6 do
- mon.setCursorPos(28,i) mon.write(" ")
- end
- while true do
- local event,p1,p2,p3 = os.pullEvent()
- if event=="monitor_touch" and p3 >=4 and p3 <= 6 then
- if p2 >=20 and p2 <= 27 then -- OK
- resetMusic()
- tempSave()
- listen()
- elseif p2 >=31 and p2 <= 38 then -- CANCEL
- listen()
- end
- end
- end
- end
- elseif event=="monitor_touch" and p3==9 or p3==10 then
- if p2 >= 51 and p2 <= 56 then -- BACK clicked
- listen()
- end
- end
- end
- end
- function diskOps()
- mon.clear()
- if disk.hasData("left")==false then
- mon.setCursorPos(16,2)
- mon.write("Please insert a floppy disk")
- mon.setBackgroundColour(colours.yellow)
- mon.setTextColour(colours.black)
- mon.setCursorPos(20,4)
- mon.write(" ")
- mon.setCursorPos(20,5)
- mon.write(" OK CANCEL ")
- mon.setCursorPos(20,6)
- mon.write(" ")
- mon.setBackgroundColour(colours.black)
- mon.setTextColour(colours.white)
- for i=4,6 do
- mon.setCursorPos(28,i) mon.write(" ")
- end
- while true do
- local event,p1,p2,p3 = os.pullEvent()
- if event=="monitor_touch" and p3 >=4 and p3 <= 6 then
- if p2 >=20 and p2 <= 27 then
- mon.clear()
- sleep(0.5)
- diskOps()
- elseif p2 >=31 and p2 <= 38 then
- listen()
- end
- end
- end
- else
- if state=="load" then
- load()
- elseif state=="save" then
- save()
- end
- end
- end
- function listen()
- term.clear()
- term.setCursorPos(1,1)
- welcomeScreen()
- drawNotes()
- drawTempo()
- repeat
- local event,p1,p2,p3 = os.pullEvent()
- if event=="monitor_touch" and p2 > 1 and p2 < 50 then
- --print("width "..p2..", height "..p3)
- wPos=p2
- hPos=p3
- if p3 == 1 or p3 == 2 then instrument = piano
- elseif p3==3 or p3==4 then instrument = drum
- elseif p3==5 or p3==6 then instrument = snare
- elseif p3==7 or p3==8 then instrument = clicks
- elseif p3==9 or p3==10 then instrument= guitar
- end
- return addClick()
- elseif event =="monitor_touch" and p2 >= 51 and p2 <= 53 and p3== 3 then
- tempo=tempo+1
- if tempo > 9 then tempo = 9 end
- if tempo < 1 then tempo = 1 end
- drawTempo()
- elseif event =="monitor_touch" and p2 >= 54 and p2 <= 56 and p3== 3 then
- tempo=tempo-1
- if tempo > 9 then tempo = 9 end
- if tempo < 1 then tempo = 1 end
- drawTempo()
- elseif event=="monitor_touch" and p2 >= 51 and p2 <= 56 and p3 >= 4 and p3 <= 6 then
- play()
- elseif event=="monitor_touch" and p2 >= 51 and p2 <= 56 and p3 >= 9 and p3 <= 10 then
- menu()
- end
- until event=="char" and p1==("x")
- end
- function play()
- mon.setTextColour(colours.white)
- mon.setBackgroundColour(colours.black)
- for i=1,10 do
- mon.setCursorPos(50,i)
- mon.write(" ")
- end
- mon.setCursorPos(54,2)
- mon.write("P")
- mon.setCursorPos(54,3)
- mon.write("L")
- mon.setCursorPos(54,4)
- mon.write("A")
- mon.setCursorPos(54,5)
- mon.write("Y")
- mon.setCursorPos(54,6)
- mon.write("I")
- mon.setCursorPos(54,7)
- mon.write("N")
- mon.setCursorPos(54,8)
- mon.write("G")
- mon.setBackgroundColour(colours.yellow)
- mon.setTextColour(colours.red)
- mon.setCursorPos(53,10)
- mon.write("STOP")
- mon.setTextColour(colours.white)
- mon.setBackgroundColour(colours.black)
- local noteCount=1
- local speed = ((10 - tempo)/10)/2
- playTimer=os.startTimer(speed)
- while noteCount < 49 do
- local event,p1,p2,p3 = os.pullEvent()
- if event=="timer" and playTimer==p1 then
- playTimer=os.startTimer(speed)
- if piano[noteCount] ~= 25 then nb.playNote(0,piano[noteCount]) end
- if drum[noteCount] ~= 25 then nb.playNote(1,drum[noteCount]) end
- if snare[noteCount] ~= 25 then nb.playNote(2,snare[noteCount]) end
- if clicks[noteCount] ~= 25 then nb.playNote(3,clicks[noteCount]) end
- if guitar[noteCount] ~= 25 then nb.playNote(4,guitar[noteCount]) end
- noteCount=noteCount+1
- elseif event=="monitor_touch" and p3 == 10 and p2 >= 53 and p2 <= 56 then
- listen()
- end
- end
- listen()
- end
- if fs.exists("temp/tempFile") then
- tempLoad()
- else
- resetMusic()
- end
- listen()
Add Comment
Please, Sign In to add comment