Skip to content

Commit

Permalink
fix: avoid reading from SwitchingAudioSource with no source set
Browse files Browse the repository at this point in the history
  • Loading branch information
devgianlu committed May 26, 2024
1 parent a178714 commit 5385999
Showing 1 changed file with 30 additions and 13 deletions.
43 changes: 30 additions & 13 deletions player/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,37 +10,44 @@ import (
type SwitchingAudioSource struct {
source map[bool]librespot.AudioSource
which bool
mu sync.RWMutex
cond *sync.Cond

done chan struct{}
}

func NewSwitchingAudioSource() *SwitchingAudioSource {
return &SwitchingAudioSource{
source: map[bool]librespot.AudioSource{},
cond: sync.NewCond(&sync.Mutex{}),
done: make(chan struct{}, 1),
}
}

func (s *SwitchingAudioSource) SetPrimary(source librespot.AudioSource) {
s.mu.Lock()
defer s.mu.Unlock()
s.cond.L.Lock()
defer s.cond.L.Unlock()
s.source[s.which] = source
s.cond.Broadcast()
}

func (s *SwitchingAudioSource) SetSecondary(source librespot.AudioSource) {
s.mu.Lock()
defer s.mu.Unlock()
s.cond.L.Lock()
defer s.cond.L.Unlock()
s.source[!s.which] = source
s.cond.Broadcast()
}

func (s *SwitchingAudioSource) Done() <-chan struct{} {
return s.done
}

func (s *SwitchingAudioSource) Read(p []float32) (n int, err error) {
s.mu.RLock()
defer s.mu.RUnlock()
s.cond.L.Lock()
defer s.cond.L.Unlock()

for s.source[s.which] == nil {
s.cond.Wait()
}

n, err = s.source[s.which].Read(p)
if errors.Is(err, io.EOF) {
Expand All @@ -59,8 +66,8 @@ func (s *SwitchingAudioSource) Read(p []float32) (n int, err error) {
}

func (s *SwitchingAudioSource) Drained() {
s.mu.Lock()
defer s.mu.Unlock()
s.cond.L.Lock()
defer s.cond.L.Unlock()

// notify this source is done
s.done <- struct{}{}
Expand All @@ -71,14 +78,24 @@ func (s *SwitchingAudioSource) Drained() {
}

func (s *SwitchingAudioSource) SetPositionMs(pos int64) error {
s.mu.RLock()
defer s.mu.RUnlock()
s.cond.L.Lock()
defer s.cond.L.Unlock()

for s.source[s.which] == nil {
s.cond.Wait()
}

return s.source[s.which].SetPositionMs(pos)
}

func (s *SwitchingAudioSource) PositionMs() int64 {
s.mu.RLock()
defer s.mu.RUnlock()
s.cond.L.Lock()
defer s.cond.L.Unlock()

for s.source[s.which] == nil {
s.cond.Wait()
}

return s.source[s.which].PositionMs()
}

Expand Down

0 comments on commit 5385999

Please sign in to comment.