Mercurial > hg > audiostuff
view intercom/g711/g711demo.c @ 6:22a74b01a099 default tip
implement more meaningful test program
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 16:14:50 +0200 |
parents | 13be24d74cd2 |
children |
line wrap: on
line source
/* 11.Apr.2000 v3.2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ G711DEMO.C Description: ~~~~~~~~~~~~ Example-program for converting from linear samples to A/u law log compression and vice-versa, according to ITU-T Rec.G711. Usage: ~~~~~~ $ g711demo [-?] [-r] [-skip skip] Law Transf InpFile OutFile [BlockSize [1stBlock [NoOfBlocks]]] where: Law is the law desired (either A or u) Transf is the desired convertion on the input file: [lili], linear to linear: lin -> (A/u)log -> lin [lilo], linear to (A/u)-log [loli], (A/u) log to linear InpFile is the name of the file to be processed; OutFile is the name with the compressed/expanded data; BlockSize is the block size, in number of samples (16 -bit words) (default is 256); 1stBlock is the number of the first block of the input file to be processed. (Default: 1) NoOfBlocks is the number of blocks to be processed, starting on block "1stBlock". (default is til end-of-file) Options: -? display usage and quit. -r disables even-bit swap by A-law encoding and decoding. By default, even bits of the A-law samples ARE inverted by alaw_compress() at return time, as well as by alaw_expand() at its beginning. With the option "-r", the log samples have NOT their even bits inverted before being saved to disk NOR after read from a file. -skip is the number of samples to skip before the beginning of the 1st block. Example: $ G711 u lili voice.ref voice.rel 256 3 45 The command above takes the samples in file "voice.ref" and converts them to A-law and back to linear, saving them into file "voice.rel", starting at block 3 for 45 blocks, each block being 256 samples wide. Variables: ~~~~~~~~~~ law law to use (either A or u) conv desired processing inpfil input file name; outfil output file name; N block size; N1 first block to filter; N2 no. of blocks to filter; Compilation of Demo Program: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The test program allows to process binary/ILS files of any size by loading segments of data from/to file. The size of the working segment must be entered. VAX/VMS: $ CC G711 $ link G711 $ G711 :== $G711_Disk:[G711_Dir]G711 $ G711 u lili ifile ofile 233 3 47 This command line invokes the u-law utility, converts from linear over ulaw to linear. It processes the input file "ifile" by loading segments of 233 samples and writes the result to "ofile", from the 3rd segment, for 47 segments. Turbo-C, Turbo-C++: > tcc G711 > G711 a lilo ifile ofile 39 1 This command line invokes the a-law utility, converts from linear to a-law. It processes the input file "ifile" by loading segments of 39 samples and writes the result (alaw-samples) to "ofile", starting from the beginning of the file. It will ask the number of segments. HighC (MetaWare, version R2.32): > hc386 G711.c > Run386 G711 a loli ifile ofile 3333 This command line invokes the a-law utility, converts from a-law to linear It processes the input file "ifile" (alaw-samples) by loading segments of 3333 samples and writes the result (linear samples) to "ofile". It will ask the starting segment and the number of segments. SunC (SunOS - BSD Unix) # cc -o g711demo g711demo.c # g711demo a lilo ifile ofile 256 1 132 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 reading input file; 6 error writing to file; 7 invalid law 8 invalid conversion 10 error allocating memory Prototypes: ~~~~~~~~~~~ Needs ugstdemo.h and includes g711.h. Authors: ~~~~~~~~ Simao Ferraz de Campos Neto Rudolf Hofmann CPqD/Telebras PHILIPS KOMMUNIKATIONS INDUSTRIE AG DDS/Pr.11 Kommunikationssysteme Rd. Mogi Mirim-Campinas Km.118 Thurn-und-Taxis-Strasse 14 13.080-061 - Campinas - SP (Brazil) D-8500 Nuernberg 10 (Germany) Phone : +55-192-39-6637 Phone : +49-911-526-2603 FAX : +55-192-39-2179 FAX : +49-911-526-3385 EMail : tdsimao@cpqd.ansp.br EMail : hf@pkinbg.uucp History: ~~~~~~~~ 07.Feb.1991 v1.0 Release of 1st demo program for G711 module (CPqD). 10.Dec.1991 v2.0 Demo program incorporated in G711 module and rebuild by PKI. 08.Feb.1992 v2.1 Demo separated from module file; ILS header manipulation removed; low level I/O; changes to assure compatibility with Unix (SunOS). 14.Apr.1993 v3.0 Inclusion of display_usage() and of option "-r" <tdsimao@venus.cpqd.ansp.br> 22.Feb.1996 v3.1 Removed compilation warnings, included headers as suggested by Kirchherr (FI/DBP Telekom) to run under OpenVMS/AXP <simao@ctd.comsat.com> 11.Apr.2000 v3.2 Corrected bug that made incorrect calculation on total number of blocks to process when the block size is not a multiple of the file size. <simao.campos@labs.comsat.com> 13jan2005 Byte for compressed data ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #include "ugstdemo.h" /* UGST defines for demo programs */ /* Include general headers */ #include <stdio.h> /* UNIX Standard I/O Definitions */ #include <ctype.h> /* Character Type Classification */ #include <string.h> /* String handling functions */ #include <stdlib.h> /* General utility definitions */ #include <math.h> /* Include OS dependent headers */ #if defined(VMS) #include <stat.h> #else /* Others */ #include <sys/stat.h> #endif /* G711 module functions */ #include "g711.h" /* -------------------------------------------------------------------------- void display_usage() Displays usage of the program. Upon completion, aborts the program. Created by <tdsimao@cpqd.ansp.br>, 14.Apr.93 -------------------------------------------------------------------------- */ #define FP(x) fprintf(stderr, x) void display_usage() { FP("\n G711DEMO.C --- Version v3.2 of 11.Apr.2000 \n"); FP("\n"); FP(" Description:\n"); FP(" ~~~~~~~~~~~~\n"); FP(" Example-program for converting from linear samples to A/u law log\n"); FP(" compression and vice-versa, according to ITU-T Rec.G711.\n"); FP("\n"); FP(" Usage:\n"); FP(" ~~~~~~\n"); FP(" $ G711 [-r] Law Transf InpFile OutFile BlkSize 1stBlock NoOfBlocks\n"); FP("\n"); FP(" where:\n"); FP(" Law is the law desired (either A or u)\n"); FP(" Transf is the desired convertion on the input file:\n"); FP(" [lili], linear to linear: lin -> (A/u)log -> lin\n"); FP(" [lilo], linear to (A/u)-log\n"); FP(" [loli], (A/u) log to linear\n"); FP(" InpFile is the name of the file to be processed;\n"); FP(" OutFile is the name with the compressed/expanded data;\n"); FP(" BlkSize is number of samples per block [256];\n"); FP(" 1stBlock is the number of the first block of the input file\n"); FP(" to be processed [1].\n"); FP(" NoOfBlocks is the number of blocks to be processed, starting on\n"); FP(" block `1stBlock'. Default is til end-of-file.\n"); FP("\n"); FP(" Options:\n"); FP(" -? displays this message.\n"); FP(" -r disables even-bit swap by A-law encoding and decoding.\n"); FP(" -skip is the number of samples to skip.\n"); FP("\n"); /* Quit program */ exit(1); } #undef FP /* ..................... End of display_usage() .......................... */ /* ************************************************************************** *** *** *** Demo-Program for testing the correct implementation *** *** and to show how to use the programs *** *** *** ************************************************************************** */ int main(argc, argv) int argc; char *argv[]; { long i, N, N1, N2, smpno, tot_smpno, cur_blk; short *lin_buff; /* linear input samples */ Byte *log_buff; /* compressed data */ short *lon_buff; /* quantized output samples */ char inpfil[127], outfil[127]; FILE *Fi, *Fo; int inp, out; char law[4], lilo[8]; short inp_type, out_type; char revert_even_bits = 1; clock_t t1, t2; /* aux. for CPU-time measurement */ #ifdef VMS char mrs[15]; /* for correct mrs in VMS environment */ #endif long start_byte, skip = 0; /* * GETTING PARAMETERS */ /* Get options */ if (argc < 2) display_usage(); else { while (argc > 1 && argv[1][0] == '-') if (argv[1][1] == 'r') { /* Disable revertion of even bits */ revert_even_bits = 0; /* Move argv over the option to the 1st mandatory argument */ argv++; /* Update argc */ argc--; } else if (strcmp(argv[1], "-skip") == 0) { /* Get skip length */ skip = atol(argv[2]); /* Check bounds */ if (skip < 0) { fprintf(stderr, "Skip has to be > 0!\n"); exit(10); } /* Move argv over the option to the next argument */ argv += 2; /* Update argc */ argc -= 2; } else if (argv[1][1] == '?') { /* Display intructions */ display_usage(); } else { fprintf(stderr, "ERROR! Invalid option \"%s\" in command line\n\n", argv[1]); display_usage(); } } /* Get parameters */ GET_PAR_S(1, "_Law (A, u): ................. ", law); GET_PAR_S(2, "_Transf (lili,lilo,loli): .... ", lilo); GET_PAR_S(3, "_File to be converted: ....... ", inpfil); GET_PAR_S(4, "_Output File: ................ ", outfil); FIND_PAR_L(5, "_Block Length: ............... ", N, 256); FIND_PAR_L(6, "_Start Block: ................ ", N1, 1); FIND_PAR_L(7, "_No. of Blocks: .............. ", N2, 0); /* ......... SOME INITIALIZATIONS ......... */ --N1; /* Classification of the conversion desired */ inp_type = toupper(lilo[1]) == 'O' ? IS_LOG : IS_LIN; out_type = toupper(lilo[3]) == 'O' ? IS_LOG : IS_LIN; if ((out_type == IS_LOG) && (inp_type == IS_LOG)) HARAKIRI("log. to log. makes no sense! Aborted...\n", 8); /* Classification of law */ law[0] = toupper(law[0]); if ((law[0] != (char) 'A') && (law[0] != (char) 'U')) HARAKIRI(" Invalid law!\n", 7); /* .......... ALLOCATION OF BUFFERS .......... */ if ((lin_buff = (short *) calloc(N, sizeof(short))) == NULL) HARAKIRI("Can't allocate memory for input buffer\n", 10); if ((log_buff = (Byte *) calloc(N, sizeof(Byte))) == NULL) HARAKIRI("Can't allocate memory for output buffer\n", 10); if ((lon_buff = (short *) calloc(N, sizeof(short))) == NULL) HARAKIRI("Can't allocate memory for temporary buffer\n", 10); /* .......... FILE OPERATIONS .......... */ #ifdef VMS sprintf(mrs, "mrs=%d", 2 * N); #endif /* Open input file */ if ((Fi = fopen(inpfil, RB)) == NULL) KILL(inpfil, 2); inp = fileno(Fi); /* Open (create) output file */ if ((Fo = fopen(outfil, WB)) == NULL) KILL(outfil, 3); out = fileno(Fo); /* Define starting byte in file */ start_byte = (N1 * N + skip) * sizeof(short); /* ... and move file's pointer to 1st desired block */ if (fseek(Fi, (N1 * N + skip) * sizeof(short), 0) < 0l) KILL(inpfil, 4); /* Check whether is to process til end-of-file */ if (N2 == 0) { struct stat st; /* ... hey, need to skip the delayed samples! ... */ stat(inpfil, &st); N2 = ceil((st.st_size - start_byte) / (double) (N * sizeof(short))); } /* * ......... COMPRESSION/EXPANSION ......... */ t1 = clock(); /* measure CPU-time */ tot_smpno = 0; switch (law[0]) { /* ......... Process A-law rule ......... */ case 'A': /* Input: LINEAR | Output: LOG */ if (inp_type == IS_LIN && out_type == IS_LOG) for (tot_smpno = cur_blk = 0; cur_blk < N2; cur_blk++, tot_smpno += smpno) { if ((smpno = fread(lin_buff, sizeof(short), N, Fi)) < 0) KILL(inpfil, 5); alaw_compress(smpno, lin_buff, log_buff); if (!revert_even_bits) for (i = 0; i < smpno; i++) log_buff[i] ^= 0x0055; if ((smpno = fwrite(log_buff, sizeof(Byte), smpno, Fo)) < 0) KILL(outfil, 6); } /* Input: LINEAR | Output: LINEAR */ else if (inp_type == IS_LIN && out_type == IS_LIN) for (tot_smpno = cur_blk = 0; cur_blk < N2; cur_blk++, tot_smpno += smpno) { if ((smpno = fread(lin_buff, sizeof(short), N, Fi)) < 0) KILL(inpfil, 5); alaw_compress(smpno, lin_buff, log_buff); alaw_expand(smpno, log_buff, lon_buff); if ((smpno = fwrite(lon_buff, sizeof(short), smpno, Fo)) < 0) KILL(outfil, 6); } /* Input: LOG | Output: LINEAR */ else if (inp_type == IS_LOG) for (tot_smpno = cur_blk = 0; cur_blk < N2; cur_blk++, tot_smpno += smpno) { if ((smpno = fread(log_buff, sizeof(Byte), N, Fi)) < 0) KILL(inpfil, 5); if (!revert_even_bits) for (i = 0; i < smpno; i++) log_buff[i] ^= 0x0055; alaw_expand(smpno, log_buff, lon_buff); if ((smpno = fwrite(lon_buff, sizeof(short), smpno, Fo)) < 0) KILL(outfil, 6); } break; /* ......... Process u-law rule ......... */ case 'U': /* Input: LINEAR | Output: LOG */ if (inp_type == IS_LIN && out_type == IS_LOG) for (tot_smpno = cur_blk = 0; cur_blk < N2; cur_blk++, tot_smpno += smpno) { smpno = fread(lin_buff, sizeof(short), N, Fi); ulaw_compress(smpno, lin_buff, log_buff); smpno = fwrite(log_buff, sizeof(Byte), smpno, Fo); } /* Input: LINEAR | Output: LINEAR */ else if (inp_type == IS_LIN && out_type == IS_LIN) for (tot_smpno = cur_blk = 0; cur_blk < N2; cur_blk++, tot_smpno += smpno) { smpno = fread(lin_buff, sizeof(short), N, Fi); ulaw_compress(smpno, lin_buff, log_buff); ulaw_expand(smpno, log_buff, lon_buff); smpno = fwrite(lon_buff, sizeof(short), smpno, Fo); } /* Input: LOG | Output: LINEAR */ else if (inp_type == IS_LOG) for (tot_smpno = cur_blk = 0; cur_blk < N2; cur_blk++, tot_smpno += smpno) { smpno = fread(log_buff, sizeof(Byte), N, Fi); ulaw_expand(smpno, log_buff, lon_buff); smpno = fwrite(lon_buff, sizeof(short), smpno, Fo); } break; } /* ......... FINALIZATIONS ......... */ t2 = clock(); printf("Speed: %f sec CPU-time for %ld processed samples\n", (t2 - t1) / (double) CLOCKS_PER_SEC, tot_smpno); fclose(Fi); fclose(Fo); #ifndef VMS return (0); #endif }