2
0
mirror of synced 2025-02-23 14:58:12 +00:00
mobile/exp/audio/al/alc.go
Burcu Dogan adcf40b30c exp/audio/al: avoid creation of multiple contexts
This CL reverts the changes made in golang/go#11299.

Allowing creation of multiple contexts break the case of multiple
third party packages depending on the al bindings. These packages
need to make sure that there is a valid current context or initiate
and make a context current. Packages racing to create and make a
context current is what we would like to avoid.

Therefore, al bindings will support only a single context that is
initiated during OpenDevice.

Fixes golang/go#11385.

Change-Id: I662f70e49d12833a545005cf0724cc21f67bea09
Reviewed-on: https://go-review.googlesource.com/12001
Reviewed-by: Nigel Tao <nigeltao@golang.org>
2015-07-11 16:23:18 +00:00

75 lines
1.4 KiB
Go

// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin linux
package al
import (
"errors"
"sync"
"unsafe"
)
var (
mu sync.Mutex
device unsafe.Pointer
context unsafe.Pointer
)
// DeviceError returns the last known error from the current device.
func DeviceError() int32 {
return alcGetError(device)
}
// TODO(jbd): Investigate the cases where multiple audio output
// devices might be needed.
// OpenDevice opens the default audio device.
// Calls to OpenDevice are safe for concurrent use.
func OpenDevice() error {
mu.Lock()
defer mu.Unlock()
// already opened
if device != nil {
return nil
}
dev := alcOpenDevice("")
if dev == nil {
return errors.New("al: cannot open the default audio device")
}
ctx := alcCreateContext(dev, nil)
if ctx == nil {
alcCloseDevice(dev)
return errors.New("al: cannot create a new context")
}
if !alcMakeContextCurrent(ctx) {
alcCloseDevice(dev)
return errors.New("al: cannot make context current")
}
device = dev
context = ctx
return nil
}
// CloseDevice closes the device and frees related resources.
// Calls to CloseDevice are safe for concurrent use.
func CloseDevice() {
mu.Lock()
defer mu.Unlock()
if device == nil {
return
}
alcCloseDevice(device)
if context != nil {
alcDestroyContext(context)
}
device = nil
context = nil
}