Mercurial > hg > audiostuff
comparison intercom/g711/g711demo.c @ 2:13be24d74cd2
import intercom-0.4.1
| author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
|---|---|
| date | Fri, 25 Jun 2010 09:57:52 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:9cadc470e3da | 2:13be24d74cd2 |
|---|---|
| 1 /* 11.Apr.2000 v3.2 | |
| 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 3 | |
| 4 G711DEMO.C | |
| 5 | |
| 6 Description: | |
| 7 ~~~~~~~~~~~~ | |
| 8 Example-program for converting from linear samples to A/u law log | |
| 9 compression and vice-versa, according to ITU-T Rec.G711. | |
| 10 | |
| 11 Usage: | |
| 12 ~~~~~~ | |
| 13 $ g711demo [-?] [-r] [-skip skip] Law Transf InpFile OutFile | |
| 14 [BlockSize [1stBlock [NoOfBlocks]]] | |
| 15 | |
| 16 where: | |
| 17 Law is the law desired (either A or u) | |
| 18 Transf is the desired convertion on the input file: | |
| 19 [lili], linear to linear: lin -> (A/u)log -> lin | |
| 20 [lilo], linear to (A/u)-log | |
| 21 [loli], (A/u) log to linear | |
| 22 InpFile is the name of the file to be processed; | |
| 23 OutFile is the name with the compressed/expanded data; | |
| 24 BlockSize is the block size, in number of samples (16 -bit words) | |
| 25 (default is 256); | |
| 26 1stBlock is the number of the first block of the input file | |
| 27 to be processed. (Default: 1) | |
| 28 NoOfBlocks is the number of blocks to be processed, starting on | |
| 29 block "1stBlock". (default is til end-of-file) | |
| 30 | |
| 31 Options: | |
| 32 -? display usage and quit. | |
| 33 -r disables even-bit swap by A-law encoding and decoding. | |
| 34 By default, even bits of the A-law samples ARE inverted | |
| 35 by alaw_compress() at return time, as well as by | |
| 36 alaw_expand() at its beginning. With the option | |
| 37 "-r", the log samples have NOT their even bits | |
| 38 inverted before being saved to disk NOR after | |
| 39 read from a file. | |
| 40 -skip is the number of samples to skip before the beginning | |
| 41 of the 1st block. | |
| 42 | |
| 43 Example: | |
| 44 $ G711 u lili voice.ref voice.rel 256 3 45 | |
| 45 | |
| 46 The command above takes the samples in file "voice.ref" and converts | |
| 47 them to A-law and back to linear, saving them into file "voice.rel", | |
| 48 starting at block 3 for 45 blocks, each block being 256 samples wide. | |
| 49 | |
| 50 Variables: | |
| 51 ~~~~~~~~~~ | |
| 52 law law to use (either A or u) | |
| 53 conv desired processing | |
| 54 inpfil input file name; | |
| 55 outfil output file name; | |
| 56 N block size; | |
| 57 N1 first block to filter; | |
| 58 N2 no. of blocks to filter; | |
| 59 | |
| 60 Compilation of Demo Program: | |
| 61 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 62 | |
| 63 The test program allows to process binary/ILS files of any size by | |
| 64 loading segments of data from/to file. The size of the working | |
| 65 segment must be entered. | |
| 66 | |
| 67 VAX/VMS: | |
| 68 $ CC G711 | |
| 69 $ link G711 | |
| 70 $ G711 :== $G711_Disk:[G711_Dir]G711 | |
| 71 $ G711 u lili ifile ofile 233 3 47 | |
| 72 | |
| 73 This command line invokes the u-law utility, converts from linear | |
| 74 over ulaw to linear. It processes the input file "ifile" by | |
| 75 loading segments of 233 samples and writes the result to "ofile", | |
| 76 from the 3rd segment, for 47 segments. | |
| 77 | |
| 78 Turbo-C, Turbo-C++: | |
| 79 > tcc G711 | |
| 80 > G711 a lilo ifile ofile 39 1 | |
| 81 | |
| 82 This command line invokes the a-law utility, converts from linear | |
| 83 to a-law. It processes the input file "ifile" by loading | |
| 84 segments of 39 samples and writes the result (alaw-samples) to | |
| 85 "ofile", starting from the beginning of the file. It will ask | |
| 86 the number of segments. | |
| 87 | |
| 88 HighC (MetaWare, version R2.32): | |
| 89 > hc386 G711.c | |
| 90 > Run386 G711 a loli ifile ofile 3333 | |
| 91 | |
| 92 This command line invokes the a-law utility, converts from a-law | |
| 93 to linear It processes the input file "ifile" (alaw-samples) by | |
| 94 loading segments of 3333 samples and writes the result (linear | |
| 95 samples) to "ofile". It will ask the starting segment and the | |
| 96 number of segments. | |
| 97 | |
| 98 SunC (SunOS - BSD Unix) | |
| 99 # cc -o g711demo g711demo.c | |
| 100 # g711demo a lilo ifile ofile 256 1 132 | |
| 101 | |
| 102 Exit values: | |
| 103 ~~~~~~~~~~~~ | |
| 104 0 success (all but VMS); | |
| 105 1 success (only in VMS); | |
| 106 2 error opening input file; | |
| 107 3 error creating output file; | |
| 108 4 error moving pointer to desired start of conversion; | |
| 109 5 error reading input file; | |
| 110 6 error writing to file; | |
| 111 7 invalid law | |
| 112 8 invalid conversion | |
| 113 10 error allocating memory | |
| 114 | |
| 115 Prototypes: | |
| 116 ~~~~~~~~~~~ | |
| 117 Needs ugstdemo.h and includes g711.h. | |
| 118 | |
| 119 Authors: | |
| 120 ~~~~~~~~ | |
| 121 Simao Ferraz de Campos Neto Rudolf Hofmann | |
| 122 CPqD/Telebras PHILIPS KOMMUNIKATIONS INDUSTRIE AG | |
| 123 DDS/Pr.11 Kommunikationssysteme | |
| 124 Rd. Mogi Mirim-Campinas Km.118 Thurn-und-Taxis-Strasse 14 | |
| 125 13.080-061 - Campinas - SP (Brazil) D-8500 Nuernberg 10 (Germany) | |
| 126 | |
| 127 Phone : +55-192-39-6637 Phone : +49-911-526-2603 | |
| 128 FAX : +55-192-39-2179 FAX : +49-911-526-3385 | |
| 129 EMail : tdsimao@cpqd.ansp.br EMail : hf@pkinbg.uucp | |
| 130 | |
| 131 History: | |
| 132 ~~~~~~~~ | |
| 133 07.Feb.1991 v1.0 Release of 1st demo program for G711 module (CPqD). | |
| 134 10.Dec.1991 v2.0 Demo program incorporated in G711 module and | |
| 135 rebuild by PKI. | |
| 136 08.Feb.1992 v2.1 Demo separated from module file; ILS header | |
| 137 manipulation removed; low level I/O; changes to | |
| 138 assure compatibility with Unix (SunOS). | |
| 139 14.Apr.1993 v3.0 Inclusion of display_usage() and of option "-r" | |
| 140 <tdsimao@venus.cpqd.ansp.br> | |
| 141 22.Feb.1996 v3.1 Removed compilation warnings, included headers as | |
| 142 suggested by Kirchherr (FI/DBP Telekom) to run under | |
| 143 OpenVMS/AXP <simao@ctd.comsat.com> | |
| 144 11.Apr.2000 v3.2 Corrected bug that made incorrect calculation on | |
| 145 total number of blocks to process when the block | |
| 146 size is not a multiple of the file | |
| 147 size. <simao.campos@labs.comsat.com> | |
| 148 13jan2005 Byte for compressed data | |
| 149 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ | |
| 150 #include "ugstdemo.h" /* UGST defines for demo programs */ | |
| 151 | |
| 152 /* Include general headers */ | |
| 153 #include <stdio.h> /* UNIX Standard I/O Definitions */ | |
| 154 #include <ctype.h> /* Character Type Classification */ | |
| 155 #include <string.h> /* String handling functions */ | |
| 156 #include <stdlib.h> /* General utility definitions */ | |
| 157 #include <math.h> | |
| 158 | |
| 159 /* Include OS dependent headers */ | |
| 160 #if defined(VMS) | |
| 161 #include <stat.h> | |
| 162 #else /* Others */ | |
| 163 #include <sys/stat.h> | |
| 164 #endif | |
| 165 | |
| 166 | |
| 167 /* G711 module functions */ | |
| 168 #include "g711.h" | |
| 169 | |
| 170 | |
| 171 /* | |
| 172 -------------------------------------------------------------------------- | |
| 173 void display_usage() | |
| 174 | |
| 175 Displays usage of the program. Upon completion, aborts the program. | |
| 176 | |
| 177 Created by <tdsimao@cpqd.ansp.br>, 14.Apr.93 | |
| 178 | |
| 179 -------------------------------------------------------------------------- | |
| 180 */ | |
| 181 #define FP(x) fprintf(stderr, x) | |
| 182 void display_usage() | |
| 183 { | |
| 184 FP("\n G711DEMO.C --- Version v3.2 of 11.Apr.2000 \n"); | |
| 185 FP("\n"); | |
| 186 FP(" Description:\n"); | |
| 187 FP(" ~~~~~~~~~~~~\n"); | |
| 188 FP(" Example-program for converting from linear samples to A/u law log\n"); | |
| 189 FP(" compression and vice-versa, according to ITU-T Rec.G711.\n"); | |
| 190 FP("\n"); | |
| 191 FP(" Usage:\n"); | |
| 192 FP(" ~~~~~~\n"); | |
| 193 FP(" $ G711 [-r] Law Transf InpFile OutFile BlkSize 1stBlock NoOfBlocks\n"); | |
| 194 FP("\n"); | |
| 195 FP(" where:\n"); | |
| 196 FP(" Law is the law desired (either A or u)\n"); | |
| 197 FP(" Transf is the desired convertion on the input file:\n"); | |
| 198 FP(" [lili], linear to linear: lin -> (A/u)log -> lin\n"); | |
| 199 FP(" [lilo], linear to (A/u)-log\n"); | |
| 200 FP(" [loli], (A/u) log to linear\n"); | |
| 201 FP(" InpFile is the name of the file to be processed;\n"); | |
| 202 FP(" OutFile is the name with the compressed/expanded data;\n"); | |
| 203 FP(" BlkSize is number of samples per block [256];\n"); | |
| 204 FP(" 1stBlock is the number of the first block of the input file\n"); | |
| 205 FP(" to be processed [1].\n"); | |
| 206 FP(" NoOfBlocks is the number of blocks to be processed, starting on\n"); | |
| 207 FP(" block `1stBlock'. Default is til end-of-file.\n"); | |
| 208 FP("\n"); | |
| 209 FP(" Options:\n"); | |
| 210 FP(" -? displays this message.\n"); | |
| 211 FP(" -r disables even-bit swap by A-law encoding and decoding.\n"); | |
| 212 FP(" -skip is the number of samples to skip.\n"); | |
| 213 FP("\n"); | |
| 214 | |
| 215 /* Quit program */ | |
| 216 exit(1); | |
| 217 } | |
| 218 | |
| 219 #undef FP | |
| 220 /* ..................... End of display_usage() .......................... */ | |
| 221 | |
| 222 | |
| 223 /* | |
| 224 ************************************************************************** | |
| 225 *** *** | |
| 226 *** Demo-Program for testing the correct implementation *** | |
| 227 *** and to show how to use the programs *** | |
| 228 *** *** | |
| 229 ************************************************************************** | |
| 230 */ | |
| 231 int main(argc, argv) | |
| 232 int argc; | |
| 233 char *argv[]; | |
| 234 { | |
| 235 long i, N, N1, N2, smpno, tot_smpno, cur_blk; | |
| 236 short *lin_buff; /* linear input samples */ | |
| 237 Byte *log_buff; /* compressed data */ | |
| 238 short *lon_buff; /* quantized output samples */ | |
| 239 char inpfil[127], outfil[127]; | |
| 240 FILE *Fi, *Fo; | |
| 241 int inp, out; | |
| 242 char law[4], lilo[8]; | |
| 243 short inp_type, out_type; | |
| 244 char revert_even_bits = 1; | |
| 245 clock_t t1, t2; /* aux. for CPU-time measurement */ | |
| 246 #ifdef VMS | |
| 247 char mrs[15]; /* for correct mrs in VMS environment */ | |
| 248 #endif | |
| 249 long start_byte, skip = 0; | |
| 250 | |
| 251 /* | |
| 252 * GETTING PARAMETERS | |
| 253 */ | |
| 254 /* Get options */ | |
| 255 if (argc < 2) | |
| 256 display_usage(); | |
| 257 else { | |
| 258 while (argc > 1 && argv[1][0] == '-') | |
| 259 if (argv[1][1] == 'r') { | |
| 260 /* Disable revertion of even bits */ | |
| 261 revert_even_bits = 0; | |
| 262 | |
| 263 /* Move argv over the option to the 1st mandatory argument */ | |
| 264 argv++; | |
| 265 | |
| 266 /* Update argc */ | |
| 267 argc--; | |
| 268 } else if (strcmp(argv[1], "-skip") == 0) { | |
| 269 /* Get skip length */ | |
| 270 skip = atol(argv[2]); | |
| 271 | |
| 272 /* Check bounds */ | |
| 273 if (skip < 0) { | |
| 274 fprintf(stderr, "Skip has to be > 0!\n"); | |
| 275 exit(10); | |
| 276 } | |
| 277 | |
| 278 /* Move argv over the option to the next argument */ | |
| 279 argv += 2; | |
| 280 | |
| 281 /* Update argc */ | |
| 282 argc -= 2; | |
| 283 } else if (argv[1][1] == '?') { | |
| 284 /* Display intructions */ | |
| 285 display_usage(); | |
| 286 } else { | |
| 287 fprintf(stderr, | |
| 288 "ERROR! Invalid option \"%s\" in command line\n\n", argv[1]); | |
| 289 display_usage(); | |
| 290 } | |
| 291 } | |
| 292 | |
| 293 | |
| 294 /* Get parameters */ | |
| 295 GET_PAR_S(1, "_Law (A, u): ................. ", law); | |
| 296 GET_PAR_S(2, "_Transf (lili,lilo,loli): .... ", lilo); | |
| 297 GET_PAR_S(3, "_File to be converted: ....... ", inpfil); | |
| 298 GET_PAR_S(4, "_Output File: ................ ", outfil); | |
| 299 FIND_PAR_L(5, "_Block Length: ............... ", N, 256); | |
| 300 FIND_PAR_L(6, "_Start Block: ................ ", N1, 1); | |
| 301 FIND_PAR_L(7, "_No. of Blocks: .............. ", N2, 0); | |
| 302 | |
| 303 | |
| 304 /* ......... SOME INITIALIZATIONS ......... */ | |
| 305 --N1; | |
| 306 | |
| 307 /* Classification of the conversion desired */ | |
| 308 inp_type = toupper(lilo[1]) == 'O' ? IS_LOG : IS_LIN; | |
| 309 out_type = toupper(lilo[3]) == 'O' ? IS_LOG : IS_LIN; | |
| 310 if ((out_type == IS_LOG) && (inp_type == IS_LOG)) | |
| 311 HARAKIRI("log. to log. makes no sense! Aborted...\n", 8); | |
| 312 | |
| 313 /* Classification of law */ | |
| 314 law[0] = toupper(law[0]); | |
| 315 if ((law[0] != (char) 'A') && (law[0] != (char) 'U')) | |
| 316 HARAKIRI(" Invalid law!\n", 7); | |
| 317 | |
| 318 /* .......... ALLOCATION OF BUFFERS .......... */ | |
| 319 | |
| 320 if ((lin_buff = (short *) calloc(N, sizeof(short))) == NULL) | |
| 321 HARAKIRI("Can't allocate memory for input buffer\n", 10); | |
| 322 | |
| 323 if ((log_buff = (Byte *) calloc(N, sizeof(Byte))) == NULL) | |
| 324 HARAKIRI("Can't allocate memory for output buffer\n", 10); | |
| 325 | |
| 326 if ((lon_buff = (short *) calloc(N, sizeof(short))) == NULL) | |
| 327 HARAKIRI("Can't allocate memory for temporary buffer\n", 10); | |
| 328 | |
| 329 | |
| 330 /* .......... FILE OPERATIONS .......... */ | |
| 331 | |
| 332 #ifdef VMS | |
| 333 sprintf(mrs, "mrs=%d", 2 * N); | |
| 334 #endif | |
| 335 | |
| 336 /* Open input file */ | |
| 337 if ((Fi = fopen(inpfil, RB)) == NULL) | |
| 338 KILL(inpfil, 2); | |
| 339 inp = fileno(Fi); | |
| 340 | |
| 341 /* Open (create) output file */ | |
| 342 if ((Fo = fopen(outfil, WB)) == NULL) | |
| 343 KILL(outfil, 3); | |
| 344 out = fileno(Fo); | |
| 345 | |
| 346 /* Define starting byte in file */ | |
| 347 start_byte = (N1 * N + skip) * sizeof(short); | |
| 348 | |
| 349 /* ... and move file's pointer to 1st desired block */ | |
| 350 if (fseek(Fi, (N1 * N + skip) * sizeof(short), 0) < 0l) | |
| 351 KILL(inpfil, 4); | |
| 352 | |
| 353 /* Check whether is to process til end-of-file */ | |
| 354 if (N2 == 0) { | |
| 355 struct stat st; | |
| 356 /* ... hey, need to skip the delayed samples! ... */ | |
| 357 stat(inpfil, &st); | |
| 358 N2 = ceil((st.st_size - start_byte) / (double) (N * sizeof(short))); | |
| 359 } | |
| 360 | |
| 361 | |
| 362 /* | |
| 363 * ......... COMPRESSION/EXPANSION ......... | |
| 364 */ | |
| 365 t1 = clock(); /* measure CPU-time */ | |
| 366 tot_smpno = 0; | |
| 367 | |
| 368 switch (law[0]) { | |
| 369 /* ......... Process A-law rule ......... */ | |
| 370 case 'A': | |
| 371 | |
| 372 /* Input: LINEAR | Output: LOG */ | |
| 373 if (inp_type == IS_LIN && out_type == IS_LOG) | |
| 374 for (tot_smpno = cur_blk = 0; cur_blk < N2; | |
| 375 cur_blk++, tot_smpno += smpno) { | |
| 376 if ((smpno = fread(lin_buff, sizeof(short), N, Fi)) < 0) | |
| 377 KILL(inpfil, 5); | |
| 378 alaw_compress(smpno, lin_buff, log_buff); | |
| 379 if (!revert_even_bits) | |
| 380 for (i = 0; i < smpno; i++) | |
| 381 log_buff[i] ^= 0x0055; | |
| 382 | |
| 383 if ((smpno = fwrite(log_buff, sizeof(Byte), smpno, Fo)) < 0) | |
| 384 KILL(outfil, 6); | |
| 385 } | |
| 386 | |
| 387 /* Input: LINEAR | Output: LINEAR */ | |
| 388 else if (inp_type == IS_LIN && out_type == IS_LIN) | |
| 389 for (tot_smpno = cur_blk = 0; cur_blk < N2; | |
| 390 cur_blk++, tot_smpno += smpno) { | |
| 391 if ((smpno = fread(lin_buff, sizeof(short), N, Fi)) < 0) | |
| 392 KILL(inpfil, 5); | |
| 393 alaw_compress(smpno, lin_buff, log_buff); | |
| 394 alaw_expand(smpno, log_buff, lon_buff); | |
| 395 if ((smpno = fwrite(lon_buff, sizeof(short), smpno, Fo)) < 0) | |
| 396 KILL(outfil, 6); | |
| 397 } | |
| 398 | |
| 399 /* Input: LOG | Output: LINEAR */ | |
| 400 else if (inp_type == IS_LOG) | |
| 401 for (tot_smpno = cur_blk = 0; cur_blk < N2; | |
| 402 cur_blk++, tot_smpno += smpno) { | |
| 403 if ((smpno = fread(log_buff, sizeof(Byte), N, Fi)) < 0) | |
| 404 KILL(inpfil, 5); | |
| 405 if (!revert_even_bits) | |
| 406 for (i = 0; i < smpno; i++) | |
| 407 log_buff[i] ^= 0x0055; | |
| 408 alaw_expand(smpno, log_buff, lon_buff); | |
| 409 if ((smpno = fwrite(lon_buff, sizeof(short), smpno, Fo)) < 0) | |
| 410 KILL(outfil, 6); | |
| 411 } | |
| 412 break; | |
| 413 | |
| 414 /* ......... Process u-law rule ......... */ | |
| 415 | |
| 416 case 'U': | |
| 417 /* Input: LINEAR | Output: LOG */ | |
| 418 if (inp_type == IS_LIN && out_type == IS_LOG) | |
| 419 for (tot_smpno = cur_blk = 0; cur_blk < N2; | |
| 420 cur_blk++, tot_smpno += smpno) { | |
| 421 smpno = fread(lin_buff, sizeof(short), N, Fi); | |
| 422 ulaw_compress(smpno, lin_buff, log_buff); | |
| 423 smpno = fwrite(log_buff, sizeof(Byte), smpno, Fo); | |
| 424 } | |
| 425 | |
| 426 /* Input: LINEAR | Output: LINEAR */ | |
| 427 else if (inp_type == IS_LIN && out_type == IS_LIN) | |
| 428 for (tot_smpno = cur_blk = 0; cur_blk < N2; | |
| 429 cur_blk++, tot_smpno += smpno) { | |
| 430 smpno = fread(lin_buff, sizeof(short), N, Fi); | |
| 431 ulaw_compress(smpno, lin_buff, log_buff); | |
| 432 ulaw_expand(smpno, log_buff, lon_buff); | |
| 433 smpno = fwrite(lon_buff, sizeof(short), smpno, Fo); | |
| 434 } | |
| 435 | |
| 436 /* Input: LOG | Output: LINEAR */ | |
| 437 else if (inp_type == IS_LOG) | |
| 438 for (tot_smpno = cur_blk = 0; cur_blk < N2; | |
| 439 cur_blk++, tot_smpno += smpno) { | |
| 440 smpno = fread(log_buff, sizeof(Byte), N, Fi); | |
| 441 ulaw_expand(smpno, log_buff, lon_buff); | |
| 442 smpno = fwrite(lon_buff, sizeof(short), smpno, Fo); | |
| 443 } | |
| 444 break; | |
| 445 } | |
| 446 | |
| 447 | |
| 448 /* ......... FINALIZATIONS ......... */ | |
| 449 | |
| 450 t2 = clock(); | |
| 451 printf("Speed: %f sec CPU-time for %ld processed samples\n", | |
| 452 (t2 - t1) / (double) CLOCKS_PER_SEC, tot_smpno); | |
| 453 | |
| 454 fclose(Fi); | |
| 455 fclose(Fo); | |
| 456 #ifndef VMS | |
| 457 return (0); | |
| 458 #endif | |
| 459 } |
