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