Created
March 21, 2014 04:41
-
-
Save josefnpat/9679636 to your computer and use it in GitHub Desktop.
Simple synth
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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