📄 rgl_decode_v1.c
字号:
// 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 + -