⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rgl_decode_v1.c

📁 经典的音频G711和G729编码和解码源代码,G711是纯C源代码,G279为静态链接库,里面有PDF格式的开发文档
💻 C
📖 第 1 页 / 共 2 页
字号:
// write to console
(void) fprintf(stdout, "Processed file : %s - without errors \n\n",
               rgl_input_file_name);

// tidy up
fclose(rgl_input_file);
fclose(output_file);
return(0);                                   /* end of main program */
}


// "RGL Decompression" function (with reserved overhead codes)
// Copyright (c) 2003 Cisco Systems Inc.
// Author: M. A. Ramalho, Cisco Systems, Sarasota, FL 34238
// Last Revision: January 28, 2003
// Version 1.0.0
//
// This function has been designed so that it will be easily portable
// to DSP code by means of standard C language cross-compliers.
//
// This function takes a "number_of_rgl_bytes" sized array of RGL
// encoded bytes and decompresses them to an "mu_or_al_output_frame"
// sized array of bytes of either mu-law or A-law encoded output
// (see ITU-T G7ll documentation for details on the mu-law or A-law
// format).
//
// INPUT PARAMETERS:
// This function will produce either G711 A-law or mu-law output
// dependent on the value of the integer input parameter "mu_or_a".
// If "mu_or_a" is set to one, mu-law output is produced; if "mu_or_a"
// is set to zero, A-law output is produced. The "mu_or_a" parameter
// *MUST* be set to the identical value that the RGL_Compress function
// used (i.e., the RGL_Compress and RGL_Decompress fucntions do not
// perform A-law to mu-law conversion or visa-versa). Pointers to the
// "rgl_input_frame" and the "output_frame" arrays must be passed to
// this function. The number of (G711) samples represented in RGL
// input frame, "number_of_samples", must be passed to this function.
// The integer "number_of_samples" *MUST* equal the "input_frame_size"
// used by the RGL_Compress function.
//
// NOTES:
// The actual size (in bytes) of the RGL frame is determined
// internally to RGL_Decompress function by decoding the first
// overhead byte in the RGL frame and the knowledge of how
// many (G711) samples are contained in the RGL frame. Thus the RGL
// frame size is inferred by the RGL_Decompress function and *NOT*
// passed as an input parameter to it (see the "RGL Codec"
// documentation for RGL packetization format details). As noted in
// the RGL_Compress function, the worse case RGL frame size is at most
// one byte greater than the G711 input array size.
//
// OUTPUT PARAMETERS:
// This function returns the integer "rgl_bytes_processed". If
// "rgl_bytes_processed" is a non-negative integer, this value should
// be the number of bytes of the RGL frame passed to the function
// (via the "rgl_input_frame" pointer). As an error check, the
// calling program can verify that the RGL input frame passed to this
// function (typically a voice packet payload payload) was, in fact,
// exactly "rgl_bytes_processed" bytes long. This verification check
// is highly recommended. If the returned "rgl_bytes_processed" is a
// negative number, an error occurred. A "-1" returned indicates that
// a "reserved first overhead byte" was encountered (note: seven of
// the 2^8=256 possbile overhead byte values are reserved for other
// or future uses, see RGL documention for Version 1.0.0). When this
// occurs, a G.711 output frame of "mumber_of_samples" long is
// produced, each sample having a value of analog zero (q(127)).
// A "-2" indicates that "mu_or_a" was set to a value other than 0 or
// 1 and an A-law output frame "mumber_of_samples" long is produced,
// each sample having a value of analog zero (q(127)). A "-3"
// returned indicates an error that is most likely casued by the
// number_of_samples parameter sent to RGL_Decompress being
// incorrect. Lastly, any other negative number returned
// indicates an unspecified error in RGL_Decompress. These errors
// are processed in priority order and only the highest error
// priority error is reported (in order -1, -2, -3, -4 with -1 being
// the most severe error).The G711 (mu-law or A-law) decoded output
// frame is placed in the "mu_or_a_output_frame" array as determined
// by the "mu_or_a_output_frame" pointer.
//
// DSP DATA MEMORY REQUIREMENTS:
// The calling program must allocate data memory for the
// "rgl_input_frame" array (of size (max_frame_size+1)), the
// "mu_or_al_output_frame" array output (of size max_frame_size), and
// the integers "mu_or_a", "number_of_samples", and
// "rgl_bytes_processed". The maximum frame size the calling program
// accommodates (i.e., max_fame_size) should be #defined in the
// calling program.
//
//
//
/************************VOVIDA LICENSE******************************/
//
//The Vovida Software License, Version 1.0 
//Copyright (c) 2002 Vovida Networks, Inc.  All rights reserved.
//
//Redistribution and use in source and binary forms, with or without
//modification, are permitted provided that the following conditions
//are met:
//
//1. Redistributions of source code must retain the above copyright
//   notice, this list of conditions and the following disclaimer.
//
//2. Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in
//   the documentation and/or other materials provided with the
//   distribution.
//
//3. The names "VOCAL", "Vovida Open Communication Application Library",
//   and "Vovida Open Communication Application Library (VOCAL)" must
//   not be used to endorse or promote products derived from this
//   software without prior written permission. For written
//   permission, please contact vocal@vovida.org.
//
//4. Products derived from this software may not be called "VOCAL", nor
//   may "VOCAL" appear in their name, without prior written
//   permission.
//
//THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
//WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
//OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
//NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
//NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DAMAGES
//IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
//EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
//OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
//(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
//USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
//DAMAGE.
//
/************************VOVIDA LICENSE******************************/
//
//

int RGL_Decompress (int mu_or_a, uint8 *rgl_input_frame,
          int number_of_samples, uint8 *mu_or_al_output_frame,
          int rgl_bytes_processed)
{
int i, j, rgl_byte_count, remainder_bits;
int error_flag1 = 0, error_flag2 = 0;     /* initialize error flags */
uint8 y_anchor, num_bits, n_codepoint, a_codepoint;
uint8 uint8_temp1, uint8_temp2, bits_left_in_byte, num_bits_unpacked;

j=1;                                    /* j is the rgl byte index */
n_codepoint = ( ( 0x07 & ( rgl_input_frame[0] >>5) ) );
a_codepoint =   ( 0x1F &   rgl_input_frame[0] );
if ( (n_codepoint == 0) && (a_codepoint == 30) ){
 num_bits =8;          /* a_codepoint=30 and n_codepoint=0 signals */
 y_anchor = 0;   /*num_bits=8 and 8 bit encodings are anchored at 0*/ 
}
else num_bits = n_codepoint;

// create a rgl_byte_count to check with number of bytes processed
// during unpack later
rgl_byte_count = (number_of_samples*num_bits)/8;
remainder_bits = (number_of_samples*num_bits) - ( rgl_byte_count*8 );
if (remainder_bits != 0) rgl_byte_count++; /*last byte was not full*/
rgl_byte_count++;            /* include 1st overhead byte in count */

// find y_anchor (if num_bits != 8)
if (num_bits != 8) {
switch (a_codepoint)
{
case  0: y_anchor = 129; break;
case  1: y_anchor = 128; break;
case  2: y_anchor = 127; break;
case  3: y_anchor = 126; break;
case  4: y_anchor = 125; break;
case  5: y_anchor = 124; break;
case  6: y_anchor = 123; break;
case  7: y_anchor = 122; break;
case  8: y_anchor = 121; break;
case  9: y_anchor = 119; break;
case 10: y_anchor = 117; break;
case 11: y_anchor = 115; break;
case 12: y_anchor = 113; break;
case 13: y_anchor = 111; break;
case 14: y_anchor = 108; break;
case 15: y_anchor = 105; break;
case 16: y_anchor = 102; break;
case 17: y_anchor =  99; break;
case 18: y_anchor =  96; break;
case 19: y_anchor =  92; break;
case 20: y_anchor =  88; break;
case 21: y_anchor =  84; break;
case 22: y_anchor =  80; break;
case 23: y_anchor =  75; break;
case 24: y_anchor =  70; break;
case 25: y_anchor =  65; break;
case 26: y_anchor =  60; break;
case 27: y_anchor =  54; break;
case 28: y_anchor =  48; break;
case 29: y_anchor =  41; break;
case 30: error_flag1 =  1; break;  /* "reserved code"; report error*/
case 31:                                     /*explicit anchor case*/
y_anchor =rgl_input_frame[j++];
rgl_byte_count++;
break;
default: error_flag2 = 4;   /* this statement should never execute */
}
}                 /* end of "if(num_bits !=8)" statement */

// For num_bits=0 case, fill the output frame with zeros
if ( num_bits == 0 ){
for(j=0; j< number_of_samples; j++) mu_or_al_output_frame[j] = 0;
rgl_bytes_processed = rgl_byte_count;
}
else {     /* Unpacking routine begins here (for num_bits !=0 case) */
i=0;           /* "i" is the sample counter (rgl_input_frame) index */
bits_left_in_byte = 8;            /* bit accounting for unused bits */
num_bits_unpacked = 0;      /*accounting for bits in subsequent byte*/

while (i < number_of_samples){  /* Do while more samples to process */

//Case 1: Entire sample is in present byte
if (bits_left_in_byte >= num_bits) {
uint8_temp1 = (rgl_input_frame[j]>>(bits_left_in_byte - num_bits));
 if ( (bits_left_in_byte != 8 ) || ( num_bits != 8 )) {
// mask MSBs not in sample
  switch (num_bits){
   case 1: mu_or_al_output_frame[i++] = ( 0x01 & uint8_temp1 ); break;
   case 2: mu_or_al_output_frame[i++] = ( 0x03 & uint8_temp1 ); break;
   case 3: mu_or_al_output_frame[i++] = ( 0x07 & uint8_temp1 ); break;
   case 4: mu_or_al_output_frame[i++] = ( 0x0f & uint8_temp1 ); break;
   case 5: mu_or_al_output_frame[i++] = ( 0x1f & uint8_temp1 ); break;
   case 6: mu_or_al_output_frame[i++] = ( 0x3f & uint8_temp1 ); break;
   case 7: mu_or_al_output_frame[i++] = ( 0x7f & uint8_temp1 ); break;
   default: error_flag2 = 4;           /* this should never execute */
  }
 }
 else mu_or_al_output_frame[i++] = uint8_temp1; /*no garbage in samp*/
bits_left_in_byte = (bits_left_in_byte - num_bits);
if ( ( bits_left_in_byte == 0) && (i < number_of_samples) ) {
j++;                                /* go onto next RGL sample byte */
bits_left_in_byte = 8;                  /* refill bits_left_in_byte */
}
}        /* close of Case 1 "if" */

// Case 2: Part of sample in present byte and the other part is in
// the subsequent byte
else if ( (bits_left_in_byte>>0) && (bits_left_in_byte<num_bits) ) {
num_bits_unpacked = num_bits - bits_left_in_byte;
 switch ( bits_left_in_byte ){      /* mask out MSBs not in sample */
  case 1: uint8_temp1 = ( 0x01 & rgl_input_frame[j] ); break;
  case 2: uint8_temp1 = ( 0x03 & rgl_input_frame[j] ); break;
  case 3: uint8_temp1 = ( 0x07 & rgl_input_frame[j] ); break;
  case 4: uint8_temp1 = ( 0x0f & rgl_input_frame[j] ); break;
  case 5: uint8_temp1 = ( 0x1f & rgl_input_frame[j] ); break;
  case 6: uint8_temp1 = ( 0x3f & rgl_input_frame[j] ); break;
  case 7: uint8_temp1 = ( 0x7f & rgl_input_frame[j] ); break;
  default: error_flag2 = 4;           /* this should never execute */
  } 
// first part of sample
uint8_temp1 = (uint8_temp1<<(num_bits - bits_left_in_byte));
//second part of sample
uint8_temp2 = (rgl_input_frame[++j]>>(8 - num_bits_unpacked));
// put sample together
mu_or_al_output_frame[i++] = ( uint8_temp1 | uint8_temp2 );
bits_left_in_byte = ( 8 - num_bits_unpacked ); /* set this counter */
}                     /* close of Case 2 "else if" */

}                     /* close of while statement */

// If index j isn't correct at completion of unpacking routine, then
// note this as an error.
if (j != ( rgl_byte_count - 1 )) error_flag2 = 3;
else rgl_bytes_processed = (j+1);

}   /* close of else of "if( num_bits == 0 )" way above */

// Add back y_anchor to all samples in (quantized sample) payload
// unless a "reserved code" was found as the first overrhead byte
// or if "mu_or_a" was not set correctly (i.e., to 1 or 0).
// If either of thsese cases are found, fill the output frame with
// "analog zero" (q(127)).
if ( (mu_or_a < 0) || (mu_or_a > 1) ) error_flag2 = 2;
if ( (error_flag1 == 1) || (error_flag2 == 2) ) {
 for(j=0; j< number_of_samples; j++){
 mu_or_al_output_frame[j] = 127; /* fill output frame with "zeros" */
 }
}
else {
 for (j=0; j< number_of_samples; j++) {
 mu_or_al_output_frame[j] = mu_or_al_output_frame[j] + y_anchor;
 }
}

// Map the 0 - 255 linear values to mu-law or A-law output format
// Note: If "mu_or_a" was set incorrectly, this routine assumes
// A-law output (as did the RGL_Compress function).
if (mu_or_a == 1) {
 for(j=0; j< number_of_samples; j++){  /* 0 - 255 linear to mu-law */
  if (mu_or_al_output_frame[j] > 127) {
  // mask MSB to zero
  mu_or_al_output_frame[j] = (mu_or_al_output_frame[j] & 0x7F);
  // rest of rule
  mu_or_al_output_frame[j] = 255 - mu_or_al_output_frame[j];
  }
 }
}
else {
 for(j=0; j< number_of_samples; j++){   /* 0 - 255 linear to A-law */
 if(mu_or_al_output_frame[j]<128)
             mu_or_al_output_frame[j]=(127-mu_or_al_output_frame[j]);
 // invert the even bits
 mu_or_al_output_frame[j] = ( mu_or_al_output_frame[j] ^ 0x55 );
 }
}

// Return negative "rgl_bytes_processed" if errors have occurred
// Note: Error priority is: 1) "reserve code" found, 2) mu_or_a set
// incorrectly, 3) rgl_bytes_processed not correct, 4) all other
// errors. If errors are found, only one error is reported - the
// one with the highest error priority (i.e., -1 is the highest).
if ( error_flag2 > 0 ) rgl_bytes_processed = -error_flag2;
if ( error_flag1 > 0 ) rgl_bytes_processed = -error_flag1;
return(rgl_bytes_processed);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -