Ticket #774:
 - Initial source of G.722.1/Annex C integration.
 - Disabled some "odd" modes of L16 codec (11kHz & 22kHz mono & stereo) while releasing some payload types.



git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@2563 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/third_party/g7221/decode/coef2sam.c b/third_party/g7221/decode/coef2sam.c
new file mode 100644
index 0000000..18a88ac
--- /dev/null
+++ b/third_party/g7221/decode/coef2sam.c
@@ -0,0 +1,180 @@
+/*****************************************************************************
+**
+**   ITU-T G.722.1 (2005-05) - Fixed point implementation for main body and Annex C
+**   > Software Release 2.1 (2008-06)
+**     (Simple repackaging; no change from 2005-05 Release 2.0 code)
+**
+**   © 2004 Polycom, Inc.
+**
+**   All rights reserved.
+**
+*****************************************************************************/
+
+/*****************************************************************************
+* Filename: rmlt_coefs_to_samples.c
+*
+* Purpose:  Convert Reversed MLT (Modulated Lapped Transform) 
+*           Coefficients to Samples
+*
+*     The "Reversed MLT" is an overlapped block transform which uses
+*     even symmetry * on the left, odd symmetry on the right and a
+*     Type IV DCT as the block transform.  * It is thus similar to a
+*     MLT which uses odd symmetry on the left, even symmetry * on the
+*     right and a Type IV DST as the block transform.  In fact, it is
+*     equivalent * to reversing the order of the samples, performing
+*     an MLT and then negating all * the even-numbered coefficients.
+*
+*****************************************************************************/
+
+/***************************************************************************
+ Include files                                                           
+***************************************************************************/
+#include "defs.h"
+#include "tables.h"
+#include "count.h"
+
+/***************************************************************************
+ Function:     rmlt_coefs_to_samples 
+
+ Syntax:       void rmlt_coefs_to_samples(Word16 *coefs,       
+                                          Word16 *old_samples, 
+                                          Word16 *out_samples, 
+                                          Word16 dct_length,
+                                          Word16 mag_shift)    
+            
+               inputs:    Word16 *coefs
+                          Word16 *old_samples
+                          Word16 dct_length
+                          Word16 mag_shift
+                          
+                          
+               outputs:   Word16 *out_samples
+               
+ Description:  Converts the mlt_coefs to samples
+
+ Design Notes:
+ 
+ WMOPS:     7kHz |    24kbit    |    32kbit
+          -------|--------------|----------------
+            AVG  |     1.91     |    1.91
+          -------|--------------|----------------  
+            MAX  |     1.91     |    1.91
+          -------|--------------|---------------- 
+				
+           14kHz |    24kbit    |    32kbit      |     48kbit
+          -------|--------------|----------------|----------------
+            AVG  |     3.97     |    3.97        |     3.97   
+          -------|--------------|----------------|----------------
+            MAX  |     3.97     |    3.97        |     3.97   
+          -------|--------------|----------------|----------------
+
+***************************************************************************/
+
+void rmlt_coefs_to_samples(Word16 *coefs,     
+                           Word16 *old_samples,
+                           Word16 *out_samples,           
+                           Word16 dct_length,
+                           Word16 mag_shift)             
+{
+
+    
+    Word16	index, vals_left;
+    Word16	new_samples[MAX_DCT_LENGTH];
+    Word16	*new_ptr, *old_ptr;
+    Word16	*win_new, *win_old;
+    Word16	*out_ptr;
+    Word16  half_dct_size;
+    Word32  sum;
+
+    
+
+    half_dct_size = shr(dct_length,1);
+    
+    /* Perform a Type IV (inverse) DCT on the coefficients */
+    dct_type_iv_s(coefs, new_samples, dct_length);
+    
+    test();
+    if (mag_shift > 0) 
+    {
+        for(index=0;index<dct_length;index++)
+        {
+            new_samples[index] = shr(new_samples[index],mag_shift);
+            move16();
+        }
+    }
+    else 
+    {
+        test();
+        if (mag_shift < 0) 
+        {
+            mag_shift = negate(mag_shift);
+            for(index=0;index<dct_length;index++)
+            {
+                new_samples[index] = shl(new_samples[index],mag_shift);
+                move16();
+            }
+        }
+
+    }
+
+    /* Get the first half of the windowed samples */
+    
+    out_ptr = out_samples;
+    move16();
+    test();
+    if (dct_length==DCT_LENGTH)
+    {
+        win_new = rmlt_to_samples_window;
+        move16();
+        win_old = rmlt_to_samples_window + dct_length;
+        move16();
+    }
+    else
+    {
+        win_new = max_rmlt_to_samples_window;
+        move16();
+        win_old = max_rmlt_to_samples_window + dct_length;
+        move16();
+    }
+    old_ptr = old_samples;
+    move16();
+    new_ptr = new_samples + half_dct_size;
+    move16();
+    
+    for (vals_left = half_dct_size;    vals_left > 0;    vals_left--)
+    {
+        sum = 0L;
+        move32();
+        sum = L_mac(sum,*win_new++, *--new_ptr);
+        sum = L_mac(sum,*--win_old, *old_ptr++);
+        *out_ptr++ = round(L_shl(sum,2));
+        move16();
+
+    }
+    
+    /* Get the second half of the windowed samples */
+    
+    for (vals_left = half_dct_size;    vals_left > 0;    vals_left--)
+    {
+        sum = 0L;
+        move32();
+        sum = L_mac(sum,*win_new++, *new_ptr++);
+        sum = L_mac(sum,negate(*--win_old), *--old_ptr);
+        *out_ptr++ = round(L_shl(sum,2));
+        move16();
+    }
+        
+    /* Save the second half of the new samples for   */
+    /* next time, when they will be the old samples. */
+    
+    /* pointer arithmetic */
+    new_ptr = new_samples + half_dct_size;
+    move16();
+    old_ptr = old_samples;
+    move16();
+    for (vals_left = half_dct_size;    vals_left > 0;    vals_left--)
+    {
+        *old_ptr++ = *new_ptr++;
+        move16();
+    }
+}