mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
audio: Refactoring
This commit is contained in:
parent
e04e709a10
commit
a6b3f32f3a
@ -48,6 +48,10 @@ const (
|
||||
bytesPerSample = 2 * channelNum
|
||||
)
|
||||
|
||||
type newPlayerImpler interface {
|
||||
newPlayerImpl(context *Context, src io.Reader) (playerImpl, error)
|
||||
}
|
||||
|
||||
// A Context represents a current state of audio.
|
||||
//
|
||||
// At most one Context object can exist in one process.
|
||||
@ -55,7 +59,7 @@ const (
|
||||
//
|
||||
// For a typical usage example, see examples/wav/main.go.
|
||||
type Context struct {
|
||||
wc writerContext
|
||||
np newPlayerImpler
|
||||
|
||||
// inited represents whether the audio device is initialized and available or not.
|
||||
// On Android, audio loop cannot be started unless JVM is accessible. After updating one frame, JVM should exist.
|
||||
@ -97,7 +101,7 @@ func NewContext(sampleRate int) *Context {
|
||||
|
||||
c := &Context{
|
||||
sampleRate: sampleRate,
|
||||
wc: newWriterContext(sampleRate),
|
||||
np: newWriterContext(sampleRate),
|
||||
players: map[playerImpl]struct{}{},
|
||||
inited: make(chan struct{}),
|
||||
semaphore: make(chan struct{}, 1),
|
||||
@ -268,7 +272,7 @@ type playerImpl interface {
|
||||
// A Player doesn't close src even if src implements io.Closer.
|
||||
// Closing the source is src owner's responsibility.
|
||||
func NewPlayer(context *Context, src io.Reader) (*Player, error) {
|
||||
pi, err := newWriterContextPlayerImpl(context, context.wc, src)
|
||||
pi, err := context.np.newPlayerImpl(context, src)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -19,15 +19,15 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
dummyContext struct{}
|
||||
dummyPlayer struct{}
|
||||
dummyDriver struct{}
|
||||
dummyPlayer struct{}
|
||||
)
|
||||
|
||||
func (d *dummyContext) NewPlayer() io.WriteCloser {
|
||||
func (d *dummyDriver) NewPlayer() io.WriteCloser {
|
||||
return &dummyPlayer{}
|
||||
}
|
||||
|
||||
func (d *dummyContext) Close() error {
|
||||
func (d *dummyDriver) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ func (p *dummyPlayer) Close() error {
|
||||
}
|
||||
|
||||
func init() {
|
||||
writerContextForTesting = &dummyContext{}
|
||||
writerDriverForTesting = &dummyDriver{}
|
||||
}
|
||||
|
||||
type dummyHook struct {
|
||||
|
@ -21,14 +21,14 @@ import (
|
||||
"github.com/hajimehoshi/oto"
|
||||
)
|
||||
|
||||
func newOtoContext(sampleRate int, initCh chan struct{}) *otoContext {
|
||||
return &otoContext{
|
||||
func newOtoDriver(sampleRate int, initCh chan struct{}) *otoDriver {
|
||||
return &otoDriver{
|
||||
sampleRate: sampleRate,
|
||||
initCh: initCh,
|
||||
}
|
||||
}
|
||||
|
||||
type otoContext struct {
|
||||
type otoDriver struct {
|
||||
sampleRate int
|
||||
initCh <-chan struct{}
|
||||
|
||||
@ -36,18 +36,18 @@ type otoContext struct {
|
||||
once sync.Once
|
||||
}
|
||||
|
||||
func (c *otoContext) NewPlayer() io.WriteCloser {
|
||||
func (c *otoDriver) NewPlayer() io.WriteCloser {
|
||||
return &otoPlayer{c: c}
|
||||
}
|
||||
|
||||
func (c *otoContext) Close() error {
|
||||
func (c *otoDriver) Close() error {
|
||||
if c.c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.c.Close()
|
||||
}
|
||||
|
||||
func (c *otoContext) ensureContext() error {
|
||||
func (c *otoDriver) ensureContext() error {
|
||||
var err error
|
||||
c.once.Do(func() {
|
||||
<-c.initCh
|
||||
@ -57,7 +57,7 @@ func (c *otoContext) ensureContext() error {
|
||||
}
|
||||
|
||||
type otoPlayer struct {
|
||||
c *otoContext
|
||||
c *otoDriver
|
||||
p *oto.Player
|
||||
once sync.Once
|
||||
}
|
@ -23,18 +23,18 @@ import (
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/hooks"
|
||||
)
|
||||
|
||||
// writerContext represents a context represented as io.WriteClosers.
|
||||
// The actual implementation is oto.Context.
|
||||
type writerContext interface {
|
||||
// writerDriver represents a driver using io.WriteClosers.
|
||||
// The actual implementation is otoDriver.
|
||||
type writerDriver interface {
|
||||
NewPlayer() io.WriteCloser
|
||||
io.Closer
|
||||
}
|
||||
|
||||
var writerContextForTesting writerContext
|
||||
var writerDriverForTesting writerDriver
|
||||
|
||||
func newWriterContext(sampleRate int) writerContext {
|
||||
if writerContextForTesting != nil {
|
||||
return writerContextForTesting
|
||||
func newWriterDriver(sampleRate int) writerDriver {
|
||||
if writerDriverForTesting != nil {
|
||||
return writerDriverForTesting
|
||||
}
|
||||
|
||||
ch := make(chan struct{})
|
||||
@ -45,12 +45,22 @@ func newWriterContext(sampleRate int) writerContext {
|
||||
})
|
||||
return nil
|
||||
})
|
||||
return newOtoContext(sampleRate, ch)
|
||||
return newOtoDriver(sampleRate, ch)
|
||||
}
|
||||
|
||||
type writerContext struct {
|
||||
driver writerDriver
|
||||
}
|
||||
|
||||
func newWriterContext(sampleRate int) *writerContext {
|
||||
return &writerContext{
|
||||
driver: newWriterDriver(sampleRate),
|
||||
}
|
||||
}
|
||||
|
||||
type writerContextPlayerImpl struct {
|
||||
context *Context
|
||||
writerContext writerContext
|
||||
driver writerDriver
|
||||
src io.Reader
|
||||
playing bool
|
||||
closedExplicitly bool
|
||||
@ -64,12 +74,12 @@ type writerContextPlayerImpl struct {
|
||||
m sync.Mutex
|
||||
}
|
||||
|
||||
func newWriterContextPlayerImpl(context *Context, writerContext writerContext, src io.Reader) (*writerContextPlayerImpl, error) {
|
||||
func (c *writerContext) newPlayerImpl(context *Context, src io.Reader) (playerImpl, error) {
|
||||
p := &writerContextPlayerImpl{
|
||||
context: context,
|
||||
writerContext: writerContext,
|
||||
src: src,
|
||||
volume: 1,
|
||||
context: context,
|
||||
driver: c.driver,
|
||||
src: src,
|
||||
volume: 1,
|
||||
}
|
||||
if seeker, ok := p.src.(io.Seeker); ok {
|
||||
// Get the current position of the source.
|
||||
@ -119,7 +129,7 @@ func (p *writerContextPlayerImpl) Play() {
|
||||
func (p *writerContextPlayerImpl) loop() {
|
||||
p.context.waitUntilInited()
|
||||
|
||||
w := p.writerContext.NewPlayer()
|
||||
w := p.driver.NewPlayer()
|
||||
wclosed := make(chan struct{})
|
||||
defer func() {
|
||||
<-wclosed
|
||||
|
Loading…
Reference in New Issue
Block a user