view intercom/g726/g726_rfc3551.c @ 5:f762bf195c4b

import spandsp-0.0.3
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 16:00:21 +0200
parents 13be24d74cd2
children
line wrap: on
line source

/* 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.