Guest User

Karplus-Strong 'piano' for love2d

a guest
Feb 26th, 2018
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 2.02 KB | None | 0 0
  1. local SAMPLE_RATE = 44100
  2.  
  3. -- Karplus-Strong generator
  4.  
  5. local function tick(buffer, attenuation)
  6.   local previous_position = buffer.current
  7.   local first = buffer[buffer.current]
  8.   buffer.current = buffer.current + 1
  9.  
  10.   if buffer.current > buffer.n then
  11.     buffer.current = 1
  12.   end
  13.  
  14.   local second = buffer[buffer.current]
  15.   local value = attenuation * (second + first) / 2
  16.   buffer[previous_position] = value
  17.   return value
  18. end
  19.  
  20. local function create_buffer(frequency)
  21.   local buffer_size = math.floor(SAMPLE_RATE / frequency + 0.5)
  22.   local buf = {}
  23.   for i = 1, buffer_size do
  24.     buf[i] = math.random(-1, 1)
  25.   end
  26.   buf.current = 1
  27.   buf.n = buffer_size
  28.   return buf
  29. end
  30.  
  31. local function generate_sound(frequency, length, attenuation)
  32.   local sound = {}
  33.   local ringbuffer = create_buffer(frequency)
  34.   local length_in_samples = length * SAMPLE_RATE
  35.   for i = 1, length_in_samples do
  36.     sound[i] = tick(ringbuffer, attenuation)
  37.   end
  38.   return sound
  39. end
  40.  
  41. -- Convert array to love2d's SoundData
  42. local function array_to_sound_data(array)
  43.   local data = love.sound.newSoundData(#array, SAMPLE_RATE, 16, 1)
  44.   for i, v in ipairs(array) do
  45.     data:setSample(i-1, v)
  46.   end
  47.   return data
  48. end
  49.  
  50. local attenuation = 1
  51. local notes = {}
  52. do
  53.   local base_frequency = 200
  54.   local keys = {"q", "2", "w", "3", "e", "r", "5", "t", "6", "y", "7", "u", "i"}
  55.   for i, key in pairs(keys) do
  56.     notes[key] = base_frequency * math.pow(2, i/12)
  57.   end
  58. end
  59.  
  60. function love.keypressed(key)
  61.   if key == "up" then
  62.     attenuation = attenuation + 0.01
  63.     if attenuation > 1 then
  64.       attenuation = 1
  65.     end
  66.   elseif key == "down" then
  67.     attenuation = attenuation - 0.01
  68.     if attenuation < 0 then
  69.       attenuation = 0
  70.     end
  71.   end
  72.  
  73.   local frequency = notes[key]
  74.   if frequency then
  75.     local sound = generate_sound(frequency, 5, attenuation)
  76.     local soundData = array_to_sound_data(sound)
  77.     local audiosrc = love.audio.newSource(soundData)
  78.     love.audio.stop()
  79.     love.audio.play(audiosrc)
  80.   end
  81. end
Advertisement
Add Comment
Please, Sign In to add comment