Updates: use uint64 since we won't have negative numbers here

This commit is contained in:
Alex P 2025-09-09 21:37:08 +00:00
parent 2a81497d34
commit d4c10aef87
3 changed files with 61 additions and 44 deletions

View File

@ -260,14 +260,14 @@ var (
lastMetricsUpdate int64 lastMetricsUpdate int64
// Counter value tracking (since prometheus counters don't have Get() method) // Counter value tracking (since prometheus counters don't have Get() method)
audioFramesReceivedValue int64 audioFramesReceivedValue uint64
audioFramesDroppedValue int64 audioFramesDroppedValue uint64
audioBytesProcessedValue int64 audioBytesProcessedValue uint64
audioConnectionDropsValue int64 audioConnectionDropsValue uint64
micFramesSentValue int64 micFramesSentValue uint64
micFramesDroppedValue int64 micFramesDroppedValue uint64
micBytesProcessedValue int64 micBytesProcessedValue uint64
micConnectionDropsValue int64 micConnectionDropsValue uint64
// Atomic counters for device health metrics - functionality removed, no longer used // Atomic counters for device health metrics - functionality removed, no longer used
@ -277,11 +277,11 @@ var (
// UnifiedAudioMetrics provides a common structure for both input and output audio streams // UnifiedAudioMetrics provides a common structure for both input and output audio streams
type UnifiedAudioMetrics struct { type UnifiedAudioMetrics struct {
FramesReceived int64 `json:"frames_received"` FramesReceived uint64 `json:"frames_received"`
FramesDropped int64 `json:"frames_dropped"` FramesDropped uint64 `json:"frames_dropped"`
FramesSent int64 `json:"frames_sent,omitempty"` FramesSent uint64 `json:"frames_sent,omitempty"`
BytesProcessed int64 `json:"bytes_processed"` BytesProcessed uint64 `json:"bytes_processed"`
ConnectionDrops int64 `json:"connection_drops"` ConnectionDrops uint64 `json:"connection_drops"`
LastFrameTime time.Time `json:"last_frame_time"` LastFrameTime time.Time `json:"last_frame_time"`
AverageLatency time.Duration `json:"average_latency"` AverageLatency time.Duration `json:"average_latency"`
} }
@ -303,10 +303,10 @@ func convertAudioMetricsToUnified(metrics AudioMetrics) UnifiedAudioMetrics {
func convertAudioInputMetricsToUnified(metrics AudioInputMetrics) UnifiedAudioMetrics { func convertAudioInputMetricsToUnified(metrics AudioInputMetrics) UnifiedAudioMetrics {
return UnifiedAudioMetrics{ return UnifiedAudioMetrics{
FramesReceived: 0, // AudioInputMetrics doesn't have FramesReceived FramesReceived: 0, // AudioInputMetrics doesn't have FramesReceived
FramesDropped: metrics.FramesDropped, FramesDropped: uint64(metrics.FramesDropped),
FramesSent: metrics.FramesSent, FramesSent: uint64(metrics.FramesSent),
BytesProcessed: metrics.BytesProcessed, BytesProcessed: uint64(metrics.BytesProcessed),
ConnectionDrops: metrics.ConnectionDrops, ConnectionDrops: uint64(metrics.ConnectionDrops),
LastFrameTime: metrics.LastFrameTime, LastFrameTime: metrics.LastFrameTime,
AverageLatency: metrics.AverageLatency, AverageLatency: metrics.AverageLatency,
} }
@ -314,22 +314,22 @@ func convertAudioInputMetricsToUnified(metrics AudioInputMetrics) UnifiedAudioMe
// UpdateAudioMetrics updates Prometheus metrics with current audio data // UpdateAudioMetrics updates Prometheus metrics with current audio data
func UpdateAudioMetrics(metrics UnifiedAudioMetrics) { func UpdateAudioMetrics(metrics UnifiedAudioMetrics) {
oldReceived := atomic.SwapInt64(&audioFramesReceivedValue, metrics.FramesReceived) oldReceived := atomic.SwapUint64(&audioFramesReceivedValue, metrics.FramesReceived)
if metrics.FramesReceived > oldReceived { if metrics.FramesReceived > oldReceived {
audioFramesReceivedTotal.Add(float64(metrics.FramesReceived - oldReceived)) audioFramesReceivedTotal.Add(float64(metrics.FramesReceived - oldReceived))
} }
oldDropped := atomic.SwapInt64(&audioFramesDroppedValue, metrics.FramesDropped) oldDropped := atomic.SwapUint64(&audioFramesDroppedValue, metrics.FramesDropped)
if metrics.FramesDropped > oldDropped { if metrics.FramesDropped > oldDropped {
audioFramesDroppedTotal.Add(float64(metrics.FramesDropped - oldDropped)) audioFramesDroppedTotal.Add(float64(metrics.FramesDropped - oldDropped))
} }
oldBytes := atomic.SwapInt64(&audioBytesProcessedValue, metrics.BytesProcessed) oldBytes := atomic.SwapUint64(&audioBytesProcessedValue, metrics.BytesProcessed)
if metrics.BytesProcessed > oldBytes { if metrics.BytesProcessed > oldBytes {
audioBytesProcessedTotal.Add(float64(metrics.BytesProcessed - oldBytes)) audioBytesProcessedTotal.Add(float64(metrics.BytesProcessed - oldBytes))
} }
oldDrops := atomic.SwapInt64(&audioConnectionDropsValue, metrics.ConnectionDrops) oldDrops := atomic.SwapUint64(&audioConnectionDropsValue, metrics.ConnectionDrops)
if metrics.ConnectionDrops > oldDrops { if metrics.ConnectionDrops > oldDrops {
audioConnectionDropsTotal.Add(float64(metrics.ConnectionDrops - oldDrops)) audioConnectionDropsTotal.Add(float64(metrics.ConnectionDrops - oldDrops))
} }
@ -345,22 +345,22 @@ func UpdateAudioMetrics(metrics UnifiedAudioMetrics) {
// UpdateMicrophoneMetrics updates Prometheus metrics with current microphone data // UpdateMicrophoneMetrics updates Prometheus metrics with current microphone data
func UpdateMicrophoneMetrics(metrics UnifiedAudioMetrics) { func UpdateMicrophoneMetrics(metrics UnifiedAudioMetrics) {
oldSent := atomic.SwapInt64(&micFramesSentValue, metrics.FramesSent) oldSent := atomic.SwapUint64(&micFramesSentValue, metrics.FramesSent)
if metrics.FramesSent > oldSent { if metrics.FramesSent > oldSent {
microphoneFramesSentTotal.Add(float64(metrics.FramesSent - oldSent)) microphoneFramesSentTotal.Add(float64(metrics.FramesSent - oldSent))
} }
oldDropped := atomic.SwapInt64(&micFramesDroppedValue, metrics.FramesDropped) oldDropped := atomic.SwapUint64(&micFramesDroppedValue, metrics.FramesDropped)
if metrics.FramesDropped > oldDropped { if metrics.FramesDropped > oldDropped {
microphoneFramesDroppedTotal.Add(float64(metrics.FramesDropped - oldDropped)) microphoneFramesDroppedTotal.Add(float64(metrics.FramesDropped - oldDropped))
} }
oldBytes := atomic.SwapInt64(&micBytesProcessedValue, metrics.BytesProcessed) oldBytes := atomic.SwapUint64(&micBytesProcessedValue, metrics.BytesProcessed)
if metrics.BytesProcessed > oldBytes { if metrics.BytesProcessed > oldBytes {
microphoneBytesProcessedTotal.Add(float64(metrics.BytesProcessed - oldBytes)) microphoneBytesProcessedTotal.Add(float64(metrics.BytesProcessed - oldBytes))
} }
oldDrops := atomic.SwapInt64(&micConnectionDropsValue, metrics.ConnectionDrops) oldDrops := atomic.SwapUint64(&micConnectionDropsValue, metrics.ConnectionDrops)
if metrics.ConnectionDrops > oldDrops { if metrics.ConnectionDrops > oldDrops {
microphoneConnectionDropsTotal.Add(float64(metrics.ConnectionDrops - oldDrops)) microphoneConnectionDropsTotal.Add(float64(metrics.ConnectionDrops - oldDrops))
} }

View File

@ -532,8 +532,17 @@ func (ais *AudioInputServer) processOpusConfig(data []byte) error {
logger.Info().Interface("config", config).Msg("applying dynamic Opus encoder configuration") logger.Info().Interface("config", config).Msg("applying dynamic Opus encoder configuration")
// Apply the Opus encoder configuration dynamically // Ensure capture is initialized before updating encoder parameters
err := CGOUpdateOpusEncoderParams( // The C function requires both encoder and capture_initialized to be true
if err := CGOAudioInit(); err != nil {
logger.Debug().Err(err).Msg("Audio capture already initialized or initialization failed")
// Continue anyway - capture may already be initialized
}
// Apply the Opus encoder configuration dynamically with retry logic
var err error
for attempt := 0; attempt < 3; attempt++ {
err = CGOUpdateOpusEncoderParams(
config.Bitrate, config.Bitrate,
config.Complexity, config.Complexity,
config.VBR, config.VBR,
@ -542,9 +551,17 @@ func (ais *AudioInputServer) processOpusConfig(data []byte) error {
config.Bandwidth, config.Bandwidth,
config.DTX, config.DTX,
) )
if err == nil {
break
}
logger.Warn().Err(err).Int("attempt", attempt+1).Msg("Failed to update Opus encoder parameters, retrying")
if attempt < 2 {
time.Sleep(time.Duration(attempt+1) * 50 * time.Millisecond)
}
}
if err != nil { if err != nil {
logger.Error().Err(err).Msg("failed to apply Opus encoder configuration") logger.Error().Err(err).Msg("failed to apply Opus encoder configuration after retries")
return fmt.Errorf("failed to apply Opus configuration: %w", err) return fmt.Errorf("failed to apply Opus configuration: %w", err)
} }

View File

@ -63,10 +63,10 @@ type AudioConfig struct {
// AudioMetrics tracks audio performance metrics // AudioMetrics tracks audio performance metrics
type AudioMetrics struct { type AudioMetrics struct {
FramesReceived int64 FramesReceived uint64
FramesDropped int64 FramesDropped uint64
BytesProcessed int64 BytesProcessed uint64
ConnectionDrops int64 ConnectionDrops uint64
LastFrameTime time.Time LastFrameTime time.Time
AverageLatency time.Duration AverageLatency time.Duration
} }
@ -398,16 +398,16 @@ func flushBatchedMetrics() {
// Update main metrics if we have any batched data // Update main metrics if we have any batched data
if framesReceived > 0 { if framesReceived > 0 {
atomic.AddInt64(&metrics.FramesReceived, framesReceived) atomic.AddUint64(&metrics.FramesReceived, uint64(framesReceived))
} }
if bytesProcessed > 0 { if bytesProcessed > 0 {
atomic.AddInt64(&metrics.BytesProcessed, bytesProcessed) atomic.AddUint64(&metrics.BytesProcessed, uint64(bytesProcessed))
} }
if framesDropped > 0 { if framesDropped > 0 {
atomic.AddInt64(&metrics.FramesDropped, framesDropped) atomic.AddUint64(&metrics.FramesDropped, uint64(framesDropped))
} }
if connectionDrops > 0 { if connectionDrops > 0 {
atomic.AddInt64(&metrics.ConnectionDrops, connectionDrops) atomic.AddUint64(&metrics.ConnectionDrops, uint64(connectionDrops))
} }
// Update last flush time // Update last flush time