ebiten/internal/audio/audio_openal.go
2016-02-10 00:09:23 +09:00

93 lines
2.3 KiB
Go

// 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
package audio
import (
"log"
"runtime"
"time"
"golang.org/x/mobile/exp/audio/al"
)
func isPlaying(channel int) bool {
ch := channels[channel]
return 0 < len(ch.buffer)
}
func initialize() {
// Creating OpenAL device must be done after initializing UI. I'm not sure the reason.
ch := make(chan struct{})
go func() {
runtime.LockOSThread()
if err := al.OpenDevice(); err != nil {
log.Printf("OpenAL initialize error: %v", err)
close(ch)
// Graceful ending: Audio is not available on Travis CI.
return
}
audioEnabled = true
sources := al.GenSources(MaxChannel)
close(ch)
const bufferSize = 2048
emptyBytes := make([]byte, bufferSize)
for _, source := range sources {
// 3 is the least number?
// http://stackoverflow.com/questions/14932004/play-sound-with-openalstream
const bufferNum = 4
buffers := al.GenBuffers(bufferNum)
for _, buffer := range buffers {
buffer.BufferData(al.FormatStereo16, emptyBytes, SampleRate)
source.QueueBuffers(buffer)
}
al.PlaySources(source)
}
for {
oneProcessed := false
for ch, source := range sources {
processed := source.BuffersProcessed()
if processed == 0 {
continue
}
oneProcessed = true
buffers := make([]al.Buffer, processed)
source.UnqueueBuffers(buffers...)
for _, buffer := range buffers {
b := make([]byte, bufferSize)
copy(b, loadChannelBuffer(ch, bufferSize))
buffer.BufferData(al.FormatStereo16, b, SampleRate)
source.QueueBuffers(buffer)
}
if source.State() == al.Stopped {
al.RewindSources(source)
al.PlaySources(source)
}
}
if !oneProcessed {
time.Sleep(1 * time.Millisecond)
}
}
}()
<-ch
}