Browse Source

Use fancy slicing for RTP buffer.

pull/2/head
Justine Alexandra Roberts Tunney 11 years ago
parent
commit
996ef32bff
3 changed files with 47 additions and 43 deletions
  1. +1
    -0
      fone/main.go
  2. +21
    -19
      rtp/rtp.go
  3. +25
    -24
      rtp/session.go

+ 1
- 0
fone/main.go View File

@ -180,6 +180,7 @@ func main() {
case ch := <-keyboard:
if err := rs.SendDTMF(ch); err != nil {
log.Printf("DTMF: %s\r\n", err.Error())
break
}
log.Printf("DTMF: %c\r\n", ch)


+ 21
- 19
rtp/rtp.go View File

@ -93,31 +93,33 @@ type EventHeader struct {
Duration uint16
}
// Writes an rtp header to a buffer. You need 12 bytes.
func (h *Header) Write(b []byte) {
b[0] = (Version & mask2) << 6
// Write appends an RTP header to a byte slice.
func (h *Header) Write(b []byte) []byte {
var b0, b1 byte
b0 = (Version & mask2) << 6
if h.Pad {
b[0] |= (1 & mask1) << 5
b0 |= (1 & mask1) << 5
}
// if extend { b[0] |= (1 & mask1) << 4 }
// b[0] |= (csrcCount & mask4) << 0
b[1] = (h.PT & mask7) << 0
// if extend { b0 |= (1 & mask1) << 4 }
// b0 |= (csrcCount & mask4) << 0
b1 = (h.PT & mask7) << 0
if h.Mark {
b[1] |= (1 & mask1) << 7
b1 |= (1 & mask1) << 7
}
b[2] = byte(h.Seq >> 8)
b[3] = byte(h.Seq)
b[4] = byte(h.TS >> 24)
b[5] = byte(h.TS >> 16)
b[6] = byte(h.TS >> 8)
b[7] = byte(h.TS)
b[8] = byte(h.Ssrc >> 24)
b[9] = byte(h.Ssrc >> 16)
b[10] = byte(h.Ssrc >> 8)
b[11] = byte(h.Ssrc)
return append(b, b0, b1,
byte(h.Seq>>8),
byte(h.Seq),
byte(h.TS>>24),
byte(h.TS>>16),
byte(h.TS>>8),
byte(h.TS),
byte(h.Ssrc>>24),
byte(h.Ssrc>>16),
byte(h.Ssrc>>8),
byte(h.Ssrc))
}
// Reads header bits from buffer.
// Read extracts an RTP header from a byte slice.
func (h *Header) Read(b []byte) error {
if b[0]>>6 != Version {
return ErrBadVersion


+ 25
- 24
rtp/session.go View File

@ -17,10 +17,13 @@ const (
rtpBindMaxAttempts = 10
rtpBindPortMin = 16384
rtpBindPortMax = 32768
dtmfVolume = 6
dtmfDuration = 400
dtmfInterval = 100
)
var (
dtmfCodes = map[byte]byte{'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, '*': 10, '#': 11, 'a': 12, 'A': 12, 'b': 13, 'B': 13, 'c': 14, 'C': 14, 'd': 15, 'D': 15, '!': 16}
dtmfCodes = [256]byte{'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, '*': 10, '#': 11, 'a': 12, 'A': 12, 'b': 13, 'B': 13, 'c': 14, 'C': 14, 'd': 15, 'D': 15, '!': 16}
)
type Frame [160]int16
@ -70,7 +73,7 @@ func NewSession(host string) (rs *Session, err error) {
TS: 0,
Ssrc: rand.Uint32(),
},
obuf: make([]byte, HeaderSize+160),
obuf: make([]byte, 0, 1500),
}, nil
}
@ -79,13 +82,14 @@ func (rs *Session) Send(frame *Frame) (err error) {
return nil
}
rs.Header.PT = sdp.ULAWCodec.PT
rs.Header.Write(rs.obuf)
buf := rs.Header.Write(rs.obuf)
buf = buf[0 : len(buf)+160]
rs.Header.TS += 160
rs.Header.Seq++
for n := 0; n < 160; n++ {
rs.obuf[HeaderSize+n] = byte(dsp.LinearToUlaw(int64(frame[n])))
buf[HeaderSize+n] = byte(dsp.LinearToUlaw(int64(frame[n])))
}
_, err = rs.Sock.WriteTo(rs.obuf[:HeaderSize+160], rs.Peer)
_, err = rs.Sock.WriteTo(buf, rs.Peer)
return
}
@ -94,19 +98,16 @@ func (rs *Session) SendRaw(pt uint8, data []byte, samps uint32) (err error) {
return nil
}
rs.Header.PT = pt
rs.Header.Write(rs.obuf)
buf := rs.Header.Write(rs.obuf)
rs.Header.TS += samps
rs.Header.Seq++
_, err = rs.Sock.WriteTo(append(rs.obuf[:HeaderSize], data...), rs.Peer)
_, err = rs.Sock.WriteTo(append(buf, data...), rs.Peer)
return
}
func (rs *Session) SendDTMF(digit byte) error {
const volume = 6
const duration = 1600
const interval = 400
code, ok := dtmfCodes[digit]
if !ok {
code := dtmfCodes[digit]
if code == 0 && digit != '0' {
return errors.New("Invalid DTMF digit: " + string(digit))
}
if rs == nil || rs.Sock == nil || rs.Peer == nil {
@ -114,30 +115,30 @@ func (rs *Session) SendDTMF(digit byte) error {
}
rs.Header.PT = sdp.DTMFCodec.PT
rs.Header.Mark = true
rs.obuf[HeaderSize+0] = code
rs.obuf[HeaderSize+1] = volume & 0x3f
var event [4]byte
event[0] = code
event[1] = dtmfVolume & 0x3f
dur := uint16(1)
for {
rs.obuf[HeaderSize+2] = byte(dur >> 8)
rs.obuf[HeaderSize+3] = byte(dur & 0xff)
rs.Header.Write(rs.obuf)
_, err := rs.Sock.WriteTo(rs.obuf[:HeaderSize+4], rs.Peer)
event[2] = byte(dur >> 8)
event[3] = byte(dur & 0xff)
_, err := rs.Sock.WriteTo(append(rs.Header.Write(rs.obuf), event[:]...), rs.Peer)
if err != nil {
return err
}
rs.Header.Seq++
rs.Header.Mark = false
dur += interval
if dur >= duration {
dur += dtmfInterval
if dur >= dtmfDuration {
break
}
}
rs.obuf[HeaderSize+1] |= 0x80
rs.obuf[HeaderSize+2] = byte(duration >> 8)
rs.obuf[HeaderSize+3] = byte(duration & 0xff)
event[1] |= 0x80
event[2] = byte(dtmfDuration >> 8)
event[3] = byte(dtmfDuration & 0xff)
for n := 0; n < 3; n++ {
rs.Header.Write(rs.obuf)
_, err := rs.Sock.WriteTo(rs.obuf[:HeaderSize+4], rs.Peer)
_, err := rs.Sock.WriteTo(append(rs.Header.Write(rs.obuf), event[:]...), rs.Peer)
if err != nil {
return err
}


Loading…
Cancel
Save