Commits

Leonard Ritter committed ab46ae3

added test case and more function wrappers

Comments (0)

Files changed (8)

 
 from __future__ import (print_function, division, absolute_import)
 
-from ._al import *
-
-################################################################################
-
-def _cstr(data):
-    if data is None:
-        return _ffi.NULL
-    if isinstance(data, unicode):
-        data = data.encode('utf-8')
-    return _ffi.new('char[]', data)
-    
-def _array(type_, data):
-    if data is None:
-        return _ffi.NULL
-    return _ffi.new(type_+'[]', data)
-
-def _flatten(l):
-    for el in l:
-        if isinstance(el, collections.Iterable) and not isinstance(el, basestring):
-            for sub in _flatten(el):
-                yield sub
-        else:
-            yield el
-            
-################################################################################
-
-def alcOpenDevice(name):
-    return _alcOpenDevice(_cstr(name))
-
-def alcCreateContext(device, data):
-    return _alcCreateContext(device, _array('int', data))
-
-################################################################################
-
-# add wrapped functions
-_module_names = set(locals().keys())
-def get_mangled_names():
-    for name in UNMANGLED_EXPORTS:
-        mangled_name = name.lstrip('_')
-        if mangled_name in _module_names:
-            yield mangled_name
-        else:
-            yield name 
-__all__ = EXPORTS + list(get_mangled_names()) + [
-]
-del _module_names
+from .al import *
+from .managed import *
+from .internal import ALError
 from cffi import FFI
 
 UNMANGLED_EXPORTS = [
+"_alGetFloatv",
+"_alcCaptureCloseDevice",
+"_alGetBufferf",
+"_alGetBuffer3i",
+"_alcIsExtensionPresent",
+"_alGetListeneriv",
+"_alSourceQueueBuffers",
+"_alcCaptureStart",
+"_alcGetCurrentContext",
+"_alcGetIntegerv",
+"_alGetBufferi",
+"_alcGetString",
+"_alcGetProcAddress",
+"_alcDestroyContext",
+"_alGetBufferfv",
+"_alcMakeContextCurrent",
+"_alGetSourcefv",
+"_alSourceUnqueueBuffers",
+"_alGetEnumValue",
+"_alBufferfv",
+"_alGetListenerf",
+"_alGetListeneri",
+"_alGetSourceiv",
+"_alcCaptureSamples",
+"_alSourcefv",
+"_alGetListenerfv",
 "_alcCreateContext",
+"_alcCloseDevice",
+"_alSourceRewindv",
 "_alcOpenDevice",
+"_alListeneriv",
+"_alGetBufferiv",
+"_alSourceStopv",
+"_alSourceiv",
+"_alGetSourcef",
+"_alListenerfv",
+"_alGetSourcei",
+"_alGetListener3i",
+"_alGetProcAddress",
+"_alcGetContextsDevice",
+"_alGetListener3f",
+"_alGenSources",
+"_alDeleteBuffers",
+"_alGetBuffer3f",
+"_alGetIntegerv",
+"_alSourcePausev",
+"_alBufferiv",
+"_alDeleteSources",
+"_alGenBuffers",
+"_alcProcessContext",
+"_alIsExtensionPresent",
+"_alcCaptureStop",
+"_alcCaptureOpenDevice",
+"_alGetDoublev",
+"_alSourcePlayv",
+"_alcGetError",
+"_alBufferData",
+"_alGetSource3f",
+"_alGetBooleanv",
+"_alcSuspendContext",
+"_alcGetEnumValue",
+"_alGetSource3i",
+"_alGetString",
 
 ]
 
 EXPORTS = [
 "alBuffer3i",
 "AL_SOURCE_STATE",
-"alGetFloatv",
 "alBuffer3f",
 "AL_PAUSED",
 "alDisable",
 "AL_STATIC",
-"alcCaptureCloseDevice",
 "AL_BUFFER",
-"alGetBufferf",
 "AL_BUFFERS_PROCESSED",
 "AL_INITIAL",
 "AL_PROCESSED",
-"alGetBuffer3i",
 "AL_PENDING",
 "AL_SAMPLE_OFFSET",
-"alcIsExtensionPresent",
 "ALC_MAJOR_VERSION",
 "AL_FORMAT_STEREO8",
 "AL_SPEED_OF_SOUND",
 "AL_MAX_DISTANCE",
 "alEnable",
-"alGetListeneriv",
 "alSourcei",
-"alSourceQueueBuffers",
-"alcCaptureStart",
-"alcGetCurrentContext",
-"alcGetIntegerv",
 "ALC_INVALID",
-"alGetBufferi",
 "alSourcef",
 "AL_BUFFERS_QUEUED",
-"alcGetString",
 "AL_ILLEGAL_COMMAND",
 "AL_INVALID_VALUE",
 "alSourceRewind",
 "alBufferi",
 "alListenerf",
-"alcGetProcAddress",
 "AL_GAIN",
 "alListeneri",
-"alcDestroyContext",
 "alGetError",
-"alGetBufferfv",
 "AL_DISTANCE_MODEL",
-"alcMakeContextCurrent",
 "ALC_FALSE",
 "alListener3f",
 "AL_ROLLOFF_FACTOR",
 "AL_ORIENTATION",
 "alListener3i",
 "AL_LOOPING",
-"alGetSourcefv",
 "alSource3f",
-"alSourceUnqueueBuffers",
 "AL_CHANNELS",
 "alSource3i",
 "AL_LINEAR_DISTANCE_CLAMPED",
 "AL_DOPPLER_VELOCITY",
 "AL_REFERENCE_DISTANCE",
-"alGetEnumValue",
 "AL_FREQUENCY",
 "ALC_DEFAULT_DEVICE_SPECIFIER",
 "alSourcePlay",
 "AL_INVALID_OPERATION",
 "AL_TRUE",
 "AL_CONE_OUTER_GAIN",
-"alBufferfv",
 "AL_EXPONENT_DISTANCE_CLAMPED",
 "AL_FORMAT_MONO8",
-"alGetListenerf",
-"alGetListeneri",
 "alBufferf",
 "AL_ILLEGAL_ENUM",
-"alGetSourceiv",
 "AL_CONE_OUTER_ANGLE",
-"alcCaptureSamples",
 "AL_FORMAT_STEREO16",
 "ALC_CAPTURE_SAMPLES",
-"alSourcefv",
 "ALC_EXTENSIONS",
 "ALC_DEVICE_SPECIFIER",
 "AL_LINEAR_DISTANCE",
-"alGetListenerfv",
 "AL_POSITION",
 "alSourceStop",
-"alcCloseDevice",
 "alIsEnabled",
 "ALC_STEREO_SOURCES",
-"alSourceRewindv",
 "ALC_CAPTURE_DEVICE_SPECIFIER",
 "AL_INVALID",
 "AL_INVERSE_DISTANCE",
 "ALC_FREQUENCY",
 "AL_SOURCE_TYPE",
 "AL_SOURCE_RELATIVE",
-"alListeneriv",
-"alGetBufferiv",
 "AL_OUT_OF_MEMORY",
 "alDistanceModel",
-"alSourceStopv",
-"alSourceiv",
 "AL_UNUSED",
 "ALC_VERSION_0_1",
-"alGetSourcef",
 "AL_INVALID_NAME",
 "AL_STREAMING",
 "AL_NO_ERROR",
 "AL_FORMAT_MONO16",
-"alListenerfv",
 "AL_INVALID_ENUM",
 "AL_UNDETERMINED",
-"alGetSourcei",
-"alGetListener3i",
 "AL_NONE",
 "AL_RENDERER",
 "AL_DIRECTION",
 "ALC_INVALID_VALUE",
 "AL_PITCH",
-"alGetProcAddress",
-"alcGetContextsDevice",
-"alGetListener3f",
-"alGenSources",
 "AL_INVERSE_DISTANCE_CLAMPED",
-"alDeleteBuffers",
 "alGetFloat",
 "AL_FALSE",
 "alGetBoolean",
-"alGetBuffer3f",
 "ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER",
-"alGetIntegerv",
 "ALC_MINOR_VERSION",
-"alSourcePausev",
 "ALC_OUT_OF_MEMORY",
 "alDopplerFactor",
-"alBufferiv",
-"alDeleteSources",
 "alIsSource",
 "AL_SIZE",
 "alSourcePause",
-"alGenBuffers",
 "ALC_REFRESH",
 "AL_EXTENSIONS",
-"alcProcessContext",
 "AL_SEC_OFFSET",
 "ALC_ATTRIBUTES_SIZE",
-"alIsExtensionPresent",
-"alcCaptureStop",
 "alDopplerVelocity",
 "ALC_INVALID_CONTEXT",
 "AL_VELOCITY",
-"alcCaptureOpenDevice",
 "ALC_ALL_ATTRIBUTES",
 "AL_DOPPLER_FACTOR",
 "AL_EXPONENT_DISTANCE",
 "ALC_MONO_SOURCES",
 "AL_VENDOR",
 "ALC_INVALID_DEVICE",
-"alGetDoublev",
-"alSourcePlayv",
-"alcGetError",
-"alBufferData",
-"alGetSource3f",
 "AL_MIN_GAIN",
-"alGetBooleanv",
 "alGetInteger",
-"alcSuspendContext",
-"alcGetEnumValue",
 "AL_CONE_INNER_ANGLE",
-"alGetSource3i",
 "AL_BITS",
 "AL_PLAYING",
 "ALC_NO_ERROR",
 "AL_VERSION",
-"alGetString",
 
 ]
 
 
 alBuffer3i = guard(lookup('alBuffer3i'))
 AL_SOURCE_STATE = 4112
-alGetFloatv = guard(lookup('alGetFloatv'))
+_alGetFloatv = guard(lookup('alGetFloatv'))
 alBuffer3f = guard(lookup('alBuffer3f'))
 AL_PAUSED = 4115
 alDisable = guard(lookup('alDisable'))
 AL_STATIC = 4136
-alcCaptureCloseDevice = guard(lookup('alcCaptureCloseDevice'))
+_alcCaptureCloseDevice = guard(lookup('alcCaptureCloseDevice'))
 AL_BUFFER = 4105
-alGetBufferf = guard(lookup('alGetBufferf'))
+_alGetBufferf = guard(lookup('alGetBufferf'))
 AL_BUFFERS_PROCESSED = 4118
 AL_INITIAL = 4113
 AL_PROCESSED = 8210
-alGetBuffer3i = guard(lookup('alGetBuffer3i'))
+_alGetBuffer3i = guard(lookup('alGetBuffer3i'))
 AL_PENDING = 8209
 AL_SAMPLE_OFFSET = 4133
-alcIsExtensionPresent = guard(lookup('alcIsExtensionPresent'))
+_alcIsExtensionPresent = guard(lookup('alcIsExtensionPresent'))
 ALC_MAJOR_VERSION = 4096
 AL_FORMAT_STEREO8 = 4354
 AL_SPEED_OF_SOUND = 49155
 AL_MAX_DISTANCE = 4131
 alEnable = guard(lookup('alEnable'))
-alGetListeneriv = guard(lookup('alGetListeneriv'))
+_alGetListeneriv = guard(lookup('alGetListeneriv'))
 alSourcei = guard(lookup('alSourcei'))
-alSourceQueueBuffers = guard(lookup('alSourceQueueBuffers'))
-alcCaptureStart = guard(lookup('alcCaptureStart'))
-alcGetCurrentContext = guard(lookup('alcGetCurrentContext'))
-alcGetIntegerv = guard(lookup('alcGetIntegerv'))
+_alSourceQueueBuffers = guard(lookup('alSourceQueueBuffers'))
+_alcCaptureStart = guard(lookup('alcCaptureStart'))
+_alcGetCurrentContext = guard(lookup('alcGetCurrentContext'))
+_alcGetIntegerv = guard(lookup('alcGetIntegerv'))
 ALC_INVALID = 0
-alGetBufferi = guard(lookup('alGetBufferi'))
+_alGetBufferi = guard(lookup('alGetBufferi'))
 alSourcef = guard(lookup('alSourcef'))
 AL_BUFFERS_QUEUED = 4117
-alcGetString = guard(lookup('alcGetString'))
+_alcGetString = lookup('alcGetString')
 AL_ILLEGAL_COMMAND = 40964
 AL_INVALID_VALUE = 40963
 alSourceRewind = guard(lookup('alSourceRewind'))
 alBufferi = guard(lookup('alBufferi'))
 alListenerf = guard(lookup('alListenerf'))
-alcGetProcAddress = guard(lookup('alcGetProcAddress'))
+_alcGetProcAddress = guard(lookup('alcGetProcAddress'))
 AL_GAIN = 4106
 alListeneri = guard(lookup('alListeneri'))
-alcDestroyContext = guard(lookup('alcDestroyContext'))
-alGetError = guard(lookup('alGetError'))
-alGetBufferfv = guard(lookup('alGetBufferfv'))
+_alcDestroyContext = lookup('alcDestroyContext')
+alGetError = lookup('alGetError')
+_alGetBufferfv = guard(lookup('alGetBufferfv'))
 AL_DISTANCE_MODEL = 53248
-alcMakeContextCurrent = guard(lookup('alcMakeContextCurrent'))
+_alcMakeContextCurrent = guard(lookup('alcMakeContextCurrent'))
 ALC_FALSE = 0
 alListener3f = guard(lookup('alListener3f'))
 AL_ROLLOFF_FACTOR = 4129
 AL_ORIENTATION = 4111
 alListener3i = guard(lookup('alListener3i'))
 AL_LOOPING = 4103
-alGetSourcefv = guard(lookup('alGetSourcefv'))
+_alGetSourcefv = guard(lookup('alGetSourcefv'))
 alSource3f = guard(lookup('alSource3f'))
-alSourceUnqueueBuffers = guard(lookup('alSourceUnqueueBuffers'))
+_alSourceUnqueueBuffers = guard(lookup('alSourceUnqueueBuffers'))
 AL_CHANNELS = 8195
 alSource3i = guard(lookup('alSource3i'))
 AL_LINEAR_DISTANCE_CLAMPED = 53252
 AL_DOPPLER_VELOCITY = 49153
 AL_REFERENCE_DISTANCE = 4128
-alGetEnumValue = guard(lookup('alGetEnumValue'))
+_alGetEnumValue = guard(lookup('alGetEnumValue'))
 AL_FREQUENCY = 8193
 ALC_DEFAULT_DEVICE_SPECIFIER = 4100
 alSourcePlay = guard(lookup('alSourcePlay'))
 AL_INVALID_OPERATION = 40964
 AL_TRUE = 1
 AL_CONE_OUTER_GAIN = 4130
-alBufferfv = guard(lookup('alBufferfv'))
+_alBufferfv = guard(lookup('alBufferfv'))
 AL_EXPONENT_DISTANCE_CLAMPED = 53254
 AL_FORMAT_MONO8 = 4352
-alGetListenerf = guard(lookup('alGetListenerf'))
-alGetListeneri = guard(lookup('alGetListeneri'))
+_alGetListenerf = guard(lookup('alGetListenerf'))
+_alGetListeneri = guard(lookup('alGetListeneri'))
 alBufferf = guard(lookup('alBufferf'))
 AL_ILLEGAL_ENUM = 40962
-alGetSourceiv = guard(lookup('alGetSourceiv'))
+_alGetSourceiv = guard(lookup('alGetSourceiv'))
 AL_CONE_OUTER_ANGLE = 4098
-alcCaptureSamples = guard(lookup('alcCaptureSamples'))
+_alcCaptureSamples = guard(lookup('alcCaptureSamples'))
 AL_FORMAT_STEREO16 = 4355
 ALC_CAPTURE_SAMPLES = 786
-alSourcefv = guard(lookup('alSourcefv'))
+_alSourcefv = guard(lookup('alSourcefv'))
 ALC_EXTENSIONS = 4102
 ALC_DEVICE_SPECIFIER = 4101
 AL_LINEAR_DISTANCE = 53251
-alGetListenerfv = guard(lookup('alGetListenerfv'))
+_alGetListenerfv = guard(lookup('alGetListenerfv'))
 AL_POSITION = 4100
-_alcCreateContext = guard(lookup('alcCreateContext'))
+_alcCreateContext = lookup('alcCreateContext')
 alSourceStop = guard(lookup('alSourceStop'))
-alcCloseDevice = guard(lookup('alcCloseDevice'))
+_alcCloseDevice = lookup('alcCloseDevice')
 alIsEnabled = guard(lookup('alIsEnabled'))
 ALC_STEREO_SOURCES = 4113
-alSourceRewindv = guard(lookup('alSourceRewindv'))
+_alSourceRewindv = guard(lookup('alSourceRewindv'))
 ALC_CAPTURE_DEVICE_SPECIFIER = 784
 AL_INVALID = -1
 AL_INVERSE_DISTANCE = 53249
 ALC_FREQUENCY = 4103
-_alcOpenDevice = guard(lookup('alcOpenDevice'))
+_alcOpenDevice = lookup('alcOpenDevice')
 AL_SOURCE_TYPE = 4135
 AL_SOURCE_RELATIVE = 514
-alListeneriv = guard(lookup('alListeneriv'))
-alGetBufferiv = guard(lookup('alGetBufferiv'))
+_alListeneriv = guard(lookup('alListeneriv'))
+_alGetBufferiv = guard(lookup('alGetBufferiv'))
 AL_OUT_OF_MEMORY = 40965
 alDistanceModel = guard(lookup('alDistanceModel'))
-alSourceStopv = guard(lookup('alSourceStopv'))
-alSourceiv = guard(lookup('alSourceiv'))
+_alSourceStopv = guard(lookup('alSourceStopv'))
+_alSourceiv = guard(lookup('alSourceiv'))
 AL_UNUSED = 8208
 ALC_VERSION_0_1 = 1
-alGetSourcef = guard(lookup('alGetSourcef'))
+_alGetSourcef = guard(lookup('alGetSourcef'))
 AL_INVALID_NAME = 40961
 AL_STREAMING = 4137
 AL_NO_ERROR = 0
 AL_FORMAT_MONO16 = 4353
-alListenerfv = guard(lookup('alListenerfv'))
+_alListenerfv = guard(lookup('alListenerfv'))
 AL_INVALID_ENUM = 40962
 AL_UNDETERMINED = 4144
-alGetSourcei = guard(lookup('alGetSourcei'))
-alGetListener3i = guard(lookup('alGetListener3i'))
+_alGetSourcei = guard(lookup('alGetSourcei'))
+_alGetListener3i = guard(lookup('alGetListener3i'))
 AL_NONE = 0
 AL_RENDERER = 45059
 AL_DIRECTION = 4101
 ALC_INVALID_VALUE = 40964
 AL_PITCH = 4099
-alGetProcAddress = guard(lookup('alGetProcAddress'))
-alcGetContextsDevice = guard(lookup('alcGetContextsDevice'))
-alGetListener3f = guard(lookup('alGetListener3f'))
-alGenSources = guard(lookup('alGenSources'))
+_alGetProcAddress = guard(lookup('alGetProcAddress'))
+_alcGetContextsDevice = guard(lookup('alcGetContextsDevice'))
+_alGetListener3f = guard(lookup('alGetListener3f'))
+_alGenSources = guard(lookup('alGenSources'))
 AL_INVERSE_DISTANCE_CLAMPED = 53250
-alDeleteBuffers = guard(lookup('alDeleteBuffers'))
+_alDeleteBuffers = guard(lookup('alDeleteBuffers'))
 alGetFloat = guard(lookup('alGetFloat'))
 AL_FALSE = 0
 alGetBoolean = guard(lookup('alGetBoolean'))
-alGetBuffer3f = guard(lookup('alGetBuffer3f'))
+_alGetBuffer3f = guard(lookup('alGetBuffer3f'))
 ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER = 785
-alGetIntegerv = guard(lookup('alGetIntegerv'))
+_alGetIntegerv = guard(lookup('alGetIntegerv'))
 ALC_MINOR_VERSION = 4097
-alSourcePausev = guard(lookup('alSourcePausev'))
+_alSourcePausev = guard(lookup('alSourcePausev'))
 ALC_OUT_OF_MEMORY = 40965
 alDopplerFactor = guard(lookup('alDopplerFactor'))
-alBufferiv = guard(lookup('alBufferiv'))
-alDeleteSources = guard(lookup('alDeleteSources'))
+_alBufferiv = guard(lookup('alBufferiv'))
+_alDeleteSources = guard(lookup('alDeleteSources'))
 alIsSource = guard(lookup('alIsSource'))
 AL_SIZE = 8196
 alSourcePause = guard(lookup('alSourcePause'))
-alGenBuffers = guard(lookup('alGenBuffers'))
+_alGenBuffers = guard(lookup('alGenBuffers'))
 ALC_REFRESH = 4104
 AL_EXTENSIONS = 45060
-alcProcessContext = guard(lookup('alcProcessContext'))
+_alcProcessContext = guard(lookup('alcProcessContext'))
 AL_SEC_OFFSET = 4132
 ALC_ATTRIBUTES_SIZE = 4098
-alIsExtensionPresent = guard(lookup('alIsExtensionPresent'))
-alcCaptureStop = guard(lookup('alcCaptureStop'))
+_alIsExtensionPresent = guard(lookup('alIsExtensionPresent'))
+_alcCaptureStop = guard(lookup('alcCaptureStop'))
 alDopplerVelocity = guard(lookup('alDopplerVelocity'))
 ALC_INVALID_CONTEXT = 40962
 AL_VELOCITY = 4102
-alcCaptureOpenDevice = guard(lookup('alcCaptureOpenDevice'))
+_alcCaptureOpenDevice = guard(lookup('alcCaptureOpenDevice'))
 ALC_ALL_ATTRIBUTES = 4099
 AL_DOPPLER_FACTOR = 49152
 AL_EXPONENT_DISTANCE = 53253
 ALC_MONO_SOURCES = 4112
 AL_VENDOR = 45057
 ALC_INVALID_DEVICE = 40961
-alGetDoublev = guard(lookup('alGetDoublev'))
-alSourcePlayv = guard(lookup('alSourcePlayv'))
-alcGetError = guard(lookup('alcGetError'))
-alBufferData = guard(lookup('alBufferData'))
-alGetSource3f = guard(lookup('alGetSource3f'))
+_alGetDoublev = guard(lookup('alGetDoublev'))
+_alSourcePlayv = guard(lookup('alSourcePlayv'))
+_alcGetError = lookup('alcGetError')
+_alBufferData = guard(lookup('alBufferData'))
+_alGetSource3f = guard(lookup('alGetSource3f'))
 AL_MIN_GAIN = 4109
-alGetBooleanv = guard(lookup('alGetBooleanv'))
+_alGetBooleanv = guard(lookup('alGetBooleanv'))
 alGetInteger = guard(lookup('alGetInteger'))
-alcSuspendContext = guard(lookup('alcSuspendContext'))
-alcGetEnumValue = guard(lookup('alcGetEnumValue'))
+_alcSuspendContext = guard(lookup('alcSuspendContext'))
+_alcGetEnumValue = guard(lookup('alcGetEnumValue'))
 AL_CONE_INNER_ANGLE = 4097
-alGetSource3i = guard(lookup('alGetSource3i'))
+_alGetSource3i = guard(lookup('alGetSource3i'))
 AL_BITS = 8194
 AL_PLAYING = 4114
 ALC_NO_ERROR = 0
 AL_VERSION = 45058
-alGetString = guard(lookup('alGetString'))
+_alGetString = guard(lookup('alGetString'))
 
 
+update_defs(locals())
 
+
+from __future__ import (print_function, division, absolute_import)
+
+from ._al import *
+from .internal import wrap_retstr, wrap_gen, wrap_del
+
+# providing our own until ffi has it
+CData = type(_ffi.cast("int", 0))
+CType = type(_ffi.typeof("int"))
+
+################################################################################
+
+def _cstr(data):
+    if data is None:
+        return _ffi.NULL
+    if isinstance(data, unicode):
+        data = data.encode('utf-8')
+    return _ffi.new('char[]', data)
+    
+def _array(type_, data):
+    if data is None:
+        return _ffi.NULL
+    return _ffi.new(type_+'[]', data)
+
+def _flatten(l):
+    for el in l:
+        if isinstance(el, collections.Iterable) and not isinstance(el, basestring):
+            for sub in _flatten(el):
+                yield sub
+        else:
+            yield el
+            
+################################################################################
+
+def alcOpenDevice(name=None):
+    return _alcOpenDevice(_cstr(name))
+
+def alcCreateContext(device, data=None):
+    if not data:
+        data = _ffi.NULL
+    else:
+        data = _ffi.new('int[]', data + [0,0])
+    return _alcCreateContext(device, data)
+
+def alBufferData(buffer, format, data, freq):
+    if isinstance(data, CData):
+        ptr = data
+    elif isinstance(data, (tuple,list)):
+        ptr = _ffi.new('unsigned char[]', data)
+    else:
+        ptr = _ffi.new('char[]', data)
+    _alBufferData(buffer, format, ptr, len(data), freq)
+
+def alListenerfv(enum, values):
+    _alListenerfv(enum, values)    
+
+def alcMakeContextCurrent(context):
+    return ord(_alcMakeContextCurrent(context))
+
+def alGetSourcei(source, pname):
+    value = _ffi.new('ALint *')
+    _alGetSourcei(source, pname, value)
+    return value[0]
+
+alcDestroyContext = _alcDestroyContext
+alcCloseDevice = _alcCloseDevice 
+
+################################################################################
+
+_symmetric_managers = [
+    ('Sources','Source'),
+    ('Buffers','Buffer'),
+]
+
+_wrap_methods = {
+    wrap_retstr : [
+        'alGetString',
+        'alcGetString',
+    ],
+    wrap_gen : [
+    ],
+    wrap_del : [
+    ],
+}
+
+def build_wrappers(ns):
+    wrapgenlist = _wrap_methods[wrap_gen]
+    wrapdellist = _wrap_methods[wrap_del]
+    for plural,singular in _symmetric_managers:
+        wrapgenlist.append('alGen' + plural)
+        wrapdellist.append('alDelete' + plural)
+    
+    for method,names in _wrap_methods.items():
+        for name in names:
+            ns[name] = method(ns['_'+name])
+
+build_wrappers(locals())
+del _wrap_methods
+
+################################################################################
+
+# add wrapped functions
+_module_names = set(locals().keys())
+def get_mangled_names():
+    for name in UNMANGLED_EXPORTS:
+        mangled_name = name.lstrip('_')
+        if mangled_name in _module_names:
+            yield mangled_name
+        else:
+            yield name 
+__all__ = EXPORTS + list(get_mangled_names()) + [
+]
+del _module_names
 THISDIR = os.path.dirname(__file__)
 
 POST_TEMPLATE = """
+update_defs(locals())
 """
 
 autobind = AutoBind(options=dict(
     DEFINES = [
     ],
     PRIVATE_SYMBOLS = [
-        'alcOpenDevice',
-        'alcCreateContext'
     ],
     AUTOCHECK_BLACKLIST = [
+        'alGetError',
+        'alcGetError',
+        'alcGetString',
+        'alcOpenDevice',
+        'alcCreateContext',
+        'alcDestroyContext',
+        'alcCloseDevice',
     ],
     REPLACES = [
         #('AL_APIENTRY', '*'),
         ('ALC_API', ''),
     ],
     LIBNAME = 'openal',
-    AUTOMANGLE = False,
+    AUTOMANGLE = True,
     PYPREDEFS = os.path.join(THISDIR, '..', 'predefs', 'al.pypredef'),
     OUTMODULE = os.path.join(THISDIR, '_al.py'),
     GENPOSTFIX = POST_TEMPLATE,
     'lookup',
     'check_error',
     'guard',
+    'update_defs',
     'ALError',
 ]
 
     _LIB = _ffi.dlopen(libname)
     return _LIB
 
+def wrapstr(result):
+    if result:
+        return _ffi.string(result)
+    return None
+
+def wrap_retstr(func):
+    def wrapper(*argv):
+        return wrapstr(func(*argv))
+    return wrapper
+
+def wrap_gen(func):
+    def wrapper(count):
+        ids = _ffi.new('ALuint[]',[0]*count)
+        func(count, ids)
+        return [int(i) for i in ids]
+    return wrapper
+    
+def wrap_del(func):
+    def wrapper(ids):
+        func(len(ids), ids)
+    return wrapper
+
 def lookup(name):
     if hasattr(_LIB, name):
         return getattr(_LIB, name)
     print("AL warning: function",name,"missing.")
     return None 
     
+_ERROR_DESC = {}
 def check_error():
-    pass
+    error = _LIB.alGetError()
+    if error == 0:
+        return
+    traceback.print_stack()
+    print(_ERROR_DESC.get(error, repr(error)))
+    #raise ALError, _ERROR_DESC.get(error, repr(error))
 
 def guard(func):
     if not func:
     newfunc.func_name = name
     newfunc.__doc__ = func.__doc__
     return newfunc
+
+def update_defs(m):
+    global _ERROR_DESC
+    _ERROR_DESC = {
+        m['AL_NO_ERROR'] : "AL_NO_ERROR: There is no current error.",
+        m['AL_INVALID_NAME'] : "AL_INVALID_NAME: Invalid name parameter.",
+        m['AL_INVALID_ENUM'] : "AL_INVALID_ENUM: Invalid parameter.",
+        m['AL_INVALID_VALUE'] : "AL_INVALID_VALUE: Invalid enum parameter value.",
+        m['AL_INVALID_OPERATION'] : "AL_INVALID_OPERATION: Illegal call.",
+        m['AL_OUT_OF_MEMORY'] : "AL_OUT_OF_MEMORY: Unable to allocate memory.",
+    }
+
+# a collection of classes to help with managing the lifetime of AL resources
+
+from __future__ import (print_function, division, absolute_import)
+
+from .al import *
+from .al import _symmetric_managers 
+
+__all__ = [
+    'alSource', 'alSources',
+    'alBuffer', 'alBuffers',
+]
+
+################################################################################
+
+def build_class_r2r(name, create_func, delete_func):
+    """build class for single resource functions"""
+    def __init__(self, *args):
+        self._id = create_func(*args)
+        
+    def __int__(self):
+        return self._id
+
+    def Delete(self):
+        delete_func(self._id)
+        self._id = 0
+
+    def __del__(self):
+        if self._id:
+            self.Delete()
+    
+    return type(name, (), dict(
+            __init__ = __init__,
+            __int__ = __int__,
+            Delete = Delete,
+            __del__ = __del__,
+        ))
+
+def build_class_rr2r(name, create_func, delete_func):
+    """build single class for array resource functions"""
+    def __init__(self):
+        self._id = create_func(1)[0]
+        
+    def __int__(self):
+        return self._id
+
+    def Delete(self):
+        delete_func([self._id])
+        self._id = 0
+
+    def __del__(self):
+        if self._id:
+            self.Delete()
+    
+    return type(name, (), dict(
+            __init__ = __init__,
+            __int__ = __int__,
+            Delete = Delete,
+            __del__ = __del__,
+        ))
+
+def build_class_rr2rr(name, create_func, delete_func):
+    """build array class for array resource functions"""
+    def __init__(self, count):
+        self._ids = create_func(count)
+        
+    def __iter__(self):
+        return iter(self._ids)
+    
+    def __getitem__(self, index):
+        return self._ids[index]
+
+    def Delete(self):
+        delete_func(self._ids)
+        self._ids = None
+
+    def __del__(self):
+        if self._ids:
+            self.Delete()
+    
+    return type(name, (), dict(
+            __init__ = __init__,
+            __iter__ = __iter__,
+            __getitem__ = __getitem__,
+            Delete = Delete,
+            __del__ = __del__,
+        ))
+    
+################################################################################
+
+def build_classes(ns):
+    for plural,singular in _symmetric_managers:
+        genfunc = ns['alGen'+plural]
+        delfunc = ns['alDelete'+plural]
+        clsname = 'al' + singular
+        ns[clsname] = build_class_rr2r(clsname, genfunc, delfunc)
+        __all__.append(clsname)
+        clsname = 'al' + plural
+        ns[clsname] = build_class_rr2rr(clsname, genfunc, delfunc)
+        __all__.append(clsname)
+
+build_classes(locals())
+
+################################################################################

testing/data/laser.wav

Binary file added.
+from __future__ import (print_function, division, absolute_import)
+
+import time
+import os
+import wave
+
+from al import *
+
+thisdir = os.path.abspath(os.path.dirname(__file__))
+
+def test_al():
+    device = alcOpenDevice()
+    context = alcCreateContext(device, [
+        ALC_FREQUENCY, 44100,
+        #ALC_REFRESH, 60,
+        #ALC_SYNC, 1,
+        ALC_MONO_SOURCES, 16,
+        ALC_STEREO_SOURCES, 8,
+    ])
+    result = alcMakeContextCurrent(context)
+    assert result == AL_TRUE, result
+    print('ALC_DEVICE_SPECIFIER:', alcGetString(device, ALC_DEVICE_SPECIFIER))
+    print('AL_VERSION:',alGetString(AL_VERSION))
+    print('AL_RENDERER:',alGetString(AL_RENDERER))
+    print('AL_VENDOR:',alGetString(AL_VENDOR))
+    print('AL_EXTENSIONS:',alGetString(AL_EXTENSIONS))
+    
+    alListener3f(AL_POSITION, 0, 0, 0)
+    alListener3f(AL_VELOCITY, 0, 0, 0)
+    alListenerfv(AL_ORIENTATION, [0, 0, -1, 0, 1, 0])
+    
+    buffer = alBuffer()
+    # load wave file into buffer
+    f = wave.open(os.path.join(thisdir,'data','laser.wav'), 'rb')
+    assert f.getnchannels() == 1
+    assert f.getsampwidth() == 2
+    assert f.getnframes() == 16963
+    assert f.getcomptype() == 'NONE'
+    assert f.getframerate() == 44100
+    samples = f.readframes(f.getnframes())
+    assert len(samples) == f.getnframes()*f.getsampwidth()*f.getnchannels()
+    assert len(samples)%2 == 0
+    alBufferData(buffer, AL_FORMAT_MONO16, samples, f.getframerate())
+    f.close()
+    
+    source = alSource()
+    alSourcef(source, AL_PITCH, 1)
+    alSourcef(source, AL_GAIN, 1)
+    alSource3f(source, AL_POSITION, 0, 0, 0)
+    alSource3f(source, AL_VELOCITY, 0, 0, 0)
+    alSourcei(source, AL_LOOPING, AL_TRUE)
+    alSourcei(source, AL_BUFFER, buffer)
+    alSourcePlay(source)
+    for i in range(5):
+        print(alGetSourcei(source, AL_BYTE_OFFSET))
+        time.sleep(1.0)
+    
+    alcDestroyContext(context)
+    alcCloseDevice(device)
+
+if __name__ == '__main__':
+    test_al()