audio: Lock OS Thread during initializing OpenAL audio

This commit is contained in:
Hajime Hoshi 2016-04-09 23:13:54 +09:00
parent 52aa9d4784
commit 96296f076d

View File

@ -52,30 +52,45 @@ func alFormat(channelNum, bytesPerSample int) uint32 {
} }
func NewPlayer(src io.Reader, sampleRate, channelNum, bytesPerSample int) (*Player, error) { func NewPlayer(src io.Reader, sampleRate, channelNum, bytesPerSample int) (*Player, error) {
if e := al.OpenDevice(); e != nil { var p *Player
return nil, fmt.Errorf("driver: OpenAL initialization failed: %v", e) var err error
} ch := make(chan struct{})
s := al.GenSources(1) go func() {
if err := al.Error(); err != 0 { defer close(ch)
return nil, fmt.Errorf("driver: al.GenSources error: %d", err) // Lock the OS thread to avoid switching the native threads during initialization.
} // This seems to solve #195, but I'm not sure.
p := &Player{ runtime.LockOSThread()
alSource: s[0], if e := al.OpenDevice(); e != nil {
alBuffers: []al.Buffer{}, err = fmt.Errorf("driver: OpenAL initialization failed: %v", e)
source: src, return
sampleRate: sampleRate, }
alFormat: alFormat(channelNum, bytesPerSample), s := al.GenSources(1)
} if e := al.Error(); e != 0 {
runtime.SetFinalizer(p, (*Player).Close) err = fmt.Errorf("driver: al.GenSources error: %d", e)
return
}
p = &Player{
alSource: s[0],
alBuffers: []al.Buffer{},
source: src,
sampleRate: sampleRate,
alFormat: alFormat(channelNum, bytesPerSample),
}
runtime.SetFinalizer(p, (*Player).Close)
bs := al.GenBuffers(maxBufferNum) bs := al.GenBuffers(maxBufferNum)
emptyBytes := make([]byte, bufferSize) emptyBytes := make([]byte, bufferSize)
for _, b := range bs { for _, b := range bs {
// Note that the third argument of only the first buffer is used. // Note that the third argument of only the first buffer is used.
b.BufferData(p.alFormat, emptyBytes, int32(p.sampleRate)) b.BufferData(p.alFormat, emptyBytes, int32(p.sampleRate))
p.alSource.QueueBuffers(b) p.alSource.QueueBuffers(b)
}
al.PlaySources(p.alSource)
}()
<-ch
if err != nil {
return nil, err
} }
al.PlaySources(p.alSource)
return p, nil return p, nil
} }