Synchronize connection-owned audio resources
This commit is contained in:
committed by
Brandon McGinty
parent
b407a20132
commit
57961ffc9f
+19
-4
@@ -32,6 +32,7 @@ type Barnard struct {
|
|||||||
TLSConfig tls.Config
|
TLSConfig tls.Config
|
||||||
|
|
||||||
Stream *gumbleopenal.Stream
|
Stream *gumbleopenal.Stream
|
||||||
|
connectionMutex sync.RWMutex
|
||||||
Tx bool
|
Tx bool
|
||||||
AutoTransmit bool // auto-start transmission on connect
|
AutoTransmit bool // auto-start transmission on connect
|
||||||
Connected bool
|
Connected bool
|
||||||
@@ -96,11 +97,13 @@ type Barnard struct {
|
|||||||
// reconnect replaces them. It is intentionally idempotent for repeated
|
// reconnect replaces them. It is intentionally idempotent for repeated
|
||||||
// disconnect notifications.
|
// disconnect notifications.
|
||||||
func (b *Barnard) cleanupConnectionAudio() {
|
func (b *Barnard) cleanupConnectionAudio() {
|
||||||
|
b.connectionMutex.Lock()
|
||||||
if b.Stream != nil {
|
if b.Stream != nil {
|
||||||
stream := b.Stream
|
stream := b.Stream
|
||||||
b.Stream = nil
|
b.Stream = nil
|
||||||
stream.Destroy()
|
stream.Destroy()
|
||||||
}
|
}
|
||||||
|
b.connectionMutex.Unlock()
|
||||||
b.FileStreamMutex.Lock()
|
b.FileStreamMutex.Lock()
|
||||||
if b.FileStream != nil {
|
if b.FileStream != nil {
|
||||||
_ = b.FileStream.Stop()
|
_ = b.FileStream.Stop()
|
||||||
@@ -121,9 +124,21 @@ func (b *Barnard) cleanupToneTestAudio() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *Barnard) updateUserGain(user *gumble.User) {
|
func (b *Barnard) updateUserGain(user *gumble.User) {
|
||||||
if b.Stream != nil {
|
b.withStream(func(stream *gumbleopenal.Stream) {
|
||||||
b.Stream.UpdateUserGain(user)
|
stream.UpdateUserGain(user)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// withStream keeps a connection-owned stream alive for the complete operation.
|
||||||
|
// Reconnect cleanup takes the write lock before destroying or replacing it.
|
||||||
|
func (b *Barnard) withStream(action func(*gumbleopenal.Stream)) bool {
|
||||||
|
b.connectionMutex.RLock()
|
||||||
|
defer b.connectionMutex.RUnlock()
|
||||||
|
if b.Stream == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
action(b.Stream)
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Barnard) isChannelMuted(channelID uint32) bool {
|
func (b *Barnard) isChannelMuted(channelID uint32) bool {
|
||||||
@@ -212,8 +227,8 @@ func (b *Barnard) StopTransmission() {
|
|||||||
close(b.toneTestStop)
|
close(b.toneTestStop)
|
||||||
b.toneTestStop = nil
|
b.toneTestStop = nil
|
||||||
}
|
}
|
||||||
} else if b.Stream != nil {
|
} else {
|
||||||
b.Stream.StopSource()
|
b.withStream(func(stream *gumbleopenal.Stream) { _ = stream.StopSource() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,11 +87,10 @@ func (b *Barnard) connect(reconnect bool) bool {
|
|||||||
b.exitWithError(err)
|
b.exitWithError(err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
b.Stream = stream
|
stream.SetMicVolume(b.UserConfig.GetMicVolume(), false)
|
||||||
b.Stream.SetMicVolume(b.UserConfig.GetMicVolume(), false)
|
stream.AttachStream(b.Client)
|
||||||
b.Stream.AttachStream(b.Client)
|
stream.SetNoiseProcessor(b.NoiseSuppressor)
|
||||||
b.Stream.SetNoiseProcessor(b.NoiseSuppressor)
|
stream.SetErrorFunc(func(err error) {
|
||||||
b.Stream.SetErrorFunc(func(err error) {
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.AddOutputLine(fmt.Sprintf("Microphone: %s", err.Error()))
|
b.AddOutputLine(fmt.Sprintf("Microphone: %s", err.Error()))
|
||||||
} else {
|
} else {
|
||||||
@@ -110,8 +109,11 @@ func (b *Barnard) connect(reconnect bool) bool {
|
|||||||
b.Client.DisableStereoEncoder()
|
b.Client.DisableStereoEncoder()
|
||||||
b.AddOutputLine(fmt.Sprintf("File playback: %s", err.Error()))
|
b.AddOutputLine(fmt.Sprintf("File playback: %s", err.Error()))
|
||||||
})
|
})
|
||||||
b.Stream.SetFilePlayer(b.FileStream)
|
stream.SetFilePlayer(b.FileStream)
|
||||||
b.FileStreamMutex.Unlock()
|
b.FileStreamMutex.Unlock()
|
||||||
|
b.connectionMutex.Lock()
|
||||||
|
b.Stream = stream
|
||||||
|
b.connectionMutex.Unlock()
|
||||||
|
|
||||||
b.setConnected(true)
|
b.setConnected(true)
|
||||||
// Dial delivers OnConnect before connect creates the OpenAL stream, so
|
// Dial delivers OnConnect before connect creates the OpenAL stream, so
|
||||||
@@ -166,16 +168,21 @@ func (b *Barnard) OnConnect(e *gumble.ConnectEvent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *Barnard) startAutoTransmit() {
|
func (b *Barnard) startAutoTransmit() {
|
||||||
if !b.AutoTransmit || b.Stream == nil || b.isTransmitting() {
|
if !b.AutoTransmit || b.isTransmitting() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := b.Stream.StartSource(b.UserConfig.GetInputDevice()); err != nil {
|
started := b.withStream(func(stream *gumbleopenal.Stream) {
|
||||||
|
if err := stream.StartSource(b.UserConfig.GetInputDevice()); err != nil {
|
||||||
b.AddOutputLine(fmt.Sprintf("auto-transmit failed: %s", err.Error()))
|
b.AddOutputLine(fmt.Sprintf("auto-transmit failed: %s", err.Error()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
b.setTransmitting(true)
|
b.setTransmitting(true)
|
||||||
b.UpdateGeneralStatus(" AutoTx ", true)
|
b.UpdateGeneralStatus(" AutoTx ", true)
|
||||||
b.AddOutputLine("Auto-transmit started")
|
b.AddOutputLine("Auto-transmit started")
|
||||||
|
})
|
||||||
|
if !started {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Barnard) OnDisconnect(e *gumble.DisconnectEvent) {
|
func (b *Barnard) OnDisconnect(e *gumble.DisconnectEvent) {
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.stormux.org/storm/barnard/gumble/gumbleopenal"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestWithStreamHandlesAbsentConnectionResource(t *testing.T) {
|
||||||
|
if (&Barnard{}).withStream(func(*gumbleopenal.Stream) {}) {
|
||||||
|
t.Fatal("nil connection stream was treated as available")
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user