Mercurial > hg > audiostuff
diff intercom/g726/g726_rfc3551.c @ 2:13be24d74cd2
import intercom-0.4.1
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 09:57:52 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/intercom/g726/g726_rfc3551.c Fri Jun 25 09:57:52 2010 +0200 @@ -0,0 +1,134 @@ +/* g726_rfc3551.c + * + * Copyright (C) DFS Deutsche Flugsicherung (2004, 2005). + * All Rights Reserved. + * Author: Andre Adrian + */ + + +/* RFC3551 + + name of sampling default + encoding sample/frame bits/sample rate ms/frame ms/packet + __________________________________________________________________ + G726-40 sample 5 8,000 20 + G726-32 sample 4 8,000 20 + G726-24 sample 3 8,000 20 + G726-16 sample 2 8,000 20 + + Applications MUST + determine the encoding type of packed codewords from the RTP payload + identifier. + + the first codeword is placed into the first octet + such that the least significant bit of the codeword aligns with the + least significant bit in the octet, the second codeword is then + packed so that its least significant bit coincides with the least + significant unoccupied bit in the octet. When a complete codeword + cannot be placed into an octet, the bits overlapping the octet + boundary are placed into the least significant bits of the next + octet. Packing MUST end with a completely packed final octet. The + number of codewords packed will therefore be a multiple of 8, 2, 8, + and 4 for G726-40, G726-32, G726-24, and G726-16, respectively. An + example of the packing scheme for G726-32 codewords is as shown, + where bit 7 is the least significant bit of the first octet, and bit + A3 is the least significant bit of the first codeword: + + 0 1 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- + |B B B B|A A A A|D D D D|C C C C| ... + |0 1 2 3|0 1 2 3|0 1 2 3|0 1 2 3| + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- + + An example of the packing scheme for G726-24 codewords follows, where + again bit 7 is the least significant bit of the first octet, and bit + A2 is the least significant bit of the first codeword: + + 0 1 2 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- + |C C|B B B|A A A|F|E E E|D D D|C|H H H|G G G|F F| ... + |1 2|0 1 2|0 1 2|2|0 1 2|0 1 2|0|0 1 2|0 1 2|0 1| + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- + + PT encoding media type clock rate channels + name (Hz) + ___________________________________________________ + dyn G726-40 A 8,000 1 + dyn G726-32 A 8,000 1 + dyn G726-24 A 8,000 1 + dyn G726-16 A 8,000 1 + +*/ + +#include <string.h> +#include "g711.h" +#include "g726.h" + +/* G.726 subset: 32kBit/s, A-law */ + +static void g726pack(Byte *packed, short *in, int cnt) +{ + int i; + for (i = 0; i <= cnt; i += 2, ++packed, ++in) { + *packed = (*in & 0xF); + ++in; + *packed += (*in & 0xF) * 16; + } +} + +static void g726unpack(short *out, Byte *packed, int cnt) +{ + int i; + for (i = 0; i <= cnt; i += 2, ++packed, ++out) { + *out = (*packed & 0xF); + ++out; + *out = (*packed & 0xF0) / 16; + } +} + +void g726_initEncode(G726_state *encoder_state) +{ + memset(encoder_state, 0, sizeof(G726_state)); +} + +void g726_initDecode(G726_state *decoder_state) +{ + memset(decoder_state, 0, sizeof(G726_state)); +} + +short g726_encode( /* (o) Number of bytes encoded */ + G726_state *state, /* (i/o) Encoder instance */ + unsigned char *encoded_data, /* (o) The encoded bytes */ + short *inp_buf /* (i) The signal block to encode */ + ) +{ + unsigned char inpb_buf[20*8]; + short out_buf[20*8]; + static char law[] = "1"; + + alaw_compress(20*8, inp_buf, inpb_buf); + G726_encode(inpb_buf, out_buf, 20*8, law, 4, 0, state); + g726pack(encoded_data, out_buf, 20*8); + + return 20*8/2; +} + +short g726_decode( /* (o) Number of decoded samples */ + G726_state *state, /* (i/o) Decoder instance */ + short *decoded_data, /* (o) Decoded signal block */ + unsigned char *encoded_data, /* (i) Encoded bytes */ + short mode /* (i) 0=PL, 1=Normal */ + ) +{ + short inp_buf[20*8]; + unsigned char outb_buf[20*8]; + static char law[] = "1"; + + g726unpack(inp_buf, encoded_data, 20*8); + G726_decode(inp_buf, outb_buf, 20*8, law, 4, 0, state); + alaw_expand(20*8, outb_buf, decoded_data); + + return 20*8; +}