mirror of https://github.com/jetkvm/kvm.git
142 lines
3.1 KiB
Go
142 lines
3.1 KiB
Go
//go:build cgo
|
|
// +build cgo
|
|
|
|
package audio
|
|
|
|
import (
|
|
"sync/atomic"
|
|
)
|
|
|
|
// AudioBufferPool provides a simple buffer pool for audio processing
|
|
type AudioBufferPool struct {
|
|
// Atomic counters
|
|
hitCount int64 // Pool hit counter (atomic)
|
|
missCount int64 // Pool miss counter (atomic)
|
|
|
|
// Pool configuration
|
|
bufferSize int
|
|
pool chan []byte
|
|
maxSize int
|
|
}
|
|
|
|
// NewAudioBufferPool creates a new simple audio buffer pool
|
|
func NewAudioBufferPool(bufferSize int) *AudioBufferPool {
|
|
maxSize := Config.MaxPoolSize
|
|
if maxSize <= 0 {
|
|
maxSize = Config.BufferPoolDefaultSize
|
|
}
|
|
|
|
pool := &AudioBufferPool{
|
|
bufferSize: bufferSize,
|
|
pool: make(chan []byte, maxSize),
|
|
maxSize: maxSize,
|
|
}
|
|
|
|
// Pre-populate the pool
|
|
for i := 0; i < maxSize/2; i++ {
|
|
buf := make([]byte, bufferSize)
|
|
select {
|
|
case pool.pool <- buf:
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
|
|
return pool
|
|
}
|
|
|
|
// Get retrieves a buffer from the pool
|
|
func (p *AudioBufferPool) Get() []byte {
|
|
select {
|
|
case buf := <-p.pool:
|
|
atomic.AddInt64(&p.hitCount, 1)
|
|
return buf[:0] // Reset length but keep capacity
|
|
default:
|
|
atomic.AddInt64(&p.missCount, 1)
|
|
return make([]byte, 0, p.bufferSize)
|
|
}
|
|
}
|
|
|
|
// Put returns a buffer to the pool
|
|
func (p *AudioBufferPool) Put(buf []byte) {
|
|
if buf == nil || cap(buf) != p.bufferSize {
|
|
return // Invalid buffer
|
|
}
|
|
|
|
// Reset the buffer
|
|
buf = buf[:0]
|
|
|
|
// Try to return to pool
|
|
select {
|
|
case p.pool <- buf:
|
|
// Successfully returned to pool
|
|
default:
|
|
// Pool is full, discard buffer
|
|
}
|
|
}
|
|
|
|
// GetStats returns pool statistics
|
|
func (p *AudioBufferPool) GetStats() AudioBufferPoolStats {
|
|
hitCount := atomic.LoadInt64(&p.hitCount)
|
|
missCount := atomic.LoadInt64(&p.missCount)
|
|
totalRequests := hitCount + missCount
|
|
|
|
var hitRate float64
|
|
if totalRequests > 0 {
|
|
hitRate = float64(hitCount) / float64(totalRequests) * Config.BufferPoolHitRateBase
|
|
}
|
|
|
|
return AudioBufferPoolStats{
|
|
BufferSize: p.bufferSize,
|
|
MaxPoolSize: p.maxSize,
|
|
CurrentSize: int64(len(p.pool)),
|
|
HitCount: hitCount,
|
|
MissCount: missCount,
|
|
HitRate: hitRate,
|
|
}
|
|
}
|
|
|
|
// AudioBufferPoolStats represents pool statistics
|
|
type AudioBufferPoolStats struct {
|
|
BufferSize int
|
|
MaxPoolSize int
|
|
CurrentSize int64
|
|
HitCount int64
|
|
MissCount int64
|
|
HitRate float64
|
|
}
|
|
|
|
// Global buffer pools
|
|
var (
|
|
audioFramePool = NewAudioBufferPool(Config.AudioFramePoolSize)
|
|
audioControlPool = NewAudioBufferPool(Config.BufferPoolControlSize)
|
|
)
|
|
|
|
// GetAudioFrameBuffer gets a buffer for audio frames
|
|
func GetAudioFrameBuffer() []byte {
|
|
return audioFramePool.Get()
|
|
}
|
|
|
|
// PutAudioFrameBuffer returns a buffer to the frame pool
|
|
func PutAudioFrameBuffer(buf []byte) {
|
|
audioFramePool.Put(buf)
|
|
}
|
|
|
|
// GetAudioControlBuffer gets a buffer for control messages
|
|
func GetAudioControlBuffer() []byte {
|
|
return audioControlPool.Get()
|
|
}
|
|
|
|
// PutAudioControlBuffer returns a buffer to the control pool
|
|
func PutAudioControlBuffer(buf []byte) {
|
|
audioControlPool.Put(buf)
|
|
}
|
|
|
|
// GetAudioBufferPoolStats returns statistics for all pools
|
|
func GetAudioBufferPoolStats() map[string]AudioBufferPoolStats {
|
|
return map[string]AudioBufferPoolStats{
|
|
"frame_pool": audioFramePool.GetStats(),
|
|
"control_pool": audioControlPool.GetStats(),
|
|
}
|
|
}
|