Mercurial > hg > audiostuff
comparison intercom/g726/g726demo.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.2 | |
| 2 ============================================================================ | |
| 3 | |
| 4 G726DEMO.C | |
| 5 ~~~~~~~~~~ | |
| 6 | |
| 7 Description: | |
| 8 ~~~~~~~~~~~~ | |
| 9 | |
| 10 Demonstration program for UGST/ITU-T G.726 module (the same as the Blue | |
| 11 Book G.726). Takes the input file and processes by the G.726 codec, | |
| 12 depending on user's option: for encoding, input must be in either A | |
| 13 or mu law (G711), for decoding, in ADPCM format. The modules called have | |
| 14 been originally written in Fortran, and were translated into C by the | |
| 15 converter f2c, version of October 15, 1990 at 19:58:17. | |
| 16 | |
| 17 Input data is supposed to be aligned at word boundaries, i.e., | |
| 18 organized in 16-bit words, following the operating system normal | |
| 19 organization (low-byte first for VMS and DOS; high byte first | |
| 20 for most Unix systems). G711 compressed data is supposed to be | |
| 21 in the 8 LEAST significant bits of the word and the ADPCM data | |
| 22 is in the LEAST 5 bits. Both are without sign extension. | |
| 23 | |
| 24 Output data will be generated in the same format as decribed | |
| 25 above for the input data. | |
| 26 | |
| 27 Usage: | |
| 28 ~~~~~~ | |
| 29 $ G726demo [-options] Law Transf Rate InpFile OutFile | |
| 30 [BlockSize [1stBlock [NoOfBlocks [Reset]]]] | |
| 31 where: | |
| 32 Law is the law desired (either A or u) | |
| 33 Transf is the desired conversion on the input file: | |
| 34 [lolo], (A/u)log -> ADPCM -> (A/u) log | |
| 35 [load], (A/u)log -> ADPCM | |
| 36 [adlo], ADPCM -> (A/u) log | |
| 37 Rate is the number of ADPCM bits per sample: | |
| 38 [5],[40] -> 5 bits per sample (40 kbit/s) | |
| 39 [4],[32] -> 4 bits per sample (32 kbit/s) | |
| 40 [3],[24] -> 3 bits per sample (24 kbit/s) | |
| 41 [2],[16] -> 2 bits per sample (16 kbit/s) | |
| 42 InpFile is the name of the file to be processed; | |
| 43 OutFile is the name with the processed data; | |
| 44 BlockSize is the block size, in number of samples | |
| 45 1stBlock is the number of the first block of the input file | |
| 46 to be processed; | |
| 47 NoOfBlocks is the number of blocks to be processed, starting on | |
| 48 block "1stBlock" | |
| 49 Reset is the optional reset. If specified as 1, the | |
| 50 coder and decoder will be reset at the very beginning of | |
| 51 the processings. If 0, the processing will start with | |
| 52 the variables at a unknown state. It defaults to 1 | |
| 53 (reset ON). | |
| 54 Options: | |
| 55 -noreset don't apply reset to the encoder/decoder | |
| 56 -?/-help print help message | |
| 57 | |
| 58 | |
| 59 Example: | |
| 60 $ G726demo u lolo 4 voice.ref voice.rel 256 3 45 *OR* | |
| 61 $ G726demo u lolo 32 voice.ref voice.rel 256 3 45 | |
| 62 | |
| 63 The command above takes the samples in file "voice.ref", already | |
| 64 in mu law format, processes the data through the G726 encoder | |
| 65 and decoder at a rate of 32 bkit/s, saving them into the file | |
| 66 "voice.rel". The processing starts at block 3 for 45 blocks, | |
| 67 each block being 256 samples wide. | |
| 68 | |
| 69 Original authors: | |
| 70 ~~~~~~~~~~~~~~~~~ | |
| 71 Simao Ferraz de Campos Neto EMail : simao@cpqd.ansp.br (32k) | |
| 72 Fernando Tofolli Queiroz EMail : tdfernan@cpqd.ansp.br (extension) | |
| 73 | |
| 74 CPqD/Telebras Rd. Mogi Mirim-Campinas Km.118 | |
| 75 DDS/Pr.11 13.088-061 - Campinas - SP (Brazil) | |
| 76 | |
| 77 History: | |
| 78 ~~~~~~~~ | |
| 79 28/Feb/1994 v1.0 Release of 1st version of this demo program | |
| 80 based on the g721demo of the STL92. G.726 | |
| 81 functionality added by Fernando Toffoli Queiroz | |
| 82 <tdfernan@cpqd.ansp.br>; usage routine and | |
| 83 portability tests by Simao. | |
| 84 22/Feb/1996 v1.1 Removed compilation warnings, included headers as | |
| 85 suggested by Kirchherr (FI/DBP Telekom) to run under | |
| 86 OpenVMS/AXP <simao@ctd.comsat.com> | |
| 87 21/Mar/2000 v1.2 Changed memory allocation of floating point buffers | |
| 88 tmp_buf[], inp_buf[] and out_buf[] from static to | |
| 89 dynamic, to prevent memory invasion | |
| 90 when block sizes larger than 256 are specified. | |
| 91 Corrected bug that made incorrect calculation on | |
| 92 total number of blocks to process when the block | |
| 93 size is not a multiple of the file | |
| 94 size. <simao.campos@labs.comsat.com> | |
| 95 | |
| 96 ============================================================================ | |
| 97 */ | |
| 98 | |
| 99 | |
| 100 /* ..... General definitions for UGST demo programs ..... */ | |
| 101 #include "ugstdemo.h" | |
| 102 | |
| 103 /* ..... General include ..... */ | |
| 104 #include <stdio.h> | |
| 105 #include <string.h> | |
| 106 #include <stdlib.h> | |
| 107 #include <ctype.h> | |
| 108 #include <math.h> | |
| 109 | |
| 110 #if defined(VMS) | |
| 111 #include <stat.h> | |
| 112 #else /* Unix/DOS */ | |
| 113 #include <sys/stat.h> | |
| 114 #endif | |
| 115 | |
| 116 /* ..... G.726 module as include functions ..... */ | |
| 117 #include "g726.h" | |
| 118 | |
| 119 /* | |
| 120 ------------------------------------------------------------------------- | |
| 121 void display_usage(void); | |
| 122 ~~~~~~~~~~~~~~~~~~ | |
| 123 Display proper usage for the demo program. Generated automatically from | |
| 124 program documentation. | |
| 125 | |
| 126 History: | |
| 127 ~~~~~~~~ | |
| 128 8.Mar.94 v1.0 Created. | |
| 129 ------------------------------------------------------------------------- | |
| 130 */ | |
| 131 #define P(x) printf x | |
| 132 void display_usage() | |
| 133 { | |
| 134 P(("G726DEMO - Version 1.2 of 21/Mar/2000 \n\n")); | |
| 135 | |
| 136 P(("> Description:\n")); | |
| 137 P((" Demonstration program for UGST/ITU-T G.726 module. Takes the\n")); | |
| 138 P((" input file and processes by the G.726 codec,\n")); | |
| 139 P((" depending on user's option: for encoding, input must be in\n")); | |
| 140 P((" either A or mu law (G711), for decoding, in ADPCM format. The\n")); | |
| 141 P((" modules called have been originally written in Fortran, and were\n")); | |
| 142 P((" translated into C by the converter f2c, version of October 15,1990\n")); | |
| 143 P(("\n")); | |
| 144 P((" Input data is supposed to be aligned at word boundaries, i.e.,\n")); | |
| 145 P((" organized in 16-bit words, following the operating system normal\n")); | |
| 146 P((" organization (low-byte first for VMS and DOS; high byte first\n")); | |
| 147 P((" for most Unix systems). G711 compressed data is supposed to be\n")); | |
| 148 P((" in the 8 LEAST significant bits of the word and the ADPCM data\n")); | |
| 149 P((" is in the LEAST 5 bits. Both are without sign extension.\n")); | |
| 150 P(("\n")); | |
| 151 P((" Output data will be generated in the same format as decribed\n")); | |
| 152 P((" above for the input data.\n")); | |
| 153 P(("\n")); | |
| 154 | |
| 155 P(("> Usage:\n")); | |
| 156 P(("$ G726demo [-options] Law Transf Rate InpFile OutFile \n")); | |
| 157 P((" [BlockSize [1stBlock [NoOfBlocks [Reset]]]]\n")); | |
| 158 P((" where:\n")); | |
| 159 P((" Law is the law desired (either A or u)\n")); | |
| 160 P((" Transf is the desired conversion on the input file:\n")); | |
| 161 P((" [lolo], (A/u)log -> ADPCM -> (A/u) log\n")); | |
| 162 P((" [load], (A/u)log -> ADPCM \n")); | |
| 163 P((" [adlo], ADPCM -> (A/u) log\n")); | |
| 164 P((" Rate is the number of ADPCM bits per sample:\n")); | |
| 165 P((" [5],[40] -> 5 bits per sample (40 kbit/s)\n")); | |
| 166 P((" [4],[32] -> 4 bits per sample (32 kbit/s)\n")); | |
| 167 P((" [3],[24] -> 3 bits per sample (24 kbit/s)\n")); | |
| 168 P((" [2],[16] -> 2 bits per sample (16 kbit/s)\n")); | |
| 169 P((" InpFile is the name of the file to be processed;\n")); | |
| 170 P((" OutFile is the name with the processed data;\n")); | |
| 171 P((" BlockSize is the block size, in number of samples\n")); | |
| 172 P((" 1stBlock is the number of the first block of the input file\n")); | |
| 173 P((" to be processed;\n")); | |
| 174 P((" NoOfBlocks is the number of blocks to be processed, starting on\n")); | |
| 175 P((" block \"1stBlock\"\n")); | |
| 176 P((" Reset is the optional reset. If specified as 1, the\n")); | |
| 177 P((" coder and decoder will be reset at the very\n")); | |
| 178 P((" beginning of the processings. If 0, the\n")); | |
| 179 P((" processing will start with the variables at a\n")); | |
| 180 P((" unknown state. It defaults to 1 (reset ON). \n")); | |
| 181 P((" Options: \n")); | |
| 182 P((" -noreset don't apply reset to the encoder/decoder\n")); | |
| 183 P((" -? or -help print this help message\n")); | |
| 184 P(("\n")); | |
| 185 | |
| 186 /* Quit program */ | |
| 187 exit(-128); | |
| 188 } | |
| 189 | |
| 190 #undef P | |
| 191 /* .................... End of display_usage() ........................... */ | |
| 192 | |
| 193 | |
| 194 /* | |
| 195 ************************************************************************** | |
| 196 *** *** | |
| 197 *** Demo-Program for testing the correct implementation *** | |
| 198 *** and to show how to use the programs *** | |
| 199 *** *** | |
| 200 ************************************************************************** | |
| 201 */ | |
| 202 int main(argc, argv) | |
| 203 int argc; | |
| 204 char *argv[]; | |
| 205 { | |
| 206 G726_state encoder_state, decoder_state; | |
| 207 long N = 256, N1 = 1, N2 = 0, cur_blk, smpno; | |
| 208 short *tmp_buf, *inp_buf, *out_buf, reset = 1; | |
| 209 short inp_type, out_type, rate; | |
| 210 | |
| 211 /* Progress indication */ | |
| 212 static char quiet = 0, funny[9] = "|/-\\|/-\\"; | |
| 213 | |
| 214 /* File variables */ | |
| 215 char FileIn[80], FileOut[80], law[4], lilo[8]; | |
| 216 FILE *Fi, *Fo; | |
| 217 int inp, out; | |
| 218 long start_byte; | |
| 219 #ifdef VMS | |
| 220 char mrs[15]; | |
| 221 #endif | |
| 222 | |
| 223 /* | |
| 224 * ......... PARAMETERS FOR PROCESSING ......... | |
| 225 */ | |
| 226 | |
| 227 /* GETTING OPTIONS */ | |
| 228 | |
| 229 if (argc < 2) | |
| 230 display_usage(); | |
| 231 else { | |
| 232 while (argc > 1 && argv[1][0] == '-') | |
| 233 if (strcmp(argv[1], "-noreset") == 0) { | |
| 234 /* No reset */ | |
| 235 reset = 0; | |
| 236 | |
| 237 /* Update argc/argv to next valid option/argument */ | |
| 238 argv++; | |
| 239 argc--; | |
| 240 } else if (strcmp(argv[1], "-q") == 0) { | |
| 241 /* Don't print progress indicator */ | |
| 242 quiet = 1; | |
| 243 | |
| 244 /* Move argv over the option to the next argument */ | |
| 245 argv++; | |
| 246 argc--; | |
| 247 } else if (strcmp(argv[1], "-?") == 0 | |
| 248 || strcmp(argv[1], "-help") == 0) { | |
| 249 /* Print help */ | |
| 250 display_usage(); | |
| 251 } else { | |
| 252 fprintf(stderr, | |
| 253 "ERROR! Invalid option \"%s\" in command line\n\n", argv[1]); | |
| 254 display_usage(); | |
| 255 } | |
| 256 } | |
| 257 | |
| 258 /* Now get regular parameters */ | |
| 259 GET_PAR_S(1, "_Law (A,u): ................... ", law); | |
| 260 GET_PAR_S(2, "_Operation (lolo,load,adlo): .. ", lilo); | |
| 261 GET_PAR_I(3, "_Rate or bits/ADPCM sample: ... ", rate); | |
| 262 GET_PAR_S(4, "_Input File: .................. ", FileIn); | |
| 263 GET_PAR_S(5, "_Output File: ................. ", FileOut); | |
| 264 FIND_PAR_L(6, "_Block Size: .................. ", N, 256); | |
| 265 FIND_PAR_L(7, "_Starting Block: .............. ", N1, 1); | |
| 266 FIND_PAR_L(8, "_No. of Blocks: ............... ", N2, 0); | |
| 267 FIND_PAR_I(9, "_Reset (YES=1, NO=0): ......... ", reset, 1); | |
| 268 | |
| 269 /* Find starting byte in file */ | |
| 270 start_byte = sizeof(short) * (long) (--N1) * (long) N; | |
| 271 | |
| 272 /* Check if is to process the whole file */ | |
| 273 if (N2 == 0) { | |
| 274 struct stat st; | |
| 275 | |
| 276 /* ... find the input file size ... */ | |
| 277 stat(FileIn, &st); | |
| 278 N2 = ceil((st.st_size - start_byte) / (double) (N * sizeof(short))); | |
| 279 } | |
| 280 | |
| 281 /* Classification of the conversion desired */ | |
| 282 inp_type = toupper(lilo[1]) == 'O' ? IS_LOG : IS_ADPCM; | |
| 283 out_type = toupper(lilo[3]) == 'O' ? IS_LOG : IS_ADPCM; | |
| 284 if ((out_type == IS_ADPCM) && (inp_type == IS_ADPCM)) | |
| 285 HARAKIRI("Bad conversion chosen (lolo,load,adlo)! Aborted...\n", 8); | |
| 286 | |
| 287 /* Classification of law */ | |
| 288 if (toupper(law[0]) == (char) 'A') | |
| 289 law[0] = '1'; | |
| 290 else if (toupper(law[0]) == (char) 'U') | |
| 291 law[0] = '0'; | |
| 292 else | |
| 293 HARAKIRI(" Invalid law (A or u)! Aborted...\n", 7); | |
| 294 | |
| 295 /* Classification of rate */ | |
| 296 if (rate > 5) { | |
| 297 if (rate == 40) | |
| 298 rate = 5; | |
| 299 else if (rate == 32) | |
| 300 rate = 4; | |
| 301 else if (rate == 24) | |
| 302 rate = 3; | |
| 303 else if (rate == 16) | |
| 304 rate = 2; | |
| 305 else { | |
| 306 HARAKIRI(" Invalid rate (5/4/3/2) or (40/32/24/16)! Aborted...\n", | |
| 307 9); | |
| 308 } | |
| 309 } | |
| 310 | |
| 311 /* | |
| 312 * ...... MEMORY ALLOCATION ......... | |
| 313 */ | |
| 314 | |
| 315 if ((inp_buf = (short *) calloc(N, sizeof(short))) == NULL) | |
| 316 HARAKIRI("Error in memory allocation!\n", 1); | |
| 317 if ((out_buf = (short *) calloc(N, sizeof(short))) == NULL) | |
| 318 HARAKIRI("Error in memory allocation!\n", 1); | |
| 319 if ((tmp_buf = (short *) calloc(N, sizeof(short))) == NULL) | |
| 320 HARAKIRI("Error in memory allocation!\n", 1); | |
| 321 | |
| 322 /* | |
| 323 * ......... FILE PREPARATION ......... | |
| 324 */ | |
| 325 | |
| 326 /* Opening input file; abort if there's any problem */ | |
| 327 if ((Fi = fopen(FileIn, "rb")) == NULL) | |
| 328 KILL(FileIn, 2); | |
| 329 inp = fileno(Fi); | |
| 330 | |
| 331 /* Creates output file */ | |
| 332 #ifdef VMS | |
| 333 sprintf(mrs, "mrs=%d", 512); | |
| 334 #endif | |
| 335 if ((Fo = fopen(FileOut, WB)) == NULL) | |
| 336 KILL(FileOut, 3); | |
| 337 out = fileno(Fo); | |
| 338 | |
| 339 /* Move pointer to 1st block of interest */ | |
| 340 if (fseek(Fi, start_byte, 0) < 0l) | |
| 341 KILL(FileIn, 4); | |
| 342 | |
| 343 /* | |
| 344 * ......... PROCESSING ACCORDING TO ITU-T G.726 ......... | |
| 345 */ | |
| 346 | |
| 347 for (cur_blk = 0; cur_blk < N2; cur_blk++) { | |
| 348 /* Print progress flag */ | |
| 349 if (!quiet) | |
| 350 fprintf(stderr, "%c\r", funny[cur_blk % 8]); | |
| 351 | |
| 352 /* Read a block of samples */ | |
| 353 if ((smpno = fread(inp_buf, sizeof(short), N, Fi)) < 0) | |
| 354 KILL(FileIn, 5); | |
| 355 | |
| 356 /* Check if reset is needed */ | |
| 357 reset = (reset == 1 && cur_blk == 0) ? 1 : 0; | |
| 358 | |
| 359 /* Carry out the desired operation */ | |
| 360 if (inp_type == IS_LOG && out_type == IS_ADPCM) { | |
| 361 G726_encode(inp_buf, out_buf, smpno, law, rate, reset, | |
| 362 &encoder_state); | |
| 363 } else if (inp_type == IS_ADPCM && out_type == IS_LOG) { | |
| 364 G726_decode(inp_buf, out_buf, smpno, law, rate, reset, | |
| 365 &decoder_state); | |
| 366 } else if (inp_type == IS_LOG && out_type == IS_LOG) { | |
| 367 G726_encode(inp_buf, tmp_buf, smpno, law, rate, reset, | |
| 368 &encoder_state); | |
| 369 G726_decode(tmp_buf, out_buf, smpno, law, rate, reset, | |
| 370 &decoder_state); | |
| 371 } | |
| 372 | |
| 373 /* Write ADPCM output word */ | |
| 374 if ((smpno = fwrite(out_buf, sizeof(short), smpno, Fo)) < 0) | |
| 375 KILL(FileOut, 6); | |
| 376 } | |
| 377 | |
| 378 /* | |
| 379 * ......... FINALIZATIONS ......... | |
| 380 */ | |
| 381 | |
| 382 /* Close input and output files */ | |
| 383 fclose(Fi); | |
| 384 fclose(Fo); | |
| 385 | |
| 386 /* Exit with success for non-vms systems */ | |
| 387 #ifndef VMS | |
| 388 return (0); | |
| 389 #endif | |
| 390 } | |
| 391 | |
| 392 /* ............................. end of main() ............................. */ |
