Advertisement
bob558

Mуз - разобрать

Nov 20th, 2016
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.56 KB | None | 0 0
  1. --[[Runs notes inside a table or a string (notes seperated by free spaces, then) using special syntax, the Note API and computer.beep
  2.   Examples:
  3.   "E5": Plays the note "E5" for the duration specified in the second parameter (default 0.125, equaling 120 bpm)
  4.   "-E5": Plays the note "E5" with double the specified duration
  5.   "E5_4": Plays the note "E5" with 4 times the specified duration, change "4" to any number x to play the note x times the duration specified
  6.   "P_4": Plays a pause with 4 times the specified duration, change "4" to any number x to play the note x times the duration specified
  7.   For note names, use the syntax of the strings of the Note API
  8.  
  9.   if you set the third parameter to true, you may insert a table containing tables or strings looking the same as explained above.
  10.   This will allow you to play multiple channels of a song simultaneously, up to 8 at a time.
  11.   This mode requires the mod Computronics to be present and the computer to contain a Beep Card from that mod.
  12.  
  13. https://github.com/OpenPrograms/Vexatos-Programs/tree/master/song
  14. https://github.com/OpenPrograms/Vexatos-Programs/blob/master/song/song-example1.lua
  15. ]]
  16.  
  17. local n = require("note")
  18. local song = {}
  19.  
  20. local function insertSynchronized(tMain, tInsert)
  21.   tMain = tMain or {}
  22.   if not tInsert then
  23.     error("Error during song parsing, found nil insert table", 2)
  24.   elseif #tInsert == 0 then
  25.     return tMain
  26.   end
  27.   if #tMain == 0 then
  28.     for i,j in ipairs(tInsert) do
  29.       table.insert(tMain, {j[1], {j[2]}})
  30.     end
  31.     return tMain
  32.   end
  33.  
  34.   --now the fun begins
  35.  
  36.   for i,j in ipairs(tInsert) do
  37.     for k,v in ipairs(tMain) do
  38.       --is the time frame already there?
  39.       if v[1] == j[1] then
  40.         table.insert(v[2], j[2])
  41.         break
  42.       elseif  v[1] > j[1] then
  43.        --it is not.
  44.        table.insert(tMain, k, {j[1], {j[2]}})
  45.        break
  46.       end
  47.     end
  48.   end
  49.   return tMain
  50. end
  51.  
  52. function song.play(notes, shortest, multi)
  53.   if not shortest then shortest = 0.125 end
  54.   if type(shortest)~="number" then
  55.     shortest = 0.125
  56.   end
  57.   if shortest < 0.05 then
  58.     error("Error: Shortest note must not be smaller than 0.05", 2)
  59.   end
  60.   multi = multi or false
  61.   if type(multi)~="boolean" then
  62.     multi = false
  63.   end
  64.   if not multi then
  65.     local tNotes = notes
  66.     if type(tNotes) == "string" then
  67.         local tB = {}
  68.         for j in string.gmatch(notes,"%S+") do
  69.           table.insert(tB, j)
  70.         end
  71.         tNotes = tB
  72.     end
  73.     if type(tNotes) ~= "table" then
  74.       error("Wrong input given, song.play requires a table or a string as first parameter", 2)
  75.     end
  76.     local noteMap = {}
  77.     do
  78.       local duration
  79.       for i,j in ipairs(tNotes) do
  80.         if string.find(j,"P") then
  81.           duration = 0
  82.         elseif string.find(j,"%-") then
  83.           duration = 2
  84.         elseif string.find(j,"_") then
  85.           duration = tonumber(string.match(j,".*_(%d+)"))
  86.         else
  87.           duration = 1
  88.         end
  89.         if duration ~= 0 then
  90.           table.insert(noteMap, i, {string.match(j,"(%a.?%d)_?%d*"),shortest*duration})
  91.         else
  92.           table.insert(noteMap, i, {-1, shortest*tonumber(string.match(j,"P_(%d+)"))})
  93.         end
  94.       end
  95.     end
  96.     for i,j in ipairs(noteMap) do
  97.       if type(j[1]) == "number" then
  98.         os.sleep(j[2])
  99.       else
  100.         n.play(j[1], j[2])
  101.       end
  102.     end
  103.   else
  104.     --beep card mode
  105.     local component = require("component")
  106.     if not component.isAvailable("beep") then
  107.       error("No beep card found, not possible to have multiple sound channels")
  108.     end
  109.     local beep = component.beep
  110.     local freqMap = {}
  111.    
  112.     if not type(notes) == "table" then
  113.       error("Wrong input given, song.play in multi mode requires a table as first parameter", 2)
  114.     end
  115.     --parsing start
  116.    
  117.     for k,v in ipairs(notes) do
  118.       local duration
  119.       local timeMap = {}
  120.       local timecount = 0
  121.       local pause = -1
  122.       if(type(v) == "string") then
  123.         local tB = {}
  124.         for j in string.gmatch(notes,"%S+") do
  125.           table.insert(tB, j)
  126.         end
  127.         v = tB
  128.       end
  129.       for i,j in ipairs(v) do
  130.         if string.find(j,"P") then
  131.           --os.sleep(shortest*tonumber(string.match(j,"P_(%d+)")))
  132.           duration = 0
  133.         elseif string.find(j,"%-") then
  134.           duration = 2
  135.         elseif string.find(j,"_") then
  136.           duration = tonumber(string.match(j,".*_(%d+)"))
  137.         else
  138.           duration = 1
  139.         end
  140.         if duration ~= 0 then
  141.           table.insert(timeMap, {timecount, {n.freq(string.match(j,"(%a.?%d)_?%d*")), shortest*duration}})
  142.           timecount = timecount + duration
  143.         else
  144.           table.insert(timeMap, {timecount, {pause, shortest*tonumber(string.match(j,"P_(%d+)"))}})
  145.           timecount = timecount + tonumber(string.match(j,"P_(%d+)"))
  146.           pause = pause - 1
  147.         end
  148.       end
  149.       --timeMap: {{time, {freq, duration}}, {time2, freq2, duration2}}}
  150.       insertSynchronized(freqMap, timeMap)
  151.     end
  152.     --freqMap: {{time, {channel={freq, duration}, channel2={freq2, duration2}}}, {time3, {channel3={freq3, duration3}, channel4={freq4, duration4}}}}
  153.    
  154.     --parsing end
  155.    
  156.     for k,v in ipairs(freqMap) do
  157.       local fMap = {}
  158.       for i,j in pairs(v[2]) do
  159.         if type(j[1]) == "number" and j[1] >= 0 then
  160.           fMap[j[1]] = j[2]
  161.         else
  162.           --pause here
  163.         end
  164.       end
  165.       beep.beep(fMap)
  166.       if k < #freqMap then
  167.         os.sleep((freqMap[k+1][1] - v[1]) * shortest)
  168.       end
  169.     end
  170.   end
  171. end
  172.  
  173. return song
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement