Skip to content

Commit 9c21182

Browse files
Track mixer target output time between runs (#349)
When determining the amount of times to run the mixer, use the media end time enqueued during the previous run, instead of the wall clock time of the end of the last run. If the ticker runs late, or the mixing takes a non negligible amount of time, we would currently ignore partial frame times, potentially causing us to enqueue too little media.
1 parent c0ece76 commit 9c21182

File tree

2 files changed

+19
-11
lines changed

2 files changed

+19
-11
lines changed

pkg/internal/ringbuf/buffer.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package ringbuf
22

3-
import "io"
3+
import (
4+
"io"
5+
)
46

57
// New creates a new ring buffer with s specified size.
68
func New[T any](sz int) *Buffer[T] {

pkg/mixer/mixer.go

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ type Mixer struct {
5555
mixBuf []int32 // mix result buffer
5656
mixTmp media.PCM16Sample // temp buffer for reading input buffers
5757

58-
lastMix time.Time
59-
stopped core.Fuse
60-
mixCnt uint
58+
lastMixEndTs time.Time
59+
stopped core.Fuse
60+
mixCnt uint
6161
}
6262

6363
func NewMixer(out media.Writer[media.PCM16Sample], bufferDur time.Duration) *Mixer {
@@ -125,23 +125,29 @@ func (m *Mixer) mixOnce() {
125125
}
126126

127127
func (m *Mixer) mixUpdate() {
128-
n := 1
129-
if !m.lastMix.IsZero() {
128+
n := 0
129+
now := time.Now()
130+
131+
if m.lastMixEndTs.IsZero() {
132+
m.lastMixEndTs = now
133+
n = 1
134+
} else {
130135
// In case scheduler stops us for too long, we will detect it and run mix multiple times.
131136
// This happens if we get scheduled by OS/K8S on a lot of CPUs, but for a very short time.
132-
if dt := time.Since(m.lastMix); dt > 0 {
137+
if dt := now.Sub(m.lastMixEndTs); dt > 0 {
133138
n = int(dt / m.tickerDur)
139+
m.lastMixEndTs = m.lastMixEndTs.Add(time.Duration(n) * m.tickerDur)
134140
}
135141
}
136-
if n == 0 {
137-
n = 1
138-
} else if n > inputBufferFrames {
142+
if n > inputBufferFrames {
139143
n = inputBufferFrames
144+
// reset
145+
m.lastMixEndTs = now
140146
}
147+
141148
for i := 0; i < n; i++ {
142149
m.mixOnce()
143150
}
144-
m.lastMix = time.Now()
145151
}
146152

147153
func (m *Mixer) start() {

0 commit comments

Comments
 (0)