Fix ESP32 audio dropouts and improve streaming reliability
FLAC encoder now tracks frame numbers and reuses per-channel sample buffers to reduce allocations. Client dialer always frees the active slot on release so mDNS re-emissions can reconnect cleanly. Server send buffer uses drop-oldest instead of hard failure, with lateness tracking. Added engine stats logging (chunks/sec, kbps) and writer diagnostics. UI simplified to a single play/pause toggle that auto-starts playback on preset selection. Added --preset CLI flag for headless startup. Removed stale systemd service files. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -18,6 +18,8 @@ func (s *Server) streamAudio() {
|
||||
|
||||
tickBudget := time.Duration(ChunkDurationMs) * time.Millisecond
|
||||
var lastTick time.Time
|
||||
var chunkCount int
|
||||
rateWindowStart := time.Now()
|
||||
for {
|
||||
select {
|
||||
case t := <-ticker.C:
|
||||
@@ -35,6 +37,21 @@ func (s *Server) streamAudio() {
|
||||
lastTick = t
|
||||
|
||||
s.generateAndSendChunk()
|
||||
chunkCount++
|
||||
|
||||
if elapsed := time.Since(rateWindowStart); elapsed >= 10*time.Second {
|
||||
rate := float64(chunkCount) / elapsed.Seconds()
|
||||
avgBytes := 0
|
||||
if chunkCount > 0 {
|
||||
avgBytes = int(s.lastWindowBytes) / chunkCount
|
||||
}
|
||||
kbps := float64(s.lastWindowBytes) * 8 / 1000.0 / elapsed.Seconds()
|
||||
log.Printf("ENGINE STATS: %.3f chunks/sec, avg %d bytes/chunk, %.1f kbps over %s (%d chunks)",
|
||||
rate, avgBytes, kbps, elapsed.Round(time.Millisecond), chunkCount)
|
||||
chunkCount = 0
|
||||
s.lastWindowBytes = 0
|
||||
rateWindowStart = time.Now()
|
||||
}
|
||||
case <-s.stopChan:
|
||||
log.Printf("Audio streaming stopping")
|
||||
return
|
||||
@@ -100,6 +117,10 @@ func (s *Server) generateAndSendChunk() {
|
||||
tracker := c.bufferTracker
|
||||
c.mu.RUnlock()
|
||||
|
||||
if codec == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
switch codec {
|
||||
case "opus":
|
||||
if opusEncoder != nil {
|
||||
@@ -139,6 +160,7 @@ func (s *Server) generateAndSendChunk() {
|
||||
}
|
||||
|
||||
chunk := CreateAudioChunk(playbackTime, audioData)
|
||||
s.lastWindowBytes += int64(len(chunk))
|
||||
|
||||
if tracker != nil {
|
||||
chunkDurationUs := int64(ChunkDurationMs) * 1000
|
||||
|
||||
Reference in New Issue
Block a user