initial
This commit is contained in:
commit
b6289fd8cc
96
main.lua
Normal file
96
main.lua
Normal file
|
@ -0,0 +1,96 @@
|
|||
soundgen=require "soundgen"
|
||||
love.window.setMode(800,600,{resizable=true})
|
||||
|
||||
function znoise(...)
|
||||
return love.math.noise(...)*2-1
|
||||
end
|
||||
|
||||
local sdata
|
||||
local source
|
||||
|
||||
function love.keypressed(k)
|
||||
local p="sounds/"..k..".lua"
|
||||
if love.filesystem.getInfo(p) and k~="0" and k~="space" then
|
||||
if source then
|
||||
source:stop()
|
||||
source=nil
|
||||
sdata=nil
|
||||
end
|
||||
package.loaded.soundgen=nil
|
||||
soundgen=require"soundgen"
|
||||
local ok,err=xpcall(function()return dofile("sounds/"..k..".lua")end,debug.traceback)
|
||||
if ok and err then
|
||||
print("booooom")
|
||||
sdata=err
|
||||
source=love.audio.newSource(sdata)
|
||||
source:setLooping(true)
|
||||
source:play()
|
||||
else
|
||||
print("bad",ok,source,err)
|
||||
end
|
||||
elseif k=="0" then
|
||||
if source then
|
||||
source:stop()
|
||||
source=nil
|
||||
sdata=nil
|
||||
end
|
||||
elseif k=="space" then
|
||||
if source then
|
||||
local _ = source:isPlaying() and {source:pause()} or source:play()
|
||||
end
|
||||
end
|
||||
end
|
||||
local l1={}
|
||||
local l2={}
|
||||
local res=4096
|
||||
local chanc=0
|
||||
local upd=nil
|
||||
local pitch=1
|
||||
function love.mousemoved(x,y,dx,dy)
|
||||
local w,h=love.graphics.getDimensions()
|
||||
local dy=-dy/h*2*(math.abs(pitch)+.1)
|
||||
if love.mouse.isDown(1) then
|
||||
pitch=math.min(10,math.max(-10,pitch+dy))
|
||||
end
|
||||
end
|
||||
function love.update(dt)
|
||||
local w,h=love.graphics.getDimensions()
|
||||
local rate=sdata and sdata:getSampleRate() or 0
|
||||
chanc=sdata and sdata:getChannelCount() or 1
|
||||
local s2i=chanc==2
|
||||
if source then
|
||||
source:setPitch(math.max(0.001,pitch))
|
||||
if pitch<0.001 then
|
||||
source:seek(math.max(0,source:tell()+pitch*dt))
|
||||
end
|
||||
end
|
||||
local ma=sdata and sdata:getSampleCount() or 1
|
||||
for n=1,res do
|
||||
local sami=(source and source:tell("samples") or 0)-math.floor(rate*((n-1)/(res-1))*0.05)
|
||||
sami=sami%ma
|
||||
l1[(n-1)*2+1],l1[(n-1)*2+2]
|
||||
=w-(n-1)/(res-1)*w,(sdata and (-sdata:getSample(s2i and sami*2 or sami)*0.5*0.5+0.5) or 0.5)*h
|
||||
if s2i then
|
||||
l2[(n-1)*2+1],l2[(n-1)*2+2]
|
||||
=w-(n-1)/(res-1)*w,(sdata and (-sdata:getSample(sami*2+1)*0.5*0.5+0.5) or 0.5)*h
|
||||
end
|
||||
end
|
||||
upd=true
|
||||
end
|
||||
function love.draw()
|
||||
love.graphics.print(pitch)
|
||||
love.graphics.push("all")
|
||||
love.graphics.setLineJoin("none")
|
||||
love.graphics.setLineWidth(1)
|
||||
love.graphics.setLineStyle("rough")
|
||||
if chanc==1 then
|
||||
love.graphics.setColor(1,1,1)
|
||||
love.graphics.line(l1)
|
||||
elseif chanc==2 then
|
||||
love.graphics.setColor(0.8,0.8,1)
|
||||
love.graphics.line(l1)
|
||||
love.graphics.setColor(1,0.8,0.8)
|
||||
love.graphics.line(l2)
|
||||
end
|
||||
love.graphics.pop()
|
||||
end
|
204
soundgen.lua
Normal file
204
soundgen.lua
Normal file
|
@ -0,0 +1,204 @@
|
|||
local smt={}
|
||||
smt.__index=smt
|
||||
smt.proto=smt
|
||||
|
||||
local function round(x)
|
||||
return math.floor(x+.5)
|
||||
end
|
||||
|
||||
function smt:bounds_and(a,b,c,...)
|
||||
if not a or not b then return false end
|
||||
local mi,ma
|
||||
mi=math.max(a[1],b[1])
|
||||
ma=math.min(a[2],b[2])
|
||||
if ma-mi<=0 then return false end
|
||||
if c then
|
||||
return self:bounds_and({mi,ma},c,...)
|
||||
end
|
||||
return {mi,ma}
|
||||
end
|
||||
|
||||
function smt:bounds_or(a,b,c,...)
|
||||
local mi,ma=math.min(a[1],b[1]),math.max(a[2],b[2])
|
||||
if not a then return b end
|
||||
if not b then return a end
|
||||
if c then
|
||||
return self:bounds_or({mi,ma},c,...)
|
||||
end
|
||||
return {mi,ma}
|
||||
end
|
||||
|
||||
function smt:new(fn,bounds)
|
||||
local obj={}
|
||||
obj.bounds=bounds
|
||||
if obj.bounds==nil then
|
||||
obj.bounds={-math.huge,math.huge}
|
||||
end
|
||||
obj.sample=fn
|
||||
return setmetatable(obj,self.proto)
|
||||
end
|
||||
|
||||
function smt:sine()
|
||||
return self:new(function(self,t)
|
||||
return math.sin(t*math.pi*2)
|
||||
end)
|
||||
end
|
||||
|
||||
function smt:square()
|
||||
return self:new(function(self,t)
|
||||
return (t%1)<=0.5 and -1 or 1
|
||||
end)
|
||||
end
|
||||
|
||||
function smt:sawtooth()
|
||||
return self:new(function(self,t)
|
||||
return (t%1)*2-1
|
||||
end)
|
||||
end
|
||||
|
||||
function smt:triangle()
|
||||
return self:new(function(self,t)
|
||||
--return ((t%1)<=0.5 and (t*2)%1 or 1-(t*2)%1)*2-1 -- sounds cool and glitchy but wrong
|
||||
local a=t%1
|
||||
if a>0.5 then
|
||||
return (1-(a*2-1))*2-1
|
||||
end
|
||||
return (a*2)*2-1
|
||||
end)
|
||||
end
|
||||
|
||||
function smt:noise(y,z,x)
|
||||
return self:new(function(self,t)
|
||||
return love.math.noise(t,y,z,x)*2-1
|
||||
end)
|
||||
end
|
||||
|
||||
function smt:silence(a)
|
||||
a=a or 0
|
||||
return smt:new(function()return a end)
|
||||
end
|
||||
|
||||
local function rated_bounds(bounds,rate)
|
||||
local mi,ma=bounds[1],bounds[2]
|
||||
mi,ma=mi*rate,ma*rate
|
||||
mi,ma=round(mi),round(ma)-1
|
||||
return mi,ma
|
||||
end
|
||||
|
||||
local function prefi(y)
|
||||
return math.min(1,math.max(-1,y))
|
||||
end
|
||||
|
||||
function smt:compile(rate,bits,alt)
|
||||
rate=rate or 44100
|
||||
bits=bits or 16
|
||||
local bounds=self.bounds
|
||||
local mi,ma=rated_bounds(bounds,rate)
|
||||
if alt then
|
||||
bounds=self:bounds_and(bounds,alt.bounds)
|
||||
local mi,ma=rated_bounds(bounds,rate)
|
||||
local sdata=love.sound.newSoundData(ma-mi+1,rate,bits,2)
|
||||
for x=mi,ma do
|
||||
local x=x+mi
|
||||
sdata:setSample(x*2,prefi(self:sample(x/rate+0.5/rate)))
|
||||
sdata:setSample(x*2+1,prefi(alt:sample(x/rate+0.5/rate)))
|
||||
end
|
||||
return sdata
|
||||
end
|
||||
local sdata=love.sound.newSoundData(ma-mi+1,rate,bits,1)
|
||||
for x=mi,ma do
|
||||
local xx=x-mi
|
||||
sdata:setSample(xx,prefi(self:sample(x/rate+0.5/rate)))
|
||||
end
|
||||
return sdata
|
||||
end
|
||||
|
||||
function smt:phase(p)
|
||||
local bb=self.bounds
|
||||
if bb then
|
||||
bb={bb[1]-p,bb[2]-p}
|
||||
end
|
||||
return self:new(function(obj,t)
|
||||
return self:sample(t+p)
|
||||
end,bb)
|
||||
end
|
||||
|
||||
function smt:amp(a)
|
||||
return self:new(function(obj,t)
|
||||
return self:sample(t)*a
|
||||
end,self.bounds)
|
||||
end
|
||||
|
||||
function smt:freq(f)
|
||||
local bb=self.bounds
|
||||
if bb then
|
||||
bb={bb[1]/f,bb[2]/f}
|
||||
if bb[2]<bb[1] then
|
||||
bb={bb[2],bb[1]}
|
||||
end
|
||||
end
|
||||
return self:new(function(obj,t)
|
||||
return self:sample(t*f)
|
||||
end,bb)
|
||||
end
|
||||
|
||||
function smt:clamp(mi,ma)
|
||||
return self:new(function(nself,t)
|
||||
if t<mi or t>ma then return 0 end
|
||||
return self.sample(self,t)
|
||||
end,self:bounds_and(self.bounds,{mi,ma}))
|
||||
end
|
||||
|
||||
function smt.am(car,mod,mi,ma)
|
||||
return smt:new(function(self,t)
|
||||
return car:sample(t)*((mod:sample(t)*0.5+0.5)*(ma-mi)+mi)
|
||||
end,car:bounds_and(car.bounds,mod.bounds))
|
||||
end
|
||||
|
||||
function smt.pm(car,mod,mi,ma)
|
||||
assert(car.bounds
|
||||
and car.bounds[1]==-math.huge
|
||||
and car.bounds[2]==math.huge,
|
||||
"infinite carrier expected")
|
||||
mod=mod:add(mod:silence())
|
||||
return smt:new(function(self,t)
|
||||
return car:sample(t+((mod:sample(t)*0.5+0.5)*(ma-mi)+mi))
|
||||
end,car.bounds)
|
||||
end
|
||||
|
||||
function smt.add(a,b,...)
|
||||
if not b then
|
||||
if not a then return smt:silence() end
|
||||
return a
|
||||
end
|
||||
local ls={a,b,...}
|
||||
local bbs={}
|
||||
for k,v in pairs(ls) do
|
||||
bbs[k]=v.bounds
|
||||
end
|
||||
return smt:new(function(self,t)
|
||||
local r=0
|
||||
for k,v in pairs(ls) do
|
||||
r=r+v:sample(t)
|
||||
end
|
||||
return r
|
||||
end,a:bounds_or(unpack(bbs)))
|
||||
end
|
||||
|
||||
do
|
||||
local fwav=smt:sine():phase(0.75):freq(0.25)
|
||||
fwav=fwav:clamp(0,1)
|
||||
fwav=fwav:add(smt:silence(-1):clamp(-math.huge,0))
|
||||
function smt.fade(wave,ma,mi)
|
||||
local ff=fwav:freq(1/(mi-ma)):phase(-ma)
|
||||
return wave:am(ff,1,-1)
|
||||
end
|
||||
end
|
||||
|
||||
function smt.fm(car,mod,rate,mi,ma) -- TODO
|
||||
local cframe,cache=0,{}
|
||||
return smt.new(function(self,t)
|
||||
end,mod.bounds)
|
||||
end
|
||||
|
||||
return smt
|
40
sounds/1.lua
Normal file
40
sounds/1.lua
Normal file
|
@ -0,0 +1,40 @@
|
|||
local rate=44100
|
||||
local len=1
|
||||
local bfreq=500
|
||||
local lacu,pers=1.5,0.5
|
||||
local octas=4
|
||||
local rta=0
|
||||
local oofs={}
|
||||
math.randomseed(os.time())
|
||||
do
|
||||
local pe=1
|
||||
for n=1,octas do
|
||||
oofs[n]=math.random()*2-1
|
||||
rta=rta+(pe)
|
||||
pe=pe*pers
|
||||
end
|
||||
end
|
||||
local sd=love.sound.newSoundData(rate*len,rate,16,1)
|
||||
local function gsample(t)
|
||||
local arg=(bfreq*(t^((1+math.sin(t*2*math.pi)*0.1)*love.math.noise(t*0.1-0.05,5244,love.math.noise(t*1000,2949)*0.01-0.005))))
|
||||
--print(arg)
|
||||
local nn=0
|
||||
local pe=1/rta
|
||||
local ao=1
|
||||
for n=1,octas do
|
||||
local nnn=znoise(arg*ao,n/5+oofs[n])*pe
|
||||
--nn=math.max(-1,math.min(1,nn+nnn))
|
||||
nn=nn+nnn
|
||||
--print(n,nn,nnn,pe,ao)
|
||||
pe=pe*pers
|
||||
ao=ao*lacu
|
||||
end
|
||||
nn=nn*0.5+znoise((1-t)^(math.sin(t*math.pi*10*math.cos(t*10))*1+6+znoise(423,5453,t*1000)*0.05)*1000)*0.5
|
||||
nn=nn*1.5
|
||||
return (nn*(1-t)^5)*(math.min(1,math.max(t*100))^0.5)
|
||||
end
|
||||
for n=0,len*rate-1 do
|
||||
local a=gsample(n/(rate))
|
||||
sd:setSample(n,a)
|
||||
end
|
||||
return sd
|
15
sounds/2.lua
Normal file
15
sounds/2.lua
Normal file
|
@ -0,0 +1,15 @@
|
|||
local ss=
|
||||
soundgen:sine():freq(100)
|
||||
:pm(soundgen:sine():freq(50),-0.01,0.01)
|
||||
:pm(soundgen:sine():freq(50.5):pm(soundgen:sine():freq(1000):am(soundgen:sine():freq(10),0.4,0.6),-0.0001,0.0001),-0.01,0.01)
|
||||
:pm(soundgen:sine():freq(0.5):phase(0.4552),0,0.01)
|
||||
:am(soundgen:sine():freq(500):pm(soundgen:sine():freq(50),-0.015,0.015),0.5,1)
|
||||
:clamp(0,2):amp(0.5):add(
|
||||
soundgen:sine():freq(2500)
|
||||
:pm(soundgen:sine():freq(100)
|
||||
:am(soundgen:sine():freq(100),-0.01,0.01)
|
||||
,-0.1,0.1):amp(0.05):am(soundgen:sine():freq(50),0,1):am(soundgen:sine():freq(0),0.5,1)
|
||||
:clamp(0,2)
|
||||
)
|
||||
:compile()
|
||||
return ss
|
7
sounds/3.lua
Normal file
7
sounds/3.lua
Normal file
|
@ -0,0 +1,7 @@
|
|||
local sg=soundgen
|
||||
local ss=
|
||||
sg:sine():freq(1000):pm(sg:sine():freq(105.46):am(sg:sine():freq(505.3),-1,1),-0.001,0.001)
|
||||
:am(sg:sine():freq(500),-2,0.1)
|
||||
:am(sg:sine():phase(0.25):freq(0.5):clamp(0,0.5):freq(0.5):freq(3):add(sg:silence(-1)),0,1):clamp(0,1)
|
||||
:compile()
|
||||
return ss
|
9
sounds/4.lua
Normal file
9
sounds/4.lua
Normal file
|
@ -0,0 +1,9 @@
|
|||
local sg=soundgen
|
||||
return
|
||||
sg:square():freq(1000)
|
||||
:pm(sg:sine():phase(0.5):freq(0.1):am(sg:sine():freq(100),0,0.1),-0.05,0.05)
|
||||
:am(sg:sine():freq(200),-1,1):amp(0.4):am(sg:sine():freq(150):pm(sg:sine():freq(0.5),-0.1,0.1),0.25,1)
|
||||
--:clamp(0,10)
|
||||
:fade(0.01,0):fade(0.01,0.5):add(sg:silence()):clamp(0,2)
|
||||
:compile()
|
||||
|
8
sounds/5.lua
Normal file
8
sounds/5.lua
Normal file
|
@ -0,0 +1,8 @@
|
|||
local sg=soundgen
|
||||
--[[local sine=sg:sine():freq(800)
|
||||
for n=1,8 do
|
||||
sine=sine:am(sg:sine():freq(50*2^n):phase(n/8),0.85-(2^-n),0.85+(2^-n)):pm(sg:sine():freq(4*2^(n*0.99)):phase(1/n),-0.004/(n*0.8),0.004/(n*0.8))
|
||||
end]]
|
||||
local sine=sg:noise(0):freq(200):pm(sg:noise():freq(5000),-1/500,1/500):am(sg:sine():freq(150),0.2,1):am(sg:sine():phase(0.2):clamp(0,0.27):freq(2):add(sg:silence(0)),-1,1)
|
||||
sine=sine:clamp(0,1):freq(0.5)
|
||||
return sine:compile()
|
16
sounds/6.lua
Normal file
16
sounds/6.lua
Normal file
|
@ -0,0 +1,16 @@
|
|||
local sg=soundgen
|
||||
local wave=sg.add(
|
||||
sg:sine():freq(1):amp(0.1),
|
||||
sg:sine():freq(2):amp(0.1),
|
||||
sg:sine():freq(4):amp(0.1),
|
||||
sg:sine():freq(8):amp(0.1),
|
||||
sg:sine():freq(16):amp(0.1),
|
||||
sg:sine():freq(32):amp(0.1),
|
||||
sg:sine():freq(64):amp(0.1),
|
||||
sg:sine():freq(128):amp(0.1),
|
||||
sg:sine():freq(256):amp(0.1),
|
||||
sg:sine():freq(512):amp(0.1),
|
||||
sg:sine():freq(1024):amp(0.1)
|
||||
)
|
||||
wave=wave:clamp(0,10)
|
||||
return wave:compile(44100,16)
|
29
sounds/7.lua
Normal file
29
sounds/7.lua
Normal file
|
@ -0,0 +1,29 @@
|
|||
local sg=soundgen
|
||||
local fade
|
||||
do
|
||||
local fwav=sg:sine():phase(0.75):freq(0.25)
|
||||
fwav=fwav:clamp(0,1)
|
||||
fwav=fwav:add(sg:silence(-1):clamp(-math.huge,0))
|
||||
function fade(wave,ma,mi)
|
||||
local ff=fwav:freq(1/(mi-ma)):phase(-ma)
|
||||
return wave:am(ff,1,-1)
|
||||
end
|
||||
end
|
||||
local function new()
|
||||
local wave=sg:noise():phase(math.random()*1000):freq(1000):amp(0.25)
|
||||
:pm(sg:triangle():freq(50):am(sg:silence(1):fade(0,0.04),-1,1),-0.01,0.01)
|
||||
:add(sg:sine():amp(0.55):freq(50):pm(sg:noise():freq(500):phase(0.834715384),-0.01,0.01))
|
||||
wave=wave:fade(0,0.1)
|
||||
wave=wave:fade(0.001,0)
|
||||
return wave
|
||||
end
|
||||
local waves={}
|
||||
for n=0,1-1 do
|
||||
waves[#waves+1]=new():phase(-n*0.1):amp(0.3)
|
||||
end
|
||||
local wave=sg:silence():clamp(0,1):add(unpack(waves))
|
||||
return wave:compile()
|
||||
|
||||
|
||||
|
||||
|
19
sounds/8.lua
Normal file
19
sounds/8.lua
Normal file
|
@ -0,0 +1,19 @@
|
|||
local sg=soundgen
|
||||
local waves={}
|
||||
local function sign(n)
|
||||
return n>0 and 1 or (n<0 and -1 or 0)
|
||||
end
|
||||
for n=1,32 do
|
||||
local a=sg:noise(0):phase(n):freq(50*2^(n^0.8*2)):amp(0.5^(n/2)^1.2)
|
||||
local b=sg:noise(0):freq(50*n)
|
||||
waves[n]=sg:new(function(self,t)
|
||||
local aa=(n)/100
|
||||
local t=t
|
||||
local y=a:sample(t^(0.15*((n-1)^1.1/30+1))+b:sample(t)*aa)
|
||||
return math.abs(y)^2*sign(y)
|
||||
end)
|
||||
end
|
||||
local wave=sg.add(unpack(waves)):amp(1.2)
|
||||
wave=wave:fade(0.001,0)
|
||||
wave=wave:fade(0.001,0.5)
|
||||
return wave:compile()
|
25
sounds/9.lua
Normal file
25
sounds/9.lua
Normal file
|
@ -0,0 +1,25 @@
|
|||
local sg=soundgen
|
||||
local wave=sg:square():freq(50*(1+math.random()*0.4-0.2)):phase(math.random())
|
||||
local wave=sg:new(function(self,t)
|
||||
local ttcc,ttt=0,0
|
||||
for n=1,20 do
|
||||
local ttc,tt=0,0
|
||||
local ma=1/(512+math.random()*256-128)
|
||||
local st=ma/2
|
||||
for n=-ma,ma,st do
|
||||
ttc=ttc+1
|
||||
tt=tt+wave:sample(t+n)
|
||||
end
|
||||
ttcc,ttt=ttcc+1,tt/ttc
|
||||
end
|
||||
return ttt/ttcc
|
||||
end)
|
||||
--wave=wave:pm(wave:am(sg:sine():freq(70):phase(math.random()),0,1),-0.01,0.01)
|
||||
--wave=wave:pm(sg:noise():phase(0.5+math.random()*100):freq(3000):am(wave,-0.1,0.1),-0.005,0.005)
|
||||
local wave=sg:new(function(self,t)
|
||||
return wave:sample((t/4)^0.5*4)
|
||||
end)
|
||||
--wave=wave:amp(0.5):add(sg:sine():freq(102):pm(sg:sine():freq(49),-0.01,0.01):amp(0.5))
|
||||
wave=wave:fade(0.001,0)
|
||||
wave=wave:fade(0.001,0.5)
|
||||
return wave:compile()
|
Loading…
Reference in a new issue