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