audio: Add (*Context).NewPlayer and (*Context).NewPlayerFromBytes

Closes #1708
This commit is contained in:
Hajime Hoshi 2021-07-22 16:39:02 +09:00
parent 1dc8002689
commit 92bc5c1908
9 changed files with 29 additions and 16 deletions

View File

@ -330,8 +330,8 @@ type playerImpl interface {
// //
// A Player doesn't close src even if src implements io.Closer. // A Player doesn't close src even if src implements io.Closer.
// Closing the source is src owner's responsibility. // Closing the source is src owner's responsibility.
func NewPlayer(context *Context, src io.Reader) (*Player, error) { func (c *Context) NewPlayer(src io.Reader) (*Player, error) {
pi, err := context.np.newPlayerImpl(context, src) pi, err := c.np.newPlayerImpl(c, src)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -343,15 +343,21 @@ func NewPlayer(context *Context, src io.Reader) (*Player, error) {
return p, nil return p, nil
} }
// NewPlayer creates a new player with the given stream.
//
// Deprecated: as of v2.2. Use (*Context).NewPlayer instead.
func NewPlayer(context *Context, src io.Reader) (*Player, error) {
return context.NewPlayer(src)
}
// NewPlayerFromBytes creates a new player with the given bytes. // NewPlayerFromBytes creates a new player with the given bytes.
// //
// As opposed to NewPlayer, you don't have to care if src is already used by another player or not. // As opposed to NewPlayer, you don't have to care if src is already used by another player or not.
// src can be shared by multiple players. // src can be shared by multiple players.
// //
// The format of src should be same as noted at NewPlayer. // The format of src should be same as noted at NewPlayer.
func NewPlayerFromBytes(context *Context, src []byte) *Player { func (c *Context) NewPlayerFromBytes(src []byte) *Player {
b := bytes.NewReader(src) p, err := c.NewPlayer(bytes.NewReader(src))
p, err := NewPlayer(context, b)
if err != nil { if err != nil {
// Errors should never happen. // Errors should never happen.
panic(fmt.Sprintf("audio: %v at NewPlayerFromBytes", err)) panic(fmt.Sprintf("audio: %v at NewPlayerFromBytes", err))
@ -359,6 +365,13 @@ func NewPlayerFromBytes(context *Context, src []byte) *Player {
return p return p
} }
// NewPlayerFromBytes creates a new player with the given bytes.
//
// Deprecated: as of v2.2. Use (*Context).NewPlayerFromBytes instead.
func NewPlayerFromBytes(context *Context, src []byte) *Player {
return context.NewPlayerFromBytes(src)
}
func (p *Player) finalize() { func (p *Player) finalize() {
runtime.SetFinalizer(p, nil) runtime.SetFinalizer(p, nil)
if !p.IsPlaying() { if !p.IsPlaying() {

View File

@ -147,7 +147,7 @@ func NewPlayer(game *Game, audioContext *audio.Context, musicType musicType) (*P
default: default:
panic("not reached") panic("not reached")
} }
p, err := audio.NewPlayer(audioContext, s) p, err := audioContext.NewPlayer(s)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -246,7 +246,7 @@ func (p *Player) playSEIfNeeded() {
if !p.shouldPlaySE() { if !p.shouldPlaySE() {
return return
} }
sePlayer := audio.NewPlayerFromBytes(p.audioContext, p.seBytes) sePlayer := p.audioContext.NewPlayerFromBytes(p.seBytes)
sePlayer.Play() sePlayer.Play()
} }

View File

@ -64,7 +64,7 @@ func (g *Game) Update() error {
// s is still an io.ReadCloser and io.Seeker. // s is still an io.ReadCloser and io.Seeker.
s := audio.NewInfiniteLoopWithIntro(oggS, introLengthInSecond*4*sampleRate, loopLengthInSecond*4*sampleRate) s := audio.NewInfiniteLoopWithIntro(oggS, introLengthInSecond*4*sampleRate, loopLengthInSecond*4*sampleRate)
g.player, err = audio.NewPlayer(g.audioContext, s) g.player, err = g.audioContext.NewPlayer(s)
if err != nil { if err != nil {
return err return err
} }

View File

@ -78,7 +78,7 @@ func (g *Game) initAudio() {
// Wrap the raw audio with the StereoPanStream // Wrap the raw audio with the StereoPanStream
g.panstream = NewStereoPanStreamFromReader(audio.NewInfiniteLoop(oggS, oggS.Length())) g.panstream = NewStereoPanStreamFromReader(audio.NewInfiniteLoop(oggS, oggS.Length()))
g.player, err = audio.NewPlayer(g.audioContext, g.panstream) g.player, err = g.audioContext.NewPlayer(g.panstream)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }

View File

@ -181,7 +181,7 @@ func (g *Game) init() {
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
g.jumpPlayer, err = audio.NewPlayer(g.audioContext, jumpD) g.jumpPlayer, err = g.audioContext.NewPlayer(jumpD)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -190,7 +190,7 @@ func (g *Game) init() {
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
g.hitPlayer, err = audio.NewPlayer(g.audioContext, jabD) g.hitPlayer, err = g.audioContext.NewPlayer(jabD)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }

View File

@ -130,7 +130,7 @@ func (g *Game) playNote(scoreIndex int) rune {
square(l, vol, freq, 0.25) square(l, vol, freq, 0.25)
square(r, vol, freq, 0.25) square(r, vol, freq, 0.25)
p := audio.NewPlayerFromBytes(g.audioContext, toBytes(l, r)) p := g.audioContext.NewPlayerFromBytes(toBytes(l, r))
p.Play() p.Play()
return rune(note) return rune(note)

View File

@ -221,7 +221,7 @@ func (g *Game) Update() error {
// playNote plays piano sound with the given frequency. // playNote plays piano sound with the given frequency.
func (g *Game) playNote(freq float64) { func (g *Game) playNote(freq float64) {
f := int(freq) f := int(freq)
p := audio.NewPlayerFromBytes(g.audioContext, pianoNoteSamples[f]) p := g.audioContext.NewPlayerFromBytes(pianoNoteSamples[f])
p.Play() p.Play()
} }

View File

@ -94,10 +94,10 @@ func (g *Game) Update() error {
g.audioContext = audio.NewContext(sampleRate) g.audioContext = audio.NewContext(sampleRate)
} }
if g.player == nil { if g.player == nil {
// Pass the (infinite) stream to audio.NewPlayer. // Pass the (infinite) stream to NewPlayer.
// After calling Play, the stream never ends as long as the player object lives. // After calling Play, the stream never ends as long as the player object lives.
var err error var err error
g.player, err = audio.NewPlayer(g.audioContext, &stream{}) g.player, err = g.audioContext.NewPlayer(&stream{})
if err != nil { if err != nil {
return err return err
} }

View File

@ -68,7 +68,7 @@ func NewGame() (*Game, error) {
} }
// Create an audio.Player that has one stream. // Create an audio.Player that has one stream.
g.audioPlayer, err = audio.NewPlayer(g.audioContext, d) g.audioPlayer, err = g.audioContext.NewPlayer(d)
if err != nil { if err != nil {
return nil, err return nil, err
} }