LÖVE エンジンでのシンセサイズサンプル。
参考資料
https://pastebin.com/uu0hBkfW
これがなくなるのも辛いので、自分でもまとめておく。
ちなみにLuaです。
-- source
-- https://pastebin.com/uu0hBkfW
local SD -- SoundData, used as a short buffer
local QS -- Queueable Source
local phaseAccum
local samplerate
local frequency
local lfo_on=false
local note_on=false
-- 準備
function love.load()
phaseAccum = 0.0
samplerate = 44100
frequency = 490.0
buf =512
SD = love.sound.newSoundData(buf, samplerate, 16, 1) -- 2048 samplepoints, at a sampling rate of 44.1kHz, that's 46.44 milliseconds
QS = love.audio.newQueueableSource(SD:getSampleRate(), SD:getBitDepth(), SD:getChannelCount()) -- one is enough to push data into it
QS:play() -- start it up
end
local smp=0
-- 波形生成
function generate(buffer)
-- 0-サンプルバッファの数値
for i=0, buffer:getSampleCount()-1 do
-- 周波数修正
if lfo_on == true then
frequency = frequency + math.sin(phaseAccum/75) * 0.001
end
-- if you want to modify the frequency in realtime
-- 位相の定義(書き込むステップサイズ)
local phaseDelta = frequency / samplerate -- step size
-- 最終的な波形の位置を定義
if note_on == true then
phaseAccum = phaseAccum + phaseDelta
-- サイン波を生成する
-- make a sine wave
smp = math.sin(2.0 * math.pi * phaseAccum)
else
-- 無音を書き込む
smp=0
end
-- サンプルを配置する
buffer:setSample(i, smp)
end
end
function love.keypressed( key )
if love.keyboard.isDown("space") then
note_on=true
print("key on")
end
end
function love.keyreleased( key )
if key == "space" then
note_on= false
print("key off")
phaseAccum=0
end
end
function love.update(dt)
while QS:getFreeBufferCount() > 0 do -- timing
generate(SD) -- make one buffer's worth of samplepoints
QS:queue(SD) -- push buffer
end
QS:play() -- doesn't hurt to have, but kinda pointless
end
