mirror of https://github.com/jetkvm/kvm.git
refactor(audio): remove redundant config variable assignments
Replace repeated local config variable assignments with direct Config access to reduce memory allocations and improve code maintainability
This commit is contained in:
parent
1d1658db15
commit
6f10010d71
|
@ -82,19 +82,16 @@ type batchWriteResult struct {
|
|||
|
||||
// NewBatchAudioProcessor creates a new batch audio processor
|
||||
func NewBatchAudioProcessor(batchSize int, batchDuration time.Duration) *BatchAudioProcessor {
|
||||
// Get cached config to avoid GetConfig() calls
|
||||
cache := Config
|
||||
|
||||
// Validate input parameters with minimal overhead
|
||||
if batchSize <= 0 || batchSize > 1000 {
|
||||
batchSize = cache.BatchProcessorFramesPerBatch
|
||||
batchSize = Config.BatchProcessorFramesPerBatch
|
||||
}
|
||||
if batchDuration <= 0 {
|
||||
batchDuration = cache.BatchProcessingDelay
|
||||
batchDuration = Config.BatchProcessingDelay
|
||||
}
|
||||
|
||||
// Use optimized queue sizes from configuration
|
||||
queueSize := cache.BatchProcessorMaxQueueSize
|
||||
queueSize := Config.BatchProcessorMaxQueueSize
|
||||
if queueSize <= 0 {
|
||||
queueSize = batchSize * 2 // Fallback to double batch size
|
||||
}
|
||||
|
@ -103,8 +100,7 @@ func NewBatchAudioProcessor(batchSize int, batchDuration time.Duration) *BatchAu
|
|||
// Pre-allocate logger to avoid repeated allocations
|
||||
logger := logging.GetDefaultLogger().With().Str("component", "batch-audio").Logger()
|
||||
|
||||
// Pre-calculate frame size to avoid repeated GetConfig() calls
|
||||
frameSize := cache.MinReadEncodeBuffer
|
||||
frameSize := Config.MinReadEncodeBuffer
|
||||
if frameSize == 0 {
|
||||
frameSize = 1500 // Safe fallback
|
||||
}
|
||||
|
@ -119,13 +115,11 @@ func NewBatchAudioProcessor(batchSize int, batchDuration time.Duration) *BatchAu
|
|||
writeQueue: make(chan batchWriteRequest, queueSize),
|
||||
readBufPool: &sync.Pool{
|
||||
New: func() interface{} {
|
||||
// Use pre-calculated frame size to avoid GetConfig() calls
|
||||
return make([]byte, 0, frameSize)
|
||||
},
|
||||
},
|
||||
writeBufPool: &sync.Pool{
|
||||
New: func() interface{} {
|
||||
// Use pre-calculated frame size to avoid GetConfig() calls
|
||||
return make([]byte, 0, frameSize)
|
||||
},
|
||||
},
|
||||
|
@ -172,9 +166,6 @@ func (bap *BatchAudioProcessor) Stop() {
|
|||
|
||||
// BatchReadEncode performs batched audio read and encode operations
|
||||
func (bap *BatchAudioProcessor) BatchReadEncode(buffer []byte) (int, error) {
|
||||
// Get cached config to avoid GetConfig() calls in hot path
|
||||
cache := Config
|
||||
|
||||
// Validate buffer before processing
|
||||
if err := ValidateBufferSize(len(buffer)); err != nil {
|
||||
// Only log validation errors in debug mode to reduce overhead
|
||||
|
@ -219,7 +210,7 @@ func (bap *BatchAudioProcessor) BatchReadEncode(buffer []byte) (int, error) {
|
|||
select {
|
||||
case result := <-resultChan:
|
||||
return result.length, result.err
|
||||
case <-time.After(cache.BatchProcessorTimeout):
|
||||
case <-time.After(Config.BatchProcessorTimeout):
|
||||
// Timeout, fallback to single operation
|
||||
// Use sampling to reduce atomic operations overhead
|
||||
if atomic.LoadInt64(&bap.stats.SingleReads)%10 == 0 {
|
||||
|
@ -233,9 +224,6 @@ func (bap *BatchAudioProcessor) BatchReadEncode(buffer []byte) (int, error) {
|
|||
// BatchDecodeWrite performs batched audio decode and write operations
|
||||
// This is the legacy version that uses a single buffer
|
||||
func (bap *BatchAudioProcessor) BatchDecodeWrite(buffer []byte) (int, error) {
|
||||
// Get cached config to avoid GetConfig() calls in hot path
|
||||
cache := Config
|
||||
|
||||
// Validate buffer before processing
|
||||
if err := ValidateBufferSize(len(buffer)); err != nil {
|
||||
// Only log validation errors in debug mode to reduce overhead
|
||||
|
@ -280,7 +268,7 @@ func (bap *BatchAudioProcessor) BatchDecodeWrite(buffer []byte) (int, error) {
|
|||
select {
|
||||
case result := <-resultChan:
|
||||
return result.length, result.err
|
||||
case <-time.After(cache.BatchProcessorTimeout):
|
||||
case <-time.After(Config.BatchProcessorTimeout):
|
||||
// Use sampling to reduce atomic operations overhead
|
||||
if atomic.LoadInt64(&bap.stats.SingleWrites)%10 == 0 {
|
||||
atomic.AddInt64(&bap.stats.SingleWrites, 10)
|
||||
|
@ -292,9 +280,6 @@ func (bap *BatchAudioProcessor) BatchDecodeWrite(buffer []byte) (int, error) {
|
|||
|
||||
// BatchDecodeWriteWithBuffers performs batched audio decode and write operations with separate opus and PCM buffers
|
||||
func (bap *BatchAudioProcessor) BatchDecodeWriteWithBuffers(opusData []byte, pcmBuffer []byte) (int, error) {
|
||||
// Get cached config to avoid GetConfig() calls in hot path
|
||||
cache := Config
|
||||
|
||||
// Validate buffers before processing
|
||||
if len(opusData) == 0 {
|
||||
return 0, fmt.Errorf("empty opus data buffer")
|
||||
|
@ -335,7 +320,7 @@ func (bap *BatchAudioProcessor) BatchDecodeWriteWithBuffers(opusData []byte, pcm
|
|||
select {
|
||||
case result := <-resultChan:
|
||||
return result.length, result.err
|
||||
case <-time.After(cache.BatchProcessorTimeout):
|
||||
case <-time.After(Config.BatchProcessorTimeout):
|
||||
atomic.AddInt64(&bap.stats.SingleWrites, 1)
|
||||
atomic.AddInt64(&bap.stats.WriteFrames, 1)
|
||||
// Use the optimized function with separate buffers
|
||||
|
@ -422,11 +407,9 @@ func (bap *BatchAudioProcessor) processBatchRead(batch []batchReadRequest) {
|
|||
return
|
||||
}
|
||||
|
||||
// Get cached config once - avoid repeated calls
|
||||
cache := Config
|
||||
threadPinningThreshold := cache.BatchProcessorThreadPinningThreshold
|
||||
threadPinningThreshold := Config.BatchProcessorThreadPinningThreshold
|
||||
if threadPinningThreshold == 0 {
|
||||
threadPinningThreshold = cache.MinBatchSizeForThreadPinning // Fallback
|
||||
threadPinningThreshold = Config.MinBatchSizeForThreadPinning // Fallback
|
||||
}
|
||||
|
||||
// Only pin to OS thread for large batches to reduce thread contention
|
||||
|
@ -475,11 +458,9 @@ func (bap *BatchAudioProcessor) processBatchWrite(batch []batchWriteRequest) {
|
|||
return
|
||||
}
|
||||
|
||||
// Get cached config to avoid GetConfig() calls in hot path
|
||||
cache := Config
|
||||
threadPinningThreshold := cache.BatchProcessorThreadPinningThreshold
|
||||
threadPinningThreshold := Config.BatchProcessorThreadPinningThreshold
|
||||
if threadPinningThreshold == 0 {
|
||||
threadPinningThreshold = cache.MinBatchSizeForThreadPinning // Fallback
|
||||
threadPinningThreshold = Config.MinBatchSizeForThreadPinning // Fallback
|
||||
}
|
||||
|
||||
// Only pin to OS thread for large batches to reduce thread contention
|
||||
|
@ -581,10 +562,7 @@ func GetBatchAudioProcessor() *BatchAudioProcessor {
|
|||
|
||||
// Initialize on first use
|
||||
if atomic.CompareAndSwapInt32(&batchProcessorInitialized, 0, 1) {
|
||||
// Get cached config to avoid GetConfig() calls
|
||||
cache := Config
|
||||
|
||||
processor := NewBatchAudioProcessor(cache.BatchProcessorFramesPerBatch, cache.BatchProcessorTimeout)
|
||||
processor := NewBatchAudioProcessor(Config.BatchProcessorFramesPerBatch, Config.BatchProcessorTimeout)
|
||||
atomic.StorePointer(&globalBatchProcessor, unsafe.Pointer(processor))
|
||||
return processor
|
||||
}
|
||||
|
@ -596,8 +574,7 @@ func GetBatchAudioProcessor() *BatchAudioProcessor {
|
|||
}
|
||||
|
||||
// Fallback: create a new processor (should rarely happen)
|
||||
config := Config
|
||||
return NewBatchAudioProcessor(config.BatchProcessorFramesPerBatch, config.BatchProcessorTimeout)
|
||||
return NewBatchAudioProcessor(Config.BatchProcessorFramesPerBatch, Config.BatchProcessorTimeout)
|
||||
}
|
||||
|
||||
// EnableBatchAudioProcessing enables the global batch processor
|
||||
|
|
|
@ -30,21 +30,21 @@ static snd_pcm_t *pcm_playback_handle = NULL;
|
|||
static OpusEncoder *encoder = NULL;
|
||||
static OpusDecoder *decoder = NULL;
|
||||
// Opus encoder settings - initialized from Go configuration
|
||||
static int opus_bitrate = 96000; // Will be set from GetConfig().CGOOpusBitrate
|
||||
static int opus_complexity = 3; // Will be set from GetConfig().CGOOpusComplexity
|
||||
static int opus_vbr = 1; // Will be set from GetConfig().CGOOpusVBR
|
||||
static int opus_vbr_constraint = 1; // Will be set from GetConfig().CGOOpusVBRConstraint
|
||||
static int opus_signal_type = 3; // Will be set from GetConfig().CGOOpusSignalType
|
||||
static int opus_bitrate = 96000; // Will be set from Config.CGOOpusBitrate
|
||||
static int opus_complexity = 3; // Will be set from Config.CGOOpusComplexity
|
||||
static int opus_vbr = 1; // Will be set from Config.CGOOpusVBR
|
||||
static int opus_vbr_constraint = 1; // Will be set from Config.CGOOpusVBRConstraint
|
||||
static int opus_signal_type = 3; // Will be set from Config.CGOOpusSignalType
|
||||
static int opus_bandwidth = 1105; // OPUS_BANDWIDTH_WIDEBAND for compatibility (was 1101)
|
||||
static int opus_dtx = 0; // Will be set from GetConfig().CGOOpusDTX
|
||||
static int opus_dtx = 0; // Will be set from Config.CGOOpusDTX
|
||||
static int opus_lsb_depth = 16; // LSB depth for improved bit allocation on constrained hardware
|
||||
static int sample_rate = 48000; // Will be set from GetConfig().CGOSampleRate
|
||||
static int channels = 2; // Will be set from GetConfig().CGOChannels
|
||||
static int frame_size = 960; // Will be set from GetConfig().CGOFrameSize
|
||||
static int max_packet_size = 1500; // Will be set from GetConfig().CGOMaxPacketSize
|
||||
static int sleep_microseconds = 1000; // Will be set from GetConfig().CGOUsleepMicroseconds
|
||||
static int max_attempts_global = 5; // Will be set from GetConfig().CGOMaxAttempts
|
||||
static int max_backoff_us_global = 500000; // Will be set from GetConfig().CGOMaxBackoffMicroseconds
|
||||
static int sample_rate = 48000; // Will be set from Config.CGOSampleRate
|
||||
static int channels = 2; // Will be set from Config.CGOChannels
|
||||
static int frame_size = 960; // Will be set from Config.CGOFrameSize
|
||||
static int max_packet_size = 1500; // Will be set from Config.CGOMaxPacketSize
|
||||
static int sleep_microseconds = 1000; // Will be set from Config.CGOUsleepMicroseconds
|
||||
static int max_attempts_global = 5; // Will be set from Config.CGOMaxAttempts
|
||||
static int max_backoff_us_global = 500000; // Will be set from Config.CGOMaxBackoffMicroseconds
|
||||
// Hardware optimization flags for constrained environments
|
||||
static int use_mmap_access = 0; // Disable MMAP for compatibility (was 1)
|
||||
static int optimized_buffer_size = 0; // Disable optimized buffer sizing for stability (was 1)
|
||||
|
@ -709,9 +709,9 @@ func cgoAudioInit() error {
|
|||
C.int(cache.channels.Load()),
|
||||
C.int(cache.frameSize.Load()),
|
||||
C.int(cache.maxPacketSize.Load()),
|
||||
C.int(GetConfig().CGOUsleepMicroseconds),
|
||||
C.int(GetConfig().CGOMaxAttempts),
|
||||
C.int(GetConfig().CGOMaxBackoffMicroseconds),
|
||||
C.int(Config.CGOUsleepMicroseconds),
|
||||
C.int(Config.CGOMaxAttempts),
|
||||
C.int(Config.CGOMaxBackoffMicroseconds),
|
||||
)
|
||||
|
||||
result := C.jetkvm_audio_init()
|
||||
|
@ -726,7 +726,6 @@ func cgoAudioClose() {
|
|||
}
|
||||
|
||||
// AudioConfigCache provides a comprehensive caching system for audio configuration
|
||||
// to minimize GetConfig() calls in the hot path
|
||||
type AudioConfigCache struct {
|
||||
// Atomic int64 fields MUST be first for ARM32 alignment (8-byte alignment required)
|
||||
minFrameDuration atomic.Int64 // Store as nanoseconds
|
||||
|
@ -815,52 +814,50 @@ func (c *AudioConfigCache) Update() {
|
|||
|
||||
// Double-check after acquiring lock
|
||||
if !c.initialized.Load() || time.Since(c.lastUpdate) > c.cacheExpiry {
|
||||
config := GetConfig() // Call GetConfig() only once
|
||||
|
||||
// Update atomic values for lock-free access - CGO values
|
||||
c.minReadEncodeBuffer.Store(int32(config.MinReadEncodeBuffer))
|
||||
c.maxDecodeWriteBuffer.Store(int32(config.MaxDecodeWriteBuffer))
|
||||
c.maxPacketSize.Store(int32(config.CGOMaxPacketSize))
|
||||
c.maxPCMBufferSize.Store(int32(config.MaxPCMBufferSize))
|
||||
c.opusBitrate.Store(int32(config.CGOOpusBitrate))
|
||||
c.opusComplexity.Store(int32(config.CGOOpusComplexity))
|
||||
c.opusVBR.Store(int32(config.CGOOpusVBR))
|
||||
c.opusVBRConstraint.Store(int32(config.CGOOpusVBRConstraint))
|
||||
c.opusSignalType.Store(int32(config.CGOOpusSignalType))
|
||||
c.opusBandwidth.Store(int32(config.CGOOpusBandwidth))
|
||||
c.opusDTX.Store(int32(config.CGOOpusDTX))
|
||||
c.sampleRate.Store(int32(config.CGOSampleRate))
|
||||
c.channels.Store(int32(config.CGOChannels))
|
||||
c.frameSize.Store(int32(config.CGOFrameSize))
|
||||
c.minReadEncodeBuffer.Store(int32(Config.MinReadEncodeBuffer))
|
||||
c.maxDecodeWriteBuffer.Store(int32(Config.MaxDecodeWriteBuffer))
|
||||
c.maxPacketSize.Store(int32(Config.CGOMaxPacketSize))
|
||||
c.maxPCMBufferSize.Store(int32(Config.MaxPCMBufferSize))
|
||||
c.opusBitrate.Store(int32(Config.CGOOpusBitrate))
|
||||
c.opusComplexity.Store(int32(Config.CGOOpusComplexity))
|
||||
c.opusVBR.Store(int32(Config.CGOOpusVBR))
|
||||
c.opusVBRConstraint.Store(int32(Config.CGOOpusVBRConstraint))
|
||||
c.opusSignalType.Store(int32(Config.CGOOpusSignalType))
|
||||
c.opusBandwidth.Store(int32(Config.CGOOpusBandwidth))
|
||||
c.opusDTX.Store(int32(Config.CGOOpusDTX))
|
||||
c.sampleRate.Store(int32(Config.CGOSampleRate))
|
||||
c.channels.Store(int32(Config.CGOChannels))
|
||||
c.frameSize.Store(int32(Config.CGOFrameSize))
|
||||
|
||||
// Update additional validation values
|
||||
c.maxAudioFrameSize.Store(int32(config.MaxAudioFrameSize))
|
||||
c.maxChannels.Store(int32(config.MaxChannels))
|
||||
c.minFrameDuration.Store(int64(config.MinFrameDuration))
|
||||
c.maxFrameDuration.Store(int64(config.MaxFrameDuration))
|
||||
c.minOpusBitrate.Store(int32(config.MinOpusBitrate))
|
||||
c.maxOpusBitrate.Store(int32(config.MaxOpusBitrate))
|
||||
c.maxAudioFrameSize.Store(int32(Config.MaxAudioFrameSize))
|
||||
c.maxChannels.Store(int32(Config.MaxChannels))
|
||||
c.minFrameDuration.Store(int64(Config.MinFrameDuration))
|
||||
c.maxFrameDuration.Store(int64(Config.MaxFrameDuration))
|
||||
c.minOpusBitrate.Store(int32(Config.MinOpusBitrate))
|
||||
c.maxOpusBitrate.Store(int32(Config.MaxOpusBitrate))
|
||||
|
||||
// Update batch processing related values
|
||||
c.BatchProcessingTimeout = 100 * time.Millisecond // Fixed timeout for batch processing
|
||||
c.BatchProcessorFramesPerBatch = config.BatchProcessorFramesPerBatch
|
||||
c.BatchProcessorTimeout = config.BatchProcessorTimeout
|
||||
c.BatchProcessingDelay = config.BatchProcessingDelay
|
||||
c.MinBatchSizeForThreadPinning = config.MinBatchSizeForThreadPinning
|
||||
c.BatchProcessorMaxQueueSize = config.BatchProcessorMaxQueueSize
|
||||
c.BatchProcessorAdaptiveThreshold = config.BatchProcessorAdaptiveThreshold
|
||||
c.BatchProcessorThreadPinningThreshold = config.BatchProcessorThreadPinningThreshold
|
||||
c.BatchProcessorFramesPerBatch = Config.BatchProcessorFramesPerBatch
|
||||
c.BatchProcessorTimeout = Config.BatchProcessorTimeout
|
||||
c.BatchProcessingDelay = Config.BatchProcessingDelay
|
||||
c.MinBatchSizeForThreadPinning = Config.MinBatchSizeForThreadPinning
|
||||
c.BatchProcessorMaxQueueSize = Config.BatchProcessorMaxQueueSize
|
||||
c.BatchProcessorAdaptiveThreshold = Config.BatchProcessorAdaptiveThreshold
|
||||
c.BatchProcessorThreadPinningThreshold = Config.BatchProcessorThreadPinningThreshold
|
||||
|
||||
// Pre-allocate common errors
|
||||
c.bufferTooSmallReadEncode = newBufferTooSmallError(0, config.MinReadEncodeBuffer)
|
||||
c.bufferTooLargeDecodeWrite = newBufferTooLargeError(config.MaxDecodeWriteBuffer+1, config.MaxDecodeWriteBuffer)
|
||||
c.bufferTooSmallReadEncode = newBufferTooSmallError(0, Config.MinReadEncodeBuffer)
|
||||
c.bufferTooLargeDecodeWrite = newBufferTooLargeError(Config.MaxDecodeWriteBuffer+1, Config.MaxDecodeWriteBuffer)
|
||||
|
||||
c.lastUpdate = time.Now()
|
||||
c.initialized.Store(true)
|
||||
|
||||
// Update the global validation cache as well
|
||||
if cachedMaxFrameSize != 0 {
|
||||
cachedMaxFrameSize = config.MaxAudioFrameSize
|
||||
cachedMaxFrameSize = Config.MaxAudioFrameSize
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,13 +87,11 @@ func ValidateBufferSize(size int) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Slower path: full validation against SocketMaxBuffer
|
||||
config := Config
|
||||
// Use SocketMaxBuffer as the upper limit for general buffer validation
|
||||
// This allows for socket buffers while still preventing extremely large allocations
|
||||
if size > config.SocketMaxBuffer {
|
||||
if size > Config.SocketMaxBuffer {
|
||||
return fmt.Errorf("%w: buffer size %d exceeds maximum %d",
|
||||
ErrInvalidBufferSize, size, config.SocketMaxBuffer)
|
||||
ErrInvalidBufferSize, size, Config.SocketMaxBuffer)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -123,16 +121,14 @@ func ValidateLatency(latency time.Duration) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Slower path: full validation with GetConfig()
|
||||
config := Config
|
||||
minLatency := time.Millisecond // Minimum reasonable latency
|
||||
if latency > 0 && latency < minLatency {
|
||||
return fmt.Errorf("%w: latency %v below minimum %v",
|
||||
ErrInvalidLatency, latency, minLatency)
|
||||
}
|
||||
if latency > config.MaxLatency {
|
||||
if latency > Config.MaxLatency {
|
||||
return fmt.Errorf("%w: latency %v exceeds maximum %v",
|
||||
ErrInvalidLatency, latency, config.MaxLatency)
|
||||
ErrInvalidLatency, latency, Config.MaxLatency)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -158,10 +154,8 @@ func ValidateMetricsInterval(interval time.Duration) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Slower path: full validation with GetConfig()
|
||||
config := Config
|
||||
minInterval = config.MinMetricsUpdateInterval
|
||||
maxInterval = config.MaxMetricsUpdateInterval
|
||||
minInterval = Config.MinMetricsUpdateInterval
|
||||
maxInterval = Config.MaxMetricsUpdateInterval
|
||||
if interval < minInterval {
|
||||
return ErrInvalidMetricsInterval
|
||||
}
|
||||
|
@ -192,11 +186,9 @@ func ValidateAdaptiveBufferConfig(minSize, maxSize, defaultSize int) error {
|
|||
|
||||
// ValidateInputIPCConfig validates input IPC configuration
|
||||
func ValidateInputIPCConfig(sampleRate, channels, frameSize int) error {
|
||||
// Use config values
|
||||
config := Config
|
||||
minSampleRate := config.MinSampleRate
|
||||
maxSampleRate := config.MaxSampleRate
|
||||
maxChannels := config.MaxChannels
|
||||
minSampleRate := Config.MinSampleRate
|
||||
maxSampleRate := Config.MaxSampleRate
|
||||
maxChannels := Config.MaxChannels
|
||||
if sampleRate < minSampleRate || sampleRate > maxSampleRate {
|
||||
return ErrInvalidSampleRate
|
||||
}
|
||||
|
@ -211,11 +203,9 @@ func ValidateInputIPCConfig(sampleRate, channels, frameSize int) error {
|
|||
|
||||
// ValidateOutputIPCConfig validates output IPC configuration
|
||||
func ValidateOutputIPCConfig(sampleRate, channels, frameSize int) error {
|
||||
// Use config values
|
||||
config := Config
|
||||
minSampleRate := config.MinSampleRate
|
||||
maxSampleRate := config.MaxSampleRate
|
||||
maxChannels := config.MaxChannels
|
||||
minSampleRate := Config.MinSampleRate
|
||||
maxSampleRate := Config.MaxSampleRate
|
||||
maxChannels := Config.MaxChannels
|
||||
if sampleRate < minSampleRate || sampleRate > maxSampleRate {
|
||||
return ErrInvalidSampleRate
|
||||
}
|
||||
|
@ -236,7 +226,7 @@ func ValidateLatencyConfig(config LatencyConfig) error {
|
|||
if err := ValidateLatency(config.MaxLatency); err != nil {
|
||||
return err
|
||||
}
|
||||
if config.TargetLatency >= config.MaxLatency {
|
||||
if config.TargetLatency >= Config.MaxLatency {
|
||||
return ErrInvalidLatency
|
||||
}
|
||||
if err := ValidateMetricsInterval(config.OptimizationInterval); err != nil {
|
||||
|
@ -271,8 +261,7 @@ func ValidateSampleRate(sampleRate int) error {
|
|||
}
|
||||
|
||||
// Slower path: check against all valid rates
|
||||
config := Config
|
||||
validRates := config.ValidSampleRates
|
||||
validRates := Config.ValidSampleRates
|
||||
for _, rate := range validRates {
|
||||
if sampleRate == rate {
|
||||
return nil
|
||||
|
@ -340,17 +329,15 @@ func ValidateBitrate(bitrate int) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Slower path: full validation with GetConfig()
|
||||
config := Config
|
||||
// Convert kbps to bps for comparison with config limits
|
||||
bitrateInBps := bitrate * 1000
|
||||
if bitrateInBps < config.MinOpusBitrate {
|
||||
if bitrateInBps < Config.MinOpusBitrate {
|
||||
return fmt.Errorf("%w: bitrate %d kbps (%d bps) below minimum %d bps",
|
||||
ErrInvalidBitrate, bitrate, bitrateInBps, config.MinOpusBitrate)
|
||||
ErrInvalidBitrate, bitrate, bitrateInBps, Config.MinOpusBitrate)
|
||||
}
|
||||
if bitrateInBps > config.MaxOpusBitrate {
|
||||
if bitrateInBps > Config.MaxOpusBitrate {
|
||||
return fmt.Errorf("%w: bitrate %d kbps (%d bps) exceeds maximum %d bps",
|
||||
ErrInvalidBitrate, bitrate, bitrateInBps, config.MaxOpusBitrate)
|
||||
ErrInvalidBitrate, bitrate, bitrateInBps, Config.MaxOpusBitrate)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -462,11 +449,11 @@ func ValidateAudioConfigConstants(config *AudioConfigConstants) error {
|
|||
}
|
||||
// Validate configuration values if config is provided
|
||||
if config != nil {
|
||||
if config.MaxFrameSize <= 0 {
|
||||
return fmt.Errorf("invalid MaxFrameSize: %d", config.MaxFrameSize)
|
||||
if Config.MaxFrameSize <= 0 {
|
||||
return fmt.Errorf("invalid MaxFrameSize: %d", Config.MaxFrameSize)
|
||||
}
|
||||
if config.SampleRate <= 0 {
|
||||
return fmt.Errorf("invalid SampleRate: %d", config.SampleRate)
|
||||
if Config.SampleRate <= 0 {
|
||||
return fmt.Errorf("invalid SampleRate: %d", Config.SampleRate)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -478,8 +465,7 @@ var cachedMaxFrameSize int
|
|||
// InitValidationCache initializes cached validation values with actual config
|
||||
func InitValidationCache() {
|
||||
// Initialize the global cache variable for backward compatibility
|
||||
config := Config
|
||||
cachedMaxFrameSize = config.MaxAudioFrameSize
|
||||
cachedMaxFrameSize = Config.MaxAudioFrameSize
|
||||
|
||||
// Initialize the global audio config cache
|
||||
cachedMaxFrameSize = Config.MaxAudioFrameSize
|
||||
|
|
Loading…
Reference in New Issue