Implement per-user audio control (vol/mute) and User View UI
This commit is contained in:
@@ -26,7 +26,15 @@ type Player struct {
|
||||
// User buffers for mixing
|
||||
// map[SenderID] -> AudioQueue
|
||||
userBuffers map[uint16][]int16
|
||||
bufferMu sync.Mutex
|
||||
|
||||
// User settings
|
||||
userSettings map[uint16]*UserSettings
|
||||
bufferMu sync.Mutex
|
||||
}
|
||||
|
||||
type UserSettings struct {
|
||||
Volume float32 // 0.0 - 1.0 (or higher for boost)
|
||||
Muted bool
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -105,6 +113,7 @@ func NewPlayer() (*Player, error) {
|
||||
muted: false,
|
||||
stopChan: make(chan struct{}),
|
||||
userBuffers: make(map[uint16][]int16),
|
||||
userSettings: make(map[uint16]*UserSettings),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -162,6 +171,11 @@ func (p *Player) PlayPCM(senderID uint16, samples []int16) {
|
||||
p.bufferMu.Lock()
|
||||
defer p.bufferMu.Unlock()
|
||||
|
||||
// Check per-user mute
|
||||
if settings, ok := p.userSettings[senderID]; ok && settings.Muted {
|
||||
return
|
||||
}
|
||||
|
||||
// Append to user's specific buffer
|
||||
// This ensures sequential playback for the same user
|
||||
p.userBuffers[senderID] = append(p.userBuffers[senderID], samples...)
|
||||
@@ -201,13 +215,45 @@ func (p *Player) SetMuted(muted bool) {
|
||||
p.mu.Unlock()
|
||||
}
|
||||
|
||||
// IsMuted returns mute state
|
||||
func (p *Player) IsMuted() bool {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
return p.muted
|
||||
}
|
||||
|
||||
// SetUserVolume sets volume for a specific user (1.0 is default)
|
||||
func (p *Player) SetUserVolume(clientID uint16, vol float32) {
|
||||
p.bufferMu.Lock()
|
||||
defer p.bufferMu.Unlock()
|
||||
|
||||
if _, ok := p.userSettings[clientID]; !ok {
|
||||
p.userSettings[clientID] = &UserSettings{Volume: 1.0, Muted: false}
|
||||
}
|
||||
p.userSettings[clientID].Volume = vol
|
||||
}
|
||||
|
||||
// SetUserMuted sets mute state for a specific user
|
||||
func (p *Player) SetUserMuted(clientID uint16, muted bool) {
|
||||
p.bufferMu.Lock()
|
||||
defer p.bufferMu.Unlock()
|
||||
|
||||
if _, ok := p.userSettings[clientID]; !ok {
|
||||
p.userSettings[clientID] = &UserSettings{Volume: 1.0, Muted: false}
|
||||
}
|
||||
p.userSettings[clientID].Muted = muted
|
||||
}
|
||||
|
||||
// GetUserSettings gets current volume and mute state for user
|
||||
func (p *Player) GetUserSettings(clientID uint16) (float32, bool) {
|
||||
p.bufferMu.Lock()
|
||||
defer p.bufferMu.Unlock()
|
||||
|
||||
if settings, ok := p.userSettings[clientID]; ok {
|
||||
return settings.Volume, settings.Muted
|
||||
}
|
||||
return 1.0, false
|
||||
}
|
||||
|
||||
func (p *Player) playbackLoop() {
|
||||
ticker := time.NewTicker(20 * time.Millisecond)
|
||||
defer ticker.Stop()
|
||||
@@ -249,7 +295,14 @@ func (p *Player) writeFrame() {
|
||||
}
|
||||
|
||||
for i := 0; i < toTake; i++ {
|
||||
mixed[i] += int32(buf[i])
|
||||
sample := int32(buf[i])
|
||||
|
||||
// Apply user volume if set
|
||||
if settings, ok := p.userSettings[id]; ok {
|
||||
sample = int32(float32(sample) * settings.Volume)
|
||||
}
|
||||
|
||||
mixed[i] += sample
|
||||
}
|
||||
|
||||
// Advance buffer
|
||||
|
||||
Reference in New Issue
Block a user