add a tone test mode that bypasses the soundcard
Add -tone-test to transmit a generated 440 Hz Opus tone and save incoming audio to the file named by -tone-out. Diagnosing an audio problem previously required a working capture and playback device, which is exactly what is in question. This mode opens no OpenAL device at all, so the network and codec path can be tested on a machine with no sound hardware. Open the capture file before starting the generator. Starting transmission first left a tone goroutine running with nowhere to write when the path was unusable. Refuse file playback while in tone test mode, and ignore the microphone volume keys. Both operate on a stream that does not exist here. Stop the generator and detach the file saver on disconnect. A reconnect otherwise attached a second saver to the same file. Add -auto-transmit to key the microphone as soon as the connection is up. Useful for a bot or a monitoring client that should never need a keypress. It runs from both the connect event and the point where the audio stream is created, because the server's welcome arrives before the stream exists. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
17a4662c6c
commit
ecca0a63ed
@@ -17,16 +17,27 @@ func (b *Barnard) start() {
|
||||
b.Config.Attach(gumbleutil.AutoBitrate)
|
||||
b.Config.Attach(b)
|
||||
b.Config.Address = b.Address
|
||||
// test Audio
|
||||
_, err := gumbleopenal.New(b.Client, b.UserConfig.GetInputDevice(), b.UserConfig.GetOutputDevice(), true)
|
||||
if err != nil {
|
||||
b.exitWithError(err)
|
||||
return
|
||||
|
||||
if b.ToneTest {
|
||||
// Tone test mode: skip all OpenAL/soundcard initialization.
|
||||
// We just need a network connection — the tone generator and
|
||||
// file saver are set up in connect().
|
||||
} else {
|
||||
// test Audio
|
||||
_, err := gumbleopenal.New(b.Client, b.UserConfig.GetInputDevice(), b.UserConfig.GetOutputDevice(), true)
|
||||
if err != nil {
|
||||
b.exitWithError(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
//connect, not reconnect
|
||||
b.connect(false)
|
||||
}
|
||||
|
||||
func (b *Barnard) toneTestAutoTransmit() bool {
|
||||
return b.ToneTest && b.AutoTransmit
|
||||
}
|
||||
|
||||
func (b *Barnard) exitWithError(err error) {
|
||||
b.Ui.Close()
|
||||
b.exitStatus = 1
|
||||
@@ -45,6 +56,31 @@ func (b *Barnard) connect(reconnect bool) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
if b.ToneTest {
|
||||
// --- Tone test mode: skip all OpenAL; generate 440 Hz tone
|
||||
// --- and save incoming audio to a file.
|
||||
|
||||
// Open the output first. Starting transmission before this succeeds
|
||||
// leaves an orphaned tone goroutine when the path is unusable.
|
||||
saver, err := NewAudioFileSaver(b.ToneTestOutput)
|
||||
if err != nil {
|
||||
b.exitWithError(err)
|
||||
return false
|
||||
}
|
||||
b.toneTestSaver = saver
|
||||
b.toneTestSaverDetach = b.Client.Config.AttachAudio(saver)
|
||||
|
||||
b.Connected = true
|
||||
if b.toneTestAutoTransmit() {
|
||||
b.toneTestStop = make(chan struct{})
|
||||
go StartToneGenerator(b.Client, b.toneTestStop)
|
||||
b.Tx = true
|
||||
b.UpdateGeneralStatus(" Tx ", true)
|
||||
b.AddOutputLine("Tone test transmission started")
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
stream, err := gumbleopenal.New(b.Client, b.UserConfig.GetInputDevice(), b.UserConfig.GetOutputDevice(), false)
|
||||
if err != nil {
|
||||
b.exitWithError(err)
|
||||
@@ -71,6 +107,9 @@ func (b *Barnard) connect(reconnect bool) bool {
|
||||
b.FileStreamMutex.Unlock()
|
||||
|
||||
b.Connected = true
|
||||
// Dial delivers OnConnect before connect creates the OpenAL stream, so
|
||||
// start auto-transmit here as well for initial connections and reconnects.
|
||||
b.startAutoTransmit()
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -105,6 +144,21 @@ func (b *Barnard) OnConnect(e *gumble.ConnectEvent) {
|
||||
b.AddOutputLine(fmt.Sprintf("Welcome message: %s", wmsg))
|
||||
}
|
||||
b.Ui.Refresh()
|
||||
|
||||
b.startAutoTransmit()
|
||||
}
|
||||
|
||||
func (b *Barnard) startAutoTransmit() {
|
||||
if !b.AutoTransmit || b.Tx || b.Stream == nil {
|
||||
return
|
||||
}
|
||||
if err := b.Stream.StartSource(b.UserConfig.GetInputDevice()); err != nil {
|
||||
b.AddOutputLine(fmt.Sprintf("auto-transmit failed: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
b.Tx = true
|
||||
b.UpdateGeneralStatus(" AutoTx ", true)
|
||||
b.AddOutputLine("Auto-transmit started")
|
||||
}
|
||||
|
||||
func (b *Barnard) OnDisconnect(e *gumble.DisconnectEvent) {
|
||||
@@ -121,6 +175,16 @@ func (b *Barnard) OnDisconnect(e *gumble.DisconnectEvent) {
|
||||
reason = e.String
|
||||
}
|
||||
b.stopRecordingForDisconnect()
|
||||
|
||||
// Tone test cleanup
|
||||
if b.ToneTest {
|
||||
if b.toneTestStop != nil {
|
||||
close(b.toneTestStop)
|
||||
b.toneTestStop = nil
|
||||
}
|
||||
b.cleanupToneTestAudio()
|
||||
}
|
||||
|
||||
b.Notify("disconnect", "me", reason)
|
||||
if reason == "" {
|
||||
b.AddOutputLine("Disconnected")
|
||||
|
||||
Reference in New Issue
Block a user