Guest User

punymusiclang.lua

a guest
May 5th, 2021
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.68 KB | None | 0 0
  1. local comp = require('component')
  2. local snd = comp.sound
  3. local tap = comp.tape_drive
  4. local no = require('note')
  5. local thrd = require('thread')
  6. local tbl = require('table')
  7. local sh = require('shell')
  8. local fs = require('filesystem')
  9.  
  10. local args, opts = sh.parse( ... )
  11.  
  12. if opts.t then
  13.   print("Tape mode")
  14. elseif opts.f then
  15.   print("File mode")
  16. else
  17.   print("Usage: punymusiclang [-t][-f <filename>]")
  18.   print("You must write exactly one of (-t/-f)")
  19.   print("If you use both, the program is written to crash itself.")
  20.   os.exit()
  21. end
  22.  
  23. local commsize = 2
  24. channs = 4
  25.  
  26. local channadsr = {[1]={[1]=0,[2]=0,[3]=0,[4]=0,['chg']=false},
  27. [2]={[1]=0,[2]=0,[3]=0,[4]=0,['chg']=false},
  28. [3]={[1]=0,[2]=0,[3]=0,[4]=0,['chg']=false},
  29. [4]={[1]=0,[2]=0,[3]=0,[4]=0,['chg']=false},
  30. [5]={[1]=0,[2]=0,[3]=0,[4]=0,['chg']=false},
  31. [6]={[1]=0,[2]=0,[3]=0,[4]=0,['chg']=false},
  32. [7]={[1]=0,[2]=0,[3]=0,[4]=0,['chg']=false},
  33. [8]={[1]=0,[2]=0,[3]=0,[4]=0,['chg']=false}}
  34.  
  35. function setChanns(chn)
  36.   channs = chn
  37. end
  38.  
  39. function rnoteplay(midn, chn)
  40.   if channadsr[chn].chg then
  41.     channadsr[chn].chg = false
  42.     local adsr = channadsr[chn]
  43.     snd.setADSR(chn, adsr[1], adsr[2], adsr[3], adsr[4])
  44.   end
  45.   snd.close(chn)
  46.   snd.open(chn)
  47.   snd.setFrequency(chn, no.freq(midn) * 2)
  48. end
  49.  
  50. function nnoteplay(midn, chn)
  51.   snd.setFrequency(chn, no.freq(midn) * 2)
  52. end
  53.  
  54. function noterel(chn)
  55.   snd.close(chn)
  56. end
  57.  
  58. function volume(vol, chn)
  59.   snd.setVolume(chn, (vol / 255)*0.2)
  60. end
  61.  
  62. function inst(inst, chn)
  63.   snd.setWave(chn, inst)
  64. end
  65.  
  66. function sattack(att, chn)
  67.   channadsr[chn][1] = att * 8
  68.   channadsr[chn].chg = true
  69. end
  70.  
  71. function sdelay(del, chn)
  72.   channadsr[chn][2] = del * 8
  73.   channadsr[chn].chg = true
  74. end
  75.  
  76. function ssustain(sus, chn)
  77.   channadsr[chn][3] = (sus / 255)*0.2
  78.   channadsr[chn].chg = true
  79. end
  80.  
  81. function srelease(rel, chn)
  82.   channadsr[chn][4] = rel * 8
  83.   channadsr[chn].chg = true
  84. end
  85.  
  86. if opts.t then
  87.   tap.seek(-(tap.getSize()))
  88.   tapesize = string.unpack("<I4", tap.read(4))
  89.   re = tap
  90. elseif opts.f then
  91.   fil = fs.open(sh.resolve(args[1]), "rb")
  92.   fil:seek("set", 0)
  93.   filsiz = fs.size(sh.resolve(args[1]))
  94.   filpos = 0
  95. end
  96.  
  97. currChan = 1
  98. tickwait = 1
  99.  
  100. function decComm(bytecomm, data)
  101.   if bytecomm == 118 then
  102.     setChanns(data)
  103.     currChan = 1
  104.     print("set channels to " .. data)
  105.   elseif bytecomm == 100 then
  106.     tickwait = data
  107.     currChan = 1
  108.     print("set line length to " .. data .. " ticks")
  109.   elseif bytecomm == 130 then
  110.     sattack(data, currChan)
  111.   elseif bytecomm == 131 then
  112.     sdelay(data, currChan)
  113.   elseif bytecomm == 132 then
  114.     ssustain(data, currChan)
  115.   elseif bytecomm == 133 then
  116.     srelease(data, currChan)
  117.   elseif bytecomm == 155 then
  118.     volume(data, currChan)
  119.   elseif bytecomm == 144 then
  120.     inst(data - 1, currChan)
  121.   elseif bytecomm == 2 then
  122.     rnoteplay(data, currChan)
  123.   elseif bytecomm == 3 then
  124.     nnoteplay(data, currChan)
  125.   elseif bytecomm == 4 then
  126.     noterel(currChan)
  127.   elseif bytecomm == 0 then
  128.     local linesize = commsize * channs
  129.     if opts.f then
  130.       fil:seek("cur", -((linesize * data) + 2))
  131.       filpos = filpos - (linesize * data)
  132.     elseif opts.t then re.seek(-(linesize * data)) end
  133.     currChan = 1
  134.   end
  135. end
  136.  
  137. print("OK, starting")
  138.  
  139. tickstowait = 1
  140.  
  141. while true do
  142.   tickstowait = tickstowait - 1
  143.   if tickstowait <= 0 then
  144.     while currChan <= channs do
  145.       if opts.f then
  146.         co = fil:read(2)
  147.       else
  148.         co = re.read(2) end
  149.       --if co[2] == nil then
  150.         --print("UNALIGNED FILE?")
  151.         --os.exit()
  152.       --end
  153.       --if co and not (co:len() < 2) then
  154.         comma, comval = string.unpack("<BB", co)
  155.         decComm(comma, comval)
  156.       --end
  157.       currChan = currChan + 1
  158.     end
  159.     tickstowait = tickwait
  160.   end
  161.   currChan = 1
  162.   snd.delay(50)
  163.   snd.process()
  164.   os.sleep(0.04)
  165. end
Advertisement
Add Comment
Please, Sign In to add comment