2
|
1 /* v1.1 - 22/Feb/1996
|
|
2 ============================================================================
|
|
3
|
|
4 RPEDEMO.C
|
|
5 ~~~~~~~~~~
|
|
6
|
|
7 Description:
|
|
8 ~~~~~~~~~~~~
|
|
9
|
|
10 Demonstration program for UGST/ITU-T RPE-LTP module. Takes the
|
|
11 input file and processes by the GSM 06.10 Full Rate speech codec,
|
|
12 depending on user's option: for encoding, input must be in
|
|
13 either linear, A, mu law (G711); for decoding, in GSM 06.10 76-word
|
|
14 format. The modules called have been written in Unix-C by Jutta
|
|
15 Deneger and Carsten Borman, within the Communications and
|
|
16 Operating Systems Research Group (KBS) of the Technishe Universitaet
|
|
17 Berlin. This demo program has been written by Simao F.Campos Neto,
|
|
18 from CPqD/Telebras based on previous UGST demo programs, as well on
|
|
19 a driving program by the RPE-LTP program.
|
|
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
|
|
24 most Unix systems). G711 compressed data is supposed to be in the 8
|
|
25 LEAST significant bits of the word and the RPE-LTP data will use a
|
|
26 varied number of least significant bits. Both are without sign
|
|
27 extension. Linear format, on its hand, expect data to be 16-bit
|
|
28 aligned to the left, and the algorith will take only the 13 most
|
|
29 significant bits. This complies to the general UGST integer data
|
|
30 format.
|
|
31
|
|
32 Output data will be generated in the same format as decribed
|
|
33 above for the input data.
|
|
34
|
|
35 Usage:
|
|
36 ~~~~~~
|
|
37 $ rpedemo [-l|-u|-A] [-enc|-dec] InpFile OutFile BlockSize 1stBlock
|
|
38 NoOfBlocks
|
|
39 where:
|
|
40 -l .......... input data for encoding and output data for decoding
|
|
41 are in linear format (DEFAULT).
|
|
42 -A .......... input data for encoding and output data for decoding
|
|
43 are in A-law (G.711) format.
|
|
44 -u .......... input data for encoding and output data for decoding
|
|
45 are in u-law (G.711) format.
|
|
46 -enc ........ run the only the decoder (default: run enc+dec)
|
|
47 -dec ........ run the only the encoder (default: run enc+dec)
|
|
48
|
|
49 InpFile ..... is the name of the file to be processed;
|
|
50 OutFile ..... is the name with the processed data;
|
|
51 BlockSize ... is the block size, in number of samples (default = 160)
|
|
52 1stBlock .... is the number of the first block of the input file
|
|
53 to be processed;
|
|
54 NoOfBlocks .. is the number of blocks to be processed, starting on
|
|
55 block "1stBlock"
|
|
56
|
|
57 Exit values:
|
|
58 ~~~~~~~~~~~~
|
|
59 0 success (all but VMS);
|
|
60 1 success (only in VMS);
|
|
61 2 error opening input file;
|
|
62 3 error creating output file;
|
|
63 4 error moving pointer to desired start of conversion;
|
|
64 5 error creating gsm object (i.e., state variable);
|
|
65 6 error reading input file;
|
|
66 7 error writing to file;
|
|
67
|
|
68 Original authors:
|
|
69 ~~~~~~~~~~~~~~~~~
|
|
70 Demo program:
|
|
71 Simao Ferraz de Campos Neto EMail : simao@cpqd.ansp.br
|
|
72 CPqD/Telebras Rd. Mogi Mirim-Campinas Km.118
|
|
73 DDS/Pr.11 13.088-061 - Campinas - SP (Brazil)
|
|
74
|
|
75 Module routines:
|
|
76 Jutta Degener (jutta@cs.tu-berlin.de)
|
|
77 Carsten Bormann (cabo@cs.tu-berlin.de)
|
|
78
|
|
79 History:
|
|
80 ~~~~~~~~
|
|
81 28/Oct/92 r.1.0 pl.0 by Carsten Bormann (cabo at kubus)
|
|
82 Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
|
|
83 Universitaet Berlin. See the accompanying file "COPYRIGHT" for
|
|
84 details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
|
85
|
|
86 30/Oct/92 r.1.0 pl.1 by Jutta Degener (jutta at kraftbus)
|
|
87 Switched uid/gid in toast's [f]chown calls.
|
|
88
|
|
89 29/Jan/93 r.1.0 pl.2 by Jutta Degener (jutta at kraftbus)
|
|
90 fixed L_add(0,-1) in src/add.c and inc/private.h,
|
|
91 thanks to Raphael Trommer at AT&T Bell Laboratories;
|
|
92 * ANSI C compatibility details
|
|
93
|
|
94 20/Mar/94 v1.0 Release of 1st version of demo program
|
|
95
|
|
96 22/Feb/95 v1.1 Cleaned compilation warnings, modified for Alpha VMX/AXP
|
|
97 operation (as suggested by Kirchherr, FI/DBP Telekom)
|
|
98 <simao@ctd.comsat.com>
|
|
99 ============================================================================
|
|
100 */
|
|
101
|
|
102
|
|
103 /* ..... General definitions for UGST demo programs ..... */
|
|
104 #include "ugstdemo.h"
|
|
105
|
|
106 /* ..... General include ..... */
|
|
107 #include <stdio.h>
|
|
108 #include <stdlib.h>
|
|
109 #include <string.h>
|
|
110
|
|
111 #if defined(VMS)
|
|
112 #include <stat.h>
|
|
113 #else /* Unix/DOS */
|
|
114 #include <sys/stat.h>
|
|
115 #endif
|
|
116
|
|
117 /* ..... RPE-LTP module definitions ..... */
|
|
118 #include "private.h"
|
|
119 #include "gsm.h"
|
|
120 #include "rpeltp.h"
|
|
121
|
|
122 /* ..... G.711 module definitions ..... */
|
|
123 #include "g711.h"
|
|
124
|
|
125 /* ..... Local definitions ..... */
|
|
126 #define LINEAR 0 /* binary: 00 */
|
|
127 #define U_LAW 1 /* binary: 01 */
|
|
128 #define A_LAW 3 /* binary: 11 */
|
|
129
|
|
130 /* ..... Local function prototypes ..... */
|
|
131 void display_usage ARGS((void));
|
|
132 int main ARGS((int argc, char *argv[]));
|
|
133
|
|
134
|
|
135 /*
|
|
136 -------------------------------------------------------------------------
|
|
137 void display_usage(void);
|
|
138 ~~~~~~~~~~~~~~~~~~
|
|
139 Display proper usage for the demo program. Generated automatically from
|
|
140 program documentation.
|
|
141
|
|
142 History:
|
|
143 ~~~~~~~~
|
|
144 20.Mar.94 v1.0 Created.
|
|
145 -------------------------------------------------------------------------
|
|
146 */
|
|
147 #define P(x) printf x
|
|
148 void display_usage()
|
|
149 {
|
|
150 P(("RPEDEMO: Version 1.0 of 17/Mar/1994 \n\n"));
|
|
151
|
|
152 P((" Demonstration program for UGST/ITU-T RPE-LTP based on \n"));
|
|
153 P((" module implemented in Unix-C by Jutta Deneger and Carsten \n"));
|
|
154 P((" Borman, within the Communications and Operating Systems \n"));
|
|
155 P((" Research Group (KBS) of the Technishe Universitaet Berlin.\n"));
|
|
156 P((" This demo program has been written by Simao F.Campos Neto\n"));
|
|
157 P(("\n"));
|
|
158 P((" Usage:\n"));
|
|
159 P((" $ rpedemo [-l|-u|-A] [-enc|-dec] InpFile OutFile BlockSize 1stBlock\n"));
|
|
160 P((" NoOfBlocks \n"));
|
|
161 P((" where:\n"));
|
|
162 P((" -l .......... input data for encoding and output data for decoding\n"));
|
|
163 P((" are in linear format (DEFAULT).\n"));
|
|
164 P((" -A .......... input data for encoding and output data for decoding\n"));
|
|
165 P((" are in A-law (G.711) format.\n"));
|
|
166 P((" -u .......... input data for encoding and output data for decoding\n"));
|
|
167 P((" are in u-law (G.711) format.\n"));
|
|
168 P((" -enc ........ run the only the decoder (default: run enc+dec)\n"));
|
|
169 P((" -dec ........ run the only the encoder (default: run enc+dec)\n"));
|
|
170 P(("\n"));
|
|
171 P((" InpFile ..... is the name of the file to be processed;\n"));
|
|
172 P((" OutFile ..... is the name with the processed data;\n"));
|
|
173 P((" BlockSize ... is the block size, in number of samples (default = 160)\n"));
|
|
174 P((" 1stBlock .... is the number of the first block of the input file\n"));
|
|
175 P((" to be processed;\n"));
|
|
176 P((" NoOfBlocks .. is the number of blocks to be processed, starting on\n"));
|
|
177 P((" block \"1stBlock\"\n"));
|
|
178
|
|
179 /* Quit program */
|
|
180 exit(-128);
|
|
181 }
|
|
182
|
|
183 #undef P
|
|
184
|
|
185 /*
|
|
186 **************************************************************************
|
|
187 *** ***
|
|
188 *** Demo-Program for testing the correct implementation ***
|
|
189 *** and to show how to use the programs ***
|
|
190 *** ***
|
|
191 **************************************************************************
|
|
192 */
|
|
193 main(argc, argv)
|
|
194 int argc;
|
|
195 char *argv[];
|
|
196 {
|
|
197 gsm rpe_enc_state, rpe_dec_state;
|
|
198 gsm_signal rpe_frame[RPE_FRAME_SIZE];
|
|
199 Byte gsm_frame[33];
|
|
200 long N = 256, N1 = 1, N2 = 0, cur_blk, smpno, count = 0;
|
|
201 #ifdef STATIC_ALLOCATION
|
|
202 short tmp_buf[256], inp_buf[256], out_buf[256];
|
|
203 #else
|
|
204 short *tmp_buf, *inp_buf, *out_buf;
|
|
205 #endif
|
|
206
|
|
207 /* G.711 Compression/expansion function pointers */
|
|
208 void (*compress) (), (*expand) ();
|
|
209
|
|
210 /* File variables */
|
|
211 char FileIn[80], FileOut[80];
|
|
212 FILE *Fi, *Fo;
|
|
213 long start_byte;
|
|
214 char format, run_encoder, run_decoder;
|
|
215 #ifdef VMS
|
|
216 char mrs[15];
|
|
217 #endif
|
|
218
|
|
219
|
|
220 /* SETTING DEFAULT OPTIONS */
|
|
221 format = LINEAR;
|
|
222 run_encoder = run_decoder = 1;
|
|
223
|
|
224 /* GETTING OPTIONS */
|
|
225
|
|
226 if (argc < 2)
|
|
227 display_usage();
|
|
228 else {
|
|
229 while (argc > 1 && argv[1][0] == '-')
|
|
230 if (strcmp(argv[1], "-") == 0) {
|
|
231 /* Oops, stop processing options! */
|
|
232 break;
|
|
233 } else if (strcmp(argv[1], "-l") == 0) {
|
|
234 /* Input/output (uncoded) data format is linear */
|
|
235 format = LINEAR;
|
|
236
|
|
237 /* Move arg[cv] over the next valid option */
|
|
238 argv++;
|
|
239 argc--;
|
|
240 } else if (strcmp(argv[1], "-A") == 0
|
|
241 || strcmp(argv[1], "-a") == 0) {
|
|
242 /* Input/output (uncoded) data format is A-law (G.711) */
|
|
243 format = A_LAW;
|
|
244
|
|
245 /* Move arg[cv] over the next valid option */
|
|
246 argv++;
|
|
247 argc--;
|
|
248 } else if (strcmp(argv[1], "-u") == 0) {
|
|
249 /* Input/output (uncoded) data format is u-law (G.711) */
|
|
250 format = U_LAW;
|
|
251
|
|
252 /* Move arg[cv] over the next valid option */
|
|
253 argv++;
|
|
254 argc--;
|
|
255 } else if (strcmp(argv[1], "-enc") == 0) {
|
|
256 /* Run only the encoder */
|
|
257 run_encoder = 1;
|
|
258 run_decoder = 0;
|
|
259
|
|
260 /* Move arg[cv] over the next valid option */
|
|
261 argv++;
|
|
262 argc--;
|
|
263 } else if (strcmp(argv[1], "-dec") == 0) {
|
|
264 /* Run only the encoder */
|
|
265 run_encoder = 0;
|
|
266 run_decoder = 1;
|
|
267
|
|
268 /* Move arg[cv] over the next valid option */
|
|
269 argv++;
|
|
270 argc--;
|
|
271 } else {
|
|
272 fprintf(stderr,
|
|
273 "ERROR! Invalid option \"%s\" in command line\n\n", argv[1]);
|
|
274 display_usage();
|
|
275 }
|
|
276 }
|
|
277
|
|
278 GET_PAR_S(1, "_Input File: .................. ", FileIn);
|
|
279 GET_PAR_S(2, "_Output File: ................. ", FileOut);
|
|
280 FIND_PAR_L(3, "_Block Size: .................. ", N, RPE_WIND_SIZE);
|
|
281 FIND_PAR_L(4, "_Starting Block: .............. ", N1, 1);
|
|
282 FIND_PAR_L(5, "_No. of Blocks: ............... ", N2, 0);
|
|
283
|
|
284
|
|
285 /* Find staring byte in file; all are 16-bit word-aligned =>short data type */
|
|
286 start_byte = sizeof(short) * (long) (--N1) * (long) N;
|
|
287
|
|
288 /* Check if is to process the whole file */
|
|
289 if (N2 == 0) {
|
|
290 struct stat st;
|
|
291
|
|
292 /* ... find the input file size ... */
|
|
293 stat(FileIn, &st);
|
|
294 /* convert to block count, depending on whether the input file
|
|
295 * is a uncoded or coded file */
|
|
296 if (run_encoder)
|
|
297 N2 = (st.st_size - start_byte) / (N * sizeof(short));
|
|
298 else
|
|
299 N2 = (st.st_size - start_byte) / (33 * sizeof(Byte));
|
|
300 }
|
|
301
|
|
302 /* Choose A/u law */
|
|
303 if (format == A_LAW) {
|
|
304 expand = alaw_expand;
|
|
305 compress = alaw_compress;
|
|
306 } else if (format == U_LAW) {
|
|
307 expand = ulaw_expand;
|
|
308 compress = ulaw_compress;
|
|
309 }
|
|
310
|
|
311
|
|
312 /*
|
|
313 * ...... MEMORY ALLOCATION .........
|
|
314 */
|
|
315 #ifndef STATIC_ALLOCATION
|
|
316 if ((inp_buf = (short *) calloc(N, sizeof(short))) == NULL)
|
|
317 HARAKIRI("Error in memory allocation!\n", 1);
|
|
318 if ((out_buf = (short *) calloc(N, sizeof(short))) == NULL)
|
|
319 HARAKIRI("Error in memory allocation!\n", 1);
|
|
320 if ((tmp_buf = (short *) calloc(N, sizeof(short))) == NULL)
|
|
321 HARAKIRI("Error in memory allocation!\n", 1);
|
|
322 #endif
|
|
323
|
|
324
|
|
325 /*
|
|
326 * ......... FILE PREPARATION .........
|
|
327 */
|
|
328
|
|
329 /* Define stuff for VMS binary, fixed-record files */
|
|
330 #ifdef VMS
|
|
331 sprintf(mrs, "mrs=%d", 512);
|
|
332 #endif
|
|
333
|
|
334 /* Opening input/output files; abort if there's any problem */
|
|
335 if ((Fi = fopen(FileIn, RB)) == NULL)
|
|
336 KILL(FileIn, 2);
|
|
337
|
|
338 if ((Fo = fopen(FileOut, WB)) == NULL)
|
|
339 KILL(FileOut, 3);
|
|
340
|
|
341 /* Move pointer to 1st block of interest */
|
|
342 if (fseek(Fi, start_byte, 0) < 0l)
|
|
343 KILL(FileIn, 4);
|
|
344
|
|
345 /* ......... CREATE AND INIT GSM OBJECT (STATE VARIABLE) ......... */
|
|
346 if (!(rpe_enc_state = rpeltp_init()))
|
|
347 HARAKIRI("Error creating state variable for encoder\n", 5);
|
|
348 if (!(rpe_dec_state = rpeltp_init()))
|
|
349 HARAKIRI("Error creating state variable for encoder\n", 5);
|
|
350
|
|
351
|
|
352 /* ......... PROCESSING ACCORDING TO GSM 06.10 RPE-LTP CODEC ......... */
|
|
353
|
|
354 for (cur_blk = 0; cur_blk < N2; cur_blk++) {
|
|
355 /* Reset output sample vector */
|
|
356 memset(out_buf, (int) 0, N);
|
|
357
|
|
358 /* Read a block of samples */
|
|
359 if (run_encoder) {
|
|
360 /* Reset sample vector */
|
|
361 memset(inp_buf, (int) 0, N);
|
|
362
|
|
363 /* Read a block of uncoded samples */
|
|
364 if ((smpno = fread(inp_buf, sizeof(short), (long) N, Fi)) <= 0)
|
|
365 break;
|
|
366 } else {
|
|
367 /* Reset frame vector */
|
|
368 memset(rpe_frame, (int) 0, (long) RPE_FRAME_SIZE);
|
|
369
|
|
370 /* Read a packed frame */
|
|
371 if ((smpno = fread(gsm_frame, sizeof(Byte), 33, Fi)) <= 0) {
|
|
372 fprintf(stderr, "fread gsm_frame\n");
|
|
373 break;
|
|
374 }
|
|
375 }
|
|
376
|
|
377 /* Carry out the desired operation */
|
|
378
|
|
379 /* CODEC OPERATION */
|
|
380 if (run_encoder && run_decoder) {
|
|
381 /* Run both and save decoded samples */
|
|
382
|
|
383 /* First, expand samples, if needed */
|
|
384 if (format) {
|
|
385 memcpy(tmp_buf, inp_buf, (long) (sizeof(short) * smpno));
|
|
386 expand(smpno, tmp_buf, inp_buf);
|
|
387 }
|
|
388
|
|
389 /* Encode & decode ... */
|
|
390 rpeltp_encode(rpe_enc_state, inp_buf, rpe_frame);
|
|
391 rpeltp_decode(rpe_dec_state, rpe_frame, out_buf);
|
|
392
|
|
393 /* Compress samples, if requested */
|
|
394 if (format) {
|
|
395 memcpy(tmp_buf, out_buf, (long) (sizeof(short) * N));
|
|
396 compress(N, tmp_buf, out_buf);
|
|
397 }
|
|
398
|
|
399 /* Save samples to file */
|
|
400 if (!(smpno = fwrite(out_buf, sizeof(short), (long) smpno, Fo)))
|
|
401 break;
|
|
402 }
|
|
403 /* ENCODER-ONLY OPERATION */
|
|
404 else if (run_encoder) {
|
|
405
|
|
406 /* First, expand samples, if needed */
|
|
407 if (format) {
|
|
408 memcpy(tmp_buf, inp_buf, (long) (sizeof(short) * smpno));
|
|
409 expand(smpno, tmp_buf, inp_buf);
|
|
410 }
|
|
411
|
|
412 /* Run only the encoder and save rpe-ltp frame */
|
|
413 gsm_encode(rpe_enc_state, inp_buf, gsm_frame);
|
|
414
|
|
415 if (!(smpno =
|
|
416 fwrite(gsm_frame, sizeof(Byte), 33, Fo)))
|
|
417 break;
|
|
418 }
|
|
419 /* DECODER-ONLY OPERATION */
|
|
420 else {
|
|
421 /* Decode frame */
|
|
422 gsm_decode(rpe_dec_state, gsm_frame, out_buf);
|
|
423
|
|
424 /* Compress samples, if requested */
|
|
425 if (format) {
|
|
426 memcpy(tmp_buf, out_buf, (long) (sizeof(short) * N));
|
|
427 compress(N, tmp_buf, out_buf);
|
|
428 }
|
|
429
|
|
430 /* Save the decoded samples */
|
|
431 if (!(smpno = fwrite(out_buf, sizeof(short), (long) N, Fo)))
|
|
432 break;
|
|
433 }
|
|
434 count += smpno;
|
|
435 }
|
|
436
|
|
437 /* Check for errors */
|
|
438 if (ferror(Fi))
|
|
439 KILL(FileIn, 6);
|
|
440 else if (ferror(Fo))
|
|
441 KILL(FileOut, 7);
|
|
442
|
|
443 /* ......... FINALIZATIONS ......... */
|
|
444
|
|
445 /* Close input and output files and state */
|
|
446 fclose(Fi);
|
|
447 fclose(Fo);
|
|
448 rpeltp_delete(rpe_enc_state);
|
|
449 rpeltp_delete(rpe_dec_state);
|
|
450
|
|
451 /* Exit with success for non-vms systems */
|
|
452 #ifndef VMS
|
|
453 return (0);
|
|
454 #endif
|
|
455 }
|
|
456
|
|
457 /* ............................. end of main() ............................. */
|