package javaforce.voip; /* struct rtp_header { byte version; //usually 0x80 byte type; //0x12 (18) short seqnum; int timestamp; int syncsrcid; }; */ import javaforce.*; import javaforce.codec.g729a.*; /** * Encodes/decodes g729a packets. */ public class g729a implements Coder { private Encoder encoder = new Encoder(); private Decoder decoder = new Decoder(); private RTP rtp; public g729a(RTP rtp) { this.rtp = rtp; } private byte encoded[] = new byte[20 + 12]; //((160 / 80) * 10) + 12 //samples must be 160 samples public byte[] encode(short samples[]) { RTPChannel rtpChannel = rtp.getDefaultChannel(); rtpChannel.buildHeader(encoded, 18, rtpChannel.getseqnum(), rtpChannel.gettimestamp(160), rtpChannel.getssrc(), false); encoder.encode(encoded, 12, samples, 0, 160 / 80); //output, outputOffset, input, inputOffset, # 80 samples packets (2) return encoded; } private int decode_timestamp; private short decoded[] = new short[160]; //encoded must be 20+12 bytes at least public short[] decode(byte encoded[], int off) { int decode_timestamp = BE.getuint32(encoded, off + 4); if (this.decode_timestamp == 0) { this.decode_timestamp = decode_timestamp; } else { if (RTP.debug) { JFLog.log("G729a:timestamp = " + decode_timestamp + ":" + ((this.decode_timestamp + 160 == decode_timestamp) ? "ok" : "lost packet")); } this.decode_timestamp = decode_timestamp; } decoder.decode(decoded, 0, encoded, off + 12, 20 / 10); return decoded; } public int getSampleRate() {return 8000;} }