kappanhang/audiostream.go

118 lines
3.2 KiB
Go
Raw Normal View History

2020-10-18 10:33:47 +02:00
package main
2020-10-18 15:40:25 +02:00
import (
"bytes"
"encoding/binary"
2020-10-19 09:45:49 +02:00
"errors"
2020-10-18 15:40:25 +02:00
"time"
"github.com/nonoo/kappanhang/log"
)
const audioTimeoutDuration = 3 * time.Second
2020-10-18 10:33:47 +02:00
type audioStream struct {
2020-10-18 11:01:53 +02:00
common streamCommon
2020-10-18 15:40:25 +02:00
timeoutTimer *time.Timer
receivedAudio bool
2020-10-18 15:40:25 +02:00
lastReceivedAudioSeq uint16
2020-10-18 20:09:12 +02:00
audioSendSeq uint16
2020-10-18 10:33:47 +02:00
}
2020-10-18 13:19:52 +02:00
func (s *audioStream) sendDisconnect() {
s.common.sendDisconnect()
}
2020-10-18 15:40:25 +02:00
func (s *audioStream) handleAudioPacket(r []byte) {
if s.timeoutTimer != nil {
s.timeoutTimer.Stop()
s.timeoutTimer.Reset(audioTimeoutDuration)
}
gotSeq := binary.LittleEndian.Uint16(r[6:8])
if s.receivedAudio {
expectedSeq := s.lastReceivedAudioSeq + 1
if expectedSeq != gotSeq {
var missingPkts int
if gotSeq > expectedSeq {
missingPkts = int(gotSeq) - int(expectedSeq)
} else {
missingPkts = int(gotSeq) + 65536 - int(expectedSeq)
}
log.Error("lost ", missingPkts, " audio packets")
2020-10-18 15:40:25 +02:00
}
}
s.lastReceivedAudioSeq = gotSeq
s.receivedAudio = true
2020-10-18 15:40:25 +02:00
// log.Print("got audio packet ", len(r[24:]), " bytes")
2020-10-20 08:47:42 +02:00
// TODO: audioPipes.source.Write()
2020-10-18 15:40:25 +02:00
}
2020-10-20 08:47:42 +02:00
// TODO: audioPipes.sink.Read() + sendPart1(); sendPart2()
2020-10-18 13:52:38 +02:00
func (s *audioStream) handleRead(r []byte) {
2020-10-18 15:40:25 +02:00
if len(r) >= 580 && (bytes.Equal(r[:6], []byte{0x6c, 0x05, 0x00, 0x00, 0x00, 0x00}) || bytes.Equal(r[:6], []byte{0x44, 0x02, 0x00, 0x00, 0x00, 0x00})) {
s.handleAudioPacket(r)
}
2020-10-18 13:52:38 +02:00
}
2020-10-18 20:09:12 +02:00
// sendPart1 expects 1364 bytes of PCM data.
func (s *audioStream) sendPart1(pcmData []byte) {
s.common.send(append([]byte{0x6c, 0x05, 0x00, 0x00, 0x00, 0x00, byte(s.audioSendSeq), byte(s.audioSendSeq >> 8),
byte(s.common.localSID >> 24), byte(s.common.localSID >> 16), byte(s.common.localSID >> 8), byte(s.common.localSID),
byte(s.common.remoteSID >> 24), byte(s.common.remoteSID >> 16), byte(s.common.remoteSID >> 8), byte(s.common.remoteSID),
0x80, 0x00, byte((s.audioSendSeq - 1) >> 8), byte(s.audioSendSeq - 1), 0x00, 0x00, byte(len(pcmData) >> 8), byte(len(pcmData))},
pcmData...))
s.audioSendSeq++
}
// sendPart2 expects 556 bytes of PCM data.
func (s *audioStream) sendPart2(pcmData []byte) {
s.common.send(append([]byte{0x44, 0x02, 0x00, 0x00, 0x00, 0x00, byte(s.audioSendSeq), byte(s.audioSendSeq >> 8),
byte(s.common.localSID >> 24), byte(s.common.localSID >> 16), byte(s.common.localSID >> 8), byte(s.common.localSID),
byte(s.common.remoteSID >> 24), byte(s.common.remoteSID >> 16), byte(s.common.remoteSID >> 8), byte(s.common.remoteSID),
0x80, 0x00, byte((s.audioSendSeq - 1) >> 8), byte(s.audioSendSeq - 1), 0x00, 0x00, byte(len(pcmData) >> 8), byte(len(pcmData))},
pcmData...))
s.audioSendSeq++
}
func (s *audioStream) init() {
2020-10-18 11:17:40 +02:00
s.common.open("audio", 50003)
}
2020-10-18 10:33:47 +02:00
func (s *audioStream) start() {
2020-10-18 11:01:53 +02:00
s.common.sendPkt3()
2020-10-18 13:52:38 +02:00
s.common.waitForPkt4Answer()
2020-10-18 11:01:53 +02:00
s.common.sendPkt6()
2020-10-18 13:52:38 +02:00
s.common.waitForPkt6Answer()
log.Print("stream started")
2020-10-18 13:52:38 +02:00
2020-10-18 15:40:25 +02:00
s.timeoutTimer = time.NewTimer(audioTimeoutDuration)
2020-10-18 21:35:36 +02:00
s.common.pkt7.startPeriodicSend(&s.common, 1)
2020-10-18 13:52:38 +02:00
2020-10-18 20:09:12 +02:00
s.audioSendSeq = 1
testSendTicker := time.NewTicker(80 * time.Millisecond) // TODO: remove
2020-10-18 13:52:38 +02:00
var r []byte
for {
select {
case r = <-s.common.readChan:
s.handleRead(r)
2020-10-18 15:40:25 +02:00
case <-s.timeoutTimer.C:
2020-10-19 09:45:49 +02:00
exit(errors.New("timeout"))
2020-10-18 20:09:12 +02:00
case <-testSendTicker.C: // TODO: remove
b1 := make([]byte, 1364)
s.sendPart1(b1)
b2 := make([]byte, 556)
s.sendPart2(b2)
2020-10-18 13:52:38 +02:00
}
}
2020-10-18 10:33:47 +02:00
}