Advertisement
Guest User

memusic

a guest
Jan 20th, 2020
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.45 KB | None | 0 0
  1. local patternLength = 16
  2. local beatLength = 4
  3.  
  4. local sp = peripheral.find("speaker")
  5.  
  6. local function pitch(note)
  7.     return math.pow(2, (note-12)/12)
  8. end
  9.  
  10. instruments = {
  11.     -- musical
  12.     ["bass"] = "block.note.bass",
  13.     ["bassdrum"] = "block.note.bassdrum",
  14.     ["bell"] = "block.note.bell",
  15.     ["chime"] = "block.note.chime",
  16.     ["flute"] = "block.note.flute",
  17.     ["guitar"] = "block.note.guitar",
  18.     ["hat"] = "block.note.hat",
  19.     ["snare"] = "block.note.snare",
  20.     ["harp"] = "block.note.harp",
  21.     ["xylophone"] = "block.noteblock.xylophone",
  22.     -- sfx
  23.     ["levelup"] ="entity.player.levelup"
  24. }
  25.  
  26. local function playNote(inst, vol, note)
  27.     sp.playSound(instruments[inst], vol, note)
  28. end
  29.  
  30. local notes = {
  31.     "F#", "G ", "G#", "A ", "A#", "B ",
  32.     "C ", "C#", "D ", "D#", "E ", "F "
  33. }
  34.  
  35. local song = {}
  36. local patterns = {}
  37. local instruments = {}
  38.  
  39. local currentPattern = 0
  40. local currentPatternData = {}
  41. local currentChannel = 0
  42. local currentYOffset = 0
  43. local currentXOffset = 0
  44. local pressingShift = false
  45.  
  46. local beatsOnScreen = math.floor(36/beatLength)
  47. local scrW, scrH = term.getSize()
  48.  
  49. local function addCharAt(str, char, pos)
  50.     local prev = string.sub(str, 1, pos)
  51.     local post = string.sub(str, pos+1, string.len(str))
  52.     return prev..char..post
  53. end
  54.  
  55. local function replaceCharAt(str, char, pos)
  56.     local prev = string.sub(str, 1, pos)
  57.     local post = string.sub(str, pos+2, string.len(str))
  58.     return prev..char..post
  59. end
  60.  
  61. local function DrawPattern()
  62.     local channel = currentChannel
  63.     local pattern = currentPattern
  64.     local xoffset = currentXOffset
  65.     local yoffset = currentYOffset
  66.     for _y=1, scrH-1 do
  67.         local y = scrH-_y
  68.         local octave = math.floor((_y+yoffset-7)/12)+1
  69.         local n = (_y+yoffset)%12
  70.         local c = xoffset
  71.         term.setCursorPos(1,y+1)
  72.        
  73.         term.setBackgroundColor(colors.black)
  74.         if (n==1 or n==3 or n==5 or n==8 or n==10) then
  75.             term.setTextColor(colors.blue)
  76.         else
  77.             term.setTextColor(colors.cyan)
  78.         end
  79.         term.write(notes[(n-1)%12+1]..tostring(octave))
  80.        
  81.         if (n==1 or n==3 or n==5 or n==8 or n==10) then
  82.             term.setBackgroundColor(colors.lightGray)
  83.             term.setTextColor(colors.gray)
  84.         else
  85.             term.setBackgroundColor(colors.white)
  86.             term.setTextColor(colors.lightGray)
  87.         end
  88.         for c=currentXOffset, math.min(patternLength-1, currentXOffset+beatsOnScreen-1) do
  89.             if (c%4 == 0) then
  90.                 term.write("|")
  91.             else
  92.                 term.write(",")
  93.             end
  94.             term.write(string.rep("_",beatLength-1))
  95.         end
  96.     end
  97.     term.setCursorPos(1,1)
  98.     term.setBackgroundColor(colors.black)
  99.     term.setTextColor(colors.yellow)
  100.     term.write("   ")
  101.     local i = 1
  102.     for c=xoffset, math.min(xoffset+beatsOnScreen-1, patternLength-1) do
  103.         term.setCursorPos(3+i, 1)
  104.         term.write(tonumber(c+1))
  105.         term.write(" ")
  106.         i = i+beatLength
  107.     end
  108.    
  109.     term.setBackgroundColor(colors.blue)
  110.     term.setTextColor(colors.black)
  111.     for c=xoffset*beatLength+1, math.min(xoffset+beatsOnScreen-1, patternLength-1)*beatLength+beatLength do
  112.         local n = currentPatternData[c]
  113.         if (n ~= ".") then
  114.             local x, y = musicToPixel(c, n)
  115.             term.setCursorPos(x, y)
  116.             term.write(" ")
  117.         end
  118.     end
  119. end
  120.  
  121. local function DrawScreen()
  122.     term.setBackgroundColor(colors.black)
  123.     term.setTextColor(colors.white)
  124.     DrawPattern()
  125. end
  126.  
  127. local function scrollRight()
  128.     if (currentXOffset < patternLength-beatsOnScreen) then
  129.         currentXOffset = currentXOffset+1
  130.         DrawPattern()
  131.     end
  132. end
  133.  
  134. local function scrollLeft()
  135.     if (currentXOffset > 0) then
  136.         currentXOffset = currentXOffset-1
  137.         DrawPattern()
  138.     end
  139. end
  140.  
  141. local function scrollUp()
  142.     if (currentYOffset < 26-scrH) then
  143.         currentYOffset = currentYOffset+1
  144.         DrawPattern()
  145.     end
  146. end
  147.  
  148. local function scrollDown()
  149.     if (currentYOffset > 0) then
  150.         currentYOffset = currentYOffset-1
  151.         DrawPattern()
  152.     end
  153. end
  154.  
  155. local function loadPattern(str)
  156.     if (str == nil) then
  157.         for i=1, patternLength*beatLength do
  158.             currentPatternData[i] = "."
  159.         end
  160.     end
  161. end
  162.  
  163. function pixelToMusic(x, y)
  164.     local time = x-3+currentXOffset*beatLength
  165.     local note = scrH-y+currentYOffset
  166.     return time, note
  167. end
  168.  
  169. function musicToPixel(time, note)
  170.     local x = time+3-currentXOffset*beatLength
  171.     local y = -note+currentYOffset+scrH
  172.     return x, y
  173. end
  174.  
  175. local function characterToNote(c, chord)
  176.     if (chord) then
  177.         return string.byte(c)-65
  178.     else
  179.         return string.byte(c)-97
  180.     end
  181. end
  182.  
  183. local function noteToCharacter(n, chord)
  184.     if (chord) then
  185.         return string.char(n+65) --Mayuscula
  186.     else
  187.         return string.char(n+97) --minuscula
  188.     end
  189. end
  190.  
  191. local function placeNote(x, y)
  192.     local time, note = pixelToMusic(x,y)
  193.     playNote("harp", 1, pitch(note))
  194.    
  195.     currentPatternData[time] = note
  196.    
  197.     DrawPattern()
  198. end
  199.  
  200. loadPattern()
  201. playNote("levelup", 0.5, 3)
  202. DrawScreen()
  203.  
  204. while true do
  205.     local event, a, b, c = os.pullEvent()
  206.     if (event == "key") then
  207.         local key = a
  208.         if (key == keys.up) then
  209.             scrollUp()
  210.         elseif (key == keys.down) then
  211.             scrollDown()
  212.         elseif (key == keys.left) then
  213.             scrollLeft()
  214.         elseif (key == keys.right) then
  215.             scrollRight()
  216.         elseif (key == keys.leftShift) then
  217.             pressingShift = true
  218.         end
  219.     end
  220.     if (event == "key_up") then
  221.         local key = a
  222.         if (key == keys.leftShift) then
  223.             pressingShift = false
  224.         end
  225.     end
  226.     if (event == "mouse_scroll") then
  227.         local scrollDirection = a
  228.         if (scrollDirection == 1) then
  229.             if (not pressingShift) then
  230.                 scrollDown()
  231.             else
  232.                 scrollRight()
  233.             end
  234.         else
  235.             if (not pressingShift) then
  236.                 scrollUp()
  237.             else
  238.                 scrollLeft()
  239.             end
  240.         end
  241.     end
  242.     if (event == "mouse_click") then
  243.         local button = a
  244.         local x = b
  245.         local y = c
  246.         if (x > 3 and x < 4+4*math.min(9, patternLength) and y > 1) then
  247.             placeNote(x,y)
  248.         end
  249.     end
  250. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement