Merge pull request #12 from jorio/fix-sound

Fix sound (issues #1, #2, #3, #4)
This commit is contained in:
nucular 2014-08-26 16:11:44 +02:00
commit 9fc400fca5

View File

@ -41,8 +41,13 @@ sfxr.BITS_8 = 8
-- Utilities -- Utilities
-- Simulates a C int cast
local function trunc(n) local function trunc(n)
return math.floor(n - 0.5) if n >= 0 then
return math.floor(n)
else
return -math.floor(-n)
end
end end
local function random(low, high) local function random(low, high)
@ -57,14 +62,6 @@ local function clamp(n, min, max)
return math.max(min or -math.huge, math.min(max or math.huge, n)) return math.max(min or -math.huge, math.min(max or math.huge, n))
end end
local function cpypol(a, b)
if b < 0 then
return -a
else
return a
end
end
local function shallowcopy(t) local function shallowcopy(t)
if type(t) == "table" then if type(t) == "table" then
local t2 = {} local t2 = {}
@ -245,17 +242,16 @@ function sfxr.Sound:generate(freq, bits)
local noisebuffer = {} local noisebuffer = {}
-- Reset the sample buffers -- Reset the sample buffers
for i=1, 1025 do for i=1, 1024 do
phaserbuffer[i] = 0 phaserbuffer[i] = 0
end end
for i=1, 33 do for i=1, 32 do
noisebuffer[i] = random(-1, 1) noisebuffer[i] = random(-1, 1)
end end
local function reset() local function reset()
-- subtract 0.017 to match the pitch of the original fperiod = 100 / (self.frequency.start^2 + 0.001)
fperiod = 100 / ((self.frequency.start - 0.017)^2 + 0.001)
maxperiod = 100 / (self.frequency.min^2 + 0.001) maxperiod = 100 / (self.frequency.min^2 + 0.001)
period = trunc(fperiod) period = trunc(fperiod)
@ -268,17 +264,17 @@ function sfxr.Sound:generate(freq, bits)
if self.change.amount >= 0 then if self.change.amount >= 0 then
chg_mod = 1.0 - self.change.amount^2 * 0.9 chg_mod = 1.0 - self.change.amount^2 * 0.9
else else
chg_mod = 1.0 - self.change.amount^2 * 10 chg_mod = 1.0 + self.change.amount^2 * 10
end end
chg_time = 0 chg_time = 0
chg_limit = 0
if self.change.speed == 1 then if self.change.speed == 1 then
chg_limit = 0 chg_limit = 0
else else
chg_limit = trunc((1 - self.change.speed)^2 * 20000 + 32) chg_limit = trunc((1 - self.change.speed)^2 * 20000 + 32)
end end
end end
local phase = 0
reset() reset()
local second_sample = false local second_sample = false
@ -290,13 +286,13 @@ function sfxr.Sound:generate(freq, bits)
self.envelope.sustain^2 * 100000, self.envelope.sustain^2 * 100000,
self.envelope.decay^2 * 100000} self.envelope.decay^2 * 100000}
local phase = self.phaser.offset^2 * 1020 local fphase = self.phaser.offset^2 * 1020
phase = cpypol(phase, self.phaser.offset) if self.phaser.offset < 0 then fphase = -fphase end
local dphase = self.phaser.sweep^2 local dphase = self.phaser.sweep^2
dphase = cpypol(dphase, self.phaser.sweep) if self.phaser.sweep < 0 then dphase = -dphase end
local ipp = 0 local ipp = 0
local iphase = math.abs(trunc(phase)) local iphase = math.abs(trunc(fphase))
local fltp = 0 local fltp = 0
local fltdp = 0 local fltdp = 0
@ -384,8 +380,8 @@ function sfxr.Sound:generate(freq, bits)
-- Phaser -- Phaser
phase = phase + dphase fphase = fphase + dphase
iphase = clamp(math.abs(trunc(phase)), nil, 1023) iphase = clamp(math.abs(trunc(fphase)), nil, 1023)
-- Filter stuff -- Filter stuff
@ -396,7 +392,7 @@ function sfxr.Sound:generate(freq, bits)
-- And finally the actual tone generation and supersampling -- And finally the actual tone generation and supersampling
local ssample = 0 local ssample = 0
for si = 0, self.supersamples do for si = 0, self.supersamples-1 do
local sample = 0 local sample = 0
phase = phase + 1 phase = phase + 1
@ -406,7 +402,7 @@ function sfxr.Sound:generate(freq, bits)
--phase = 0 --phase = 0
phase = phase % period phase = phase % period
if self.wavetype == sfxr.NOISE then if self.wavetype == sfxr.NOISE then
for i = 1, 33 do for i = 1, 32 do
noisebuffer[i] = random(-1, 1) noisebuffer[i] = random(-1, 1)
end end
end end