Skip to content

Instantly share code, notes, and snippets.

@josefnpat
Created March 21, 2014 04:41
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save josefnpat/9679636 to your computer and use it in GitHub Desktop.
Save josefnpat/9679636 to your computer and use it in GitHub Desktop.
Simple synth
-- public domain
-- author: LPGhatguy
local default_samples = 48000
local pitch_rate = 2^(1 / 12)
local function round(n)
return math.floor(n + 0.5)
end
local function hertz(semitones, base)
base = base or 220
return base * pitch_rate ^ semitones
end
local function build_tone(frequencies, samples)
samples = samples or default_samples
local data = love.sound.newSoundData(samples, samples, 16, 1)
local scalars = {}
for index = 1, #frequencies do
local frequency, amplitude
if (type(frequencies[index]) == "table") then
frequency = frequencies[index][1]
amplitude = frequencies[index][2] or 1
else
frequency = frequencies[index]
amplitude = 1
end
scalars[index] = {math.floor(frequency + 0.5) * math.pi * 2 / samples, amplitude}
end
for pos = 0, samples - 1 do
local sum = 0
for index = 1, #scalars do
sum = sum + (scalars[index][2] * math.sin(pos * scalars[index][1]))
end
data:setSample(pos, math.min(1, math.max(-1, sum / #frequencies)))
end
local wrapper = love.audio.newSource(data)
wrapper:setLooping(true)
return wrapper
end
local tones = {}
local fading = {}
local keys = {
a = -3,
z = -2,
s = -1,
x = 0,
d = 1,
c = 2,
v = 3,
g = 4,
b = 5,
h = 6,
n = 7,
m = 8
}
function love.update(delta)
for key, value in pairs(fading) do
value:setVolume(math.max(0, value:getVolume() - delta * 1.3))
if (value:getVolume() <= 0) then
value:stop()
end
end
end
function love.keypressed(key)
if (keys[key]) then
local semitones = keys[key]
if (not tones[semitones]) then
tones[semitones] = build_tone({
{hertz(semitones), 1},
{hertz(semitones + 12), 0.937},
{hertz(semitones + 19), 0.960},
{hertz(semitones + 24), 0.863},
{hertz(semitones + 28), 0.889},
{hertz(semitones + 31), 0.789}
}, 192000)
end
if (fading[semitones]) then
fading[semitones] = nil
end
tones[semitones]:stop()
tones[semitones]:setVolume(0.5)
tones[semitones]:play()
end
end
function love.keyreleased(key)
if (keys[key]) then
local semitones = keys[key]
if (tones[semitones]) then
fading[semitones] = tones[semitones]
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment