Mercurial > hg > audiostuff
view intercom/gsm/rpedemo.c @ 4:26cd8f1ef0b1
import spandsp-0.0.6pre17
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 15:50:58 +0200 |
parents | 13be24d74cd2 |
children |
line wrap: on
line source
/* v1.1 - 22/Feb/1996 ============================================================================ RPEDEMO.C ~~~~~~~~~~ Description: ~~~~~~~~~~~~ Demonstration program for UGST/ITU-T RPE-LTP module. Takes the input file and processes by the GSM 06.10 Full Rate speech codec, depending on user's option: for encoding, input must be in either linear, A, mu law (G711); for decoding, in GSM 06.10 76-word format. The modules called have been written in Unix-C by Jutta Deneger and Carsten Borman, within the Communications and Operating Systems Research Group (KBS) of the Technishe Universitaet Berlin. This demo program has been written by Simao F.Campos Neto, from CPqD/Telebras based on previous UGST demo programs, as well on a driving program by the RPE-LTP program. Input data is supposed to be aligned at word boundaries, i.e., organized in 16-bit words, following the operating system normal organization (low-byte first for VMS and DOS; high byte first for most Unix systems). G711 compressed data is supposed to be in the 8 LEAST significant bits of the word and the RPE-LTP data will use a varied number of least significant bits. Both are without sign extension. Linear format, on its hand, expect data to be 16-bit aligned to the left, and the algorith will take only the 13 most significant bits. This complies to the general UGST integer data format. Output data will be generated in the same format as decribed above for the input data. Usage: ~~~~~~ $ rpedemo [-l|-u|-A] [-enc|-dec] InpFile OutFile BlockSize 1stBlock NoOfBlocks where: -l .......... input data for encoding and output data for decoding are in linear format (DEFAULT). -A .......... input data for encoding and output data for decoding are in A-law (G.711) format. -u .......... input data for encoding and output data for decoding are in u-law (G.711) format. -enc ........ run the only the decoder (default: run enc+dec) -dec ........ run the only the encoder (default: run enc+dec) InpFile ..... is the name of the file to be processed; OutFile ..... is the name with the processed data; BlockSize ... is the block size, in number of samples (default = 160) 1stBlock .... is the number of the first block of the input file to be processed; NoOfBlocks .. is the number of blocks to be processed, starting on block "1stBlock" Exit values: ~~~~~~~~~~~~ 0 success (all but VMS); 1 success (only in VMS); 2 error opening input file; 3 error creating output file; 4 error moving pointer to desired start of conversion; 5 error creating gsm object (i.e., state variable); 6 error reading input file; 7 error writing to file; Original authors: ~~~~~~~~~~~~~~~~~ Demo program: Simao Ferraz de Campos Neto EMail : simao@cpqd.ansp.br CPqD/Telebras Rd. Mogi Mirim-Campinas Km.118 DDS/Pr.11 13.088-061 - Campinas - SP (Brazil) Module routines: Jutta Degener (jutta@cs.tu-berlin.de) Carsten Bormann (cabo@cs.tu-berlin.de) History: ~~~~~~~~ 28/Oct/92 r.1.0 pl.0 by Carsten Bormann (cabo at kubus) Copyright 1992 by Jutta Degener and Carsten Bormann, Technische Universitaet Berlin. See the accompanying file "COPYRIGHT" for details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. 30/Oct/92 r.1.0 pl.1 by Jutta Degener (jutta at kraftbus) Switched uid/gid in toast's [f]chown calls. 29/Jan/93 r.1.0 pl.2 by Jutta Degener (jutta at kraftbus) fixed L_add(0,-1) in src/add.c and inc/private.h, thanks to Raphael Trommer at AT&T Bell Laboratories; * ANSI C compatibility details 20/Mar/94 v1.0 Release of 1st version of demo program 22/Feb/95 v1.1 Cleaned compilation warnings, modified for Alpha VMX/AXP operation (as suggested by Kirchherr, FI/DBP Telekom) <simao@ctd.comsat.com> ============================================================================ */ /* ..... General definitions for UGST demo programs ..... */ #include "ugstdemo.h" /* ..... General include ..... */ #include <stdio.h> #include <stdlib.h> #include <string.h> #if defined(VMS) #include <stat.h> #else /* Unix/DOS */ #include <sys/stat.h> #endif /* ..... RPE-LTP module definitions ..... */ #include "private.h" #include "gsm.h" #include "rpeltp.h" /* ..... G.711 module definitions ..... */ #include "g711.h" /* ..... Local definitions ..... */ #define LINEAR 0 /* binary: 00 */ #define U_LAW 1 /* binary: 01 */ #define A_LAW 3 /* binary: 11 */ /* ..... Local function prototypes ..... */ void display_usage ARGS((void)); int main ARGS((int argc, char *argv[])); /* ------------------------------------------------------------------------- void display_usage(void); ~~~~~~~~~~~~~~~~~~ Display proper usage for the demo program. Generated automatically from program documentation. History: ~~~~~~~~ 20.Mar.94 v1.0 Created. ------------------------------------------------------------------------- */ #define P(x) printf x void display_usage() { P(("RPEDEMO: Version 1.0 of 17/Mar/1994 \n\n")); P((" Demonstration program for UGST/ITU-T RPE-LTP based on \n")); P((" module implemented in Unix-C by Jutta Deneger and Carsten \n")); P((" Borman, within the Communications and Operating Systems \n")); P((" Research Group (KBS) of the Technishe Universitaet Berlin.\n")); P((" This demo program has been written by Simao F.Campos Neto\n")); P(("\n")); P((" Usage:\n")); P((" $ rpedemo [-l|-u|-A] [-enc|-dec] InpFile OutFile BlockSize 1stBlock\n")); P((" NoOfBlocks \n")); P((" where:\n")); P((" -l .......... input data for encoding and output data for decoding\n")); P((" are in linear format (DEFAULT).\n")); P((" -A .......... input data for encoding and output data for decoding\n")); P((" are in A-law (G.711) format.\n")); P((" -u .......... input data for encoding and output data for decoding\n")); P((" are in u-law (G.711) format.\n")); P((" -enc ........ run the only the decoder (default: run enc+dec)\n")); P((" -dec ........ run the only the encoder (default: run enc+dec)\n")); P(("\n")); P((" InpFile ..... is the name of the file to be processed;\n")); P((" OutFile ..... is the name with the processed data;\n")); P((" BlockSize ... is the block size, in number of samples (default = 160)\n")); P((" 1stBlock .... is the number of the first block of the input file\n")); P((" to be processed;\n")); P((" NoOfBlocks .. is the number of blocks to be processed, starting on\n")); P((" block \"1stBlock\"\n")); /* Quit program */ exit(-128); } #undef P /* ************************************************************************** *** *** *** Demo-Program for testing the correct implementation *** *** and to show how to use the programs *** *** *** ************************************************************************** */ main(argc, argv) int argc; char *argv[]; { gsm rpe_enc_state, rpe_dec_state; gsm_signal rpe_frame[RPE_FRAME_SIZE]; Byte gsm_frame[33]; long N = 256, N1 = 1, N2 = 0, cur_blk, smpno, count = 0; #ifdef STATIC_ALLOCATION short tmp_buf[256], inp_buf[256], out_buf[256]; #else short *tmp_buf, *inp_buf, *out_buf; #endif /* G.711 Compression/expansion function pointers */ void (*compress) (), (*expand) (); /* File variables */ char FileIn[80], FileOut[80]; FILE *Fi, *Fo; long start_byte; char format, run_encoder, run_decoder; #ifdef VMS char mrs[15]; #endif /* SETTING DEFAULT OPTIONS */ format = LINEAR; run_encoder = run_decoder = 1; /* GETTING OPTIONS */ if (argc < 2) display_usage(); else { while (argc > 1 && argv[1][0] == '-') if (strcmp(argv[1], "-") == 0) { /* Oops, stop processing options! */ break; } else if (strcmp(argv[1], "-l") == 0) { /* Input/output (uncoded) data format is linear */ format = LINEAR; /* Move arg[cv] over the next valid option */ argv++; argc--; } else if (strcmp(argv[1], "-A") == 0 || strcmp(argv[1], "-a") == 0) { /* Input/output (uncoded) data format is A-law (G.711) */ format = A_LAW; /* Move arg[cv] over the next valid option */ argv++; argc--; } else if (strcmp(argv[1], "-u") == 0) { /* Input/output (uncoded) data format is u-law (G.711) */ format = U_LAW; /* Move arg[cv] over the next valid option */ argv++; argc--; } else if (strcmp(argv[1], "-enc") == 0) { /* Run only the encoder */ run_encoder = 1; run_decoder = 0; /* Move arg[cv] over the next valid option */ argv++; argc--; } else if (strcmp(argv[1], "-dec") == 0) { /* Run only the encoder */ run_encoder = 0; run_decoder = 1; /* Move arg[cv] over the next valid option */ argv++; argc--; } else { fprintf(stderr, "ERROR! Invalid option \"%s\" in command line\n\n", argv[1]); display_usage(); } } GET_PAR_S(1, "_Input File: .................. ", FileIn); GET_PAR_S(2, "_Output File: ................. ", FileOut); FIND_PAR_L(3, "_Block Size: .................. ", N, RPE_WIND_SIZE); FIND_PAR_L(4, "_Starting Block: .............. ", N1, 1); FIND_PAR_L(5, "_No. of Blocks: ............... ", N2, 0); /* Find staring byte in file; all are 16-bit word-aligned =>short data type */ start_byte = sizeof(short) * (long) (--N1) * (long) N; /* Check if is to process the whole file */ if (N2 == 0) { struct stat st; /* ... find the input file size ... */ stat(FileIn, &st); /* convert to block count, depending on whether the input file * is a uncoded or coded file */ if (run_encoder) N2 = (st.st_size - start_byte) / (N * sizeof(short)); else N2 = (st.st_size - start_byte) / (33 * sizeof(Byte)); } /* Choose A/u law */ if (format == A_LAW) { expand = alaw_expand; compress = alaw_compress; } else if (format == U_LAW) { expand = ulaw_expand; compress = ulaw_compress; } /* * ...... MEMORY ALLOCATION ......... */ #ifndef STATIC_ALLOCATION if ((inp_buf = (short *) calloc(N, sizeof(short))) == NULL) HARAKIRI("Error in memory allocation!\n", 1); if ((out_buf = (short *) calloc(N, sizeof(short))) == NULL) HARAKIRI("Error in memory allocation!\n", 1); if ((tmp_buf = (short *) calloc(N, sizeof(short))) == NULL) HARAKIRI("Error in memory allocation!\n", 1); #endif /* * ......... FILE PREPARATION ......... */ /* Define stuff for VMS binary, fixed-record files */ #ifdef VMS sprintf(mrs, "mrs=%d", 512); #endif /* Opening input/output files; abort if there's any problem */ if ((Fi = fopen(FileIn, RB)) == NULL) KILL(FileIn, 2); if ((Fo = fopen(FileOut, WB)) == NULL) KILL(FileOut, 3); /* Move pointer to 1st block of interest */ if (fseek(Fi, start_byte, 0) < 0l) KILL(FileIn, 4); /* ......... CREATE AND INIT GSM OBJECT (STATE VARIABLE) ......... */ if (!(rpe_enc_state = rpeltp_init())) HARAKIRI("Error creating state variable for encoder\n", 5); if (!(rpe_dec_state = rpeltp_init())) HARAKIRI("Error creating state variable for encoder\n", 5); /* ......... PROCESSING ACCORDING TO GSM 06.10 RPE-LTP CODEC ......... */ for (cur_blk = 0; cur_blk < N2; cur_blk++) { /* Reset output sample vector */ memset(out_buf, (int) 0, N); /* Read a block of samples */ if (run_encoder) { /* Reset sample vector */ memset(inp_buf, (int) 0, N); /* Read a block of uncoded samples */ if ((smpno = fread(inp_buf, sizeof(short), (long) N, Fi)) <= 0) break; } else { /* Reset frame vector */ memset(rpe_frame, (int) 0, (long) RPE_FRAME_SIZE); /* Read a packed frame */ if ((smpno = fread(gsm_frame, sizeof(Byte), 33, Fi)) <= 0) { fprintf(stderr, "fread gsm_frame\n"); break; } } /* Carry out the desired operation */ /* CODEC OPERATION */ if (run_encoder && run_decoder) { /* Run both and save decoded samples */ /* First, expand samples, if needed */ if (format) { memcpy(tmp_buf, inp_buf, (long) (sizeof(short) * smpno)); expand(smpno, tmp_buf, inp_buf); } /* Encode & decode ... */ rpeltp_encode(rpe_enc_state, inp_buf, rpe_frame); rpeltp_decode(rpe_dec_state, rpe_frame, out_buf); /* Compress samples, if requested */ if (format) { memcpy(tmp_buf, out_buf, (long) (sizeof(short) * N)); compress(N, tmp_buf, out_buf); } /* Save samples to file */ if (!(smpno = fwrite(out_buf, sizeof(short), (long) smpno, Fo))) break; } /* ENCODER-ONLY OPERATION */ else if (run_encoder) { /* First, expand samples, if needed */ if (format) { memcpy(tmp_buf, inp_buf, (long) (sizeof(short) * smpno)); expand(smpno, tmp_buf, inp_buf); } /* Run only the encoder and save rpe-ltp frame */ gsm_encode(rpe_enc_state, inp_buf, gsm_frame); if (!(smpno = fwrite(gsm_frame, sizeof(Byte), 33, Fo))) break; } /* DECODER-ONLY OPERATION */ else { /* Decode frame */ gsm_decode(rpe_dec_state, gsm_frame, out_buf); /* Compress samples, if requested */ if (format) { memcpy(tmp_buf, out_buf, (long) (sizeof(short) * N)); compress(N, tmp_buf, out_buf); } /* Save the decoded samples */ if (!(smpno = fwrite(out_buf, sizeof(short), (long) N, Fo))) break; } count += smpno; } /* Check for errors */ if (ferror(Fi)) KILL(FileIn, 6); else if (ferror(Fo)) KILL(FileOut, 7); /* ......... FINALIZATIONS ......... */ /* Close input and output files and state */ fclose(Fi); fclose(Fo); rpeltp_delete(rpe_enc_state); rpeltp_delete(rpe_dec_state); /* Exit with success for non-vms systems */ #ifndef VMS return (0); #endif } /* ............................. end of main() ............................. */