audio: Add Player.Close (#194)

This commit is contained in:
Hajime Hoshi 2016-03-29 00:06:37 +09:00
parent 0662e1a1de
commit d2ccbdbe23
5 changed files with 46 additions and 3 deletions

View File

@ -78,6 +78,14 @@ func playerBarRect() (x, y, w, h int) {
return return
} }
type SEStream struct {
*bytes.Reader
}
func (s *SEStream) Close() error {
return nil
}
func (p *Player) updateSE() error { func (p *Player) updateSE() error {
if seStream == nil { if seStream == nil {
return nil return nil
@ -99,7 +107,7 @@ func (p *Player) updateSE() error {
} }
seBuffer = b seBuffer = b
} }
sePlayer, err := audioContext.NewPlayer(bytes.NewReader(seBuffer)) sePlayer, err := audioContext.NewPlayer(&SEStream{bytes.NewReader(seBuffer)})
if err != nil { if err != nil {
return err return err
} }
@ -168,6 +176,10 @@ func (p *Player) updateBar() error {
return p.audioPlayer.Seek(pos) return p.audioPlayer.Seek(pos)
} }
func (p *Player) close() error {
return p.audioPlayer.Close()
}
func update(screen *ebiten.Image) error { func update(screen *ebiten.Image) error {
audioContext.Update() audioContext.Update()
if musicPlayer == nil { if musicPlayer == nil {
@ -272,4 +284,9 @@ func main() {
if err := ebiten.Run(update, screenWidth, screenHeight, 2, "Audio (Ebiten Demo)"); err != nil { if err := ebiten.Run(update, screenWidth, screenHeight, 2, "Audio (Ebiten Demo)"); err != nil {
log.Fatal(err) log.Fatal(err)
} }
if musicPlayer != nil {
if err := musicPlayer.close(); err != nil {
log.Fatal(err)
}
}
} }

View File

@ -76,6 +76,10 @@ func (s *stream) Seek(offset int64, whence int) (int64, error) {
return s.position, nil return s.position, nil
} }
func (s *stream) Close() error {
return nil
}
var player *audio.Player var player *audio.Player
func update(screen *ebiten.Image) error { func update(screen *ebiten.Image) error {

View File

@ -17,6 +17,7 @@ package audio
import ( import (
"fmt" "fmt"
"io" "io"
"runtime"
"sync" "sync"
"time" "time"
@ -148,9 +149,14 @@ func (c *Context) SampleRate() int {
return c.sampleRate return c.sampleRate
} }
type ReadSeekCloser interface {
io.ReadSeeker
io.Closer
}
type Player struct { type Player struct {
context *Context context *Context
src io.ReadSeeker src ReadSeekCloser
buf []byte buf []byte
pos int64 pos int64
volume float64 volume float64
@ -162,7 +168,7 @@ type Player struct {
// //
// src's format must be linear PCM (16bits, 2 channel stereo, little endian) // src's format must be linear PCM (16bits, 2 channel stereo, little endian)
// without a header (e.g. RIFF header). // without a header (e.g. RIFF header).
func (c *Context) NewPlayer(src io.ReadSeeker) (*Player, error) { func (c *Context) NewPlayer(src ReadSeekCloser) (*Player, error) {
c.Lock() c.Lock()
defer c.Unlock() defer c.Unlock()
p := &Player{ p := &Player{
@ -177,9 +183,15 @@ func (c *Context) NewPlayer(src io.ReadSeeker) (*Player, error) {
return nil, err return nil, err
} }
p.pos = pos p.pos = pos
runtime.SetFinalizer(p, (*Player).Close)
return p, nil return p, nil
} }
func (p *Player) Close() error {
runtime.SetFinalizer(p, nil)
return p.src.Close()
}
func (p *Player) readToBuffer(length int) (int, error) { func (p *Player) readToBuffer(length int) (int, error) {
bb := make([]byte, length) bb := make([]byte, length)
n, err := p.src.Read(bb) n, err := p.src.Read(bb)

View File

@ -32,6 +32,11 @@ func (s *Stream) Seek(offset int64, whence int) (int64, error) {
return s.buf.Seek(offset, whence) return s.buf.Seek(offset, whence)
} }
func (s *Stream) Close() error {
s.buf = nil
return nil
}
func (s *Stream) Len() time.Duration { func (s *Stream) Len() time.Duration {
const bytesPerSample = 4 const bytesPerSample = 4
return time.Duration(s.buf.Len()/bytesPerSample) * time.Second / time.Duration(s.sampleRate) return time.Duration(s.buf.Len()/bytesPerSample) * time.Second / time.Duration(s.sampleRate)

View File

@ -43,6 +43,11 @@ func (s *Stream) Seek(offset int64, whence int) (int64, error) {
return s.buf.Seek(offset, whence) return s.buf.Seek(offset, whence)
} }
func (s *Stream) Close() error {
s.buf = nil
return nil
}
func (s *Stream) Len() time.Duration { func (s *Stream) Len() time.Duration {
const bytesPerSample = 4 const bytesPerSample = 4
return time.Duration(s.buf.Len()/bytesPerSample) * time.Second / time.Duration(s.sampleRate) return time.Duration(s.buf.Len()/bytesPerSample) * time.Second / time.Duration(s.sampleRate)