Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local comp = require('component')
- local snd = comp.sound
- local tap = comp.tape_drive
- local no = require('note')
- local thrd = require('thread')
- local tbl = require('table')
- local sh = require('shell')
- local fs = require('filesystem')
- local args, opts = sh.parse( ... )
- if opts.t then
- print("Tape mode")
- elseif opts.f then
- print("File mode")
- else
- print("Usage: punymusiclang [-t][-f <filename>]")
- print("You must write exactly one of (-t/-f)")
- print("If you use both, the program is written to crash itself.")
- os.exit()
- end
- local commsize = 2
- channs = 4
- local channadsr = {[1]={[1]=0,[2]=0,[3]=0,[4]=0,['chg']=false},
- [2]={[1]=0,[2]=0,[3]=0,[4]=0,['chg']=false},
- [3]={[1]=0,[2]=0,[3]=0,[4]=0,['chg']=false},
- [4]={[1]=0,[2]=0,[3]=0,[4]=0,['chg']=false},
- [5]={[1]=0,[2]=0,[3]=0,[4]=0,['chg']=false},
- [6]={[1]=0,[2]=0,[3]=0,[4]=0,['chg']=false},
- [7]={[1]=0,[2]=0,[3]=0,[4]=0,['chg']=false},
- [8]={[1]=0,[2]=0,[3]=0,[4]=0,['chg']=false}}
- function setChanns(chn)
- channs = chn
- end
- function rnoteplay(midn, chn)
- if channadsr[chn].chg then
- channadsr[chn].chg = false
- local adsr = channadsr[chn]
- snd.setADSR(chn, adsr[1], adsr[2], adsr[3], adsr[4])
- end
- snd.close(chn)
- snd.open(chn)
- snd.setFrequency(chn, no.freq(midn) * 2)
- end
- function nnoteplay(midn, chn)
- snd.setFrequency(chn, no.freq(midn) * 2)
- end
- function noterel(chn)
- snd.close(chn)
- end
- function volume(vol, chn)
- snd.setVolume(chn, (vol / 255)*0.2)
- end
- function inst(inst, chn)
- snd.setWave(chn, inst)
- end
- function sattack(att, chn)
- channadsr[chn][1] = att * 8
- channadsr[chn].chg = true
- end
- function sdelay(del, chn)
- channadsr[chn][2] = del * 8
- channadsr[chn].chg = true
- end
- function ssustain(sus, chn)
- channadsr[chn][3] = (sus / 255)*0.2
- channadsr[chn].chg = true
- end
- function srelease(rel, chn)
- channadsr[chn][4] = rel * 8
- channadsr[chn].chg = true
- end
- if opts.t then
- tap.seek(-(tap.getSize()))
- tapesize = string.unpack("<I4", tap.read(4))
- re = tap
- elseif opts.f then
- fil = fs.open(sh.resolve(args[1]), "rb")
- fil:seek("set", 0)
- filsiz = fs.size(sh.resolve(args[1]))
- filpos = 0
- end
- currChan = 1
- tickwait = 1
- function decComm(bytecomm, data)
- if bytecomm == 118 then
- setChanns(data)
- currChan = 1
- print("set channels to " .. data)
- elseif bytecomm == 100 then
- tickwait = data
- currChan = 1
- print("set line length to " .. data .. " ticks")
- elseif bytecomm == 130 then
- sattack(data, currChan)
- elseif bytecomm == 131 then
- sdelay(data, currChan)
- elseif bytecomm == 132 then
- ssustain(data, currChan)
- elseif bytecomm == 133 then
- srelease(data, currChan)
- elseif bytecomm == 155 then
- volume(data, currChan)
- elseif bytecomm == 144 then
- inst(data - 1, currChan)
- elseif bytecomm == 2 then
- rnoteplay(data, currChan)
- elseif bytecomm == 3 then
- nnoteplay(data, currChan)
- elseif bytecomm == 4 then
- noterel(currChan)
- elseif bytecomm == 0 then
- local linesize = commsize * channs
- if opts.f then
- fil:seek("cur", -((linesize * data) + 2))
- filpos = filpos - (linesize * data)
- elseif opts.t then re.seek(-(linesize * data)) end
- currChan = 1
- end
- end
- print("OK, starting")
- tickstowait = 1
- while true do
- tickstowait = tickstowait - 1
- if tickstowait <= 0 then
- while currChan <= channs do
- if opts.f then
- co = fil:read(2)
- else
- co = re.read(2) end
- --if co[2] == nil then
- --print("UNALIGNED FILE?")
- --os.exit()
- --end
- --if co and not (co:len() < 2) then
- comma, comval = string.unpack("<BB", co)
- decComm(comma, comval)
- --end
- currChan = currChan + 1
- end
- tickstowait = tickwait
- end
- currChan = 1
- snd.delay(50)
- snd.process()
- os.sleep(0.04)
- end
Advertisement
Add Comment
Please, Sign In to add comment