diff --git a/README.md b/README.md index 8e2d7b0..eea7f37 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,14 @@ Experiment with sound generation in Lua. ![screenshot](screenshot.png) -# Usage +## Usage - Copy `sound.lua.example` to `sound.lua` - Open `sound.lua` in your text editor (autosave on change recommended) - Run this with `love .` - Edit `sound.lua`, and watch (listen) the sound update in real time + +## Keys + +- `r`: restart sound from the beginning +- `space`: pause/unpause diff --git a/main.lua b/main.lua index c1281f0..190cac8 100644 --- a/main.lua +++ b/main.lua @@ -44,6 +44,7 @@ local function init() end end end +local playing=false function love.load() love.thread.newThread("thread.lua"):start() init() @@ -54,29 +55,54 @@ function love.keypressed(key) sour:pause() sour:stop() init() + elseif key == "space" then + playing = not playing + if playing then + sour:play() + else + sour:pause() + end end end +local lastc = love.timer.getTime() +local waitingc = false function love.update(dt) + local tt = love.timer.getTime() for n=1,sour:getFreeBufferCount()-offset do push("snd",true) offset=offset+1 table.remove(chunkd,1) end + local tt1 = love.timer.getTime() + if tt1-lastc >= chunk*1.2 and not waitingc then + waitingc = true + push("slook",true) + end + local tt2 = love.timer.getTime() while sndc:getCount()>0 do local c = sndc:demand() local v = sndc:demand() if c == "snd" then sour:queue(samplify(v)) - sour:play() + if playing then sour:play() end offset=offset-1 elseif c == "pos" then pos = v elseif c == "look" then look = v + lastc = love.timer.getTime() + waitingc = false else error("unkc: "..tostring(c)) end end + local tt3 = love.timer.getTime() + if tt3-tt > 0.01 then + print("EE",tt3-tt) + print(" 1",tt1-tt) + print(" 2",tt2-tt1) + print(" 3",tt3-tt2) + end end function love.draw() local w,h = love.graphics.getDimensions() diff --git a/thread.lua b/thread.lua index bce2420..4ba40fb 100644 --- a/thread.lua +++ b/thread.lua @@ -10,37 +10,47 @@ local function send(c,v) sndc:push(c) sndc:push(v) end -local function go() +local function go(uu) local t = love.timer.getTime() local ok,err,x = xpcall(function() local snd,x = dofile("sound.lua") snd = snd:phase(pos):clamp(0,chunk,true) - snd = assert(snd:compile(rate,bits),"no sound") - assert(snd:typeOf("SoundData"),"fake sound") + if not uu then + snd = assert(snd:compile(rate,bits),"no sound") + assert(snd:typeOf("SoundData"),"fake sound") + end return snd,x end,debug.traceback) look = tonumber(x) or look + local tt = love.timer.getTime() sndc:performAtomic(function() send("look",look) - if not ok then - send("snd",emsnd) - print(err) - else - send("snd",err) + if not uu then + if not ok then + send("snd",emsnd) + print(err) + else + send("snd",err) + end + pos=pos+chunk end - pos=pos+chunk send("pos",pos) end) - t=love.timer.getTime()-t - local chnkcc=16 - local pgb=math.floor(t/chunk*chnkcc+.5) - print(("time: %.2f..%.2f\tload: %.2f%%\t[%s%s%s]"):format( - pos-chunk,pos, - math.floor(t/chunk*100+.5), - ("#"):rep(math.min(pgb,chnkcc)), - ("."):rep(math.max(0,chnkcc-pgb)), - ("!"):rep(math.max(0,-(chnkcc-pgb))) - )) + if love.timer.getTime()-tt > 0.01 then + print("TIME TAKEN:",love.timer.getTime()-tt) +end + if not uu then + t=love.timer.getTime()-t + local chnkcc=16 + local pgb=math.floor(t/chunk*chnkcc+.5) + print(("time: %.2f..%.2f\tload: %.2f%%\t[%s%s%s]"):format( + pos-chunk,pos, + math.floor(t/chunk*100+.5), + ("#"):rep(math.min(pgb,chnkcc)), + ("."):rep(math.max(0,chnkcc-pgb)), + ("!"):rep(math.max(0,-(chnkcc-pgb))) + )) + end end while true do local cmd = ctrl:demand() @@ -59,6 +69,8 @@ while true do bits = v elseif cmd == "snd" then go() + elseif cmd == "slook" then + go(true) else error("unkc: "..tostring(cmd)) end