Mercurial > hg > audiostuff
comparison intercom/g726/vbr-g726.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 /* 21.Mar.2000 V1.3 | |
| 2 ============================================================================ | |
| 3 | |
| 4 VBR-G726.C | |
| 5 ~~~~~~~~~~ | |
| 6 | |
| 7 Description: | |
| 8 ~~~~~~~~~~~~ | |
| 9 | |
| 10 Demonstration program for UGST/ITU-T G.726 module using the variable | |
| 11 bit rate feature. This version accepts either linear or G.711 A/u-law | |
| 12 input. Since this implementation of the G.726 requires G.711 compressed | |
| 13 samples, linear samples are converted to G.711 format before being | |
| 14 processed. Therefore, the same ammount of quantization distortion should | |
| 15 be expect either way. | |
| 16 | |
| 17 The modules called have been originally written in Fortran, and were | |
| 18 translated into C by the converter f2c, version of October 15, 1990 | |
| 19 at 19:58:17. | |
| 20 | |
| 21 Input data is supposed to be aligned at word boundaries, i.e., | |
| 22 organized in 16-bit words, following the operating system normal | |
| 23 organization (low-byte first for VMS and DOS; high byte first for most | |
| 24 Unix systems). Linear samples are supposed to be 16-bit right-adjusted. | |
| 25 G711 compressed data is supposed to be in the 8 LEAST | |
| 26 significant bits of the word and the ADPCM data is in the LEAST 5 | |
| 27 bits. Both are without sign extension. | |
| 28 | |
| 29 Output data will be generated in the same format as decribed above for | |
| 30 the input data. | |
| 31 | |
| 32 Usage: | |
| 33 ~~~~~~ | |
| 34 $ VBR-G726 [-options] InpFile OutFile | |
| 35 [FrameSize [1stBlock [NoOfBlocks [Reset]]]] | |
| 36 where: | |
| 37 InpFile is the name of the file to be processed; | |
| 38 OutFile is the name with the processed data; | |
| 39 FrameSize is the frame size, in number of samples; the bitrate | |
| 40 will only change in the boundaries of a frame | |
| 41 [default: 16 samples] | |
| 42 1stBlock is the number of the first block of the input file | |
| 43 to be processed [default: 1st block] | |
| 44 NoOfBlocks is the number of blocks to be processed, starting on | |
| 45 block "1stBlock" [default: all blocks] | |
| 46 | |
| 47 Options: | |
| 48 -law # the letters A or a for G.711 A-law, letter u for | |
| 49 G.711 u-law, or letter l for linear. If linear is | |
| 50 chosen, A-law is used to compress/expand samples to/from | |
| 51 the G.726 routines. Default is A-law. | |
| 52 -rate # is the bit-rate (in kbit/s): 40, 32, 24 or 16 (in kbit/s); | |
| 53 or a combination of them using dashes (e.g. 32-24 or | |
| 54 16-24-32). Default is 32 kbit/s. | |
| 55 -frame # Number of samples per frame for switching bit rates. | |
| 56 Default is 16 samples (or 2ms) | |
| 57 -enc run only the G.726 encoder on the samples | |
| 58 [default: run encoder and decoder] | |
| 59 -dec run only the G.726 decoder on the samples | |
| 60 [default: run encoder and decoder] | |
| 61 -noreset don't apply reset to the encoder/decoder | |
| 62 -?/-help print help message | |
| 63 | |
| 64 Example: | |
| 65 $ vbr-G726 -law u -enc -rate 32 voice.ref voice.adp 256 3 45 | |
| 66 | |
| 67 The command above takes the samples in file "voice.ref", already | |
| 68 in mu law format, processes the data through the G726 encoder | |
| 69 only at a rate of 32 bkit/s, saving them into the file | |
| 70 "voice.rel". The processing starts at block 3 for 45 blocks, | |
| 71 each block being 256 samples wide. | |
| 72 | |
| 73 Variables: | |
| 74 ~~~~~~~~~~ | |
| 75 law law to use (either A or u) | |
| 76 conv desired processing | |
| 77 rate desired rate | |
| 78 inpfil input file name; | |
| 79 outfil output file name; | |
| 80 N block size; | |
| 81 N1 first block to process; | |
| 82 N2 no. of blocks to process; | |
| 83 | |
| 84 Exit values: | |
| 85 ~~~~~~~~~~~~ | |
| 86 0 success (all but VMS); | |
| 87 1 success (only in VMS); | |
| 88 2 error opening input file; | |
| 89 3 error creating output file; | |
| 90 4 error moving pointer to desired start of conversion; | |
| 91 5 error reading input file; | |
| 92 6 error writing to file; | |
| 93 7 invalid law | |
| 94 8 invalid conversion | |
| 95 9 invalid rate | |
| 96 | |
| 97 Original author: | |
| 98 ~~~~~~~~~~~~~~~~ | |
| 99 Simao Ferraz de Campos Neto | |
| 100 Comsat Laboratories Tel: +1-301-428-4516 | |
| 101 22300 Comsat Drive Fax: +1-301-428-9287 | |
| 102 Clarksburg MD 20871 - USA E-mail: simao@ctd.comsat.com | |
| 103 | |
| 104 History: | |
| 105 ~~~~~~~~ | |
| 106 10/Mar/1995 v1.0 Created based on vbr-g726.c | |
| 107 22/Feb/1996 v1.1 Removed compilation warnings, included headers as | |
| 108 suggested by Kirchherr (FI/DBP Telekom) to run under | |
| 109 OpenVMS/AXP <simao@ctd.comsat.com> | |
| 110 22/Jul/1997 v1.2 Changed static allocation for data arrays to allow longer | |
| 111 frame sizes. Fix based on modifications by R. Kirchherr | |
| 112 <kirchherr@tzd.telekom.de> | |
| 113 21.Mar.2000 v1.3 Corrected bug when the bitrate is not specified by | |
| 114 the user. Corrected bug that made incorrect | |
| 115 calculation on total number of blocks to process | |
| 116 when the block size is not a multiple of the file | |
| 117 size. <simao.campos@labs.comsat.com> | |
| 118 ============================================================================ | |
| 119 */ | |
| 120 | |
| 121 /* ..... General definitions for UGST demo programs ..... */ | |
| 122 #include "ugstdemo.h" | |
| 123 | |
| 124 /* ..... General include ..... */ | |
| 125 #include <stdio.h> | |
| 126 #include <stdlib.h> | |
| 127 #include <string.h> | |
| 128 #include <math.h> | |
| 129 #include <ctype.h> | |
| 130 | |
| 131 #if defined(VMS) | |
| 132 #include <unixio.h> | |
| 133 #include <stat.h> | |
| 134 #else /* Unix/DOS */ | |
| 135 #include <sys/stat.h> | |
| 136 #endif | |
| 137 | |
| 138 /* ..... G.726 module as include functions ..... */ | |
| 139 #include "g726.h" | |
| 140 #include "g711.h" | |
| 141 | |
| 142 /* | |
| 143 ------------------------------------------------------------------------- | |
| 144 void parse_rate(char *str, short *rate); | |
| 145 ~~~~~~~~~~~~~~~ | |
| 146 Parses string str with a list of bitrates for the operation of the G726 | |
| 147 algorithm and return a list of them in rate, and the number of rates read. | |
| 148 | |
| 149 Parameters: | |
| 150 ~~~~~~~~~~~ | |
| 151 str ..... string pointing to a list of dash-separated bitrates to be used. | |
| 152 Valid examples are: 16 (single rate), 32-24 (duo-rate), etc. | |
| 153 rate .... string of short numbers with each of the specified rates. | |
| 154 | |
| 155 Return: | |
| 156 ~~~~~~~ | |
| 157 Returns the number of bitrates for the ADPCM operation, 0 if str is | |
| 158 empty or improper, and -1 if there are too many rates requested. | |
| 159 | |
| 160 History: | |
| 161 ~~~~~~~~ | |
| 162 10.Mar.95 v1.0 Created <simao@ctd.comsat.com> | |
| 163 ------------------------------------------------------------------------- | |
| 164 */ | |
| 165 int parse_rate(str, rate) | |
| 166 char *str; | |
| 167 short **rate; | |
| 168 { | |
| 169 char *s = str; | |
| 170 int count = 1, i; | |
| 171 | |
| 172 if (str == NULL) | |
| 173 return 0; | |
| 174 | |
| 175 while ((s = strchr(s, '-')) != NULL) { | |
| 176 s++; | |
| 177 count++; | |
| 178 } | |
| 179 | |
| 180 /* Allocates memory for the necessary number of rates */ | |
| 181 *rate = (short *) calloc(sizeof(short), count); | |
| 182 if (*rate == NULL) | |
| 183 return (-1); | |
| 184 | |
| 185 /* Save rates in the array */ | |
| 186 for (s = strtok(str, "-"), i = 0; i < count; i++) { | |
| 187 /* Convert to short & save */ | |
| 188 (*rate)[i] = atoi(s); | |
| 189 | |
| 190 /* Classification of rate - return 0 if invalid rate was specified */ | |
| 191 if ((*rate)[i] > 5) { | |
| 192 if ((*rate)[i] == 40) | |
| 193 (*rate)[i] = 5; | |
| 194 else if ((*rate)[i] == 32) | |
| 195 (*rate)[i] = 4; | |
| 196 else if ((*rate)[i] == 24) | |
| 197 (*rate)[i] = 3; | |
| 198 else if ((*rate)[i] == 16) | |
| 199 (*rate)[i] = 2; | |
| 200 else | |
| 201 return (0); | |
| 202 } | |
| 203 | |
| 204 /* Update s to the next valid rate number */ | |
| 205 s = strtok(NULL, "-"); | |
| 206 } | |
| 207 | |
| 208 /* Return the number of rates */ | |
| 209 return (count); | |
| 210 } | |
| 211 | |
| 212 /* .................... End of parse_rate() ........................... */ | |
| 213 | |
| 214 | |
| 215 /* | |
| 216 ------------------------------------------------------------------------- | |
| 217 void display_usage(void); | |
| 218 ~~~~~~~~~~~~~~~~~~ | |
| 219 Display proper usage for the demo program. Generated automatically from | |
| 220 program documentation. | |
| 221 | |
| 222 History: | |
| 223 ~~~~~~~~ | |
| 224 10.Mar.95 v1.0 Created <simao>. | |
| 225 ------------------------------------------------------------------------- | |
| 226 */ | |
| 227 #define P(x) printf x | |
| 228 void display_usage() | |
| 229 { | |
| 230 P(("Version 1.3 of 21/Mar/2000 \n\n")); | |
| 231 | |
| 232 P((" VBR-G726.C \n")); | |
| 233 P((" Demonstration program for UGST/ITU-T G.726 module using the variable\n")); | |
| 234 P((" bit rate feature. This version accepts either linear or G.711 A/u-law\n")); | |
| 235 P((" input. Since this implementation of the G.726 requires G.711 compressed\n")); | |
| 236 P((" samples, linear samples are converted to G.711 format before being\n")); | |
| 237 P((" processed. Therefore, the same ammount of quantization distortion should\n")); | |
| 238 P((" be expect either way.\n")); | |
| 239 P((" Input data is supposed to be aligned at word boundaries, i.e.,\n")); | |
| 240 P((" organized in 16-bit words, following the operating system normal\n")); | |
| 241 P((" organization (low-byte first for VMS and DOS; high byte first for most\n")); | |
| 242 P((" Unix systems). Linear samples are supposed to be 16-bit right-adjusted. \n")); | |
| 243 P((" G711 compressed data is supposed to be in the 8 LEAST\n")); | |
| 244 P((" significant bits of the word and the ADPCM data is in the LEAST 5\n")); | |
| 245 P((" bits. Both are without sign extension.\n")); | |
| 246 P((" \n")); | |
| 247 P((" Output data will be generated in the same format as decribed above for\n")); | |
| 248 P((" the input data.\n")); | |
| 249 P((" \n")); | |
| 250 P((" Usage:\n")); | |
| 251 P((" VBR-G726 [-options] InpFile OutFile \n")); | |
| 252 P((" [FrameSize [1stBlock [NoOfBlocks [Reset]]]]\n")); | |
| 253 P((" where:\n")); | |
| 254 P((" InpFile is the name of the file to be processed;\n")); | |
| 255 P((" OutFile is the name with the processed data;\n")); | |
| 256 P((" FrameSize is the frame size, in number of samples; the bitrate \n")); | |
| 257 P((" will only change in the boundaries of a frame \n")); | |
| 258 P((" [default: 16 samples]\n")); | |
| 259 P((" 1stBlock is the number of the first block of the input file\n")); | |
| 260 P((" to be processed [default: 1st block]\n")); | |
| 261 P((" NoOfBlocks is the number of blocks to be processed, starting on\n")); | |
| 262 P((" block \"1stBlock\" [default: all blocks]\n")); | |
| 263 P(("\n")); | |
| 264 P((" Options:\n")); | |
| 265 P((" -law # the letters A or a for G.711 A-law, letter u for \n")); | |
| 266 P((" G.711 u-law, or letter l for linear. If linear is\n")); | |
| 267 P((" chosen, A-law is used to compress/expand samples to/from\n")); | |
| 268 P((" the G.726 routines. Default is A-law.\n")); | |
| 269 P((" -rate # is the bit-rate (in kbit/s): 40, 32, 24 or 16 (in kbit/s); \n")); | |
| 270 P((" or a combination of them using dashes (e.g. 32-24 or\n")); | |
| 271 P((" 16-24-32). Default is 32 kbit/s.\n")); | |
| 272 P((" -frame # Number of samples per frame for switching bit rates.\n")); | |
| 273 P((" Default is 16 samples (or 2ms) \n")); | |
| 274 P((" -enc run only the G.726 encoder on the samples \n")); | |
| 275 P((" [default: run encoder and decoder]\n")); | |
| 276 P((" -dec run only the G.726 decoder on the samples \n")); | |
| 277 P((" [default: run encoder and decoder]\n")); | |
| 278 P((" -noreset don't apply reset to the encoder/decoder\n")); | |
| 279 P((" -?/-help print help message\n")); | |
| 280 P(("\n")); | |
| 281 | |
| 282 /* Quit program */ | |
| 283 exit(-128); | |
| 284 } | |
| 285 | |
| 286 #undef P | |
| 287 /* .................... End of display_usage() ........................... */ | |
| 288 | |
| 289 | |
| 290 void G726_initEncode(G726_state *encoder_state) | |
| 291 { | |
| 292 memset(encoder_state, 0, sizeof(G726_state)); | |
| 293 } | |
| 294 | |
| 295 void G726_initDecode(G726_state *decoder_state) | |
| 296 { | |
| 297 memset(decoder_state, 0, sizeof(G726_state)); | |
| 298 } | |
| 299 | |
| 300 void g726pack(Byte *packed, short *in, int cnt) | |
| 301 { | |
| 302 int i; | |
| 303 for (i = 0; i <= cnt; i += 2, ++packed, ++in) { | |
| 304 *packed = (*in & 0xF); | |
| 305 ++in; | |
| 306 *packed += (*in & 0xF) * 16; | |
| 307 } | |
| 308 } | |
| 309 | |
| 310 void g726unpack(short *out, Byte *packed, int cnt) | |
| 311 { | |
| 312 int i; | |
| 313 for (i = 0; i <= cnt; i += 2, ++packed, ++out) { | |
| 314 *out = (*packed & 0xF); | |
| 315 ++out; | |
| 316 *out = (*packed & 0xF0) / 16; | |
| 317 } | |
| 318 } | |
| 319 | |
| 320 /* | |
| 321 ************************************************************************** | |
| 322 *** *** | |
| 323 *** Demo-Program for testing the correct implementation *** | |
| 324 *** and to show how to use the programs *** | |
| 325 *** *** | |
| 326 ************************************************************************** | |
| 327 */ | |
| 328 int main(argc, argv) | |
| 329 int argc; | |
| 330 char *argv[]; | |
| 331 { | |
| 332 G726_state encoder_state, decoder_state; | |
| 333 long N = 16, N1 = 1, N2 = 0, cur_blk, smpno; | |
| 334 short *tmp_buf, *inp_buf, *out_buf, reset = 1; | |
| 335 Byte tmpb_buf[N], outb_buf[N]; | |
| 336 short inp_type, out_type, *rate = 0; | |
| 337 char encode = 1, decode = 1, law[4] = "A", def_rate[] = "32"; | |
| 338 int rateno = 1, rate_idx; | |
| 339 | |
| 340 /* General-purpose, progress indication */ | |
| 341 static char quiet = 0, funny[9] = "|/-\\|/-\\"; | |
| 342 | |
| 343 /* File variables */ | |
| 344 char FileIn[80], FileOut[80]; | |
| 345 FILE *Fi, *Fo; | |
| 346 int inp, out; | |
| 347 long start_byte; | |
| 348 #ifdef VMS | |
| 349 char mrs[15]; | |
| 350 #endif | |
| 351 | |
| 352 /* | |
| 353 * ......... PARAMETERS FOR PROCESSING ......... | |
| 354 */ | |
| 355 | |
| 356 /* GETTING OPTIONS */ | |
| 357 | |
| 358 if (argc < 2) | |
| 359 display_usage(); | |
| 360 else { | |
| 361 while (argc > 1 && argv[1][0] == '-') | |
| 362 if (strcmp(argv[1], "-noreset") == 0) { | |
| 363 /* No reset */ | |
| 364 reset = 0; | |
| 365 | |
| 366 /* Update argc/argv to next valid option/argument */ | |
| 367 argv++; | |
| 368 argc--; | |
| 369 } else if (strcmp(argv[1], "-enc") == 0) { | |
| 370 /* Encoder-only operation */ | |
| 371 encode = 1; | |
| 372 decode = 0; | |
| 373 | |
| 374 /* Move argv over the option to the next argument */ | |
| 375 argv++; | |
| 376 argc--; | |
| 377 } else if (strcmp(argv[1], "-dec") == 0) { | |
| 378 /*Decoder-only operation */ | |
| 379 encode = 0; | |
| 380 decode = 1; | |
| 381 | |
| 382 /* Move argv over the option to the next argument */ | |
| 383 argv++; | |
| 384 argc--; | |
| 385 } else if (strcmp(argv[1], "-law") == 0) { | |
| 386 /* Define law for operation: A, u, or linear */ | |
| 387 switch (toupper(argv[2][0])) { | |
| 388 case 'A': | |
| 389 law[0] = '1'; | |
| 390 break; | |
| 391 case 'U': | |
| 392 law[0] = '0'; | |
| 393 break; | |
| 394 case 'L': | |
| 395 law[0] = '2'; | |
| 396 break; | |
| 397 default: | |
| 398 HARAKIRI(" Invalid law (A or u)! Aborted...\n", 7); | |
| 399 } | |
| 400 | |
| 401 /* Move argv over the option to the next argument */ | |
| 402 argv += 2; | |
| 403 argc -= 2; | |
| 404 } else if (strcmp(argv[1], "-frame") == 0) { | |
| 405 /* Define Frame size for rate change during operation */ | |
| 406 N = atoi(argv[2]); | |
| 407 | |
| 408 /* Move argv over the option to the next argument */ | |
| 409 argv += 2; | |
| 410 argc -= 2; | |
| 411 } else if (strcmp(argv[1], "-rate") == 0) { | |
| 412 /*Define rate(s) for operation */ | |
| 413 rateno = parse_rate(argv[2], &rate); | |
| 414 if (rateno == 0) { | |
| 415 fprintf(stderr, "Invalid bitrate list: %s\n", argv[2]); | |
| 416 exit(9); | |
| 417 } | |
| 418 /* Move argv over the option to the next argument */ | |
| 419 argv += 2; | |
| 420 argc -= 2; | |
| 421 } else if (strcmp(argv[1], "-q") == 0) { | |
| 422 /* Don't print progress indicator */ | |
| 423 quiet = 1; | |
| 424 | |
| 425 /* Move argv over the option to the next argument */ | |
| 426 argv++; | |
| 427 argc--; | |
| 428 } else if (strcmp(argv[1], "-?") == 0 | |
| 429 || strcmp(argv[1], "-help") == 0) { | |
| 430 /* Print help */ | |
| 431 display_usage(); | |
| 432 } else { | |
| 433 fprintf(stderr, | |
| 434 "ERROR! Invalid option \"%s\" in command line\n\n", argv[1]); | |
| 435 display_usage(); | |
| 436 } | |
| 437 } | |
| 438 | |
| 439 /* Now get regular parameters */ | |
| 440 GET_PAR_S(1, "_Input File: .................. ", FileIn); | |
| 441 GET_PAR_S(2, "_Output File: ................. ", FileOut); | |
| 442 FIND_PAR_L(3, "_Block Size: .................. ", N, N); | |
| 443 FIND_PAR_L(4, "_Starting Block: .............. ", N1, N1); | |
| 444 FIND_PAR_L(5, "_No. of Blocks: ............... ", N2, N2); | |
| 445 | |
| 446 /* Uses default rate if none is given */ | |
| 447 if (rate == 0) | |
| 448 rateno = parse_rate(def_rate, &rate); | |
| 449 | |
| 450 /* Inform user of the compading law used: 0->u, 1->A, 2->linear */ | |
| 451 fprintf(stderr, "Using %s\n", | |
| 452 law[0] == '1' ? "A-law" : (law[0] == '0' ? "u-law" : "linear PCM")); | |
| 453 | |
| 454 /* Find starting byte in file */ | |
| 455 start_byte = sizeof(short) * (long) (--N1) * (long) N; | |
| 456 | |
| 457 /* Check if is to process the whole file */ | |
| 458 if (N2 == 0) { | |
| 459 struct stat st; | |
| 460 | |
| 461 /* ... find the input file size ... */ | |
| 462 stat(FileIn, &st); | |
| 463 N2 = ceil((st.st_size - start_byte) / (double) (N * sizeof(short))); | |
| 464 } | |
| 465 | |
| 466 /* Define correct data I/O types */ | |
| 467 if (encode && decode) { | |
| 468 inp_type = out_type = (law[0] == '2' ? IS_LIN : IS_LOG); | |
| 469 } else if (encode) { | |
| 470 inp_type = law[0] == '2' ? IS_LIN : IS_LOG; | |
| 471 out_type = IS_ADPCM; | |
| 472 } else { | |
| 473 inp_type = IS_ADPCM; | |
| 474 out_type = law[0] == '2' ? IS_LIN : IS_LOG; | |
| 475 } | |
| 476 | |
| 477 /* Force law to be used *by the ADPCM* to A-law, if input is linear */ | |
| 478 if (law[0] == '2') | |
| 479 law[0] = '1'; | |
| 480 | |
| 481 /* | |
| 482 * ...... MEMORY ALLOCATION ......... | |
| 483 */ | |
| 484 | |
| 485 if ((inp_buf = (short *) calloc(N, sizeof(short))) == NULL) | |
| 486 HARAKIRI("Error in memory allocation!\n", 1); | |
| 487 if ((out_buf = (short *) calloc(N, sizeof(short))) == NULL) | |
| 488 HARAKIRI("Error in memory allocation!\n", 1); | |
| 489 if ((tmp_buf = (short *) calloc(N, sizeof(short))) == NULL) | |
| 490 HARAKIRI("Error in memory allocation!\n", 1); | |
| 491 | |
| 492 /* | |
| 493 * ......... FILE PREPARATION ......... | |
| 494 */ | |
| 495 | |
| 496 /* Opening input file; abort if there's any problem */ | |
| 497 if ((Fi = fopen(FileIn, "rb")) == NULL) | |
| 498 KILL(FileIn, 2); | |
| 499 inp = fileno(Fi); | |
| 500 | |
| 501 /* Creates output file */ | |
| 502 #ifdef VMS | |
| 503 sprintf(mrs, "mrs=%d", 512); | |
| 504 #endif | |
| 505 if ((Fo = fopen(FileOut, WB)) == NULL) | |
| 506 KILL(FileOut, 3); | |
| 507 out = fileno(Fo); | |
| 508 | |
| 509 /* Move pointer to 1st block of interest */ | |
| 510 if (fseek(Fi, start_byte, 0) < 0l) | |
| 511 KILL(FileIn, 4); | |
| 512 | |
| 513 /* | |
| 514 * ......... PROCESSING ACCORDING TO ITU-T G.726 ......... | |
| 515 */ | |
| 516 /* Reset VBR counters */ | |
| 517 rate_idx = 0; | |
| 518 | |
| 519 for (cur_blk = 0; cur_blk < N2; cur_blk++) { | |
| 520 /* Set the proper rate index */ | |
| 521 rate_idx = cur_blk % rateno; | |
| 522 | |
| 523 /* Print progress flag */ | |
| 524 if (!quiet) | |
| 525 #ifdef DISPLAY_CURRENT_RATE | |
| 526 fprintf(stderr, "%d-", 8 * rate[rate_idx]); | |
| 527 #else | |
| 528 fprintf(stderr, "%c\r", funny[cur_blk % 8]); | |
| 529 #endif | |
| 530 | |
| 531 /* Read a block of samples */ | |
| 532 if ((smpno = fread(inp_buf, sizeof(short), N, Fi)) < 0) | |
| 533 KILL(FileIn, 5); | |
| 534 | |
| 535 /* Compress linear input samples */ | |
| 536 if (inp_type == IS_LIN) { | |
| 537 /* Compress using A-law */ | |
| 538 alaw_compress(smpno, inp_buf, tmpb_buf); | |
| 539 | |
| 540 /* copy temporary buffer over input buffer */ | |
| 541 // memcpy(inp_buf, tmp_buf, sizeof(short) * smpno); | |
| 542 } | |
| 543 | |
| 544 /* Check if reset is needed */ | |
| 545 reset = (reset == 1 && cur_blk == 0) ? 1 : 0; | |
| 546 | |
| 547 /* Carry out the desired operation */ | |
| 548 if (encode && !decode) | |
| 549 G726_encode(tmpb_buf, out_buf, smpno, law, | |
| 550 rate[rate_idx], reset, &encoder_state); | |
| 551 else if (decode && !encode) | |
| 552 G726_decode(inp_buf, outb_buf, smpno, law, | |
| 553 rate[rate_idx], reset, &decoder_state); | |
| 554 else if (encode && decode) { | |
| 555 Byte g726_buf[N/2]; | |
| 556 | |
| 557 G726_encode(tmpb_buf, tmp_buf, smpno, law, | |
| 558 rate[rate_idx], reset, &encoder_state); | |
| 559 // printf ("rate[rate_idx] = %d\n", rate[rate_idx]); | |
| 560 g726pack(g726_buf, tmp_buf, smpno); | |
| 561 | |
| 562 g726unpack(tmp_buf, g726_buf, smpno); | |
| 563 | |
| 564 G726_decode(tmp_buf, outb_buf, smpno, law, | |
| 565 rate[rate_idx], reset, &decoder_state); | |
| 566 } | |
| 567 | |
| 568 /* Expand linear input samples */ | |
| 569 if (out_type == IS_LIN) { | |
| 570 /* Compress using A-law */ | |
| 571 alaw_expand(smpno, outb_buf, tmp_buf); | |
| 572 | |
| 573 /* copy temporary buffer over input buffer */ | |
| 574 memcpy(out_buf, tmp_buf, sizeof(short) * smpno); | |
| 575 } | |
| 576 | |
| 577 /* Write ADPCM output word */ | |
| 578 if ((smpno = fwrite(out_buf, sizeof(short), smpno, Fo)) < 0) | |
| 579 KILL(FileOut, 6); | |
| 580 } | |
| 581 | |
| 582 /* | |
| 583 * ......... FINALIZATIONS ......... | |
| 584 */ | |
| 585 | |
| 586 /* Free allocated memory */ | |
| 587 free(tmp_buf); | |
| 588 free(out_buf); | |
| 589 free(inp_buf); | |
| 590 free(rate); | |
| 591 | |
| 592 /* Close input and output files */ | |
| 593 fclose(Fi); | |
| 594 fclose(Fo); | |
| 595 | |
| 596 /* Exit with success for non-vms systems */ | |
| 597 #ifndef VMS | |
| 598 return (0); | |
| 599 #endif | |
| 600 } | |
| 601 | |
| 602 /* ............................. end of main() ............................. */ |
