2
|
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() ............................. */
|