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

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.