Don't like ads? PRO users don't see any ads ;-)
Guest

FTB Music Player Program

By: a guest on Feb 18th, 2013  |  syntax: None  |  size: 6.65 KB  |  hits: 40  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. -- Noteblock Studio file (.nbs) player for MiscPeripherals (a ComputerCraft mod)
  2. -- You are free to copy, alter, and distribute this under the following conditions:
  3. -- 1) You leave these comments and credits attached
  4. -- 2) You do not make money off of this
  5. -- Program by James0x57 - http://www.youtube.com/watch?v=ro4EK8smULQ
  6. -- Noteblock Studio by _Davve_ - http://www.minecraftforum.net/topic/136749-minecraft-note-block-studio-150000-downloads/
  7. -- MiscPeripherals by RichardG867 - http://www.computercraft.info/forums2/index.php?/topic/4587-cc1481mc146-miscperipherals-23/
  8. -- ComputerCraft by Dan - http://www.computercraft.info/
  9.  
  10. local args = {...};
  11. local menu = {};
  12. local box = nil;
  13. local song = nil;
  14. local action = 'mainList';
  15. local maxtoshow = 12;
  16. local selected = 0;
  17. local startat = 1;
  18.  
  19. for _,side in ipairs({"left"; "right"; "back"; "bottom"; "top"; "front"}) do
  20.         if peripheral.getType(side) == "note" then
  21.                 box = peripheral.wrap(side);
  22.                 break;
  23.         end
  24. end
  25.  
  26. if turtle ~= nil then
  27.         maxtoshow = 7;
  28. end
  29.  
  30. function newSong(x)
  31.         return {
  32.                 fh = x;
  33.                 length = 0;
  34.                 height = 0;
  35.                 name = "";
  36.                 author = "";
  37.                 originalAuthor = "";
  38.                 description = "";
  39.                 tempo = 10.00; --tks per second
  40.                 autoSaving = 0;
  41.                 autoSaveDur = 0;
  42.                 timeSig = 4;
  43.                 minSpent = 0;
  44.                 leftClicks = 0;
  45.                 rightClicks = 0;
  46.                 blocksAdded = 0;
  47.                 blocksRemoved = 0;
  48.                 midi = "";
  49.                 music = { wait={}; inst={}; note={}; };
  50.         };
  51. end
  52.  
  53. if args[1] == nil or fs.isDir(args[1]) == false then
  54.         args[1] = "songs";
  55.         if fs.isDir(args[1]) == false then
  56.                 fs.makeDir("songs");
  57.         end
  58. end
  59.  
  60. for _, file in ipairs(fs.list(args[1])) do
  61.   if fs.isDir(file) == false and string.find(file, ".nbs", -4, true) ~= nil then -- if file and ends in ".nbs"
  62.         menu[#menu+1] = file;
  63.   end
  64. end
  65.  
  66. function showInfo()
  67.         term.clear();
  68.         print("Now Playing: \n\n\n\n\n\n          " .. song.name);
  69.         print("\n\n\n\n\n\nAuthor: " .. song.author);
  70.         print("Original Author: " .. song.originalAuthor);
  71.         print("Description: ");
  72.         print(song.description);
  73. end
  74.  
  75. function readInt(fh) --little endian, fh is open in rb mode
  76.         local ret = 0;
  77.         local x = fh.read();
  78.         if x == nil then return nil; end
  79.         ret = x;
  80.         x = fh.read();
  81.         if x == nil then return nil; end
  82.         ret = (x * 0x100) + ret;
  83.         x = fh.read();
  84.         if x == nil then return nil; end
  85.         ret = (x * 0x10000) + ret;
  86.         x = fh.read();
  87.         if x == nil then return nil; end
  88.         ret = (x * 0x1000000) + ret;
  89.         return ret;
  90. end
  91.  
  92. function readShort(fh) --little endian, fh is open in rb mode
  93.         local ret = 0;
  94.         local x = fh.read();
  95.         if x == nil then return nil; end
  96.         ret = x;
  97.         x = fh.read();
  98.         if x == nil then return nil; end
  99.         ret = (x * 0x100) + ret;
  100.         return ret;
  101. end
  102.  
  103. function readString(fh, len) --fh is open in rb mode
  104.         local ret = "";
  105.         local x = 0;
  106.         for i = 1, len do
  107.                 x = fh.read();
  108.                 if x == nil then return nil; end
  109.                 ret = ret .. string.char(x);
  110.         end
  111.         return ret;
  112. end
  113.  
  114. function readHeader()
  115.         song.length             = readShort(song.fh);
  116.         song.height             = readShort(song.fh);
  117.         song.name                       = readString(song.fh, readInt(song.fh));
  118.         song.author             = readString(song.fh, readInt(song.fh));
  119.         song.originalAuthor = readString(song.fh, readInt(song.fh));
  120.         song.description        = readString(song.fh, readInt(song.fh));
  121.         song.tempo                      = 1.000 / ( readShort(song.fh) / 100.00 );
  122.         song.autoSaving         = song.fh.read();
  123.         song.autoSaveDur        = song.fh.read();
  124.         song.timeSig            = song.fh.read();
  125.         song.minSpent           = readInt(song.fh);
  126.         song.leftClicks         = readInt(song.fh);
  127.         song.rightClicks        = readInt(song.fh);
  128.         song.blocksAdded        = readInt(song.fh);
  129.         song.blocksRemoved      = readInt(song.fh);
  130.         song.midi                       = readString(song.fh, readInt(song.fh));
  131. end
  132.  
  133. function readNotes()
  134.         local curtk = 1;
  135.         local tk = -1;
  136.         local layer = -1;
  137.         local inst = 0;
  138.         local note = 33; -- MC is 33 to 57
  139.  
  140.         while true do
  141.                 tk = readShort(song.fh);
  142.                 if tk == nil then return false; end
  143.                 if tk == 0 then break; end
  144.                 while true do
  145.                         song.music.wait[curtk] = (tk * song.tempo) * 0.975; -- * 0.975 to speed it up a bit because lua slow
  146.                         layer = readShort(song.fh); --can't do anything with this info (yet?)
  147.                         if layer == nil then return false; end
  148.                         if layer == 0 then break; end
  149.                         song.music.inst[curtk]=song.fh.read();
  150.                         if song.music.inst[curtk] == 0 then
  151.                                 song.music.inst[curtk] = 0;
  152.                         elseif song.music.inst[curtk] == 2 then
  153.                                 song.music.inst[curtk] = 1;
  154.                         elseif song.music.inst[curtk] == 3 then
  155.                                 song.music.inst[curtk] = 2;
  156.                         elseif song.music.inst[curtk] == 4 then
  157.                                 song.music.inst[curtk] = 3;
  158.                         elseif song.music.inst[curtk] == 1 then
  159.                                 song.music.inst[curtk] = 4;
  160.                         end
  161.                         song.music.note[curtk]=song.fh.read()-33;
  162.                         tk = 0;
  163.                         curtk = curtk + 1;
  164.                 end
  165.         end
  166.         return true;
  167. end
  168.  
  169. function playNotes()
  170.         for i = 1, #song.music.wait - 1 do
  171.                 if song.music.wait[i] ~= 0 then
  172.                         os.sleep(song.music.wait[i]);
  173.                 end
  174.                 --box.playNote(song.music.inst[i], song.music.note[i]);
  175.                 pcall(box.playNote, song.music.inst[i], song.music.note[i]);
  176.         end
  177. end
  178.  
  179. function printSongs(x)
  180.         action = 'mainList';
  181.  
  182.         term.clear();
  183.         for i = x, #menu do
  184.                 if x + maxtoshow <= i then break end
  185.                 print(i .. ") " .. menu[i]);
  186.         end
  187.         print("----------------------\n0) [More]\n\nEnter the song number to play it: ");
  188.  
  189.         term.setCursorBlink(true);
  190.         selected = tonumber(read());
  191.         print(selected);
  192.         term.setCursorBlink(false);
  193.  
  194.         if selected > 0 and selected <= #menu then
  195.                 action = 'playSong';
  196.         else
  197.                 action = 'backNextMenu';
  198.                 if true then
  199.                         return 2, x; -- just goes to the next page instead of new menu
  200.                 else
  201.                         term.clear();
  202.                         print("1) Previous Page of Songs...");
  203.                         print("2) Next Page of Songs...");
  204.                         print("\n\n0) [Back]\n\nEnter the option number: ");
  205.  
  206.                         term.setCursorBlink(true);
  207.                         selected = tonumber(read());
  208.                         term.setCursorBlink(false);
  209.                 end
  210.         end
  211.         return selected, x;
  212. end
  213.  
  214. if box == nil then
  215.         print("No Iron Noteblock Detected");
  216. else
  217.         selected, startat = printSongs(1);
  218.         while true do
  219.                 if action == 'playSong' then
  220.                         song = newSong(fs.open(args[1] .. "/" .. menu[selected], "rb"));
  221.                         readHeader();
  222.                         showInfo();
  223.                         readNotes();
  224.                         song.fh.close();
  225.                         playNotes();
  226.                         --loops if don't change action
  227.                         action = 'mainList';
  228.                 else
  229.                         if action == 'backNextMenu' then
  230.                                 if selected == 1 then
  231.                                         startat = startat - maxtoshow;
  232.                                         if startat < 1 then startat = 1; end
  233.                                         selected, startat = printSongs(startat);
  234.                                 elseif selected == 2 then
  235.                                         startat = startat + maxtoshow
  236.                                         if startat > #menu then startat = 1; end
  237.                                         selected, startat = printSongs(startat);
  238.                                 else --if selected == 0 then
  239.                                         selected, startat = printSongs(startat);
  240.                                 end
  241.                         elseif action =='mainList' then
  242.                                 selected, startat = printSongs(startat);
  243.                         end
  244.                 end
  245.         end
  246. end