Audio tutorial

An audio file can be played by the engine using one of two types of objects, music or sound. The former streams audio off the disc while the latter loads the entire sound file into a buffer. To avoid taking up too much memory, sound effects longer than several seconds should be streamed using the music object. Instances of both streamed and buffered playback are controlled using the player object. The player object allows changing the pan, pitch and volume in realtime.

Volume

In this example, we are going to load and play two audio loops recorded in the .WAV format. One of them is the bass, the other is the percussion and both are at 130 beats per minute. Before we start, we first need to initialize the global audio object by calling the "set_mode" function. The "set_mode" function defines the bits, audio channels and sampling rate that will be used for all playback.

In order to play our two sound files, we call the "play_loop" function found in the global audio object. To make this example a little more exciting we are going to let the user toggle the volume on and off for each loop. Notice that the volume property is individual for each player instance and it ranges from 0 to 1. Supplying a value greater than 1 will not make the sound any louder.

display:create ( "Volume Demo", 800, 600, 32, true )

audio:set_mode ( 16, 2, 44100 )

s1 = Sound ( )
s1:load ( "bass.wav" )
s2 = Sound ( )
s2:load ( "perc.wav" )

p1 = audio:play_loop ( s1 )
p2 = audio:play_loop ( s2 )

keyboard.on_press = function ( keyboard, key )
  if key == KEY_1 then
    p1.volume = 0
    p2.volume = 1
  elseif key == KEY_2 then
    p1.volume = 1
    p2.volume = 0
  elseif key == KEY_3 then
    p1.volume = 1
    p2.volume = 1
  end
end
Download:  volume.lua
bass.wav
perc.wav

Pan

Next, we are going to try and play a mixed sample that is about 24 seconds long. It would take up several megabytes of RAM if we were to load it as a sound object. Therefore, we are going to use the music object to play this sample. The pan property of the player object affects the "position" of the audio source. Setting the pan property to -1 will make the sound come out only from the left speaker while a value of 1 from the right.

display:create ( "Pan Demo", 800, 600, 32, true )

audio:set_mode ( 16, 2, 44100 )

m = Music ( )
m:load ( "mix.wav" )

p = audio:play_loop ( m )

keyboard.on_press = function ( keyboard, key )
  if key == KEY_1 then
    p.pan = -1
  elseif key == KEY_2 then
    p.pan = 1
  elseif key == KEY_3 then
    p.pan = 0
  end
end
Download:  pan.lua
mix.wav

Audio buffers

In the following example, we're going to manually load data into a sound object. The data buffer is basically a Lua table containing numeric values. This technique can be used to create sound effects procedurally.

-- create a sine wave
local data = {}
for i = 1, duration * sample_rate do
  data[i] = math.sin ( ( i * frequency / sample_rate ) * math.pi * 2 )
end
local s = Sound ( )
s:load_data ( data )