1
0
mirror of https://github.com/mgerb/go-discord-bot synced 2026-01-10 09:02:49 +00:00

decode full opus stream at one time - fixes #22

This commit is contained in:
2018-10-23 20:18:21 -05:00
parent a75a89a1a9
commit 8cf0ace67e
2 changed files with 30 additions and 34 deletions

View File

@@ -220,7 +220,7 @@ func (conn *AudioConnection) playSoundsInQueue() {
conn.toggleSoundPlayingLock(true) conn.toggleSoundPlayingLock(true)
// Start speaking. // Start speaking.
_ = conn.VoiceConnection.Speaking(true) conn.VoiceConnection.Speaking(true)
for { for {
select { select {
@@ -240,7 +240,7 @@ func (conn *AudioConnection) playSoundsInQueue() {
default: default:
// Stop speaking // Stop speaking
_ = conn.VoiceConnection.Speaking(false) conn.VoiceConnection.Speaking(false)
conn.toggleSoundPlayingLock(false) conn.toggleSoundPlayingLock(false)
return return
} }
@@ -293,33 +293,33 @@ func writePacketsToFile(username string, packets chan *discordgo.Packet) {
os.Mkdir(config.Config.ClipsPath, os.ModePerm) os.Mkdir(config.Config.ClipsPath, os.ModePerm)
} }
// grab everything from the voice packet channel and dump it to the file opusData := map[uint32][][]byte{}
// close when there is nothing left
// split audio into specific voice streams
pcmOut := map[uint32][]int16{}
loop: loop:
for { for {
select { select {
case p := <-packets: case p := <-packets:
// convert opus to pcm // separate opus data for each channel
pcm, err := util.OpusToPCM(p.Opus, sampleRate, channels) opusData[p.SSRC] = append(opusData[p.SSRC], p.Opus)
if err != nil {
log.Error(err)
return
}
pcmOut[p.SSRC] = append(pcmOut[p.SSRC], pcm...)
default: default:
break loop break loop
} }
} }
for key, pcmData := range pcmOut { for key, opus := range opusData {
pcmData, err := util.OpusToPCM(opus, sampleRate, channels)
if err != nil {
log.Error(err)
continue
}
// construct filename // construct filename
timestamp := time.Now().UTC().Format("2006-01-02") + "-" + strconv.Itoa(int(time.Now().Unix())) timestamp := time.Now().UTC().Format("2006-01-02") + "-" + strconv.Itoa(int(time.Now().Unix()))
filename := config.Config.ClipsPath + "/" + timestamp + "-" + strconv.Itoa(int(key)) + "-" + username + ".wav" filename := config.Config.ClipsPath + "/" + timestamp + "-" + strconv.Itoa(int(key)) + "-" + username + ".wav"
err := util.SavePCMToWavFile(pcmData, filename, sampleRate, channels) err = util.SavePCMToWavFile(pcmData, filename, sampleRate, channels)
if err != nil { if err != nil {
log.Error(err) log.Error(err)

View File

@@ -90,30 +90,26 @@ func GetFileExtension(path, fileName string) (string, error) {
return "", errors.New("file not found") return "", errors.New("file not found")
} }
// cache the opusDecoder so we don't have to make a new one every time
// was causing audio issues creating a new instance of this every time
var opusDecoder *opus.Decoder
// OpusToPCM - convert opus to pcm // OpusToPCM - convert opus to pcm
func OpusToPCM(data []byte, sampleRate, channels int) ([]int16, error) { func OpusToPCM(opusData [][]byte, sampleRate, channels int) ([]int16, error) {
if opusDecoder == nil { opusDecoder, err := opus.NewDecoder(sampleRate, channels)
var err error pcm := []int16{}
opusDecoder, err = opus.NewDecoder(sampleRate, channels)
if err != nil {
return []int16{}, err
}
}
// create pcm list with more than enough space
pcm := make([]int16, 10000)
n, err := opusDecoder.Decode(data, pcm)
if err != nil { if err != nil {
return []int16{}, err return pcm, err
} }
// trim the remaining space for _, o := range opusData {
pcm = pcm[:n*channels] // create pcm slice with more than enough space
p := make([]int16, 10000)
n, err := opusDecoder.Decode(o, p)
if err != nil {
return pcm, err
}
pcm = append(pcm, p[:n*channels]...)
}
return pcm, nil return pcm, nil
} }