forked from dustinblackman/speakerbot
/
pcm.go
63 lines (53 loc) · 1.25 KB
/
pcm.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package main
import (
"fmt"
"sync"
"github.com/bwmarrin/discordgo"
"github.com/layeh/gopus"
)
// Borrowed from https://github.com/bwmarrin/dgvoice
var (
sendpcm bool
recv chan *discordgo.Packet
mu sync.Mutex
)
const (
maxBytes int = (frameSize * 2) * 2 // max size of opus data
)
// SendPCM will receive on the provied channel encode
// received PCM data into Opus then send that to Discordgo
func SendPCM(v *discordgo.Voice, pcm <-chan []int16) {
mu.Lock()
if sendpcm || pcm == nil {
mu.Unlock()
return
}
sendpcm = true
mu.Unlock()
defer func() { sendpcm = false }()
opusEncoder, err := gopus.NewEncoder(frameRate, channels, gopus.Audio)
if err != nil {
fmt.Println("NewEncoder Error:", err)
return
}
for {
// read pcm from chan, exit if channel is closed.
recv, ok := <-pcm
if !ok {
fmt.Println("PCM Channel closed.")
return
}
// try encoding pcm frame with Opus
opus, err := opusEncoder.Encode(recv, frameSize, maxBytes)
if err != nil {
fmt.Println("Encoding Error:", err)
return
}
if v.Ready == false || v.OpusSend == nil {
// fmt.Printf("Discordgo not ready for opus packets. %+v : %+v", v.Ready, v.OpusSend)
return
}
// send encoded opus data to the sendOpus channel
v.OpusSend <- opus
}
}