github.com/SahandAslani/gomobile@v0.0.0-20210909130135-2cb2d44c09b2/exp/audio/al/alc.go (about)

     1  // Copyright 2015 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build darwin || linux || windows
     6  // +build darwin linux windows
     7  
     8  package al
     9  
    10  import (
    11  	"errors"
    12  	"sync"
    13  	"unsafe"
    14  )
    15  
    16  var (
    17  	mu      sync.Mutex
    18  	device  unsafe.Pointer
    19  	context unsafe.Pointer
    20  )
    21  
    22  // DeviceError returns the last known error from the current device.
    23  func DeviceError() int32 {
    24  	return alcGetError(device)
    25  }
    26  
    27  // TODO(jbd): Investigate the cases where multiple audio output
    28  // devices might be needed.
    29  
    30  // OpenDevice opens the default audio device.
    31  // Calls to OpenDevice are safe for concurrent use.
    32  func OpenDevice() error {
    33  	mu.Lock()
    34  	defer mu.Unlock()
    35  
    36  	// already opened
    37  	if device != nil {
    38  		return nil
    39  	}
    40  
    41  	dev := alcOpenDevice("")
    42  	if dev == nil {
    43  		return errors.New("al: cannot open the default audio device")
    44  	}
    45  	ctx := alcCreateContext(dev, nil)
    46  	if ctx == nil {
    47  		alcCloseDevice(dev)
    48  		return errors.New("al: cannot create a new context")
    49  	}
    50  	if !alcMakeContextCurrent(ctx) {
    51  		alcCloseDevice(dev)
    52  		return errors.New("al: cannot make context current")
    53  	}
    54  	device = dev
    55  	context = ctx
    56  	return nil
    57  }
    58  
    59  // CloseDevice closes the device and frees related resources.
    60  // Calls to CloseDevice are safe for concurrent use.
    61  func CloseDevice() {
    62  	mu.Lock()
    63  	defer mu.Unlock()
    64  
    65  	if device == nil {
    66  		return
    67  	}
    68  
    69  	alcCloseDevice(device)
    70  	if context != nil {
    71  		alcDestroyContext(context)
    72  	}
    73  	device = nil
    74  	context = nil
    75  }