oma-lander/audio/sounds.lua
2026-04-18 23:20:40 +01:00

84 lines
2.2 KiB
Lua

local Sounds = {}
local sources = {}
local SAMPLE_RATE = 44100
local function makeSoundData(duration, generator)
local samples = math.floor(SAMPLE_RATE * duration)
local sd = love.sound.newSoundData(samples, SAMPLE_RATE, 16, 1)
for i = 0, samples - 1 do
local t = i / SAMPLE_RATE
local p = i / samples
sd:setSample(i, math.max(-1, math.min(1, generator(t, p))))
end
return sd
end
local function makeSource(sd)
return love.audio.newSource(sd, "static")
end
local function genThrust(t, p)
local noise = (math.random() * 2 - 1) * 0.25
local low = math.sin(2 * math.pi * 45 * t) * 0.2
local rumble = math.sin(2 * math.pi * 25 * t) * 0.15
return (noise + low + rumble) * 0.4
end
local function genLandGood(t, p)
local freq
if p < 0.33 then freq = 500
elseif p < 0.66 then freq = 700
else freq = 900 end
local env = 0.7
if p > 0.9 then env = (1-p)/0.1 * 0.7 end
return math.sin(2 * math.pi * freq * t) * env * 0.35
end
local function genLandHard(t, p)
local env = (1 - p) ^ 2
return math.sin(2 * math.pi * 250 * t) * env * 0.3
end
local function genCrash(t, p)
local env = (1 - p) ^ 1.2
local sine = math.sin(2 * math.pi * (60 + 30*(1-p)) * t) * 0.5
local noise = (math.random() * 2 - 1) * 0.5
return (sine + noise) * env * 0.5
end
local function genFuelWarn(t, p)
local freq = 800
local env = 0.6
if p > 0.5 then env = 0 end
return math.sin(2 * math.pi * freq * t) * env * 0.3
end
local function genAbort(t, p)
local freq = 600 - p * 300
local env = (1 - p) ^ 1.5
local noise = (math.random() * 2 - 1) * 0.3
return (math.sin(2 * math.pi * freq * t) * 0.4 + noise) * env * 0.4
end
function Sounds.init()
sources = {}
local defs = {
thrust = {0.25, genThrust},
land_good = {0.4, genLandGood},
land_hard = {0.3, genLandHard},
crash = {0.6, genCrash},
fuel_warn = {0.15, genFuelWarn},
abort = {0.3, genAbort},
}
for name, def in pairs(defs) do
sources[name] = makeSource(makeSoundData(def[1], def[2]))
end
end
function Sounds.play(name)
local src = sources[name]
if not src then return end
src:clone():play()
end
return Sounds