From 8cf0ace67ec1e267ad0f4e9a2f9123df48a27c1f Mon Sep 17 00:00:00 2001 From: Mitchell Date: Tue, 23 Oct 2018 20:18:21 -0500 Subject: [PATCH] decode full opus stream at one time - fixes #22 --- server/bothandlers/sounds.go | 30 +++++++++++++++--------------- server/util/audio.go | 34 +++++++++++++++------------------- 2 files changed, 30 insertions(+), 34 deletions(-) diff --git a/server/bothandlers/sounds.go b/server/bothandlers/sounds.go index 6685063..c0878b1 100644 --- a/server/bothandlers/sounds.go +++ b/server/bothandlers/sounds.go @@ -220,7 +220,7 @@ func (conn *AudioConnection) playSoundsInQueue() { conn.toggleSoundPlayingLock(true) // Start speaking. - _ = conn.VoiceConnection.Speaking(true) + conn.VoiceConnection.Speaking(true) for { select { @@ -240,7 +240,7 @@ func (conn *AudioConnection) playSoundsInQueue() { default: // Stop speaking - _ = conn.VoiceConnection.Speaking(false) + conn.VoiceConnection.Speaking(false) conn.toggleSoundPlayingLock(false) return } @@ -293,33 +293,33 @@ func writePacketsToFile(username string, packets chan *discordgo.Packet) { os.Mkdir(config.Config.ClipsPath, os.ModePerm) } - // grab everything from the voice packet channel and dump it to the file - // close when there is nothing left - // split audio into specific voice streams - pcmOut := map[uint32][]int16{} + opusData := map[uint32][][]byte{} loop: for { select { case p := <-packets: - // convert opus to pcm - pcm, err := util.OpusToPCM(p.Opus, sampleRate, channels) - if err != nil { - log.Error(err) - return - } - pcmOut[p.SSRC] = append(pcmOut[p.SSRC], pcm...) + // separate opus data for each channel + opusData[p.SSRC] = append(opusData[p.SSRC], p.Opus) default: 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 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" - err := util.SavePCMToWavFile(pcmData, filename, sampleRate, channels) + err = util.SavePCMToWavFile(pcmData, filename, sampleRate, channels) if err != nil { log.Error(err) diff --git a/server/util/audio.go b/server/util/audio.go index 8091789..850fd34 100644 --- a/server/util/audio.go +++ b/server/util/audio.go @@ -90,30 +90,26 @@ func GetFileExtension(path, fileName string) (string, error) { 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 -func OpusToPCM(data []byte, sampleRate, channels int) ([]int16, error) { - if opusDecoder == nil { - var err error - 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) +func OpusToPCM(opusData [][]byte, sampleRate, channels int) ([]int16, error) { + opusDecoder, err := opus.NewDecoder(sampleRate, channels) + pcm := []int16{} if err != nil { - return []int16{}, err + return pcm, err } - // trim the remaining space - pcm = pcm[:n*channels] + for _, o := range opusData { + // 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 }