📄 rgl_decode_v1.c
字号:
// rgl_decode.c
// Copyright (c) 2003 Cisco Systems Inc.
// Author: M. A. Ramalho, Cisco Systems, Sarasota, FL 34238
// Last Revision: January 28, 2003
// Version 1.0.0
//
// Main program: "rgl_decode" will de-compress an "RGL" encoded input
// file (RGL stands for "Ramalho G711 Lossless" output format) with
// extension ".rlm" (e.g., foo.rgm - which was "RGL encoded" from a
// mu-law input file) or ".rla" (e.g., foo.rga - which was "RGL
// encoded" from an A-law input file) to a mu-law or A-law encoded
// output as appropriate. The "rgl_encode" program generated these
// ".rlm" or ".rla" files based on whether it's input data was mu-law
// or A-law. The output file of this program will have extension
// ".muo" for mu-law output or extension ".alo" for A-law output.
//
// The program is called as:
// rgl_decode [rgl_input_file_name] [number_of_samples]
//
// The input file must be of the form "*.rlm" or "*.rla". The frame
// size is entered in bytes. The valid range for the frame size is
// from 1 byte (125 nanoseconds) to 2000 (250 milliseconds) - however
// the frame size that that rgl_encode used *MUST* also be used here
// (otherwise jibberish output will result).
//
// If an end of file of the RGL input file is found before an integer
// number of frames (each of size "number_of_samples") is completed,
// the probable cause is that a number of samples other than that
// used by rgl_encode was incorrectly specified as the
// "number_of_samples" argument (either as entered on the command line
// or the default if not specified). The other cause, of course, is a
// programing error by the creator of this software that he does not
// desire to own up to. If such an end of file is encountered, a
// warning is generated and printed to the console.
//
// If the RGL input file name isn't given, the program prompts for it
// and the frame size.
//
// If the RGL input file name is provided, but the number of samples
// per RGL frame is not specified, the default frame size of 80 bytes
// is used (a message is sent to the console to remind the user of
// this fact).
//
// If the input file name and a valid number of samples per RGL frame
// (e.g., between 1 and 2000, inclusive) is provided, the program uses
// the number of samples per RGL frame over the default.
//
//
/************************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******************************/
//
//
#include <stdlib.h>
#include <stdio.h>
//
//Some elementary definitions
//
#define error(msg) { fprintf (stderr, "%s\n", msg); exit (1); }
#define max_frame_size 2000 /* 1/4 second frame, a reasonable max */
#define default_frame_size 80
typedef unsigned char uint8;
// Prototype for RGL_Decompress function used later (here instead
// of a header file for compile simplicitiy)
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 main (int argc, char *argv[])
{
char name_buffer [80];
char *rgl_input_file_name;
char output_file_name [80];
FILE *rgl_input_file, *output_file;
int i, number_read, number_written, mu_or_a;
int rgl_byte_count, remainder_bits, num_bits;
int frame_count = 0;
int rgl_bytes_processed = default_frame_size;
int number_of_samples = default_frame_size; /* init with default */
uint8 overhead_byte_1, n_codepoint, a_codepoint;
uint8 mu_or_al_output_frame[max_frame_size]; /*max size output array*/
uint8 rgl_input_frame[(max_frame_size+1)]; /* max rgl_input_frame */
/* can be one byte larger */
// get base file name
switch (argc) {
case 1:
printf(" \n Ramalho G.711 Lossless Decoding: mu-law or A-law \n");
printf(" version with first difference decoding. \n");
printf(" Copyright (c) 2002 Cisco Systems Inc. \n \n");
printf (" Enter input file to decompress (including extension): ");
fflush (stdout);
scanf ("%s", name_buffer);
rgl_input_file_name = name_buffer;
printf (" Enter the number of G711 samples per RGL frame in bytes: ");
fflush (stdout);
scanf ("%d", &number_of_samples);
break;
case 2:
rgl_input_file_name = argv [1];
number_of_samples = default_frame_size;
printf ("\n NOTE: Using default number_of_samples of 80 bytes \n\n");
break;
case 3:
rgl_input_file_name = argv [1];
number_of_samples = atoi(argv [2]);
if ((number_of_samples > max_frame_size)||(number_of_samples < 1)) {
error( " \n Error: the number of samples must be between 1 and 2000");
}
break;
default:
error (
"\n Error: rgl_decode presented with unexpectednumber of arguments");
break;
}
// make sure input file has a ".rlm" or ".rla" extension
i = 0;
while ((rgl_input_file_name[i]!=0)&&(rgl_input_file_name[++i]!='.' ))
i=i;
if ((rgl_input_file_name[++i] == 'r')
&& (rgl_input_file_name[++i] == 'l')
&& (rgl_input_file_name[++i] == 'm') ) {
mu_or_a = 1;
}
else if ((rgl_input_file_name[i--] == 'a')
&& (rgl_input_file_name[i--] == 'l')
&& (rgl_input_file_name[i] == 'r') ) {
mu_or_a = 0;
}
else error (
"\n Error: Input file name must have a \".rlm\" or \".rla\"extension"
);
// print space to console
(void) fprintf(stdout, "\n");
// create output file name and prepare files for reading and writing
i = 0;
while (rgl_input_file_name[i] && (rgl_input_file_name [i] != '.')) {
output_file_name [i] = rgl_input_file_name [i]; i++;
}
if (mu_or_a == 1) { /* create extension for mu-law output */
output_file_name[i++] = '.'; output_file_name[i++] = 'm';
output_file_name[i++] = 'u'; output_file_name[i++] = 'o';
output_file_name [i++] = 0;
}
else { /* create extension for A-law output */
output_file_name[i++] = '.'; output_file_name[i++] = 'a';
output_file_name[i++] = 'l'; output_file_name[i++] = 'o';
output_file_name [i++] = 0;
}
rgl_input_file = fopen (rgl_input_file_name, "rb");
if (rgl_input_file==NULL) error ("can't open input file for reading");
output_file = fopen (output_file_name, "wb");
if (output_file == NULL) error ("can't open output file for writing");
// write to console
(void) fprintf(stdout, "Processing file: %s \n", rgl_input_file_name);
// read first overhead byte to calculate the number of bytes in this
// RGL frame
//
// Note: We need this to determine the size of the array to send to
// the RGL_Decompress function. The RGL_Decompress function in a VoIP
// DSP would be passed the payload of the RTP IP packet. To emulate
// this, we must first find out how long the payload (in bytes) to
// read from the rgl_input_file. To determine how long the payload
// is, we must read the first overhead byte. Once the length is
// determined (by reading the first overhead byte) the remainder of
// the RGL frame is read (if any) and the whole RGL frame (including
// the first overhead byte) is passed to the RGL_Decompress function.
//
number_read = (int) fread (rgl_input_frame, sizeof(uint8), 1,
rgl_input_file);
if (number_read == 0) {
(void) fprintf(stdout,
"Problem reading rgl_input_file (overhead byte) on frame %d \n",
(frame_count +1));
error ("\n Fatal Error: Code 0");
}
// main processing loop
do {
// increment frame counter
frame_count++;
// write progress to console
(void) fprintf(stdout, "Processing frame %d \n", frame_count);
// get remaining bytes in RGL file needed for RGL-Decompress
n_codepoint = ( ( 0x07 & ( rgl_input_frame[0] >>5) ) );
a_codepoint = ( 0x1F & rgl_input_frame[0] );
if (a_codepoint == 30) {
if (n_codepoint == 0) num_bits = 8;
else {
(void) fprintf(stdout, "Illegal first overhead byte code \n");
error ("\n Fatal Error: Code 1");
}
}
else num_bits = n_codepoint;
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 full */
if (a_codepoint == 31) rgl_byte_count++; /*explicit codepoint present*/
rgl_byte_count++; /*Must include 1st overhead bytes in count */
if (rgl_byte_count > 1 ) { /* Get sample bytes if num_bits != 0 */
overhead_byte_1 = rgl_input_frame[0];
number_read = (int) fread (rgl_input_frame, sizeof(uint8),
(rgl_byte_count-1), rgl_input_file);
number_read++; /* already read the first overhead byte */
if (number_read != rgl_byte_count) {
(void) fprintf(stdout,
"Problem reading rgl_input_file (sample bytes) on frame %d \n",
frame_count );
(void) fprintf(stdout,
"Perhaps number_of_samples per RGL frame is incorrect!\n");
error ("\n Fatal Error: Code 2 ");
}
for(i = (rgl_byte_count-1); i>0 ; i--)
rgl_input_frame[i] = rgl_input_frame[(i- 1)];
rgl_input_frame[0] = overhead_byte_1; /* ready for RGL_Decompress */
} /* closing if (rgl_byte_coount > 1 ) above */
// Compress rgl_input_frame array (compressed array has length
// "rgl_bytes_processed")
rgl_bytes_processed = RGL_Decompress (mu_or_a,
&rgl_input_frame[0], number_of_samples,
&mu_or_al_output_frame[0], max_frame_size);
// RGL_Decompress returnes a negative "rgl_bytes_processed" when
// an error was encountered
if ( rgl_bytes_processed < 0 ){
if (rgl_bytes_processed == -1) { /* Illegal overhead byte case */
(void) fprintf(stdout, "\n \"RGL_Decompress\" error: Illegal\n");
(void) fprintf(stdout, "first overhead byte code passed. \n");
error ("\n Fatal Error: Code 3");
}
else if (rgl_bytes_processed == -2) { /* mu_or_a set incorrectly */
(void) fprintf(stdout, "\n \"RGL_Decompress\" error: Parameter\n");
(void) fprintf(stdout, "\"mu_or_a\" not set to zero or one. \n");
error ("\n Fatal Error: Code 4");
}
else if (rgl_bytes_processed == -3) { /* Most likely error */
(void) fprintf(stdout, "\n \"RGL_Decompress\" error: Number of\n");
(void) fprintf(stdout, "samples passed was incorrect. \n");
error ("\n Fatal Error: Code 5");
}
else { /* This shouldn't occur */
error ("\n Unspecified Fatal Error in RGL_Decompress: Code 9");
}
}
// If RGL_Decompress returned an unexpected number of
// "rgl_bytes_processed" - it is also an error
if ( rgl_bytes_processed != rgl_byte_count ){
(void) fprintf(stdout, "\n \"RGL_Decompress\" error: Unexpected \n");
(void) fprintf(stdout, " \"rgl_bytes_processed\" returned. \n");
error ("\n Fatal Error: Code 5");
}
// write G711 de-compressed data to output file
number_written = (int) fwrite (mu_or_al_output_frame, sizeof(uint8),
number_of_samples, output_file);
// read first overhead byte of next RGL frame of data
number_read = (int) fread (rgl_input_frame, sizeof(uint8), 1,
rgl_input_file);
} while (number_read !=0); /*closing "do while" statement way above*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -