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

📄 rgl_encode_v1.c

📁 经典的音频G711和G729编码和解码源代码,G711是纯C源代码,G279为静态链接库,里面有PDF格式的开发文档
💻 C
📖 第 1 页 / 共 2 页
字号:
// documentation for RGL packetization format details).
//
// INPUT PARAMETERS:
// The input G711 input frame is assumed to be mu-law encoded if the
// integer parameter "mu_or_a" is set to one. The G711 input frame is
// assumed to be A-law if the integer "mu_or_a" is set to zero.
// Pointers to the "input_frame" and the "output_frame" arrays must be
// passed to this function. The integer size of the G711 input frame,
// "input_frame_size", must be passed to this function.
//
// OUTPUT PARAMETERS:
// This function returns the size of the output RGL frame,
// "output_fame_size", to the calling program. The RGL output frame is
// placed in the "output_frame" as determined by the "output_frame"
// pointer. If an error was encountered in this routine, then the
// returned "output_frame_size" is a negative value. A "-1" value
// indicates that the "mu_or_a" parameter sent to this routine was
// not set to zero or one. Any other negative value indicates an
// unspecified error in this routine.
//
// NOTES:
// If the G711 input frame isn't "RGL compressable", then the
// resulting output frame will be one byte longer than the input frame
// (i.e., expanded by one byte per frame). For all compressable cases,
// the output array will be shorter than the input array (except for
// trivially short input fame lengths of less than 10 bytes that are
// not targeted applications for the RGL codec).
//
// DSP DATA MEMORY REQUIREMENTS:
// The calling program must allocate data memory for the "input_frame"
// array (of size max_frame_size), the "output_frame" array (of size
// (max_frame_size+1)), and the integers "mu_or_a", "input_frame_size"
// and "output frame_size". The maximum frame size the calling program
// accommodates (i.e., max_frame_size) should be #defined in the
// calling program.
// 
// OTHER:
// Depending on the version of the C compiler used, "true" and "false"
// may need to be #defined as 1 and 0, respectively 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_Compress (int mu_or_a, uint8 *input_frame,
     int input_frame_size, uint8 *output_frame, int output_frame_size)
{
int i, j, samples_min, samples_codepoint, sample_byte_count;
int remainder_bits, explicit_anchor_flag = false, error_flag = false;
uint8 y_max, y_min, y_tentative_anchor, y_anchor, num_bits;
uint8 num_bits_codepoint, n_codepoint, a_codepoint;
uint8 uint8_temp, bits_left_in_byte, num_bits_unpacked;

// determine if input frame was from a A-law or mu-law encoded, then
// map to desired {0 - 255} linear range
if (mu_or_a == 1 ){
 for(i=0; i< input_frame_size; i++){       /* Map the mu-law values */
  if (input_frame[i] > 127) {
  input_frame[i] = (input_frame[i] & 0x7F);     /* mask MSB to zero */
  input_frame[i] = 255 - input_frame[i];
  }
 }
}
else {             /* Note: If mu_or_a is set incorrectly, A-law is */
 if (mu_or_a != 0) error_flag = true; /*assumed, but note the error */
 for(i=0; i< input_frame_size; i++){        /* Map the A-law values */
 input_frame[i] = ( input_frame[i] ^ 0x55 );    /* invert even bits */
 if (input_frame[i] < 128) input_frame[i] = 127 - input_frame[i];
 }
}

// Find y_min and y_max
y_min = input_frame[0]; y_max = input_frame[0];  /*init y_min, y_max*/
for (i=1; i<input_frame_size; i++){
if (input_frame[i] > y_max) y_max = input_frame[i];
else if (input_frame[i] < y_min) y_min = input_frame[i];
}

// Find minimum number of bits needed to code the frame using
// an explicit anchor (at y_min and fd_min)
samples_min = (y_max - y_min + 1);

// Find number of bits per sample
if      (samples_min       > 128 ) num_bits           =  8;
else if (samples_min       >  64 ) num_bits           =  7;
else if (samples_min       >  32 ) num_bits           =  6;
else if (samples_min       >  16 ) num_bits           =  5;
else if (samples_min       >   8 ) num_bits           =  4;
else if (samples_min       >   4 ) num_bits           =  3;
else if (samples_min       >   2 ) num_bits           =  2;
else if (samples_min       >   1 ) num_bits           =  1;
else if (samples_min       ==  1 ) num_bits           =  0;

// If the minimum number of bits is 8, then y_anchor = 0 by default.
// Set n_codepoint, a_codepoint and y_anchor and don't bother with
// the num_bits !=8 logic below. Note: The explicit_anchor_flag was
// initialized to false (so I don't need to set it here).
if (num_bits == 8) {
n_codepoint = 0;      /* set the N and A bits for an 8 bit encoding */
a_codepoint = 30; 
y_anchor = 0;               /* all 8 bit encodings use y_anchor = 0 */
}
else {           /* Find tentative anchor and tentative a_codepoint */
if      (y_min >= 129) { y_tentative_anchor = 129; a_codepoint =  0; }
else if (y_min >= 128) { y_tentative_anchor = 128; a_codepoint =  1; }
else if (y_min >= 127) { y_tentative_anchor = 127; a_codepoint =  2; }
else if (y_min >= 126) { y_tentative_anchor = 126; a_codepoint =  3; }
else if (y_min >= 125) { y_tentative_anchor = 125; a_codepoint =  4; }
else if (y_min >= 124) { y_tentative_anchor = 124; a_codepoint =  5; }
else if (y_min >= 123) { y_tentative_anchor = 123; a_codepoint =  6; }
else if (y_min >= 122) { y_tentative_anchor = 122; a_codepoint =  7; }
else if (y_min >= 121) { y_tentative_anchor = 121; a_codepoint =  8; }
else if (y_min >= 119) { y_tentative_anchor = 119; a_codepoint =  9; }
else if (y_min >= 117) { y_tentative_anchor = 117; a_codepoint = 10; }
else if (y_min >= 115) { y_tentative_anchor = 115; a_codepoint = 11; }
else if (y_min >= 113) { y_tentative_anchor = 113; a_codepoint = 12; }
else if (y_min >= 111) { y_tentative_anchor = 111; a_codepoint = 13; }
else if (y_min >= 108) { y_tentative_anchor = 108; a_codepoint = 14; }
else if (y_min >= 105) { y_tentative_anchor = 105; a_codepoint = 15; }
else if (y_min >= 102) { y_tentative_anchor = 102; a_codepoint = 16; }
else if (y_min >=  99) { y_tentative_anchor =  99; a_codepoint = 17; }
else if (y_min >=  96) { y_tentative_anchor =  96; a_codepoint = 18; }
else if (y_min >=  92) { y_tentative_anchor =  92; a_codepoint = 19; }
else if (y_min >=  88) { y_tentative_anchor =  88; a_codepoint = 20; }
else if (y_min >=  84) { y_tentative_anchor =  84; a_codepoint = 21; }
else if (y_min >=  80) { y_tentative_anchor =  80; a_codepoint = 22; }
else if (y_min >=  75) { y_tentative_anchor =  75; a_codepoint = 23; }
else if (y_min >=  70) { y_tentative_anchor =  70; a_codepoint = 24; }
else if (y_min >=  65) { y_tentative_anchor =  65; a_codepoint = 25; }
else if (y_min >=  60) { y_tentative_anchor =  60; a_codepoint = 26; }
else if (y_min >=  54) { y_tentative_anchor =  54; a_codepoint = 27; }
else if (y_min >=  48) { y_tentative_anchor =  48; a_codepoint = 28; }
else if (y_min >=  41) { y_tentative_anchor =  41; a_codepoint = 29; }
// If (y_min < 41) and (num_bits !=8) - an explicit anchor is needed
else if (y_min <   41) { y_tentative_anchor =   0;
                                        explicit_anchor_flag = true; }

// Find number of bits per sample using fixed codepoint anchors
samples_codepoint = (y_max - y_tentative_anchor +1);
if      (samples_codepoint > 128 ) num_bits_codepoint = 8;
else if (samples_codepoint >  64 ) num_bits_codepoint = 7;
else if (samples_codepoint >  32 ) num_bits_codepoint = 6;
else if (samples_codepoint >  16 ) num_bits_codepoint = 5;
else if (samples_codepoint >   8 ) num_bits_codepoint = 4;
else if (samples_codepoint >   4 ) num_bits_codepoint = 3;
else if (samples_codepoint >   2 ) num_bits_codepoint = 2;
else if (samples_codepoint >   1 ) num_bits_codepoint = 1;
else if (samples_codepoint ==  1 ) num_bits_codepoint = 0;

if ((num_bits_codepoint==num_bits)&&(explicit_anchor_flag == false)) {
y_anchor = y_tentative_anchor;        /* explicit anchor not needed */
}
else {
y_anchor = y_min;         /* need explicit anchor, set it to y_min, */
a_codepoint = 31;                 /* set a_codepoint and set anchor */
explicit_anchor_flag = true;  /* set flag if it hasn't been set yet */
}

n_codepoint = num_bits;   /* set n_codepoint for num_bits != 8 case */

}    /* Close the "else" (of "if(num_bits==8)" statement) way above */

// Code sample points to n_bits bits to range { 0 - (2^(n_bits) -1)}
for(i=0; i < input_frame_size; i++)
                         input_frame[i] = (input_frame[i] - y_anchor);

// Packing Routine begins here
// Pack the overhead byte(s): n_codepoint, a_codepoint and
// and explicit_anchor (if required)
sample_byte_count = (input_frame_size*num_bits)/8;
remainder_bits = (input_frame_size*num_bits) - ( sample_byte_count * 8 );
// Last byte may not be full, need to increment byte count in this case
if (remainder_bits != 0) sample_byte_count++;  
// Include 1st overhead byte in count */
output_frame_size = (sample_byte_count + 1); 
output_frame[0] = (n_codepoint <<5);               /* Pack "N" bits */
output_frame[0] =  output_frame[0] | a_codepoint;  /* Pack "A" bits */

j = 1;                           /* "j" is output_frame array index */

if (explicit_anchor_flag == true ){
output_frame[j++] = y_anchor;      /* Pack the explicit anchor byte */
output_frame_size++;             /* Include this byte in size count */
}

// Zero all remaining output_frame elements (will need to do bit
// "or"-ing on them later)
for ( i=j; i< output_frame_size; i++ ) output_frame[i] =0;

//Pack the samples
if ( num_bits != 0) {  /* Do not pack sampled data if num_bits == 0 */
i=0;               /* "i" is the sample counter (input_frame) index */
bits_left_in_byte = 8;        /* accounting for bits unused in byte */

// Do while there are still samples to process
while (i < input_frame_size){

//Case: Entire sample fits in present byte here
if (bits_left_in_byte >= num_bits) {
uint8_temp = (input_frame[i++]<<(bits_left_in_byte - num_bits));
output_frame[j] = (output_frame[j] | uint8_temp);
bits_left_in_byte = (bits_left_in_byte - num_bits);
if ( ( bits_left_in_byte == 0) && (i < input_frame_size) ) {
j++;                             /* go onto next output buffer byte */
bits_left_in_byte = 8;                  /* refill bits_left_in_byte */
}
}
// Case: Part of sample fits in present byte (put other part in
//       subsequent byte).
else if( ( bits_left_in_byte>>0 )&&( bits_left_in_byte < num_bits) ) {
num_bits_unpacked = num_bits - bits_left_in_byte;
// pack as many bits as possible
uint8_temp = (input_frame[i]>>(num_bits_unpacked));
output_frame[j] = (output_frame[j] | uint8_temp);
// go onto nest output buffer byte
j++;
// pack remaining bits
uint8_temp = (input_frame[i++]<<(8 - num_bits_unpacked));
output_frame[j] = (output_frame[j] | uint8_temp);
bits_left_in_byte=(8-num_bits_unpacked);  /* set bits_left_in_byte */
}
}                      /* closing while loop */

// Return output_frame_zise = -2 as an error if index j isn't correct
if (j != (output_frame_size-1)) output_frame_size = -2;

}          /* closing if (num_bits != 0) way (the no packing case) */

// Return output_frame_size = -1 as the most more severe error if
// "mu_or_a" was not set to one or zero
if (error_flag == 1) output_frame_size = -1;

return(output_frame_size);
}

⌨️ 快捷键说明

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