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;
+}

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.