Procházet zdrojové kódy

Added opusReceiver.

Bruce Marriner před 9 roky
rodič
revize
68308c6f97
1 změnil soubory, kde provedl 59 přidání a 6 odebrání
  1. 59 6
      voice.go

+ 59 - 6
voice.go

@@ -28,12 +28,12 @@ import (
 
 // A Voice struct holds all data and functions related to Discord Voice support.
 type Voice struct {
-	sync.Mutex             // future use
-	Ready      bool        // If true, voice is ready to send/receive audio
-	Debug      bool        // If true, print extra logging
-	OP2        *voiceOP2   // exported for dgvoice, may change.
-	OpusSend   chan []byte // Chan for sending opus audio
-	OpusRecv   chan []byte // Chan for receiving opus audio
+	sync.Mutex              // future use
+	Ready      bool         // If true, voice is ready to send/receive audio
+	Debug      bool         // If true, print extra logging
+	OP2        *voiceOP2    // exported for dgvoice, may change.
+	OpusSend   chan []byte  // Chan for sending opus audio
+	OpusRecv   chan *Packet // Chan for receiving opus audio
 	//	FrameRate  int         // This can be used to set the FrameRate of Opus data
 	//	FrameSize  int         // This can be used to set the FrameSize of Opus data
 
@@ -189,6 +189,9 @@ func (v *Voice) wsEvent(messageType int, message []byte) {
 		v.OpusSend = make(chan []byte, 2)
 		go v.opusSender(v.OpusSend, 48000, 960)
 
+		// Start the opusReceiver
+		v.OpusRecv = make(chan *Packet, 2)
+		go v.opusReceiver(v.OpusRecv)
 		return
 
 	case 3: // HEARTBEAT response
@@ -458,3 +461,53 @@ func (v *Voice) opusSender(opus <-chan []byte, rate, size int) {
 		}
 	}
 }
+
+type Packet struct {
+	SSRC      uint32
+	Sequence  uint16
+	Timestamp uint32
+	Type      []byte
+	Opus      []byte
+	PCM       []int16
+}
+
+// opusReceiver listens on the UDP socket for incomming packets
+// and sends them across the given channel
+// NOTE :: This function may change names later.
+func (v *Voice) opusReceiver(c chan *Packet) {
+
+	// TODO: Better checking to prevent this from running more than
+	// one instance at a time.
+	v.Lock()
+	if c == nil {
+		v.Unlock()
+		return
+	}
+	v.Unlock()
+
+	p := Packet{}
+	recvbuf := make([]byte, 1024)
+
+	for {
+		rlen, err := v.UDPConn.Read(recvbuf)
+		if err != nil {
+			fmt.Println("opusReceiver UDP Read error:", err)
+			return
+		}
+
+		// For now, skip anything except audio.
+		if rlen < 12 || recvbuf[0] != 0x80 {
+			continue
+		}
+
+		p.Type = recvbuf[0:2]
+		p.Sequence = binary.BigEndian.Uint16(recvbuf[2:4])
+		p.Timestamp = binary.BigEndian.Uint32(recvbuf[4:8])
+		p.SSRC = binary.BigEndian.Uint32(recvbuf[8:12])
+		p.Opus = recvbuf[12:rlen]
+
+		if c != nil {
+			c <- &p
+		}
+	}
+}