ebiten/exp/audio/internal/audio_openal.go

109 lines
2.5 KiB
Go
Raw Normal View History

2015-01-24 06:50:41 +01:00
// Copyright 2015 Hajime Hoshi
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build !js,!windows
2015-01-24 06:50:41 +01:00
2015-01-27 15:00:41 +01:00
package internal
2015-01-24 06:50:41 +01:00
import (
"fmt"
"log"
"runtime"
"sync"
"time"
2015-06-07 15:01:14 +02:00
"github.com/timshannon/go-openal/openal"
)
var channelsMutex = sync.Mutex{}
func withChannels(f func()) {
channelsMutex.Lock()
defer channelsMutex.Unlock()
f()
}
2015-01-24 06:50:41 +01:00
func initialize() {
2015-01-27 14:02:23 +01:00
// Creating OpenAL device must be done after initializing UI. I'm not sure the reason.
ch := make(chan struct{})
go func() {
runtime.LockOSThread()
device := openal.OpenDevice("")
context := device.CreateContext()
context.Activate()
if alErr := openal.GetError(); alErr != 0 {
log.Printf("OpenAL initialize error: %d", alErr)
close(ch)
2015-01-25 17:39:43 +01:00
// Graceful ending: Audio is not available on Travis CI.
return
}
audioEnabled = true
sources := openal.NewSources(MaxChannel)
close(ch)
const bufferSize = 2048
emptyBytes := make([]byte, bufferSize)
for _, source := range sources {
2015-01-25 19:53:40 +01:00
// 3 is the least number?
// http://stackoverflow.com/questions/14932004/play-sound-with-openalstream
2015-01-26 02:14:03 +01:00
const bufferNum = 4
buffers := openal.NewBuffers(bufferNum)
for _, buffer := range buffers {
buffer.SetData(openal.FormatStereo16, emptyBytes, SampleRate)
source.QueueBuffer(buffer)
}
source.Play()
if alErr := openal.GetError(); alErr != 0 {
panic(fmt.Sprintf("OpenAL error: %d", alErr))
}
}
for {
oneProcessed := false
2015-06-07 15:01:14 +02:00
for ch, source := range sources {
processed := source.BuffersProcessed()
if processed == 0 {
continue
}
oneProcessed = true
buffers := make([]openal.Buffer, processed)
source.UnqueueBuffers(buffers)
for _, buffer := range buffers {
b := make([]byte, bufferSize)
copy(b, loadChannelBuffer(ch, bufferSize))
buffer.SetData(openal.FormatStereo16, b, SampleRate)
source.QueueBuffer(buffer)
}
if source.State() == openal.Stopped {
source.Rewind()
source.Play()
}
}
if !oneProcessed {
2015-06-07 15:01:14 +02:00
time.Sleep(1 * time.Millisecond)
}
}
}()
<-ch
2015-01-24 06:50:41 +01:00
}
func start() {
// Do nothing
2015-01-24 06:50:41 +01:00
}