mix multiple voices
This commit is contained in:
parent
51e55d2428
commit
39f934d810
@ -22,7 +22,7 @@ reasonably shouldn't, let me know (or fix it and then let me know!)
|
||||
- [x] handling everyone's state
|
||||
- [x] any of the actual audio stuff
|
||||
- [x] noise suppression with rnnoise
|
||||
- [ ] chat with more than a singular other person, probably
|
||||
- [x] chat with more than a singular other person, probably
|
||||
|
||||
## building
|
||||
hubbub requires go 1.23 to build. it might run on earlier versions, but i think
|
||||
|
||||
@ -31,15 +31,7 @@ const channels = 1
|
||||
type Audio struct {
|
||||
Muted bool
|
||||
Deafened bool
|
||||
OutBuffer chan string
|
||||
}
|
||||
|
||||
func NewAudio() Audio {
|
||||
return Audio{
|
||||
Muted: false,
|
||||
Deafened: false,
|
||||
OutBuffer: make(chan string),
|
||||
}
|
||||
Buffers map[string]chan string
|
||||
}
|
||||
|
||||
func (au *Audio) ProcessInput(conn *ircevent.Connection, channel string) error {
|
||||
@ -72,23 +64,36 @@ func (au *Audio) ProcessInput(conn *ircevent.Connection, channel string) error {
|
||||
}
|
||||
}
|
||||
|
||||
empty := make([]float32, len(out))
|
||||
// mix all outputs together
|
||||
mix := make([]float32, len(out))
|
||||
voices := 0
|
||||
for _, buffer := range au.Buffers {
|
||||
select {
|
||||
case str := <-au.OutBuffer:
|
||||
case str := <-buffer:
|
||||
if !au.Deafened {
|
||||
raw, err := base64.StdEncoding.DecodeString(str)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
if _, err = dec.DecodeFloat32(raw, out); err != nil {
|
||||
decoded := make([]float32, len(out))
|
||||
if _, err = dec.DecodeFloat32(raw, decoded); err != nil {
|
||||
break
|
||||
}
|
||||
} else {
|
||||
copy(out, empty)
|
||||
for i := range decoded {
|
||||
mix[i] += decoded[i]
|
||||
}
|
||||
voices++
|
||||
}
|
||||
default:
|
||||
copy(out, empty)
|
||||
}
|
||||
}
|
||||
|
||||
if voices > 0 {
|
||||
for i := range mix {
|
||||
mix[i] /= float32(voices)
|
||||
}
|
||||
}
|
||||
copy(out, mix)
|
||||
})
|
||||
if err != nil {
|
||||
log.Printf("error opening input stream: %v", err)
|
||||
|
||||
17
main.go
17
main.go
@ -119,6 +119,7 @@ func (m model) Init() tea.Cmd {
|
||||
u, ok := m.users[e.Nick()]
|
||||
if !ok {
|
||||
m.users[e.Nick()] = user{}
|
||||
m.au.Buffers[e.Nick()] = make(chan string)
|
||||
}
|
||||
|
||||
switch message {
|
||||
@ -133,7 +134,7 @@ func (m model) Init() tea.Cmd {
|
||||
u.isMuted = false
|
||||
default:
|
||||
u.lastSpoke = time.Now()
|
||||
m.au.OutBuffer <- message
|
||||
m.au.Buffers[e.Nick()] <- message
|
||||
}
|
||||
|
||||
m.users[e.Nick()] = u
|
||||
@ -141,6 +142,9 @@ func (m model) Init() tea.Cmd {
|
||||
|
||||
m.conn.AddCallback("JOIN", func(e ircmsg.Message) {
|
||||
m.users[e.Nick()] = user{}
|
||||
if e.Nick() != m.nick {
|
||||
m.au.Buffers[e.Nick()] = make(chan string)
|
||||
}
|
||||
|
||||
// advertise your muted and deafened statuses on someone joining
|
||||
if m.deafen {
|
||||
@ -157,10 +161,12 @@ func (m model) Init() tea.Cmd {
|
||||
|
||||
m.conn.AddCallback("PART", func(e ircmsg.Message) {
|
||||
delete(m.users, e.Nick())
|
||||
delete(m.au.Buffers, e.Nick())
|
||||
})
|
||||
|
||||
m.conn.AddCallback("QUIT", func(e ircmsg.Message) {
|
||||
delete(m.users, e.Nick())
|
||||
delete(m.au.Buffers, e.Nick())
|
||||
})
|
||||
|
||||
m.conn.Join(m.channel)
|
||||
@ -215,8 +221,9 @@ func (m model) View() (s string) {
|
||||
}
|
||||
s += fmt.Sprintf("%d user%s connected:\n", numUsers, plural)
|
||||
|
||||
for _, nick := range slices.Sorted(maps.Keys(m.users)) {
|
||||
user := m.users[nick]
|
||||
users := maps.Clone(m.users)
|
||||
for _, nick := range slices.Sorted(maps.Keys(users)) {
|
||||
user := users[nick]
|
||||
status := " "
|
||||
nickStyled := styleInactive.Render(nick)
|
||||
if user.isDeafened {
|
||||
@ -282,7 +289,9 @@ func start(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
au := audio.NewAudio()
|
||||
au := audio.Audio{
|
||||
Buffers: map[string](chan string){},
|
||||
}
|
||||
go func() {
|
||||
if err := au.ProcessInput(&conn.Connection, config.Channel); err != nil {
|
||||
os.Exit(1)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user