From ddf7ea2f15c22ed6f82be2db919a1412ad7f74e5 Mon Sep 17 00:00:00 2001 From: Stein Ivar Berghei Date: Thu, 1 Dec 2022 10:48:25 +0100 Subject: [PATCH] Use the same opus lib for encoding as decoding. Simplify by encoding float64 directly. --- speaker/discord.go | 46 +++++++++++++++------------------------------- 1 file changed, 15 insertions(+), 31 deletions(-) diff --git a/speaker/discord.go b/speaker/discord.go index e5c5e58..8cbd184 100644 --- a/speaker/discord.go +++ b/speaker/discord.go @@ -1,8 +1,6 @@ package discordspeaker import ( - "bytes" - "encoding/binary" "log" "sync" "time" @@ -10,7 +8,7 @@ import ( "github.com/bwmarrin/discordgo" "github.com/faiface/beep" "github.com/pkg/errors" - "layeh.com/gopus" + "gopkg.in/hraban/opus.v2" ) var ( @@ -18,15 +16,13 @@ var ( mixer beep.Mixer samples [][2]float64 done chan struct{} - encoder *gopus.Encoder + encoder *opus.Encoder voice *discordgo.VoiceConnection frameSize int = 960 channels int = 2 sampleRate int = 48000 maxBytes int = (frameSize * 2) * 2 - pcm []int16 buf []byte - pause bool ) func Init(dgv *discordgo.VoiceConnection) error { @@ -35,17 +31,15 @@ func Init(dgv *discordgo.VoiceConnection) error { mu.Lock() defer mu.Unlock() Close() + mixer = beep.Mixer{} - buf = make([]byte, maxBytes) - pcm = make([]int16, frameSize*channels) samples = make([][2]float64, frameSize) - pause = true - voice = dgv - encoder, err = gopus.NewEncoder(sampleRate, channels, gopus.Audio) + encoder, err = opus.NewEncoder(sampleRate, channels, opus.AppVoIP) + encoder.SetBitrateToMax() if err != nil { return errors.Wrap(err, "failed to initialize speaker") @@ -93,34 +87,24 @@ func update() { mu.Lock() mixer.Stream(samples) mu.Unlock() + var f32 []float32 - for i := range samples { - for c := range samples[i] { - val := samples[i][c] - if val < -1 { - val = -1 - } - if val > +1 { - val = +1 - } - valInt16 := int16(val * (1<<15 - 1)) - low := byte(valInt16) - high := byte(valInt16 >> 8) - buf[i*4+c*2+0] = low - buf[i*4+c*2+1] = high + for _, sample := range samples { + for _, val := range sample { + f32 = append(f32, float32(val)) } + } - if Silence(buf) { + if Silence(f32) { time.Sleep(100 * time.Millisecond) return } - binary.Read(bytes.NewReader(buf), binary.LittleEndian, &pcm) - - opus, err := encoder.Encode(pcm, frameSize, maxBytes) + n, err := encoder.EncodeFloat32(f32, buf) if err != nil { log.Println(err) + time.Sleep(100 * time.Millisecond) return } @@ -128,10 +112,10 @@ func update() { return } - voice.OpusSend <- opus + voice.OpusSend <- buf[:n] } -func Silence(in []byte) bool { +func Silence(in []float32) bool { for _, v := range in { if v != 0 { return false