[WIP] Cleanup, Refactor: Reduce PR complexity, common IPC layer

This commit is contained in:
Alex P 2025-09-09 07:08:32 +00:00
parent f71d18039b
commit 2bc7e50391
9 changed files with 47 additions and 44 deletions

View File

@ -234,7 +234,7 @@ func (abm *AdaptiveBufferManager) adaptationLoop() {
// The algorithm runs periodically and only applies changes when the adaptation interval
// has elapsed, preventing excessive adjustments that could destabilize the audio pipeline.
func (abm *AdaptiveBufferManager) adaptBufferSizes() {
// Use fixed system metrics since monitoring is simplified
// Use fixed system metrics for stability
systemCPU := 50.0 // Assume moderate CPU usage
systemMemory := 60.0 // Assume moderate memory usage

View File

@ -1046,7 +1046,7 @@ func updateOpusEncoderParams(bitrate, complexity, vbr, vbrConstraint, signalType
// Buffer pool for reusing buffers in CGO functions
var (
// Using SizedBufferPool for better memory management
// Track buffer pool usage for monitoring
// Track buffer pool usage
cgoBufferPoolGets atomic.Int64
cgoBufferPoolPuts atomic.Int64
// Batch processing statistics - only enabled in debug builds

View File

@ -505,11 +505,9 @@ func DefaultAudioConfig() *AudioConfigConstants {
AdaptiveMaxBufferSize: 1024, // Much higher maximum for quality changes
AdaptiveDefaultBufferSize: 512, // Higher default for stability during bursts
// Adaptive Optimizer Configuration - Faster response
CooldownPeriod: 15 * time.Second, // Reduced cooldown period
RollbackThreshold: 200 * time.Millisecond, // Lower rollback threshold
// Latency Monitor Configuration - More aggressive monitoring
MaxLatencyThreshold: 150 * time.Millisecond, // Lower max latency threshold
JitterThreshold: 15 * time.Millisecond, // Reduced jitter threshold
LatencyOptimizationInterval: 3 * time.Second, // More frequent optimization
@ -638,8 +636,6 @@ func DefaultAudioConfig() *AudioConfigConstants {
MinFrameSize: 1, // 1 byte minimum frame size (allow small frames)
FrameSizeTolerance: 512, // 512 bytes frame size tolerance
// Removed device health monitoring configuration - functionality not used
// Latency Histogram Bucket Configuration
LatencyBucket10ms: 10 * time.Millisecond, // 10ms latency bucket
LatencyBucket25ms: 25 * time.Millisecond, // 25ms latency bucket

View File

@ -406,8 +406,7 @@ func UpdateSocketBufferMetrics(component, bufferType string, size, utilization f
atomic.StoreInt64(&lastMetricsUpdate, time.Now().Unix())
}
// UpdateDeviceHealthMetrics - Device health monitoring functionality has been removed
// This function is no longer used as device health monitoring is not implemented
// UpdateDeviceHealthMetrics - Placeholder for future device health metrics
// UpdateMemoryMetrics updates memory metrics
func UpdateMemoryMetrics() {

View File

@ -132,6 +132,42 @@ func (mp *GenericMessagePool) GetStats() (hitCount, missCount int64, hitRate flo
return hits, misses, hitRate
}
// Helper functions
// EncodeMessageHeader encodes a message header into a byte slice
func EncodeMessageHeader(magic uint32, msgType uint8, length uint32, timestamp int64) []byte {
header := make([]byte, 17)
binary.LittleEndian.PutUint32(header[0:4], magic)
header[4] = msgType
binary.LittleEndian.PutUint32(header[5:9], length)
binary.LittleEndian.PutUint64(header[9:17], uint64(timestamp))
return header
}
// EncodeAudioConfig encodes basic audio configuration to binary format
func EncodeAudioConfig(sampleRate, channels, frameSize int) []byte {
data := make([]byte, 12) // 3 * int32
binary.LittleEndian.PutUint32(data[0:4], uint32(sampleRate))
binary.LittleEndian.PutUint32(data[4:8], uint32(channels))
binary.LittleEndian.PutUint32(data[8:12], uint32(frameSize))
return data
}
// EncodeOpusConfig encodes complete Opus configuration to binary format
func EncodeOpusConfig(sampleRate, channels, frameSize, bitrate, complexity, vbr, signalType, bandwidth, dtx int) []byte {
data := make([]byte, 36) // 9 * int32
binary.LittleEndian.PutUint32(data[0:4], uint32(sampleRate))
binary.LittleEndian.PutUint32(data[4:8], uint32(channels))
binary.LittleEndian.PutUint32(data[8:12], uint32(frameSize))
binary.LittleEndian.PutUint32(data[12:16], uint32(bitrate))
binary.LittleEndian.PutUint32(data[16:20], uint32(complexity))
binary.LittleEndian.PutUint32(data[20:24], uint32(vbr))
binary.LittleEndian.PutUint32(data[24:28], uint32(signalType))
binary.LittleEndian.PutUint32(data[28:32], uint32(bandwidth))
binary.LittleEndian.PutUint32(data[32:36], uint32(dtx))
return data
}
// Common write message function
func WriteIPCMessage(conn net.Conn, msg IPCMessage, pool *GenericMessagePool, droppedFramesCounter *int64) error {
if conn == nil {
@ -143,10 +179,8 @@ func WriteIPCMessage(conn net.Conn, msg IPCMessage, pool *GenericMessagePool, dr
defer pool.Put(optMsg)
// Prepare header in pre-allocated buffer
binary.LittleEndian.PutUint32(optMsg.header[0:4], msg.GetMagic())
optMsg.header[4] = msg.GetType()
binary.LittleEndian.PutUint32(optMsg.header[5:9], msg.GetLength())
binary.LittleEndian.PutUint64(optMsg.header[9:17], uint64(msg.GetTimestamp()))
header := EncodeMessageHeader(msg.GetMagic(), msg.GetType(), msg.GetLength(), msg.GetTimestamp())
copy(optMsg.header[:], header)
// Set write deadline for timeout handling (more efficient than goroutines)
if deadline := time.Now().Add(Config.WriteTimeout); deadline.After(time.Now()) {

View File

@ -767,11 +767,8 @@ func (aic *AudioInputClient) SendConfig(config InputIPCConfig) error {
return fmt.Errorf("input configuration validation failed: %w", err)
}
// Serialize config (simple binary format)
data := make([]byte, 12) // 3 * int32
binary.LittleEndian.PutUint32(data[0:4], uint32(config.SampleRate))
binary.LittleEndian.PutUint32(data[4:8], uint32(config.Channels))
binary.LittleEndian.PutUint32(data[8:12], uint32(config.FrameSize))
// Serialize config using common function
data := EncodeAudioConfig(config.SampleRate, config.Channels, config.FrameSize)
msg := &InputIPCMessage{
Magic: inputMagicNumber,
@ -799,17 +796,8 @@ func (aic *AudioInputClient) SendOpusConfig(config InputIPCOpusConfig) error {
config.SampleRate, config.Channels, config.FrameSize, config.Bitrate)
}
// Serialize Opus configuration (9 * int32 = 36 bytes)
data := make([]byte, 36)
binary.LittleEndian.PutUint32(data[0:4], uint32(config.SampleRate))
binary.LittleEndian.PutUint32(data[4:8], uint32(config.Channels))
binary.LittleEndian.PutUint32(data[8:12], uint32(config.FrameSize))
binary.LittleEndian.PutUint32(data[12:16], uint32(config.Bitrate))
binary.LittleEndian.PutUint32(data[16:20], uint32(config.Complexity))
binary.LittleEndian.PutUint32(data[20:24], uint32(config.VBR))
binary.LittleEndian.PutUint32(data[24:28], uint32(config.SignalType))
binary.LittleEndian.PutUint32(data[28:32], uint32(config.Bandwidth))
binary.LittleEndian.PutUint32(data[32:36], uint32(config.DTX))
// Serialize Opus configuration using common function
data := EncodeOpusConfig(config.SampleRate, config.Channels, config.FrameSize, config.Bitrate, config.Complexity, config.VBR, config.SignalType, config.Bandwidth, config.DTX)
msg := &InputIPCMessage{
Magic: inputMagicNumber,

View File

@ -173,11 +173,7 @@ func (s *AudioOutputServer) SendFrame(frame []byte) error {
// writeMessage writes a message to the connection
func (s *AudioOutputServer) writeMessage(conn net.Conn, msg *OutputIPCMessage) error {
header := make([]byte, 17)
binary.LittleEndian.PutUint32(header[0:4], msg.Magic)
header[4] = uint8(msg.Type)
binary.LittleEndian.PutUint32(header[5:9], msg.Length)
binary.LittleEndian.PutUint64(header[9:17], uint64(msg.Timestamp))
header := EncodeMessageHeader(msg.Magic, uint8(msg.Type), msg.Length, msg.Timestamp)
if _, err := conn.Write(header); err != nil {
return fmt.Errorf("failed to write header: %w", err)

View File

@ -365,15 +365,7 @@ func (s *UnifiedAudioServer) SendFrame(frame []byte) error {
// writeMessage writes a message to the connection
func (s *UnifiedAudioServer) writeMessage(conn net.Conn, msg *UnifiedIPCMessage) error {
// Get header buffer from pool
headerPtr := headerBufferPool.Get().(*[]byte)
header := *headerPtr
defer headerBufferPool.Put(headerPtr)
binary.LittleEndian.PutUint32(header[0:4], msg.Magic)
header[4] = uint8(msg.Type)
binary.LittleEndian.PutUint32(header[5:9], msg.Length)
binary.LittleEndian.PutUint64(header[9:17], uint64(msg.Timestamp))
header := EncodeMessageHeader(msg.Magic, uint8(msg.Type), msg.Length, msg.Timestamp)
if _, err := conn.Write(header); err != nil {
return fmt.Errorf("failed to write header: %w", err)

View File

@ -48,8 +48,6 @@ func getOutputStreamingLogger() *zerolog.Logger {
// StartAudioOutputStreaming starts audio output streaming (capturing system audio)
func StartAudioOutputStreaming(send func([]byte)) error {
// Initialize audio monitoring (latency tracking and cache cleanup)
if !atomic.CompareAndSwapInt32(&outputStreamingRunning, 0, 1) {
return ErrAudioAlreadyRunning
}