Mercurial > hg > audiostuff
comparison intercom/gsm/rpedemo.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 /* 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() ............................. */ |