Updated everything for dependencies. All sub packages are now part of the project. This was a massive update, hopefully won't have to be reverted.

This commit is contained in:
Storm Dragon
2025-01-16 17:03:01 -05:00
parent a5c0e7a71c
commit 2e337db3c5
78 changed files with 4774 additions and 82 deletions

View File

@ -0,0 +1,304 @@
// Forked by Tim Shannon 2012
// Copyright 2009 Peter H. Froehlich. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// C-level binding for OpenAL's "alc" API.
//
// Please consider using the Go-level binding instead.
//
// Note that "alc" introduces the exact same types as "al"
// but with different names. Check the documentation of
// openal/al for more information about the mapping to
// Go types.
//
// XXX: Sadly we have to returns pointers for both Device
// and Context to avoid problems with implicit assignments
// in clients. It's sad because it makes the overhead a
// lot higher, each of those calls triggers an allocation.
package openal
//#cgo linux LDFLAGS: -lopenal
//#cgo darwin LDFLAGS: -framework OpenAL
//#include <stdlib.h>
//#include <string.h>
//#include "local.h"
/*
ALCdevice *walcOpenDevice(const char *devicename) {
return alcOpenDevice(devicename);
}
const ALCchar *alcGetString( ALCdevice *device, ALCenum param );
void walcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, void *data) {
alcGetIntegerv(device, param, size, data);
}
ALCdevice *walcCaptureOpenDevice(const char *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize) {
return alcCaptureOpenDevice(devicename, frequency, format, buffersize);
}
ALCint walcGetInteger(ALCdevice *device, ALCenum param) {
ALCint result;
alcGetIntegerv(device, param, 1, &result);
return result;
}
*/
import "C"
import "unsafe"
const (
Frequency = 0x1007 // int Hz
Refresh = 0x1008 // int Hz
Sync = 0x1009 // bool
MonoSources = 0x1010 // int
StereoSources = 0x1011 // int
)
// The Specifier string for default device?
const (
DefaultDeviceSpecifier = 0x1004
DeviceSpecifier = 0x1005
Extensions = 0x1006
AllDevicesSpecifier = 0x1013
)
// ?
const (
MajorVersion = 0x1000
MinorVersion = 0x1001
)
// ?
const (
AttributesSize = 0x1002
AllAttributes = 0x1003
)
// Capture extension
const (
CaptureDeviceSpecifier = 0x310
CaptureDefaultDeviceSpecifier = 0x311
CaptureSamples = 0x312
)
//warning: this function does not free internal pointers
//warning: memory leak
func GetStrings(param int32) []string {
start := C.alcGetString(nil,C.ALenum(param))
ptr := unsafe.Pointer(start)
if ptr == nil {
return nil
}
ret := make([]string,0)
offset := uint(0)
for {
slen := uint(C.strlen((*C.char)(ptr)))
if slen==0 {
break
}
ret=append(ret,C.GoStringN((*C.char)(ptr),C.int(slen)))
ptr = unsafe.Pointer(uintptr(ptr) + uintptr(slen+1))
offset+=(slen+1)
}
ptr = unsafe.Pointer(uintptr(ptr) - uintptr(offset))
//This should be freeable; I've tried everything I can think of to free the returned pointer.
//need to make sure alcchar doesn't have a weird free thingie, but that's all I can think of.
//C.free(unsafe.Pointer(start))
return ret
}
type Device struct {
// Use uintptr instead of *C.ALCdevice.
// On Mac OS X, this value is 0x18 and might cause crash with a raw pointer.
handle uintptr
}
func (self *Device) getError() uint32 {
return uint32(C.alcGetError((*C.ALCdevice)(unsafe.Pointer(self.handle))))
}
// Err() returns the most recent error generated
// in the AL state machine.
func (self *Device) Err() error {
switch code := self.getError(); code {
case 0x0000:
return nil
case 0xA001:
return ErrInvalidDevice
case 0xA002:
return ErrInvalidContext
case 0xA003:
return ErrInvalidEnum
case 0xA004:
return ErrInvalidValue
case 0xA005:
return ErrOutOfMemory
default:
return ErrorCode(code)
}
}
func OpenDevice(name string) *Device {
// TODO: turn empty string into nil?
// TODO: what about an error return?
p := C.CString(name)
h := C.walcOpenDevice(p)
C.free(unsafe.Pointer(p))
if h==nil {
return nil
}
return &Device{uintptr((unsafe.Pointer)(h))}
}
func (self *Device) cHandle() *C.ALCdevice {
return (*C.ALCdevice)(unsafe.Pointer(self.handle))
}
func (self *Device) CloseDevice() bool {
//TODO: really a method? or not?
return C.alcCloseDevice(self.cHandle()) != 0
}
func (self *Device) CreateContext() *Context {
// TODO: really a method?
// TODO: attrlist support
c := C.alcCreateContext(self.cHandle(), nil)
if c==nil {
return nil
}
return &Context{uintptr(unsafe.Pointer(c))}
}
func (self *Device) GetIntegerv(param uint32, size uint32) (result []int32) {
result = make([]int32, size)
C.walcGetIntegerv(self.cHandle(), C.ALCenum(param), C.ALCsizei(size), unsafe.Pointer(&result[0]))
return
}
func (self *Device) GetInteger(param uint32) int32 {
return int32(C.walcGetInteger(self.cHandle(), C.ALCenum(param)))
}
type CaptureDevice struct {
Device
sampleSize uint32
}
func CaptureOpenDevice(name string, freq uint32, format Format, size uint32) *CaptureDevice {
// TODO: turn empty string into nil?
// TODO: what about an error return?
p := C.CString(name)
h := C.walcCaptureOpenDevice(p, C.ALCuint(freq), C.ALCenum(format), C.ALCsizei(size))
C.free(unsafe.Pointer(p))
if h==nil {
return nil
}
return &CaptureDevice{Device{uintptr(unsafe.Pointer(h))}, uint32(format.SampleSize())}
}
// XXX: Override Device.CloseDevice to make sure the correct
// C function is called even if someone decides to use this
// behind an interface.
func (self *CaptureDevice) CloseDevice() bool {
return C.alcCaptureCloseDevice(self.cHandle()) != 0
}
func (self *CaptureDevice) CaptureCloseDevice() bool {
return self.CloseDevice()
}
func (self *CaptureDevice) CaptureStart() {
C.alcCaptureStart(self.cHandle())
}
func (self *CaptureDevice) CaptureStop() {
C.alcCaptureStop(self.cHandle())
}
func (self *CaptureDevice) CaptureTo(data []byte) {
C.alcCaptureSamples(self.cHandle(), unsafe.Pointer(&data[0]), C.ALCsizei(uint32(len(data))/self.sampleSize))
}
func (self *CaptureDevice) CaptureToInt16(data []int16) {
C.alcCaptureSamples(self.cHandle(), unsafe.Pointer(&data[0]), C.ALCsizei(uint32(len(data))*2/self.sampleSize))
}
func (self *CaptureDevice) CaptureMono8To(data []byte) {
self.CaptureTo(data)
}
func (self *CaptureDevice) CaptureMono16To(data []int16) {
self.CaptureToInt16(data)
}
func (self *CaptureDevice) CaptureStereo8To(data [][2]byte) {
C.alcCaptureSamples(self.cHandle(), unsafe.Pointer(&data[0]), C.ALCsizei(uint32(len(data))*2/self.sampleSize))
}
func (self *CaptureDevice) CaptureStereo16To(data [][2]int16) {
C.alcCaptureSamples(self.cHandle(), unsafe.Pointer(&data[0]), C.ALCsizei(uint32(len(data))*4/self.sampleSize))
}
func (self *CaptureDevice) CaptureSamples(size uint32) (data []byte) {
data = make([]byte, size*self.sampleSize)
self.CaptureTo(data)
return
}
func (self *CaptureDevice) CaptureSamplesInt16(size uint32) (data []int16) {
data = make([]int16, size*self.sampleSize/2)
self.CaptureToInt16(data)
return
}
func (self *CaptureDevice) CapturedSamples() (size uint32) {
return uint32(self.GetInteger(CaptureSamples))
}
///// Context ///////////////////////////////////////////////////////
// Context encapsulates the state of a given instance
// of the OpenAL state machine. Only one context can
// be active in a given process.
type Context struct {
// Use uintptr instead of *C.ALCcontext
// On Mac OS X, this value is 0x19 and might cause crash with a raw pointer.
handle uintptr
}
// A context that doesn't exist, useful for certain
// context operations (see OpenAL documentation for
// details).
var NullContext Context
func (self *Context) cHandle() *C.ALCcontext {
return (*C.ALCcontext)(unsafe.Pointer(self.handle))
}
// Renamed, was MakeContextCurrent.
func (self *Context) Activate() bool {
return C.alcMakeContextCurrent(self.cHandle()) != alFalse
}
// Renamed, was ProcessContext.
func (self *Context) Process() {
C.alcProcessContext(self.cHandle())
}
// Renamed, was SuspendContext.
func (self *Context) Suspend() {
C.alcSuspendContext(self.cHandle())
}
// Renamed, was DestroyContext.
func (self *Context) Destroy() {
C.alcDestroyContext(self.cHandle())
self.handle = uintptr(unsafe.Pointer(nil))
}
// Renamed, was GetContextsDevice.
func (self *Context) GetDevice() *Device {
return &Device{uintptr(unsafe.Pointer(C.alcGetContextsDevice(self.cHandle())))}
}
// Renamed, was GetCurrentContext.
func CurrentContext() *Context {
return &Context{uintptr(unsafe.Pointer(C.alcGetCurrentContext()))}
}

View File

@ -0,0 +1,207 @@
// Copyright 2009 Peter H. Froehlich. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package openal
/*
#include <stdlib.h>
#cgo darwin LDFLAGS: -framework OpenAL
#include "local.h"
#include "wrapper.h"
*/
import "C"
import "unsafe"
// Buffers are storage space for sample data.
type Buffer uint32
// Attributes that can be queried with Buffer.Geti().
const (
alFrequency = 0x2001
alBits = 0x2002
alChannels = 0x2003
alSize = 0x2004
)
type Buffers []Buffer
// NewBuffers() creates n fresh buffers.
// Renamed, was GenBuffers.
func NewBuffers(n int) (buffers Buffers) {
buffers = make(Buffers, n)
C.walGenBuffers(C.ALsizei(n), unsafe.Pointer(&buffers[0]))
return
}
// Delete() deletes the given buffers.
func (self Buffers) Delete() {
n := len(self)
C.walDeleteBuffers(C.ALsizei(n), unsafe.Pointer(&self[0]))
}
// Renamed, was Bufferf.
func (self Buffer) setf(param int32, value float32) {
C.alBufferf(C.ALuint(self), C.ALenum(param), C.ALfloat(value))
}
// Renamed, was Buffer3f.
func (self Buffer) set3f(param int32, value1, value2, value3 float32) {
C.alBuffer3f(C.ALuint(self), C.ALenum(param), C.ALfloat(value1), C.ALfloat(value2), C.ALfloat(value3))
}
// Renamed, was Bufferfv.
func (self Buffer) setfv(param int32, values []float32) {
C.walBufferfv(C.ALuint(self), C.ALenum(param), unsafe.Pointer(&values[0]))
}
// Renamed, was Bufferi.
func (self Buffer) seti(param int32, value int32) {
C.alBufferi(C.ALuint(self), C.ALenum(param), C.ALint(value))
}
// Renamed, was Buffer3i.
func (self Buffer) set3i(param int32, value1, value2, value3 int32) {
C.alBuffer3i(C.ALuint(self), C.ALenum(param), C.ALint(value1), C.ALint(value2), C.ALint(value3))
}
// Renamed, was Bufferiv.
func (self Buffer) setiv(param int32, values []int32) {
C.walBufferiv(C.ALuint(self), C.ALenum(param), unsafe.Pointer(&values[0]))
}
// Renamed, was GetBufferf.
func (self Buffer) getf(param int32) float32 {
return float32(C.walGetBufferf(C.ALuint(self), C.ALenum(param)))
}
// Renamed, was GetBuffer3f.
func (self Buffer) get3f(param int32) (value1, value2, value3 float32) {
var v1, v2, v3 float32
C.walGetBuffer3f(C.ALuint(self), C.ALenum(param), unsafe.Pointer(&v1),
unsafe.Pointer(&v2), unsafe.Pointer(&v3))
value1, value2, value3 = v1, v2, v3
return
}
// Renamed, was GetBufferfv.
func (self Buffer) getfv(param int32, values []float32) {
C.walGetBufferfv(C.ALuint(self), C.ALenum(param), unsafe.Pointer(&values[0]))
return
}
// Renamed, was GetBufferi.
func (self Buffer) geti(param int32) int32 {
return int32(C.walGetBufferi(C.ALuint(self), C.ALenum(param)))
}
// Renamed, was GetBuffer3i.
func (self Buffer) get3i(param int32) (value1, value2, value3 int32) {
var v1, v2, v3 int32
C.walGetBuffer3i(C.ALuint(self), C.ALenum(param), unsafe.Pointer(&v1),
unsafe.Pointer(&v2), unsafe.Pointer(&v3))
value1, value2, value3 = v1, v2, v3
return
}
// Renamed, was GetBufferiv.
func (self Buffer) getiv(param int32, values []int32) {
C.walGetBufferiv(C.ALuint(self), C.ALenum(param), unsafe.Pointer(&values[0]))
}
type Format uint32
func (f Format) SampleSize() int {
switch f {
case FormatMono8:
return 1
case FormatMono16:
return 2
case FormatStereo8:
return 2
case FormatStereo16:
return 4
default:
return 1
}
}
// Format of sound samples passed to Buffer.SetData().
const (
FormatMono8 Format = 0x1100
FormatMono16 Format = 0x1101
FormatStereo8 Format = 0x1102
FormatStereo16 Format = 0x1103
)
// SetData() specifies the sample data the buffer should use.
// For FormatMono16 and FormatStereo8 the data slice must be a
// multiple of two bytes long; for FormatStereo16 the data slice
// must be a multiple of four bytes long. The frequency is given
// in Hz.
// Renamed, was BufferData.
func (self Buffer) SetData(format Format, data []byte, frequency int32) {
C.alBufferData(C.ALuint(self), C.ALenum(format), unsafe.Pointer(&data[0]),
C.ALsizei(len(data)), C.ALsizei(frequency))
}
func (self Buffer) SetDataInt16(format Format, data []int16, frequency int32) {
C.alBufferData(C.ALuint(self), C.ALenum(format), unsafe.Pointer(&data[0]),
C.ALsizei(len(data)*2), C.ALsizei(frequency))
}
func (self Buffer) SetDataMono8(data []byte, frequency int32) {
C.alBufferData(C.ALuint(self), C.ALenum(FormatMono8), unsafe.Pointer(&data[0]),
C.ALsizei(len(data)), C.ALsizei(frequency))
}
func (self Buffer) SetDataMono16(data []int16, frequency int32) {
C.alBufferData(C.ALuint(self), C.ALenum(FormatMono16), unsafe.Pointer(&data[0]),
C.ALsizei(len(data)*2), C.ALsizei(frequency))
}
func (self Buffer) SetDataStereo8(data [][2]byte, frequency int32) {
C.alBufferData(C.ALuint(self), C.ALenum(FormatStereo8), unsafe.Pointer(&data[0]),
C.ALsizei(len(data)*2), C.ALsizei(frequency))
}
func (self Buffer) SetDataStereo16(data [][2]int16, frequency int32) {
C.alBufferData(C.ALuint(self), C.ALenum(FormatStereo16), unsafe.Pointer(&data[0]),
C.ALsizei(len(data)*4), C.ALsizei(frequency))
}
// NewBuffer() creates a single buffer.
// Convenience function, see NewBuffers().
func NewBuffer() Buffer {
return Buffer(C.walGenBuffer())
}
// Delete() deletes a single buffer.
// Convenience function, see DeleteBuffers().
func (self Buffer) Delete() {
C.walDeleteSource(C.ALuint(self))
}
// GetFrequency() returns the frequency, in Hz, of the buffer's sample data.
// Convenience method.
func (self Buffer) GetFrequency() uint32 {
return uint32(self.geti(alFrequency))
}
// GetBits() returns the resolution, either 8 or 16 bits, of the buffer's sample data.
// Convenience method.
func (self Buffer) GetBits() uint32 {
return uint32(self.geti(alBits))
}
// GetChannels() returns the number of channels, either 1 or 2, of the buffer's sample data.
// Convenience method.
func (self Buffer) GetChannels() uint32 {
return uint32(self.geti(alChannels))
}
// GetSize() returns the size, in bytes, of the buffer's sample data.
// Convenience method.
func (self Buffer) GetSize() uint32 {
return uint32(self.geti(alSize))
}

View File

@ -0,0 +1,256 @@
// Forked by Tim Shannon 2012
// Copyright 2009 Peter H. Froehlich. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Go binding for OpenAL's "al" API.
//
// See http://connect.creativelabs.com/openal/Documentation/OpenAL%201.1%20Specification.htm
// for details about OpenAL not described here.
//
// OpenAL types are (in principle) mapped to Go types as
// follows:
//
// ALboolean bool (al.h says char, but Go's bool should be compatible)
// ALchar uint8 (although al.h suggests int8, Go's uint8 (aka byte) seems better)
// ALbyte int8 (al.h says char, implying that char is signed)
// ALubyte uint8 (al.h says unsigned char)
// ALshort int16
// ALushort uint16
// ALint int32
// ALuint uint32
// ALsizei int32 (although that's strange, it's what OpenAL wants)
// ALenum int32 (although that's strange, it's what OpenAL wants)
// ALfloat float32
// ALdouble float64
// ALvoid not applicable (but see below)
//
// We also stick to these (not mentioned explicitly in
// OpenAL):
//
// ALvoid* unsafe.Pointer (but never exported)
// ALchar* string
//
// Finally, in places where OpenAL expects pointers to
// C-style arrays, we use Go slices if appropriate:
//
// ALboolean* []bool
// ALvoid* []byte (see Buffer.SetData() for example)
// ALint* []int32
// ALuint* []uint32 []Source []Buffer
// ALfloat* []float32
// ALdouble* []float64
//
// Overall, the correspondence of types hopefully feels
// natural enough. Note that many of these types do not
// actually occur in the API.
//
// The names of OpenAL constants follow the established
// Go conventions: instead of AL_FORMAT_MONO16 we use
// FormatMono16 for example.
//
// Conversion to Go's camel case notation does however
// lead to name clashes between constants and functions.
// For example, AL_DISTANCE_MODEL becomes DistanceModel
// which collides with the OpenAL function of the same
// name used to set the current distance model. We have
// to rename either the constant or the function, and
// since the function name seems to be at fault (it's a
// setter but doesn't make that obvious), we rename the
// function.
//
// In fact, we renamed plenty of functions, not just the
// ones where collisions with constants were the driving
// force. For example, instead of the Sourcef/GetSourcef
// abomination, we use Getf/Setf methods on a Source type.
// Everything should still be easily recognizable for
// OpenAL hackers, but this structure is a lot more
// sensible (and reveals that the OpenAL API is actually
// not such a bad design).
//
// There are a few cases where constants would collide
// with the names of types we introduced here. Since the
// types serve a much more important function, we renamed
// the constants in those cases. For example AL_BUFFER
// would collide with the type Buffer so it's name is now
// Buffer_ instead. Not pretty, but in many cases you
// don't need the constants anyway as the functionality
// they represent is probably available through one of
// the convenience functions we introduced as well. For
// example consider the task of attaching a buffer to a
// source. In C, you'd say alSourcei(sid, AL_BUFFER, bid).
// In Go, you can say sid.Seti(Buffer_, bid) as well, but
// you probably want to say sid.SetBuffer(bid) instead.
//
// TODO: Decide on the final API design; the current state
// has only specialized methods, none of the generic ones
// anymore; it exposes everything (except stuff we can't
// do) but I am not sure whether this is the right API for
// the level we operate on. Not yet anyway. Anyone?
package openal
/*
#cgo linux LDFLAGS: -lopenal
#cgo windows LDFLAGS: -lopenal32
#cgo darwin LDFLAGS: -framework OpenAL
#include <stdlib.h>
#include "local.h"
#include "wrapper.h"
*/
import "C"
import "unsafe"
// General purpose constants. None can be used with SetDistanceModel()
// to disable distance attenuation. None can be used with Source.SetBuffer()
// to clear a Source of buffers.
const (
None = 0
alFalse = 0
alTrue = 1
)
// GetInteger() queries.
const (
alDistanceModel = 0xD000
)
// GetFloat() queries.
const (
alDopplerFactor = 0xC000
alDopplerVelocity = 0xC001
alSpeedOfSound = 0xC003
)
// GetString() queries.
const (
alVendor = 0xB001
alVersion = 0xB002
alRenderer = 0xB003
alExtensions = 0xB004
)
// Shared Source/Listener properties.
const (
AlPosition = 0x1004
AlVelocity = 0x1006
AlGain = 0x100A
)
func GetString(param int32) string {
return C.GoString(C.walGetString(C.ALenum(param)))
}
func getBoolean(param int32) bool {
return C.alGetBoolean(C.ALenum(param)) != alFalse
}
func getInteger(param int32) int32 {
return int32(C.alGetInteger(C.ALenum(param)))
}
func getFloat(param int32) float32 {
return float32(C.alGetFloat(C.ALenum(param)))
}
func getDouble(param int32) float64 {
return float64(C.alGetDouble(C.ALenum(param)))
}
// Renamed, was GetBooleanv.
func getBooleans(param int32, data []bool) {
C.walGetBooleanv(C.ALenum(param), unsafe.Pointer(&data[0]))
}
// Renamed, was GetIntegerv.
func getIntegers(param int32, data []int32) {
C.walGetIntegerv(C.ALenum(param), unsafe.Pointer(&data[0]))
}
// Renamed, was GetFloatv.
func getFloats(param int32, data []float32) {
C.walGetFloatv(C.ALenum(param), unsafe.Pointer(&data[0]))
}
// Renamed, was GetDoublev.
func getDoubles(param int32, data []float64) {
C.walGetDoublev(C.ALenum(param), unsafe.Pointer(&data[0]))
}
// GetError() returns the most recent error generated
// in the AL state machine.
func getError() uint32 {
return uint32(C.alGetError())
}
// Renamed, was DopplerFactor.
func SetDopplerFactor(value float32) {
C.alDopplerFactor(C.ALfloat(value))
}
// Renamed, was DopplerVelocity.
func SetDopplerVelocity(value float32) {
C.alDopplerVelocity(C.ALfloat(value))
}
// Renamed, was SpeedOfSound.
func SetSpeedOfSound(value float32) {
C.alSpeedOfSound(C.ALfloat(value))
}
// Distance models for SetDistanceModel() and GetDistanceModel().
const (
InverseDistance = 0xD001
InverseDistanceClamped = 0xD002
LinearDistance = 0xD003
LinearDistanceClamped = 0xD004
ExponentDistance = 0xD005
ExponentDistanceClamped = 0xD006
)
// SetDistanceModel() changes the current distance model.
// Pass "None" to disable distance attenuation.
// Renamed, was DistanceModel.
func SetDistanceModel(model int32) {
C.alDistanceModel(C.ALenum(model))
}
///// Crap ///////////////////////////////////////////////////////////
// These functions are wrapped and should work fine, but they
// have no purpose: There are *no* capabilities in OpenAL 1.1
// which is the latest specification. So we removed from from
// the API for now, it's complicated enough without them.
//
//func Enable(capability int32) {
// C.alEnable(C.ALenum(capability));
//}
//
//func Disable(capability int32) {
// C.alDisable(C.ALenum(capability));
//}
//
//func IsEnabled(capability int32) bool {
// return C.alIsEnabled(C.ALenum(capability)) != alFalse;
//}
// These constants are documented as "not yet exposed". We
// keep them here in case they ever become valid. They are
// buffer states.
//
//const (
// Unused = 0x2010;
// Pending = 0x2011;
// Processed = 0x2012;
//)
// These functions would work fine, but they are not very
// useful since we have distinct Source and Buffer types.
// Leaving them out reduces API complexity, a good thing.
//
//func IsSource(id uint32) bool {
// return C.alIsSource(C.ALuint(id)) != alFalse;
//}
//
//func IsBuffer(id uint32) bool {
// return C.alIsBuffer(C.ALuint(id)) != alFalse;
//}

Binary file not shown.

View File

@ -0,0 +1,42 @@
package openal
import (
"errors"
"fmt"
)
var (
ErrInvalidName = errors.New("openal: invalid name")
ErrInvalidEnum = errors.New("openal: invalid enum")
ErrInvalidValue = errors.New("openal: invalid value")
ErrInvalidOperation = errors.New("openal: invalid operation")
ErrInvalidContext = errors.New("openal: invalid context")
ErrInvalidDevice = errors.New("openal: invalid device")
ErrOutOfMemory = errors.New("openal: out of memory")
)
type ErrorCode uint32
func (e ErrorCode) Error() string {
return fmt.Sprintf("openal: error code %x", uint32(e))
}
// Err() returns the most recent error generated
// in the AL state machine.
func Err() error {
switch code := getError(); code {
case 0x0000:
return nil
case 0xA001:
return ErrInvalidName
case 0xA002:
return ErrInvalidEnum
case 0xA003:
return ErrInvalidValue
case 0xA004:
return ErrInvalidOperation
default:
return ErrorCode(code)
}
}

View File

@ -0,0 +1,106 @@
package openal_test
import (
"fmt"
"git.stormux.org/storm/barnard/gumble/go-openal/openal"
"io/ioutil"
"time"
)
func ExamplePlay() {
device := openal.OpenDevice("")
defer device.CloseDevice()
context := device.CreateContext()
defer context.Destroy()
context.Activate()
source := openal.NewSource()
defer source.Pause()
source.SetLooping(false)
buffer := openal.NewBuffer()
if err := openal.Err(); err != nil {
fmt.Println(err)
return
}
data, err := ioutil.ReadFile("data/welcome.wav")
if err != nil {
fmt.Println(err)
return
}
buffer.SetData(openal.FormatMono16, data, 44100)
source.SetBuffer(buffer)
source.Play()
for source.State() == openal.Playing {
// loop long enough to let the wave file finish
time.Sleep(time.Millisecond * 100)
}
source.Delete()
fmt.Println("sound played")
// Output: sound played
}
func ExampleMonitor() {
const (
frequency = 44100
format = openal.FormatStereo16
captureSize = 512
buffersCount = 10
)
mic := openal.CaptureOpenDevice("", frequency, format, frequency*2)
mic.CaptureStart()
defer mic.CloseDevice()
device := openal.OpenDevice("")
defer device.CloseDevice()
context := device.CreateContext()
context.Activate()
defer context.Destroy()
source := openal.NewSource()
source.SetLooping(false)
defer source.Stop()
buffers := openal.NewBuffers(buffersCount)
samples := make([]byte, captureSize*format.SampleSize())
start := time.Now()
for time.Since(start) < time.Second { // play for 1 second
if err := openal.Err(); err != nil {
fmt.Println("error:", err)
return
}
// Get any free buffers
if prcessed := source.BuffersProcessed(); prcessed > 0 {
buffersNew := make(openal.Buffers, prcessed)
source.UnqueueBuffers(buffersNew)
buffers = append(buffers, buffersNew...)
}
if len(buffers) == 0 {
continue
}
if mic.CapturedSamples() >= captureSize {
mic.CaptureTo(samples)
buffer := buffers[len(buffers)-1]
buffers = buffers[:len(buffers)-1]
buffer.SetData(format, samples, frequency)
source.QueueBuffer(buffer)
// If we have enough buffers, start playing
if source.State() != openal.Playing {
if source.BuffersQueued() > 2 {
source.Play()
}
}
}
}
fmt.Println(source.State())
// Output: Playing
}

View File

@ -0,0 +1,148 @@
// Copyright 2009 Peter H. Froehlich. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package openal
/*
#include <stdlib.h>
#cgo darwin LDFLAGS: -framework OpenAL
#include "local.h"
#include "wrapper.h"
*/
import "C"
import "unsafe"
// Listener properties.
const (
AlOrientation = 0x100F
)
// Listener represents the singleton receiver of
// sound in 3d space.
//
// We "fake" this type so we can provide OpenAL
// listener calls as methods. This is convenient
// and makes all those calls consistent with the
// way they work for Source and Buffer. You can't
// make new listeners, there's only one!
type Listener struct{}
// Renamed, was Listenerf.
func (self Listener) Setf(param int32, value float32) {
C.alListenerf(C.ALenum(param), C.ALfloat(value))
}
// Renamed, was Listener3f.
func (self Listener) Set3f(param int32, value1, value2, value3 float32) {
C.alListener3f(C.ALenum(param), C.ALfloat(value1), C.ALfloat(value2), C.ALfloat(value3))
}
// Renamed, was Listenerfv.
func (self Listener) Setfv(param int32, values []float32) {
C.walListenerfv(C.ALenum(param), unsafe.Pointer(&values[0]))
}
// Renamed, was Listeneri.
func (self Listener) Seti(param int32, value int32) {
C.alListeneri(C.ALenum(param), C.ALint(value))
}
// Renamed, was Listener3i.
func (self Listener) Set3i(param int32, value1, value2, value3 int32) {
C.alListener3i(C.ALenum(param), C.ALint(value1), C.ALint(value2), C.ALint(value3))
}
// Renamed, was Listeneriv.
func (self Listener) Setiv(param int32, values []int32) {
C.walListeneriv(C.ALenum(param), unsafe.Pointer(&values[0]))
}
// Renamed, was GetListenerf.
func (self Listener) Getf(param int32) float32 {
return float32(C.walGetListenerf(C.ALenum(param)))
}
// Renamed, was GetListener3f.
func (self Listener) Get3f(param int32) (v1, v2, v3 float32) {
C.walGetListener3f(C.ALenum(param), unsafe.Pointer(&v1),
unsafe.Pointer(&v2), unsafe.Pointer(&v3))
return
}
// Renamed, was GetListenerfv.
func (self Listener) Getfv(param int32, values []float32) {
C.walGetListenerfv(C.ALenum(param), unsafe.Pointer(&values[0]))
return
}
// Renamed, was GetListeneri.
func (self Listener) Geti(param int32) int32 {
return int32(C.walGetListeneri(C.ALenum(param)))
}
// Renamed, was GetListener3i.
func (self Listener) Get3i(param int32) (v1, v2, v3 int32) {
C.walGetListener3i(C.ALenum(param), unsafe.Pointer(&v1),
unsafe.Pointer(&v2), unsafe.Pointer(&v3))
return
}
// Renamed, was GetListeneriv.
func (self Listener) Getiv(param int32, values []int32) {
C.walGetListeneriv(C.ALenum(param), unsafe.Pointer(&values[0]))
}
///// Convenience ////////////////////////////////////////////////////
// Convenience method, see Listener.Setf().
func (self Listener) SetGain(gain float32) {
self.Setf(AlGain, gain)
}
// Convenience method, see Listener.Getf().
func (self Listener) GetGain() (gain float32) {
return self.Getf(AlGain)
}
// Convenience method, see Listener.Setfv().
func (self Listener) SetPosition(vector *Vector) {
self.Set3f(AlPosition, vector[x], vector[y], vector[z])
}
// Convenience method, see Listener.Getfv().
func (self Listener) GetPosition(result *Vector) {
result[x], result[y], result[z] = self.Get3f(AlPosition)
}
// Convenience method, see Listener.Setfv().
func (self Listener) SetVelocity(vector *Vector) {
self.Set3f(AlVelocity, vector[x], vector[y], vector[z])
}
// Convenience method, see Listener.Getfv().
func (self Listener) GetVelocity(result *Vector) {
result[x], result[y], result[z] = self.Get3f(AlVelocity)
}
// Convenience method, see Listener.Setfv().
func (self Listener) SetOrientation(at *Vector, up *Vector) {
tempSlice[0] = at[x]
tempSlice[1] = at[y]
tempSlice[2] = at[z]
tempSlice[3] = up[x]
tempSlice[4] = up[y]
tempSlice[5] = up[z]
self.Setfv(AlOrientation, tempSlice)
}
// Convenience method, see Listener.Getfv().
func (self Listener) GetOrientation(resultAt, resultUp *Vector) {
self.Getfv(AlOrientation, tempSlice)
resultAt[x] = tempSlice[0]
resultAt[y] = tempSlice[1]
resultAt[z] = tempSlice[2]
resultUp[x] = tempSlice[3]
resultUp[y] = tempSlice[4]
resultUp[z] = tempSlice[5]
}

View File

@ -0,0 +1,7 @@
#ifdef __APPLE__
#include<OpenAL/al.h>
#include<OpenAL/alc.h>
#else
#include<AL/al.h>
#include<AL/alc.h>
#endif

View File

@ -0,0 +1,23 @@
package openal_test
import (
"git.stormux.org/storm/barnard/gumble/go-openal/openal"
"testing"
)
func TestGetVendor(t *testing.T) {
device := openal.OpenDevice("")
defer device.CloseDevice()
context := device.CreateContext()
defer context.Destroy()
context.Activate()
vendor := openal.GetVendor()
if err := openal.Err(); err != nil {
t.Fatal(err)
} else if vendor == "" {
t.Fatal("empty vendor returned")
}
}

View File

@ -0,0 +1,452 @@
// Copyright 2009 Peter H. Froehlich. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package openal
/*
#include <stdlib.h>
#cgo darwin LDFLAGS: -framework OpenAL
#include "local.h"
#include "wrapper.h"
*/
import "C"
import (
"fmt"
"unsafe"
)
type State int32
func (s State) String() string {
switch s {
case Initial:
return "Initial"
case Playing:
return "Playing"
case Paused:
return "Paused"
case Stopped:
return "Stopped"
default:
return fmt.Sprintf("%x", int32(s))
}
}
// Results from Source.State() query.
const (
Initial State = 0x1011
Playing State = 0x1012
Paused State = 0x1013
Stopped State = 0x1014
)
// Results from Source.Type() query.
const (
Static = 0x1028
Streaming = 0x1029
Undetermined = 0x1030
)
// TODO: Source properties.
// Regardless of what your al.h header may claim, Pitch
// only applies to Sources, not to Listeners. And I got
// that from Chris Robinson himself.
const (
AlSourceRelative = 0x202
AlConeInnerAngle = 0x1001
AlConeOuterAngle = 0x1002
AlPitch = 0x1003
AlDirection = 0x1005
AlLooping = 0x1007
AlBuffer = 0x1009
AlMinGain = 0x100D
AlMaxGain = 0x100E
AlReferenceDistance = 0x1020
AlRolloffFactor = 0x1021
AlConeOuterGain = 0x1022
AlMaxDistance = 0x1023
AlSecOffset = 0x1024
AlSampleOffset = 0x1025
AlByteOffset = 0x1026
)
// Sources represent sound emitters in 3d space.
type Source uint32
type Sources []Source
// NewSources() creates n sources.
// Renamed, was GenSources.
func NewSources(n int) (sources Sources) {
sources = make(Sources, n)
C.walGenSources(C.ALsizei(n), unsafe.Pointer(&sources[0]))
return
}
// Delete deletes the sources.
func (self Sources) Delete() {
n := len(self)
C.walDeleteSources(C.ALsizei(n), unsafe.Pointer(&self[0]))
}
// Renamed, was SourcePlayv.
func (self Sources) Play() {
C.walSourcePlayv(C.ALsizei(len(self)), unsafe.Pointer(&self[0]))
}
// Renamed, was SourceStopv.
func (self Sources) Stop() {
C.walSourceStopv(C.ALsizei(len(self)), unsafe.Pointer(&self[0]))
}
// Renamed, was SourceRewindv.
func (self Sources) Rewind() {
C.walSourceRewindv(C.ALsizei(len(self)), unsafe.Pointer(&self[0]))
}
// Renamed, was SourcePausev.
func (self Sources) Pause() {
C.walSourcePausev(C.ALsizei(len(self)), unsafe.Pointer(&self[0]))
}
// Renamed, was Sourcef.
func (self Source) Setf(param int32, value float32) {
C.alSourcef(C.ALuint(self), C.ALenum(param), C.ALfloat(value))
}
// Renamed, was Source3f.
func (self Source) Set3f(param int32, value1, value2, value3 float32) {
C.alSource3f(C.ALuint(self), C.ALenum(param), C.ALfloat(value1), C.ALfloat(value2), C.ALfloat(value3))
}
// Renamed, was Sourcefv.
func (self Source) Setfv(param int32, values []float32) {
C.walSourcefv(C.ALuint(self), C.ALenum(param), unsafe.Pointer(&values[0]))
}
// Renamed, was Sourcei.
func (self Source) Seti(param int32, value int32) {
C.alSourcei(C.ALuint(self), C.ALenum(param), C.ALint(value))
}
// Renamed, was Source3i.
func (self Source) Set3i(param int32, value1, value2, value3 int32) {
C.alSource3i(C.ALuint(self), C.ALenum(param), C.ALint(value1), C.ALint(value2), C.ALint(value3))
}
// Renamed, was Sourceiv.
func (self Source) Setiv(param int32, values []int32) {
C.walSourceiv(C.ALuint(self), C.ALenum(param), unsafe.Pointer(&values[0]))
}
// Renamed, was GetSourcef.
func (self Source) Getf(param int32) float32 {
return float32(C.walGetSourcef(C.ALuint(self), C.ALenum(param)))
}
// Renamed, was GetSource3f.
func (self Source) Get3f(param int32) (v1, v2, v3 float32) {
C.walGetSource3f(C.ALuint(self), C.ALenum(param), unsafe.Pointer(&v1),
unsafe.Pointer(&v2), unsafe.Pointer(&v3))
return
}
// Renamed, was GetSourcefv.
func (self Source) Getfv(param int32, values []float32) {
C.walGetSourcefv(C.ALuint(self), C.ALenum(param), unsafe.Pointer(&values[0]))
}
// Renamed, was GetSourcei.
func (self Source) Geti(param int32) int32 {
return int32(C.walGetSourcei(C.ALuint(self), C.ALenum(param)))
}
// Renamed, was GetSource3i.
func (self Source) Get3i(param int32) (v1, v2, v3 int32) {
C.walGetSource3i(C.ALuint(self), C.ALenum(param), unsafe.Pointer(&v1),
unsafe.Pointer(&v2), unsafe.Pointer(&v3))
return
}
// Renamed, was GetSourceiv.
func (self Source) Getiv(param int32, values []int32) {
C.walGetSourceiv(C.ALuint(self), C.ALenum(param), unsafe.Pointer(&values[0]))
}
// Delete deletes the source.
// Convenience function, see DeleteSources().
func (self Source) Delete() {
C.walDeleteSource(C.ALuint(self))
}
// Renamed, was SourcePlay.
func (self Source) Play() {
C.alSourcePlay(C.ALuint(self))
}
// Renamed, was SourceStop.
func (self Source) Stop() {
C.alSourceStop(C.ALuint(self))
}
// Renamed, was SourceRewind.
func (self Source) Rewind() {
C.alSourceRewind(C.ALuint(self))
}
// Renamed, was SourcePause.
func (self Source) Pause() {
C.alSourcePause(C.ALuint(self))
}
// Renamed, was SourceQueueBuffers.
func (self Source) QueueBuffers(buffers Buffers) {
C.walSourceQueueBuffers(C.ALuint(self), C.ALsizei(len(buffers)), unsafe.Pointer(&buffers[0]))
}
// Renamed, was SourceUnqueueBuffers.
func (self Source) UnqueueBuffers(buffers Buffers) {
C.walSourceUnqueueBuffers(C.ALuint(self), C.ALsizei(len(buffers)), unsafe.Pointer(&buffers[0]))
}
///// Convenience ////////////////////////////////////////////////////
// NewSource() creates a single source.
// Convenience function, see NewSources().
func NewSource() Source {
return Source(C.walGenSource())
}
// Convenience method, see Source.QueueBuffers().
func (self Source) QueueBuffer(buffer Buffer) {
C.walSourceQueueBuffer(C.ALuint(self), C.ALuint(buffer))
}
// Convenience method, see Source.QueueBuffers().
func (self Source) UnqueueBuffer() Buffer {
return Buffer(C.walSourceUnqueueBuffer(C.ALuint(self)))
}
// Source queries.
// TODO: SourceType isn't documented as a query in the
// al.h header, but it is documented that way in
// the OpenAL 1.1 specification.
const (
AlSourceState = 0x1010
AlBuffersQueued = 0x1015
AlBuffersProcessed = 0x1016
AlSourceType = 0x1027
)
// Convenience method, see Source.Geti().
func (self Source) BuffersQueued() int32 {
return self.Geti(AlBuffersQueued)
}
// Convenience method, see Source.Geti().
func (self Source) BuffersProcessed() int32 {
return self.Geti(AlBuffersProcessed)
}
// Convenience method, see Source.Geti().
func (self Source) State() State {
return State(self.Geti(AlSourceState))
}
// Convenience method, see Source.Geti().
func (self Source) Type() int32 {
return self.Geti(AlSourceType)
}
// Convenience method, see Source.Getf().
func (self Source) GetGain() (gain float32) {
return self.Getf(AlGain)
}
// Convenience method, see Source.Setf().
func (self Source) SetGain(gain float32) {
self.Setf(AlGain, gain)
}
// Convenience method, see Source.Getf().
func (self Source) GetMinGain() (gain float32) {
return self.Getf(AlMinGain)
}
// Convenience method, see Source.Setf().
func (self Source) SetMinGain(gain float32) {
self.Setf(AlMinGain, gain)
}
// Convenience method, see Source.Getf().
func (self Source) GetMaxGain() (gain float32) {
return self.Getf(AlMaxGain)
}
// Convenience method, see Source.Setf().
func (self Source) SetMaxGain(gain float32) {
self.Setf(AlMaxGain, gain)
}
// Convenience method, see Source.Getf().
func (self Source) GetReferenceDistance() (distance float32) {
return self.Getf(AlReferenceDistance)
}
// Convenience method, see Source.Setf().
func (self Source) SetReferenceDistance(distance float32) {
self.Setf(AlReferenceDistance, distance)
}
// Convenience method, see Source.Getf().
func (self Source) GetMaxDistance() (distance float32) {
return self.Getf(AlMaxDistance)
}
// Convenience method, see Source.Setf().
func (self Source) SetMaxDistance(distance float32) {
self.Setf(AlMaxDistance, distance)
}
// Convenience method, see Source.Getf().
func (self Source) GetPitch() float32 {
return self.Getf(AlPitch)
}
// Convenience method, see Source.Setf().
func (self Source) SetPitch(pitch float32) {
self.Setf(AlPitch, pitch)
}
// Convenience method, see Source.Getf().
func (self Source) GetRolloffFactor() (gain float32) {
return self.Getf(AlRolloffFactor)
}
// Convenience method, see Source.Setf().
func (self Source) SetRolloffFactor(gain float32) {
self.Setf(AlRolloffFactor, gain)
}
// Convenience method, see Source.Geti().
func (self Source) GetLooping() bool {
return self.Geti(AlLooping) != alFalse
}
var bool2al map[bool]int32 = map[bool]int32{true: alTrue, false: alFalse}
// Convenience method, see Source.Seti().
func (self Source) SetLooping(yes bool) {
self.Seti(AlLooping, bool2al[yes])
}
// Convenience method, see Source.Geti().
func (self Source) GetSourceRelative() bool {
return self.Geti(AlSourceRelative) != alFalse
}
// Convenience method, see Source.Seti().
func (self Source) SetSourceRelative(yes bool) {
self.Seti(AlSourceRelative, bool2al[yes])
}
// Convenience method, see Source.Setfv().
func (self Source) SetPosition(vector *Vector) {
self.Set3f(AlPosition, vector[x], vector[y], vector[z])
}
// Convenience method, see Source.Getfv().
func (self Source) GetPosition(result *Vector) {
result[x], result[y], result[z] = self.Get3f(AlPosition)
}
// Convenience method, see Source.Setfv().
func (self Source) SetDirection(vector *Vector) {
self.Set3f(AlDirection, vector[x], vector[y], vector[z])
}
// Convenience method, see Source.Getfv().
func (self Source) GetDirection(result *Vector) {
result[x], result[y], result[z] = self.Get3f(AlDirection)
}
// Convenience method, see Source.Setfv().
func (self Source) SetVelocity(vector *Vector) {
self.Set3f(AlVelocity, vector[x], vector[y], vector[z])
}
// Convenience method, see Source.Getfv().
func (self Source) GetVelocity(result *Vector) {
result[x], result[y], result[z] = self.Get3f(AlVelocity)
}
// Convenience method, see Source.Getf().
func (self Source) GetOffsetSeconds() float32 {
return self.Getf(AlSecOffset)
}
// Convenience method, see Source.Setf().
func (self Source) SetOffsetSeconds(offset float32) {
self.Setf(AlSecOffset, offset)
}
// Convenience method, see Source.Geti().
func (self Source) GetOffsetSamples() int32 {
return self.Geti(AlSampleOffset)
}
// Convenience method, see Source.Seti().
func (self Source) SetOffsetSamples(offset int32) {
self.Seti(AlSampleOffset, offset)
}
// Convenience method, see Source.Geti().
func (self Source) GetOffsetBytes() int32 {
return self.Geti(AlByteOffset)
}
// Convenience method, see Source.Seti().
func (self Source) SetOffsetBytes(offset int32) {
self.Seti(AlByteOffset, offset)
}
// Convenience method, see Source.Getf().
func (self Source) GetInnerAngle() float32 {
return self.Getf(AlConeInnerAngle)
}
// Convenience method, see Source.Setf().
func (self Source) SetInnerAngle(offset float32) {
self.Setf(AlConeInnerAngle, offset)
}
// Convenience method, see Source.Getf().
func (self Source) GetOuterAngle() float32 {
return self.Getf(AlConeOuterAngle)
}
// Convenience method, see Source.Setf().
func (self Source) SetOuterAngle(offset float32) {
self.Setf(AlConeOuterAngle, offset)
}
// Convenience method, see Source.Getf().
func (self Source) GetOuterGain() float32 {
return self.Getf(AlConeOuterGain)
}
// Convenience method, see Source.Setf().
func (self Source) SetOuterGain(offset float32) {
self.Setf(AlConeOuterGain, offset)
}
// Convenience method, see Source.Geti().
func (self Source) SetBuffer(buffer Buffer) {
self.Seti(AlBuffer, int32(buffer))
}
// Convenience method, see Source.Geti().
func (self Source) GetBuffer() (buffer Buffer) {
return Buffer(self.Geti(AlBuffer))
}

View File

@ -0,0 +1,74 @@
// Copyright 2009 Peter H. Froehlich. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Convenience functions in pure Go.
//
// Not all convenience functions are here: those that need
// to call C code have to be in core.go instead due to cgo
// limitations, while those that are methods have to be in
// core.go due to language limitations. They should all be
// here of course, at least conceptually.
package openal
import "strings"
// Convenience Interface.
type Vector [3]float32
var tempSlice = make([]float32, 6)
const (
x = iota
y
z
)
// Convenience function, see GetInteger().
func GetDistanceModel() int32 {
return getInteger(alDistanceModel)
}
// Convenience function, see GetFloat().
func GetDopplerFactor() float32 {
return getFloat(alDopplerFactor)
}
// Convenience function, see GetFloat().
func GetDopplerVelocity() float32 {
return getFloat(alDopplerVelocity)
}
// Convenience function, see GetFloat().
func GetSpeedOfSound() float32 {
return getFloat(alSpeedOfSound)
}
// Convenience function, see GetString().
func GetVendor() string {
return GetString(alVendor)
}
// Convenience function, see GetString().
func GetVersion() string {
return GetString(alVersion)
}
// Convenience function, see GetString().
func GetRenderer() string {
return GetString(alRenderer)
}
// Convenience function, see GetString().
func GetExtensions() string {
return GetString(alExtensions)
}
func GetExtensionsSlice() []string {
return strings.Split(GetExtensions(), " ")
}
func IsExtensionPresent(ext string) bool {
return strings.Index(GetExtensions(), ext) >= 0
}

View File

@ -0,0 +1,212 @@
// Copyright 2009 Peter H. Froehlich. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "local.h"
#include "wrapper.h"
const char *walGetString(ALenum param) {
return alGetString(param);
}
void walGetBooleanv(ALenum param, void* data) {
alGetBooleanv(param, data);
}
void walGetIntegerv(ALenum param, void* data) {
alGetIntegerv(param, data);
}
void walGetFloatv(ALenum param, void* data) {
alGetFloatv(param, data);
}
void walGetDoublev(ALenum param, void* data) {
alGetDoublev(param, data);
}
// Listeners
void walListenerfv(ALenum param, const void* values) {
alListenerfv(param, values);
}
void walListeneriv(ALenum param, const void* values) {
alListeneriv(param, values);
}
ALfloat walGetListenerf(ALenum param) {
ALfloat result;
alGetListenerf(param, &result);
return result;
}
void walGetListener3f(ALenum param, void *value1, void *value2, void *value3) {
alGetListener3f(param, value1, value2, value3);
}
void walGetListenerfv(ALenum param, void* values) {
alGetListenerfv(param, values);
}
ALint walGetListeneri(ALenum param) {
ALint result;
alGetListeneri(param, &result);
return result;
}
void walGetListener3i(ALenum param, void *value1, void *value2, void *value3) {
alGetListener3i(param, value1, value2, value3);
}
void walGetListeneriv(ALenum param, void* values) {
alGetListeneriv(param, values);
}
// Sources
void walGenSources(ALsizei n, void *sources) {
alGenSources(n, sources);
}
void walDeleteSources(ALsizei n, const void *sources) {
alDeleteSources(n, sources);
}
void walSourcefv(ALuint sid, ALenum param, const void* values) {
alSourcefv(sid, param, values);
}
void walSourceiv(ALuint sid, ALenum param, const void* values) {
alSourceiv(sid, param, values);
}
ALfloat walGetSourcef(ALuint sid, ALenum param) {
ALfloat result;
alGetSourcef(sid, param, &result);
return result;
}
void walGetSource3f(ALuint sid, ALenum param, void *value1, void *value2, void *value3) {
alGetSource3f(sid, param, value1, value2, value3);
}
void walGetSourcefv(ALuint sid, ALenum param, void* values) {
alGetSourcefv(sid, param, values);
}
ALint walGetSourcei(ALuint sid, ALenum param) {
ALint result;
alGetSourcei(sid, param, &result);
return result;
}
void walGetSource3i(ALuint sid, ALenum param, void *value1, void *value2, void *value3) {
alGetSource3i(sid, param, value1, value2, value3);
}
void walGetSourceiv(ALuint sid, ALenum param, void* values) {
alGetSourceiv(sid, param, values);
}
void walSourcePlayv(ALsizei ns, const void *sids) {
alSourcePlayv(ns, sids);
}
void walSourceStopv(ALsizei ns, const void *sids) {
alSourceStopv(ns, sids);
}
void walSourceRewindv(ALsizei ns, const void *sids) {
alSourceRewindv(ns, sids);
}
void walSourcePausev(ALsizei ns, const void *sids) {
alSourcePausev(ns, sids);
}
void walSourceQueueBuffers(ALuint sid, ALsizei numEntries, const void *bids) {
alSourceQueueBuffers(sid, numEntries, bids);
}
void walSourceUnqueueBuffers(ALuint sid, ALsizei numEntries, void *bids) {
alSourceUnqueueBuffers(sid, numEntries, bids);
}
// Buffers
void walGenBuffers(ALsizei n, void *buffers) {
alGenBuffers(n, buffers);
}
void walDeleteBuffers(ALsizei n, const void *buffers) {
alDeleteBuffers(n, buffers);
}
void walBufferfv(ALuint bid, ALenum param, const void* values) {
alBufferfv(bid, param, values);
}
void walBufferiv(ALuint bid, ALenum param, const void* values) {
alBufferiv(bid, param, values);
}
ALfloat walGetBufferf(ALuint bid, ALenum param) {
ALfloat result;
alGetBufferf(bid, param, &result);
return result;
}
void walGetBuffer3f(ALuint bid, ALenum param, void *value1, void *value2, void *value3) {
alGetBuffer3f(bid, param, value1, value2, value3);
}
void walGetBufferfv(ALuint bid, ALenum param, void* values) {
alGetBufferfv(bid, param, values);
}
ALint walGetBufferi(ALuint bid, ALenum param) {
ALint result;
alGetBufferi(bid, param, &result);
return result;
}
void walGetBuffer3i(ALuint bid, ALenum param, void *value1, void *value2, void *value3) {
alGetBuffer3i(bid, param, value1, value2, value3);
}
void walGetBufferiv(ALuint bid, ALenum param, void* values) {
alGetBufferiv(bid, param, values);
}
// Singulars
ALuint walGenSource(void) {
ALuint source;
alGenSources(1, &source);
return source;
}
void walDeleteSource(ALuint source) {
alDeleteSources(1, &source);
}
ALuint walGenBuffer(void) {
ALuint buffer;
alGenBuffers(1, &buffer);
return buffer;
}
void walDeleteBuffer(ALuint buffer) {
alDeleteBuffers(1, &buffer);
}
void walSourceQueueBuffer(ALuint sid, ALuint bid) {
alSourceQueueBuffers(sid, 1, &bid);
}
ALuint walSourceUnqueueBuffer(ALuint sid) {
ALuint result;
alSourceUnqueueBuffers(sid, 1, &result);
return result;
}

View File

@ -0,0 +1,86 @@
#ifndef _GO_WRAPPER_AL_
#define _GO_WRAPPER_AL_
// Copyright 2009 Peter H. Froehlich. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// It's sad but the OpenAL C API uses lots and lots of typedefs
// that require wrapper functions (using basic C types) for cgo
// to grok them. So there's a lot more C code here than I would
// like...
const char *walGetString(ALenum param);
void walGetBooleanv(ALenum param, void* data);
void walGetIntegerv(ALenum param, void* data);
void walGetFloatv(ALenum param, void* data);
void walGetDoublev(ALenum param, void* data);
// We don't define wrappers for these because we have
// no clue how to make Go grok C function pointers at
// runtime. So for now, OpenAL extensions can not be
// used from Go. If you have an idea for how to make
// it work, be sure to email! I suspect we'd need a
// mechanism for generating cgo-style stubs at runtime,
// sounds like work.
//
// ALboolean alIsExtensionPresent( const ALchar* extname );
// void* alGetProcAddress( const ALchar* fname );
// ALenum alGetEnumValue( const ALchar* ename );
// Listeners
void walListenerfv(ALenum param, const void* values);
void walListeneriv(ALenum param, const void* values);
ALfloat walGetListenerf(ALenum param);
void walGetListener3f(ALenum param, void *value1, void *value2, void *value3);
void walGetListenerfv(ALenum param, void* values);
ALint walGetListeneri(ALenum param);
void walGetListener3i(ALenum param, void *value1, void *value2, void *value3);
void walGetListeneriv(ALenum param, void* values);
// Sources
void walGenSources(ALsizei n, void *sources);
void walDeleteSources(ALsizei n, const void *sources);
void walSourcefv(ALuint sid, ALenum param, const void* values);
void walSourceiv(ALuint sid, ALenum param, const void* values);
ALfloat walGetSourcef(ALuint sid, ALenum param);
void walGetSource3f(ALuint sid, ALenum param, void *value1, void *value2, void *value3);
void walGetSourcefv(ALuint sid, ALenum param, void* values);
ALint walGetSourcei(ALuint sid, ALenum param);
void walGetSource3i(ALuint sid, ALenum param, void *value1, void *value2, void *value3);
void walGetSourceiv(ALuint sid, ALenum param, void* values);
void walSourcePlayv(ALsizei ns, const void *sids);
void walSourceStopv(ALsizei ns, const void *sids);
void walSourceRewindv(ALsizei ns, const void *sids);
void walSourcePausev(ALsizei ns, const void *sids);
void walSourceQueueBuffers(ALuint sid, ALsizei numEntries, const void *bids);
void walSourceUnqueueBuffers(ALuint sid, ALsizei numEntries, void *bids);
// Buffers
void walGenBuffers(ALsizei n, void *buffers);
void walDeleteBuffers(ALsizei n, const void *buffers);
void walBufferfv(ALuint bid, ALenum param, const void* values);
void walBufferiv(ALuint bid, ALenum param, const void* values);
ALfloat walGetBufferf(ALuint bid, ALenum param);
void walGetBuffer3f(ALuint bid, ALenum param, void *value1, void *value2, void *value3);
void walGetBufferfv(ALuint bid, ALenum param, void* values);
ALint walGetBufferi(ALuint bid, ALenum param);
void walGetBuffer3i(ALuint bid, ALenum param, void *value1, void *value2, void *value3);
void walGetBufferiv(ALuint bid, ALenum param, void* values);
// For convenience we offer "singular" versions of the following
// calls as well, which require different wrappers if we want to
// be efficient. The main reason for "singular" versions is that
// Go doesn't allow us to treat a variable as an array of size 1.
ALuint walGenSource(void);
void walDeleteSource(ALuint source);
ALuint walGenBuffer(void);
void walDeleteBuffer(ALuint buffer);
void walSourceQueueBuffer(ALuint sid, ALuint bid);
ALuint walSourceUnqueueBuffer(ALuint sid);
#endif