205 lines
5.2 KiB
Lua
205 lines
5.2 KiB
Lua
local love = love
|
|
local passChimes = {}
|
|
local failChimes = {}
|
|
local wineChimes = {}
|
|
local drones = {}
|
|
local N = 12
|
|
|
|
love.audio.setDistanceModel( "exponentclamped" )
|
|
|
|
local function StartDrones()
|
|
love.audio.setEffect( "droneReverb", {
|
|
type = "reverb",
|
|
volume = 1.0,
|
|
decaytime = 20}
|
|
|
|
)
|
|
|
|
drones.wail = love.audio.newSource("sounds/drone3.flac", "stream")
|
|
drones.fuck = love.audio.newSource("sounds/noiseloop.flac", "static" )
|
|
drones.subs = love.audio.newSource("sounds/27Hz.flac", "static" )
|
|
drones.bass = love.audio.newSource("sounds/drone.flac", "stream")
|
|
drones.alto = love.audio.newSource("sounds/drone.flac", "stream")
|
|
|
|
drones.subs:setLooping( true )
|
|
drones.subs:setVolume( 0 )
|
|
drones.subs:setPitch( 2.0 )
|
|
--drones.subs:setEffect( "droneReverb", true )
|
|
drones.subs:stop()
|
|
|
|
drones.bass:setLooping( true )
|
|
drones.bass:setVolume( 0 )
|
|
drones.bass:setPitch( 0.25 )
|
|
drones.bass:setEffect( "droneReverb", true )
|
|
drones.bass:stop()
|
|
|
|
drones.alto:setLooping( true )
|
|
drones.alto:setVolume( 0 )
|
|
drones.alto:setPitch( 2 )
|
|
drones.alto:setEffect( "droneReverb", true )
|
|
drones.alto:stop()
|
|
|
|
drones.fuck:setLooping( true )
|
|
drones.fuck:setVolume( 0 )
|
|
drones.fuck:setPitch( 1.0 )
|
|
drones.fuck:setEffect( "droneReverb", true )
|
|
drones.fuck:stop()
|
|
|
|
drones.wail:setLooping( true )
|
|
drones.wail:setVolume( 0 )
|
|
drones.wail:setPitch( 1.0 )
|
|
drones.wail:setEffect( "droneReverb", true )
|
|
drones.wail:stop()
|
|
|
|
love.audio.play( drones.bass )
|
|
love.audio.play( drones.alto )
|
|
love.audio.play( drones.fuck )
|
|
love.audio.play( drones.subs )
|
|
love.audio.play( drones.wail )
|
|
end
|
|
|
|
love.audio.setEffect( "passChimeReverb", {
|
|
type = "reverb",
|
|
volume = 1.0,
|
|
gain = 1.0,} )
|
|
|
|
local wineChime = love.audio.newSource("sounds/chimewinedolce.flac", "static")
|
|
wineChime:setEffect( "passChimeReverb", true )
|
|
local passChime = love.audio.newSource("sounds/chimeb.flac", "static")
|
|
passChime:setEffect( "passChimeReverb", true )
|
|
local failChime = love.audio.newSource("sounds/chime.flac", "static")
|
|
failChime:setEffect( "passChimeReverb", true )
|
|
|
|
for i = 1, N do
|
|
wineChimes[i] = wineChime:clone()
|
|
passChimes[i] = passChime:clone()
|
|
failChimes[i] = failChime:clone()
|
|
end
|
|
|
|
local idxNextPassChime = 1
|
|
local idxNextFailChime = 1
|
|
local idxNextWineChime = 1
|
|
local function GetNextPassChime( )
|
|
idxNextPassChime = idxNextPassChime % N + 1
|
|
return passChimes[ idxNextPassChime ]
|
|
end
|
|
|
|
local function GetNextFailChime( )
|
|
idxNextFailChime = idxNextFailChime % N + 1
|
|
return failChimes[ idxNextFailChime ]
|
|
end
|
|
|
|
local function GetNextWineChime( )
|
|
idxNextWineChime = idxNextWineChime % N + 1
|
|
return wineChimes[ idxNextWineChime ]
|
|
end
|
|
|
|
local pitches =
|
|
{
|
|
1/2,
|
|
3/4,
|
|
1,
|
|
2/3,
|
|
3/2,
|
|
9/8,
|
|
27/16,
|
|
81/64,
|
|
243/128,
|
|
2 --Safety
|
|
}
|
|
|
|
local function GetPitch( th )
|
|
th = 0.5 + 0.5 * th / math.pi
|
|
return pitches[ 1 + math.floor( th * 9 )]
|
|
end
|
|
|
|
local function OnImpact( impact, score, pass, level )
|
|
|
|
--
|
|
if not pass then
|
|
--drones.bass:seek( level )
|
|
-- drones.alto:seek( level )
|
|
else
|
|
|
|
love.audio.setEffect( "passChimeReverb", {
|
|
type = "reverb",
|
|
volume = 1.0,
|
|
gain = 0.1 + 0.9 * level / 120,
|
|
highgain = 0.3,} )
|
|
|
|
end
|
|
|
|
local th = impact.th
|
|
local r = impact.r
|
|
|
|
-- Chimes
|
|
local chime = pass and GetNextPassChime() or GetNextFailChime()
|
|
chime:setPitch( GetPitch( th ) )
|
|
chime:setPosition( 2.0 * r * math.cos( th ), 2.0 * r * math.sin( th ) )
|
|
chime:setVolume( 0.1 + 0.9 * level / 120.0 )
|
|
local highgain = math.max( 0, math.min( score, 1.0 ) - (pass and 0.5 or 0.9))
|
|
chime:setFilter{
|
|
type = "lowpass",
|
|
volume = 0.5 * impact.speed,
|
|
highgain = highgain,
|
|
}
|
|
love.audio.stop( chime )
|
|
love.audio.play( chime )
|
|
|
|
local wineChime = GetNextWineChime()
|
|
wineChime:setPitch( GetPitch( th ) )
|
|
wineChime:setPosition( love.math.random(), love.math.random() )
|
|
wineChime:setVolume( 0.2 * impact.speed * math.max( 0.0, level / 60.0 - 0.5 ) )
|
|
|
|
love.audio.stop( wineChime )
|
|
love.audio.play( wineChime )
|
|
|
|
end
|
|
|
|
local function OnVictory( )
|
|
love.audio.setEffect( "passChimeReverb", {
|
|
type = "reverb",
|
|
volume = 1.0,
|
|
decaytime = 20,
|
|
lategain = 9.5,
|
|
gain = 1.0,
|
|
} )
|
|
|
|
love.audio.setEffect( "droneReverb", {
|
|
type = "reverb",
|
|
volume = 1.0,
|
|
decaytime = 20,
|
|
lategain = 10,
|
|
gain = 1.0,} )
|
|
end
|
|
|
|
--score is the hypothetical "beat score" that would be attained
|
|
--if an impact took place at this instant.
|
|
local function Update( score, level )
|
|
|
|
if level > 2 then
|
|
level = level / 120.0
|
|
drones.bass:setVolume( 0.7 * (0.0 + score) * level )
|
|
drones.alto:setVolume( 0.3 * (0.3 + score) * level * level)
|
|
drones.fuck:setVolume( 3.0 * (0.2 + score) * math.max( 0, level - 0.75 ))
|
|
drones.subs:setVolume( 0.5 * (0.2 + score) * math.max( 0, level - 0.50 ))
|
|
drones.wail:setVolume( 1.5 * (0.5 + score) * math.max( 0, level - 0.66 ))
|
|
end
|
|
|
|
end
|
|
|
|
local function Reset( )
|
|
for i = 1, N do
|
|
love.audio.stop( passChimes[i] )
|
|
love.audio.stop( failChimes[i] )
|
|
love.audio.stop( wineChimes[i] )
|
|
end
|
|
|
|
for _, drone in pairs(drones) do
|
|
love.audio.stop( drone )
|
|
end
|
|
StartDrones()
|
|
end
|
|
|
|
Reset()
|
|
return { OnImpact = OnImpact, Update = Update, Reset = Reset, OnVictory = OnVictory} |