Use the same opus lib for encoding as decoding. Simplify by encoding float64 directly.

nostruct
Stein Ivar Berghei 2022-12-01 10:48:25 +01:00
parent 2f3c14c3cb
commit ddf7ea2f15
1 changed files with 15 additions and 31 deletions

View File

@ -1,8 +1,6 @@
package discordspeaker package discordspeaker
import ( import (
"bytes"
"encoding/binary"
"log" "log"
"sync" "sync"
"time" "time"
@ -10,7 +8,7 @@ import (
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
"github.com/faiface/beep" "github.com/faiface/beep"
"github.com/pkg/errors" "github.com/pkg/errors"
"layeh.com/gopus" "gopkg.in/hraban/opus.v2"
) )
var ( var (
@ -18,15 +16,13 @@ var (
mixer beep.Mixer mixer beep.Mixer
samples [][2]float64 samples [][2]float64
done chan struct{} done chan struct{}
encoder *gopus.Encoder encoder *opus.Encoder
voice *discordgo.VoiceConnection voice *discordgo.VoiceConnection
frameSize int = 960 frameSize int = 960
channels int = 2 channels int = 2
sampleRate int = 48000 sampleRate int = 48000
maxBytes int = (frameSize * 2) * 2 maxBytes int = (frameSize * 2) * 2
pcm []int16
buf []byte buf []byte
pause bool
) )
func Init(dgv *discordgo.VoiceConnection) error { func Init(dgv *discordgo.VoiceConnection) error {
@ -35,17 +31,15 @@ func Init(dgv *discordgo.VoiceConnection) error {
mu.Lock() mu.Lock()
defer mu.Unlock() defer mu.Unlock()
Close() Close()
mixer = beep.Mixer{} mixer = beep.Mixer{}
buf = make([]byte, maxBytes) buf = make([]byte, maxBytes)
pcm = make([]int16, frameSize*channels)
samples = make([][2]float64, frameSize) samples = make([][2]float64, frameSize)
pause = true
voice = dgv voice = dgv
encoder, err = gopus.NewEncoder(sampleRate, channels, gopus.Audio) encoder, err = opus.NewEncoder(sampleRate, channels, opus.AppVoIP)
encoder.SetBitrateToMax()
if err != nil { if err != nil {
return errors.Wrap(err, "failed to initialize speaker") return errors.Wrap(err, "failed to initialize speaker")
@ -93,34 +87,24 @@ func update() {
mu.Lock() mu.Lock()
mixer.Stream(samples) mixer.Stream(samples)
mu.Unlock() mu.Unlock()
var f32 []float32
for i := range samples { for _, sample := range samples {
for c := range samples[i] { for _, val := range sample {
val := samples[i][c] f32 = append(f32, float32(val))
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
}
} }
if Silence(buf) { }
if Silence(f32) {
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
return return
} }
binary.Read(bytes.NewReader(buf), binary.LittleEndian, &pcm) n, err := encoder.EncodeFloat32(f32, buf)
opus, err := encoder.Encode(pcm, frameSize, maxBytes)
if err != nil { if err != nil {
log.Println(err) log.Println(err)
time.Sleep(100 * time.Millisecond)
return return
} }
@ -128,10 +112,10 @@ func update() {
return return
} }
voice.OpusSend <- opus voice.OpusSend <- buf[:n]
} }
func Silence(in []byte) bool { func Silence(in []float32) bool {
for _, v := range in { for _, v := range in {
if v != 0 { if v != 0 {
return false return false