audio: Refactoring

This commit is contained in:
Hajime Hoshi 2021-01-07 01:30:03 +09:00
parent e77beac235
commit bda285b376
2 changed files with 26 additions and 13 deletions

View File

@ -90,6 +90,7 @@ var (
func NewContext(sampleRate int) *Context {
theContextLock.Lock()
defer theContextLock.Unlock()
if theContext != nil {
panic("audio: context is already created")
}
@ -213,6 +214,18 @@ func (c *Context) SampleRate() int {
return c.sampleRate
}
func (c *Context) acquireSemaphore() {
c.semaphore <- struct{}{}
}
func (c *Context) releaseSemaphore() {
<-c.semaphore
}
func (c *Context) waitUntilInited() {
<-c.inited
}
// Player is an audio player which has one stream.
//
// Even when all references to a Player object is gone,
@ -255,7 +268,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, src)
pi, err := newWriterContextPlayerImpl(context, context.c, src)
if err != nil {
return nil, err
}

View File

@ -50,8 +50,8 @@ func newWriterContext(sampleRate int) writerContext {
type writerContextPlayerImpl struct {
context *Context
writerContext writerContext
src io.Reader
sampleRate int
playing bool
closedExplicitly bool
isLoopActive bool
@ -64,12 +64,12 @@ type writerContextPlayerImpl struct {
m sync.Mutex
}
func newWriterContextPlayerImpl(context *Context, src io.Reader) (*writerContextPlayerImpl, error) {
func newWriterContextPlayerImpl(context *Context, writerContext writerContext, src io.Reader) (*writerContextPlayerImpl, error) {
p := &writerContextPlayerImpl{
context: context,
src: src,
sampleRate: context.sampleRate,
volume: 1,
context: context,
writerContext: writerContext,
src: src,
volume: 1,
}
if seeker, ok := p.src.(io.Seeker); ok {
// Get the current position of the source.
@ -117,9 +117,9 @@ func (p *writerContextPlayerImpl) Play() {
}
func (p *writerContextPlayerImpl) loop() {
<-p.context.inited
p.context.waitUntilInited()
w := p.context.c.NewPlayer()
w := p.writerContext.NewPlayer()
wclosed := make(chan struct{})
defer func() {
<-wclosed
@ -176,9 +176,9 @@ func (p *writerContextPlayerImpl) read() ([]byte, bool) {
const bufSize = 2048
p.context.semaphore <- struct{}{}
p.context.acquireSemaphore()
defer func() {
<-p.context.semaphore
p.context.releaseSemaphore()
}()
if p.readbuf == nil {
@ -228,7 +228,7 @@ func (p *writerContextPlayerImpl) Seek(offset time.Duration) error {
p.m.Lock()
defer p.m.Unlock()
o := int64(offset) * bytesPerSample * int64(p.sampleRate) / int64(time.Second)
o := int64(offset) * bytesPerSample * int64(p.context.SampleRate()) / int64(time.Second)
o = o - (o % bytesPerSample)
seeker, ok := p.src.(io.Seeker)
@ -255,7 +255,7 @@ func (p *writerContextPlayerImpl) Current() time.Duration {
p.m.Lock()
sample := p.pos / bytesPerSample
p.m.Unlock()
return time.Duration(sample) * time.Second / time.Duration(p.sampleRate)
return time.Duration(sample) * time.Second / time.Duration(p.context.SampleRate())
}
func (p *writerContextPlayerImpl) Volume() float64 {