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

24
gumble/go-openal/LICENSE Normal file
View File

@ -0,0 +1,24 @@
Copyright 2009 Peter H. Froehlich. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

17
gumble/go-openal/README Normal file
View File

@ -0,0 +1,17 @@
OpenAL bindings for Go.
====================================
I've forked this library from https://github.com/phf/go-openal
and have started changing it quite a bit from the original library.
I don't have any experience with the original OpenAl libraries, so
I'm going to be rearranging this a bit to fit my needs.
To install simply install the openal and alc libs appropriately for
your platform, or build them from scratch, then run
go get -u git.stormux.org/storm/barnard/gumble/go-openal/
*Note, as of commit 0a4cd0b this library is no longer compatible with Go 1.3.3 and older.*

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