mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 11:18:54 +01:00
audio: Add player methods
This commit is contained in:
parent
38e36dedc1
commit
5ba5a1fb90
@ -18,6 +18,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: In JavaScript, mixing should be done by WebAudio for performance.
|
// TODO: In JavaScript, mixing should be done by WebAudio for performance.
|
||||||
@ -80,6 +81,7 @@ func (s *mixedPlayersStream) Read(b []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
for p := range s.context.players {
|
for p := range s.context.players {
|
||||||
p.buf = p.buf[ll:]
|
p.buf = p.buf[ll:]
|
||||||
|
p.pos += int64(ll)
|
||||||
}
|
}
|
||||||
for _, p := range closed {
|
for _, p := range closed {
|
||||||
delete(s.context.players, p)
|
delete(s.context.players, p)
|
||||||
@ -113,6 +115,7 @@ type Player struct {
|
|||||||
context *Context
|
context *Context
|
||||||
src io.ReadSeeker
|
src io.ReadSeeker
|
||||||
buf []byte
|
buf []byte
|
||||||
|
pos int64
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPlayer creates a new player with the given data to the given channel.
|
// NewPlayer creates a new player with the given data to the given channel.
|
||||||
@ -121,17 +124,20 @@ 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).
|
||||||
//
|
|
||||||
// TODO: Pass sample rate and num of channels.
|
|
||||||
func (c *Context) NewPlayer(src io.ReadSeeker) (*Player, error) {
|
func (c *Context) NewPlayer(src io.ReadSeeker) (*Player, error) {
|
||||||
c.Lock()
|
c.Lock()
|
||||||
defer c.Unlock()
|
defer c.Unlock()
|
||||||
|
|
||||||
p := &Player{
|
p := &Player{
|
||||||
context: c,
|
context: c,
|
||||||
src: src,
|
src: src,
|
||||||
buf: []byte{},
|
buf: []byte{},
|
||||||
}
|
}
|
||||||
|
// Get the current position of the source.
|
||||||
|
pos, err := p.src.Seek(0, 1)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
p.pos = pos
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,9 +149,25 @@ func (p *Player) Play() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: IsPlaying
|
func (p *Player) IsPlaying() bool {
|
||||||
// TODO: Stop
|
_, ok := p.context.players[p]
|
||||||
// TODO: Seek
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Player) Rewind() error {
|
||||||
|
return p.Seek(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Player) Seek(offset time.Duration) error {
|
||||||
|
p.buf = []byte{}
|
||||||
|
o := int64(offset) * int64(p.context.sampleRate) / int64(time.Second)
|
||||||
|
pos, err := p.src.Seek(o, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.pos = pos
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Player) Pause() error {
|
func (p *Player) Pause() error {
|
||||||
p.context.Lock()
|
p.context.Lock()
|
||||||
@ -154,3 +176,10 @@ func (p *Player) Pause() error {
|
|||||||
delete(p.context.players, p)
|
delete(p.context.players, p)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Player) Current() time.Duration {
|
||||||
|
return time.Duration(p.pos) * time.Second / time.Duration(p.context.sampleRate)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Volume / SetVolume?
|
||||||
|
// TODO: Panning
|
||||||
|
Loading…
Reference in New Issue
Block a user