Added mute option. It can work per user or per channel, so covers deafen functionality too.

This commit is contained in:
Storm Dragon 2025-01-16 13:36:46 -05:00
parent 46d0cbf8f5
commit a5c0e7a71c
5 changed files with 551 additions and 499 deletions

View File

@ -8,6 +8,7 @@ type Hotkeys struct {
Talk *uiterm.Key
VolumeDown *uiterm.Key
VolumeUp *uiterm.Key
MuteToggle *uiterm.Key
Exit *uiterm.Key
ToggleTimestamps *uiterm.Key
SwitchViews *uiterm.Key

View File

@ -4,7 +4,6 @@ import (
"fmt"
"git.2mb.codes/~cmb/barnard/uiterm"
"gopkg.in/yaml.v2"
// "encoding/yaml"
"git.2mb.codes/~cmb/barnard/gumble/gumble"
"io/ioutil"
"os"
@ -39,6 +38,7 @@ type eUser struct {
Username string
Boost uint16
Volume float32
LocallyMuted bool // Changed from Muted to LocallyMuted to match User struct
}
func (c *Config) SaveConfig() {
@ -68,6 +68,7 @@ func (c *Config) LoadConfig() {
Talk: key(uiterm.KeyF1),
VolumeDown: key(uiterm.KeyF5),
VolumeUp: key(uiterm.KeyF6),
MuteToggle: key(uiterm.KeyF7), // Added mute toggle hotkey
Exit: key(uiterm.KeyF10),
ToggleTimestamps: key(uiterm.KeyF3),
SwitchViews: key(uiterm.KeyTab),
@ -82,9 +83,9 @@ func (c *Config) LoadConfig() {
if err != nil {
fmt.Fprintf(os.Stderr, "Error parsing \"%s\".\n%s\n", c.fn, err.Error())
os.Exit(1)
} //panic
} //if data
} //if exists
}
}
}
c.config = &jc
if c.config.MicVolume == nil {
micvol := float32(1.0)
@ -152,12 +153,20 @@ func (c *Config) findUser(address string, username string) *eUser {
Username: username,
Boost: uint16(1),
Volume: 1.0,
LocallyMuted: false, // Initialize local mute state
}
s.Users = append(s.Users, t)
}
return t
}
func (c *Config) ToggleMute(u *gumble.User) {
j := c.findUser(u.GetClient().Config.Address, u.Name)
j.LocallyMuted = !j.LocallyMuted
u.LocallyMuted = j.LocallyMuted
c.SaveConfig()
}
func (c *Config) SetMicVolume(v float32) {
t := float32(v)
c.config.MicVolume = &t
@ -195,6 +204,7 @@ func (c *Config) UpdateUser(u *gumble.User) {
j = c.findUser(uc.Config.Address, u.Name)
u.Boost = j.Boost
u.Volume = j.Volume
u.LocallyMuted = j.LocallyMuted // Update LocallyMuted state from config
if u.Boost < 1 {
u.Boost = 1
}
@ -206,6 +216,7 @@ func (c *Config) UpdateConfig(u *gumble.User) {
j = c.findUser(u.GetClient().Config.Address, u.Name)
j.Boost = u.Boost
j.Volume = u.Volume
j.LocallyMuted = u.LocallyMuted // Save LocallyMuted state to config
}
func NewConfig(fn *string) *Config {
@ -267,7 +278,6 @@ func Log(s string) {
func log(s string) {
s += "\n"
// If the file doesn't exist, create it, or append to the file
f, err := os.OpenFile("log.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
panic(err)

View File

@ -31,6 +31,8 @@ type User struct {
PrioritySpeaker bool
// Is the user recording audio?
Recording bool
// Has the user been locally muted by the client?
LocallyMuted bool
// The user's comment. Contains the empty string if the user does not have a
// comment, or if the comment needs to be requested.
@ -56,6 +58,11 @@ type User struct {
Volume float32
}
// IsMuted returns true if the user is muted either server-side or locally
func (u *User) IsMuted() bool {
return u.Muted || u.LocallyMuted
}
func (u *User) GetClient() *Client {
return u.client
}

View File

@ -164,7 +164,13 @@ func (s *Stream) OnAudioStream(e *gumble.AudioStreamEvent) {
go func(e *gumble.AudioStreamEvent) {
var source = openal.NewSource()
e.User.AudioSource = &source
// Set initial gain based on volume and mute state
if e.User.LocallyMuted {
e.User.AudioSource.SetGain(0)
} else {
e.User.AudioSource.SetGain(e.User.Volume)
}
bufferCount := e.Client.Config.Buffers
if bufferCount < 64 {
@ -183,6 +189,11 @@ func (s *Stream) OnAudioStream(e *gumble.AudioStreamEvent) {
var raw [maxBufferSize]byte
for packet := range e.C {
// Skip processing if user is locally muted
if e.User.LocallyMuted {
continue
}
var boost uint16 = uint16(1)
samples := len(packet.AudioBuffer)
if samples > cap(raw)/2 {
@ -192,17 +203,13 @@ func (s *Stream) OnAudioStream(e *gumble.AudioStreamEvent) {
boost = e.User.Boost
// Check if sample count suggests stereo data
// If it's not a multiple of 2, it must be mono
// If it's more than standard frameSize, it's likely stereo
isStereo := samples > gumble.AudioDefaultFrameSize && samples%2 == 0
format := openal.FormatMono16
if isStereo {
format = openal.FormatStereo16
// Adjust samples to represent stereo frame count
samples = samples / 2
}
// Process samples
rawPtr := 0
if isStereo {
// Process stereo samples as pairs
@ -244,7 +251,6 @@ func (s *Stream) OnAudioStream(e *gumble.AudioStreamEvent) {
buffer := emptyBufs[last]
emptyBufs = emptyBufs[:last]
// Set buffer data with correct format
buffer.SetData(format, raw[:rawPtr], gumble.AudioSampleRate)
source.QueueBuffer(buffer)

View File

@ -1,8 +1,6 @@
package main
import (
//"math"
// "fmt"
"git.2mb.codes/~cmb/barnard/gumble/gumble"
"git.2mb.codes/~cmb/barnard/uiterm"
"sort"
@ -15,6 +13,9 @@ type TreeItem struct {
func (ti TreeItem) String() string {
if ti.User != nil {
if ti.User.LocallyMuted {
return "[MUTED] " + ti.User.Name
}
return ti.User.Name
}
if ti.Channel != nil {
@ -50,11 +51,7 @@ func (b *Barnard) changeVolume(users []*gumble.User, change float32) {
cv = au.GetGain() + curboost
ng = cv + change
boost = uint16(1)
//b.AddOutputLine(fmt.Sprintf("cv %.2f change %.2f ng %.2f",cv,change,ng))
if ng > 1.0 {
//1.0 will give volume of one and boost of 1
//1.1 will give volume of 1 and boost of 2
//b.AddOutputLine(fmt.Sprintf("partperc %.2f",(ng*10)))
perc := uint16((ng * 10)) - 10
perc += 1
boost = perc
@ -63,10 +60,11 @@ func (b *Barnard) changeVolume(users []*gumble.User, change float32) {
if ng < 0 {
ng = 0.0
}
//b.AddOutputLine(fmt.Sprintf("boost %d ng %.2f",boost,ng))
u.Boost = boost
u.Volume = ng
if !u.LocallyMuted {
au.SetGain(ng)
}
b.UserConfig.UpdateConfig(u)
}
b.UserConfig.SaveConfig()
@ -95,28 +93,58 @@ func (b *Barnard) TreeItemKeyPress(ui *uiterm.Ui, tree *uiterm.Tree, item uiterm
} else {
b.SetSelectedUser(treeItem.User)
b.GotoChat()
} //select
} //if user and not selected
} //if enter key
}
}
}
// Handle mute toggle
if treeItem.Channel != nil {
var c = treeItem.Channel
if key == *b.Hotkeys.MuteToggle {
// Toggle mute for all users in channel
users := makeUsersArray(treeItem.Channel.Users)
for _, u := range users {
b.UserConfig.ToggleMute(u)
if u.AudioSource != nil {
if u.LocallyMuted {
u.AudioSource.SetGain(0)
} else {
u.AudioSource.SetGain(u.Volume)
}
}
}
b.UiTree.Rebuild()
b.Ui.Refresh()
}
if key == *b.Hotkeys.VolumeDown {
b.changeVolume(makeUsersArray(c.Users), -0.1)
b.changeVolume(makeUsersArray(treeItem.Channel.Users), -0.1)
}
if key == *b.Hotkeys.VolumeUp {
b.changeVolume(makeUsersArray(c.Users), 0.1)
b.changeVolume(makeUsersArray(treeItem.Channel.Users), 0.1)
}
} //set volume
}
if treeItem.User != nil {
var u = treeItem.User
if key == *b.Hotkeys.MuteToggle {
// Toggle mute for single user
b.UserConfig.ToggleMute(treeItem.User)
if treeItem.User.AudioSource != nil {
if treeItem.User.LocallyMuted {
treeItem.User.AudioSource.SetGain(0)
} else {
treeItem.User.AudioSource.SetGain(treeItem.User.Volume)
}
}
b.UiTree.Rebuild()
b.Ui.Refresh()
}
if key == *b.Hotkeys.VolumeDown {
b.changeVolume([]*gumble.User{u}, -0.1)
b.changeVolume([]*gumble.User{treeItem.User}, -0.1)
}
if key == *b.Hotkeys.VolumeUp {
b.changeVolume([]*gumble.User{u}, 0.1)
b.changeVolume([]*gumble.User{treeItem.User}, 0.1)
}
}
}
} //user highlighted
} //func
func (b *Barnard) TreeItemBuild(item uiterm.TreeItem) []uiterm.TreeItem {
if b.Client == nil {