This repository has been archived by the owner on Oct 25, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
voice.go
125 lines (113 loc) · 2.36 KB
/
voice.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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package main
import (
"encoding/binary"
"fmt"
"io"
"math/rand"
"os"
"time"
)
func (s *Server) routineNext() {
s.Lock()
defer s.Unlock()
if s.repeat == RepeatOne {
return
}
if s.random {
if s.repeat == Repeat {
s.playing = rand.Intn(len(s.playlist))
} else {
s.playing = rand.Intn(len(s.playlist) + 1)
}
} else {
s.playing++
}
if s.playing >= len(s.playlist) {
if s.repeat != Repeat {
s.state = Stopped
}
s.playing = 0
}
}
func (s *Server) playingRoutine(soundDataChan chan []byte) {
// 960 packet size 24000 Frequency forced by discord 2 is for the number of channel
ticker := time.NewTicker(time.Millisecond * time.Duration(960/(2*24000/1000)))
vc := s.Vc()
defer ticker.Stop()
skip := s.State() == Paused
for {
select {
case reload := <-s.reloadChan:
if reload {
return
}
skip = s.State() == Paused
case <-ticker.C:
if !skip {
data, ok := <-soundDataChan
if !ok {
s.routineNext()
return
}
vc.OpusSend <- data
}
}
}
}
func (s *Server) player() {
defer func() {
s.Lock()
close(s.reloadChan)
s.reloadChan = nil
s.Unlock()
}()
for s.State() != Stopped {
soundDataChan := make(chan []byte)
stopChan := make(chan bool, 1)
go reader(s.Playlist()[s.Playing()], soundDataChan, stopChan)
s.playingRoutine(soundDataChan)
close(stopChan)
}
}
func reader(audioName string, soundDataChan chan []byte, stopChan chan bool) {
defer func() {
close(soundDataChan)
}()
file, err := os.Open(soundPath + audioName + ".dca")
if err != nil {
fmt.Println("Error opening dca file :", err)
return
}
var opuslen int16
for {
select {
case <-stopChan:
file.Close()
return
default:
// Read opus frame length from dca file.
err = binary.Read(file, binary.LittleEndian, &opuslen)
// If this is the end of the file, just return.
if err == io.EOF || err == io.ErrUnexpectedEOF {
file.Close()
return
}
if err != nil {
file.Close()
fmt.Println("Error reading from dca file :", err)
return
}
// Read encoded pcm from dca file.
InBuf := make([]byte, opuslen)
err = binary.Read(file, binary.LittleEndian, &InBuf)
// Should not be any end of file errors
if err != nil {
file.Close()
fmt.Println("Error reading from dca file :", err)
return
}
// Append encoded pcm data to the buffer.
soundDataChan <- InBuf
}
}
}