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