mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-26 11:48:55 +01:00
audio: Lazy initialization at reader players
This commit is contained in:
parent
dbdfce5fed
commit
4bc0bb607b
@ -39,11 +39,12 @@ type readerDriverPlayer interface {
|
|||||||
|
|
||||||
type readerPlayerFactory struct {
|
type readerPlayerFactory struct {
|
||||||
driver readerDriver
|
driver readerDriver
|
||||||
|
sampleRate int
|
||||||
}
|
}
|
||||||
|
|
||||||
func newReaderPlayerFactory(sampleRate int) *readerPlayerFactory {
|
func newReaderPlayerFactory(sampleRate int) *readerPlayerFactory {
|
||||||
return &readerPlayerFactory{
|
return &readerPlayerFactory{
|
||||||
driver: newReaderDriverImpl(sampleRate),
|
sampleRate: sampleRate,
|
||||||
}
|
}
|
||||||
// TODO: Consider the hooks.
|
// TODO: Consider the hooks.
|
||||||
}
|
}
|
||||||
@ -52,11 +53,11 @@ type readerPlayer struct {
|
|||||||
context *Context
|
context *Context
|
||||||
player readerDriverPlayer
|
player readerDriverPlayer
|
||||||
src *timeStream
|
src *timeStream
|
||||||
sampleRate int
|
factory *readerPlayerFactory
|
||||||
m sync.Mutex
|
m sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *readerPlayerFactory) newPlayerImpl(context *Context, src io.Reader) (playerImpl, error) {
|
func (f *readerPlayerFactory) newPlayerImpl(context *Context, src io.Reader) (playerImpl, error) {
|
||||||
sampleRate := context.SampleRate()
|
sampleRate := context.SampleRate()
|
||||||
s, err := newTimeStream(src, sampleRate)
|
s, err := newTimeStream(src, sampleRate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -65,16 +66,31 @@ func (c *readerPlayerFactory) newPlayerImpl(context *Context, src io.Reader) (pl
|
|||||||
|
|
||||||
p := &readerPlayer{
|
p := &readerPlayer{
|
||||||
context: context,
|
context: context,
|
||||||
player: c.driver.NewPlayer(s),
|
|
||||||
src: s,
|
src: s,
|
||||||
sampleRate: sampleRate,
|
factory: f,
|
||||||
}
|
}
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *readerPlayer) ensurePlayer() {
|
||||||
|
// Initialize the underlying player lazily to enable calling NewContext in an 'init' function.
|
||||||
|
// Accessing the underlying player functions requires the environment to be already initialized,
|
||||||
|
// but if Ebiten is used for a shared library, the timing when init functions are called
|
||||||
|
// is unexpectable.
|
||||||
|
// e.g. a variable for JVM on Android might not be set.
|
||||||
|
if p.factory.driver == nil {
|
||||||
|
p.factory.driver = newReaderDriverImpl(p.factory.sampleRate)
|
||||||
|
}
|
||||||
|
if p.player == nil {
|
||||||
|
p.player = p.factory.driver.NewPlayer(p.src)
|
||||||
|
}
|
||||||
|
// TODO: If some error happens, call p.context.setError().
|
||||||
|
}
|
||||||
|
|
||||||
func (p *readerPlayer) Play() {
|
func (p *readerPlayer) Play() {
|
||||||
p.m.Lock()
|
p.m.Lock()
|
||||||
defer p.m.Unlock()
|
defer p.m.Unlock()
|
||||||
|
p.ensurePlayer()
|
||||||
|
|
||||||
p.player.Play()
|
p.player.Play()
|
||||||
p.context.addPlayer(p)
|
p.context.addPlayer(p)
|
||||||
@ -83,6 +99,7 @@ func (p *readerPlayer) Play() {
|
|||||||
func (p *readerPlayer) Pause() {
|
func (p *readerPlayer) Pause() {
|
||||||
p.m.Lock()
|
p.m.Lock()
|
||||||
defer p.m.Unlock()
|
defer p.m.Unlock()
|
||||||
|
p.ensurePlayer()
|
||||||
|
|
||||||
p.player.Pause()
|
p.player.Pause()
|
||||||
}
|
}
|
||||||
@ -90,6 +107,7 @@ func (p *readerPlayer) Pause() {
|
|||||||
func (p *readerPlayer) IsPlaying() bool {
|
func (p *readerPlayer) IsPlaying() bool {
|
||||||
p.m.Lock()
|
p.m.Lock()
|
||||||
defer p.m.Unlock()
|
defer p.m.Unlock()
|
||||||
|
p.ensurePlayer()
|
||||||
|
|
||||||
return p.player.IsPlaying()
|
return p.player.IsPlaying()
|
||||||
}
|
}
|
||||||
@ -97,6 +115,7 @@ func (p *readerPlayer) IsPlaying() bool {
|
|||||||
func (p *readerPlayer) Volume() float64 {
|
func (p *readerPlayer) Volume() float64 {
|
||||||
p.m.Lock()
|
p.m.Lock()
|
||||||
defer p.m.Unlock()
|
defer p.m.Unlock()
|
||||||
|
p.ensurePlayer()
|
||||||
|
|
||||||
return p.player.Volume()
|
return p.player.Volume()
|
||||||
}
|
}
|
||||||
@ -104,6 +123,7 @@ func (p *readerPlayer) Volume() float64 {
|
|||||||
func (p *readerPlayer) SetVolume(volume float64) {
|
func (p *readerPlayer) SetVolume(volume float64) {
|
||||||
p.m.Lock()
|
p.m.Lock()
|
||||||
defer p.m.Unlock()
|
defer p.m.Unlock()
|
||||||
|
p.ensurePlayer()
|
||||||
|
|
||||||
p.player.SetVolume(volume)
|
p.player.SetVolume(volume)
|
||||||
}
|
}
|
||||||
@ -111,6 +131,7 @@ func (p *readerPlayer) SetVolume(volume float64) {
|
|||||||
func (p *readerPlayer) Close() error {
|
func (p *readerPlayer) Close() error {
|
||||||
p.m.Lock()
|
p.m.Lock()
|
||||||
defer p.m.Unlock()
|
defer p.m.Unlock()
|
||||||
|
p.ensurePlayer()
|
||||||
|
|
||||||
p.context.removePlayer(p)
|
p.context.removePlayer(p)
|
||||||
return p.player.Close()
|
return p.player.Close()
|
||||||
@ -119,9 +140,10 @@ func (p *readerPlayer) Close() error {
|
|||||||
func (p *readerPlayer) Current() time.Duration {
|
func (p *readerPlayer) Current() time.Duration {
|
||||||
p.m.Lock()
|
p.m.Lock()
|
||||||
defer p.m.Unlock()
|
defer p.m.Unlock()
|
||||||
|
p.ensurePlayer()
|
||||||
|
|
||||||
sample := (p.src.Current() - p.player.UnwrittenBufferSize()) / bytesPerSample
|
sample := (p.src.Current() - p.player.UnwrittenBufferSize()) / bytesPerSample
|
||||||
return time.Duration(sample) * time.Second / time.Duration(p.sampleRate)
|
return time.Duration(sample) * time.Second / time.Duration(p.factory.sampleRate)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *readerPlayer) Rewind() error {
|
func (p *readerPlayer) Rewind() error {
|
||||||
@ -131,6 +153,7 @@ func (p *readerPlayer) Rewind() error {
|
|||||||
func (p *readerPlayer) Seek(offset time.Duration) error {
|
func (p *readerPlayer) Seek(offset time.Duration) error {
|
||||||
p.m.Lock()
|
p.m.Lock()
|
||||||
defer p.m.Unlock()
|
defer p.m.Unlock()
|
||||||
|
p.ensurePlayer()
|
||||||
|
|
||||||
if p.player.IsPlaying() {
|
if p.player.IsPlaying() {
|
||||||
defer func() {
|
defer func() {
|
||||||
|
Loading…
Reference in New Issue
Block a user