This commit is contained in:
Kimapr 2024-05-26 17:27:13 +05:00
commit b6289fd8cc
11 changed files with 468 additions and 0 deletions

96
main.lua Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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()