Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
OpenAL with luajit
local ffi = require"ffi"
local function process_defines(file,defines)
defines = defines or {}
--TODO: unifdef
for line in io.lines(file) do
local n ,v = line:match("#define%s+(%S+)%s+(.*)")
if n then
v = defines[v] or v
v = tonumber(v) or v
defines[n] = v
end
end
return defines
end
local openal_lib = ffi.load("OpenAL32.dll")
ffi.cdef(assert(io.open([[U:\Programming\OpenAL\processed_al.h]])):read("*a"))
ffi.cdef(assert(io.open([[U:\Programming\OpenAL\processed_alc.h]])):read("*a"))
local openal_defs = {}
process_defines([[C:\Program Files (x86)\OpenAL 1.1 SDK\include\al.h]],openal_defs)
process_defines([[C:\Program Files (x86)\OpenAL 1.1 SDK\include\alc.h]],openal_defs)
local openal = setmetatable({},{__index = function (t,k) return openal_defs[k] or openal_lib[k] end;})
openal.format = {
MONO8 = openal_defs.AL_FORMAT_MONO8 ;
MONO16 = openal_defs.AL_FORMAT_MONO16 ;
STEREO8 = openal_defs.AL_FORMAT_STEREO8 ;
STEREO16 = openal_defs.AL_FORMAT_STEREO16 ;
}
openal.error = {
[openal_defs.AL_NO_ERROR] = "No Error." ;
[openal_defs.AL_INVALID_NAME] = "Invalid Name paramater passed to AL call." ;
[openal_defs.AL_ILLEGAL_ENUM] = "Invalid parameter passed to AL call." ;
[openal_defs.AL_INVALID_VALUE] = "Invalid enum parameter value." ;
[openal_defs.AL_ILLEGAL_COMMAND] = "Illegal call." ;
[openal_defs.AL_OUT_OF_MEMORY] = "Out of memory." ;
}
local function checkforerror()
local e = openal.alGetError()
return e == openal_defs.AL_NO_ERROR , openal.error[e]
end
local dev = assert(openal.alcOpenDevice(nil),"Can't Open Device")
local ctx = assert(openal.alcCreateContext(dev,nil),"Can't create context")
openal.alcMakeContextCurrent(ctx)
local NUM_BUFFERS = 3
local BUFFER_SIZE = 4096
local source = ffi.new("ALuint[1]")
local buffers = ffi.new("ALuint[?]",NUM_BUFFERS)
openal.alGenBuffers(NUM_BUFFERS,buffers)
openal.alGenSources(1,source)
assert(checkforerror())
local frequency = 44100
local format = openal.format.MONO16;
local source_data = ffi.new("int16_t[?]",BUFFER_SIZE)
local source_len = ffi.sizeof(source_data)
local m = 2*math.pi/frequency*440
for i=0,BUFFER_SIZE-1 do
source_data[i]=(2^15-1)*math.sin(m*i)
end
openal.alBufferData(buffers[0],format,source_data,source_len,frequency)
openal.alBufferData(buffers[1],format,source_data,source_len,frequency)
openal.alBufferData(buffers[2],format,source_data,source_len,frequency)
assert(checkforerror())
openal.alSourceQueueBuffers(source[0],NUM_BUFFERS,buffers)
openal.alSourcePlay(source[0]);
assert(checkforerror())
local buffer = ffi.new("ALuint[1]")
local val = ffi.new("ALint[1]")
while true do
openal.alGetSourcei(source[0],openal.AL_BUFFERS_PROCESSED,val)
--assert(checkforerror())
print(val[0])
if val[0]>0 then
for i=val[0],0,-1 do
openal.alSourceUnqueueBuffers(source[0], 1, buffer)
assert(checkforerror())
openal.alBufferData(buffer[0], format, source_data, source_len, frequency)
assert(checkforerror())
openal.alSourceQueueBuffers(source[0], 1, buffer)
assert(checkforerror())
end
openal.alGetSourcei(source[0], openal.AL_SOURCE_STATE, val)
assert(checkforerror())
if val[0] ~= openal.AL_PLAYING then
openal.alSourcePlay(source[0])
assert(checkforerror())
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.