Mercurial > hg > audiostuff
comparison spandsp-0.0.6pre17/tests/g722_tests.c @ 4:26cd8f1ef0b1
import spandsp-0.0.6pre17
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 15:50:58 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
3:c6c5a16ce2f2 | 4:26cd8f1ef0b1 |
---|---|
1 /* | |
2 * SpanDSP - a series of DSP components for telephony | |
3 * | |
4 * g722_tests.c - Test G.722 encode and decode. | |
5 * | |
6 * Written by Steve Underwood <steveu@coppice.org> | |
7 * | |
8 * Copyright (C) 2005 Steve Underwood | |
9 * | |
10 * All rights reserved. | |
11 * | |
12 * This program is free software; you can redistribute it and/or modify | |
13 * it under the terms of the GNU General Public License version 2, as | |
14 * published by the Free Software Foundation. | |
15 * | |
16 * This program is distributed in the hope that it will be useful, | |
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 * GNU General Public License for more details. | |
20 * | |
21 * You should have received a copy of the GNU General Public License | |
22 * along with this program; if not, write to the Free Software | |
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
24 * | |
25 * $Id: g722_tests.c,v 1.32 2009/06/02 14:55:36 steveu Exp $ | |
26 */ | |
27 | |
28 /*! \file */ | |
29 | |
30 /*! \page g722_tests_page G.722 tests | |
31 \section g722_tests_page_sec_1 What does it do? | |
32 This modules implements two sets of tests: | |
33 - The tests defined in the G.722 specification, using the test data files supplied | |
34 with the specification. | |
35 - A generally audio quality test, consisting of compressing and decompressing a speeech | |
36 file for audible comparison. | |
37 | |
38 The speech file should be recorded at 16 bits/sample, 16000 samples/second, and named | |
39 "pre_g722.wav". | |
40 | |
41 The ITU tests use the codec in a special mode, in which the QMFs, which split and recombine the | |
42 sub-bands, are disabled. This means they do not test 100% of the codec. This is the reason for | |
43 including the additional listening test. | |
44 | |
45 \section g722_tests_page_sec_2 How is it used? | |
46 To perform the tests in the G.722 specification you need to obtain the test data files from the | |
47 specification. These are copyright material, and so cannot be distributed with this test software. | |
48 | |
49 The files, containing test vectors, which are supplied with the G.722 specification, should be | |
50 copied to itutests/g722. The ITU tests can then be run by executing g722_tests without | |
51 any parameters. | |
52 | |
53 To perform a general audio quality test, g722_tests should be run with a parameter specifying | |
54 the required bit rate for compression. The valid parameters are "-48", "-56", and "-64". | |
55 The file ../test-data/local/short_wb_voice.wav will be compressed to the specified bit rate, decompressed, | |
56 and the resulting audio stored in post_g722.wav. | |
57 */ | |
58 | |
59 /* Enable the following definition to enable direct probing into the FAX structures */ | |
60 //#define WITH_SPANDSP_INTERNALS | |
61 | |
62 #if defined(HAVE_CONFIG_H) | |
63 #include <config.h> | |
64 #endif | |
65 | |
66 #include <stdlib.h> | |
67 #include <stdio.h> | |
68 #include <fcntl.h> | |
69 #include <unistd.h> | |
70 #include <memory.h> | |
71 #include <ctype.h> | |
72 #include <sndfile.h> | |
73 | |
74 #include "spandsp.h" | |
75 | |
76 #if 1 //defined(WITH_SPANDSP_INTERNALS) | |
77 #include "spandsp/private/g722.h" | |
78 #endif | |
79 | |
80 #define G722_SAMPLE_RATE 16000 | |
81 | |
82 #define BLOCK_LEN 320 | |
83 | |
84 #define MAX_TEST_VECTOR_LEN 40000 | |
85 | |
86 #define TESTDATA_DIR "../test-data/itu/g722/" | |
87 | |
88 #define EIGHTK_IN_FILE_NAME "../test-data/local/short_nb_voice.wav" | |
89 #define IN_FILE_NAME "../test-data/local/short_wb_voice.wav" | |
90 #define ENCODED_FILE_NAME "g722.g722" | |
91 #define OUT_FILE_NAME "post_g722.wav" | |
92 | |
93 #if 0 | |
94 static const char *itu_test_files[] = | |
95 { | |
96 TESTDATA_DIR "T1C1.XMT", /* 69973 bytes */ | |
97 TESTDATA_DIR "T1C2.XMT", /* 3605 bytes */ | |
98 TESTDATA_DIR "T1D3.COD", /* 69973 bytes */ | |
99 | |
100 TESTDATA_DIR "T2R1.COD", /* 69973 bytes */ | |
101 TESTDATA_DIR "T2R2.COD", /* 3605 bytes */ | |
102 | |
103 TESTDATA_DIR "T3L1.RC1", /* 69973 bytes */ | |
104 TESTDATA_DIR "T3L1.RC2", /* 69973 bytes */ | |
105 TESTDATA_DIR "T3L1.RC3", /* 69973 bytes */ | |
106 TESTDATA_DIR "T3H1.RC0", /* 69973 bytes */ | |
107 TESTDATA_DIR "T3L2.RC1", /* 3605 bytes */ | |
108 TESTDATA_DIR "T3L2.RC2", /* 3605 bytes */ | |
109 TESTDATA_DIR "T3L2.RC3", /* 3605 bytes */ | |
110 TESTDATA_DIR "T3H2.RC0", /* 3605 bytes */ | |
111 TESTDATA_DIR "T3L3.RC1", /* 69973 bytes */ | |
112 TESTDATA_DIR "T3L3.RC2", /* 69973 bytes */ | |
113 TESTDATA_DIR "T3L3.RC3", /* 69973 bytes */ | |
114 TESTDATA_DIR "T3H3.RC0" /* 69973 bytes */ | |
115 }; | |
116 #endif | |
117 | |
118 static const char *encode_test_files[] = | |
119 { | |
120 TESTDATA_DIR "T1C1.XMT", | |
121 TESTDATA_DIR "T2R1.COD", | |
122 TESTDATA_DIR "T1C2.XMT", | |
123 TESTDATA_DIR "T2R2.COD", | |
124 NULL | |
125 }; | |
126 | |
127 static const char *decode_test_files[] = | |
128 { | |
129 TESTDATA_DIR "T2R1.COD", | |
130 TESTDATA_DIR "T3L1.RC1", | |
131 TESTDATA_DIR "T3L1.RC2", | |
132 TESTDATA_DIR "T3L1.RC3", | |
133 TESTDATA_DIR "T3H1.RC0", | |
134 | |
135 TESTDATA_DIR "T2R2.COD", | |
136 TESTDATA_DIR "T3L2.RC1", | |
137 TESTDATA_DIR "T3L2.RC2", | |
138 TESTDATA_DIR "T3L2.RC3", | |
139 TESTDATA_DIR "T3H2.RC0", | |
140 | |
141 TESTDATA_DIR "T1D3.COD", | |
142 TESTDATA_DIR "T3L3.RC1", | |
143 TESTDATA_DIR "T3L3.RC2", | |
144 TESTDATA_DIR "T3L3.RC3", | |
145 TESTDATA_DIR "T3H3.RC0", | |
146 | |
147 NULL | |
148 }; | |
149 | |
150 int16_t itu_data[MAX_TEST_VECTOR_LEN]; | |
151 uint16_t itu_ref[MAX_TEST_VECTOR_LEN]; | |
152 uint16_t itu_ref_upper[MAX_TEST_VECTOR_LEN]; | |
153 uint8_t compressed[MAX_TEST_VECTOR_LEN]; | |
154 int16_t decompressed[MAX_TEST_VECTOR_LEN]; | |
155 | |
156 static int hex_get(char *s) | |
157 { | |
158 int i; | |
159 int value; | |
160 int x; | |
161 | |
162 for (value = i = 0; i < 4; i++) | |
163 { | |
164 x = *s++ - 0x30; | |
165 if (x > 9) | |
166 x -= 0x07; | |
167 if (x > 15) | |
168 x -= 0x20; | |
169 if (x < 0 || x > 15) | |
170 return -1; | |
171 value <<= 4; | |
172 value |= x; | |
173 } | |
174 return value; | |
175 } | |
176 /*- End of function --------------------------------------------------------*/ | |
177 | |
178 static int get_vector(FILE *file, uint16_t vec[]) | |
179 { | |
180 char buf[132 + 1]; | |
181 char *s; | |
182 int i; | |
183 int value; | |
184 | |
185 while (fgets(buf, 133, file)) | |
186 { | |
187 if (buf[0] == '/' && buf[1] == '*') | |
188 continue; | |
189 s = buf; | |
190 i = 0; | |
191 while ((value = hex_get(s)) >= 0) | |
192 { | |
193 vec[i++] = value; | |
194 s += 4; | |
195 } | |
196 return i; | |
197 } | |
198 return 0; | |
199 } | |
200 /*- End of function --------------------------------------------------------*/ | |
201 | |
202 static int get_test_vector(const char *file, uint16_t buf[], int max_len) | |
203 { | |
204 int octets; | |
205 int i; | |
206 FILE *infile; | |
207 | |
208 if ((infile = fopen(file, "r")) == NULL) | |
209 { | |
210 fprintf(stderr, " Failed to open '%s'\n", file); | |
211 exit(2); | |
212 } | |
213 octets = 0; | |
214 while ((i = get_vector(infile, buf + octets)) > 0) | |
215 octets += i; | |
216 fclose(infile); | |
217 return octets; | |
218 } | |
219 /*- End of function --------------------------------------------------------*/ | |
220 | |
221 static void itu_compliance_tests(void) | |
222 { | |
223 g722_encode_state_t enc_state; | |
224 g722_decode_state_t dec_state; | |
225 int i; | |
226 int j; | |
227 int k; | |
228 int len_comp; | |
229 int len_comp_upper; | |
230 int len_data; | |
231 int len; | |
232 int len2; | |
233 int mode; | |
234 int file; | |
235 | |
236 #if 1 | |
237 /* ITU G.722 encode tests, using configuration 1. The QMF is bypassed */ | |
238 for (file = 0; encode_test_files[file]; file += 2) | |
239 { | |
240 printf("Testing %s -> %s\n", encode_test_files[file], encode_test_files[file + 1]); | |
241 | |
242 /* Get the input data */ | |
243 len_data = get_test_vector(encode_test_files[file], (uint16_t *) itu_data, MAX_TEST_VECTOR_LEN); | |
244 | |
245 /* Get the reference output data */ | |
246 len_comp = get_test_vector(encode_test_files[file + 1], itu_ref, MAX_TEST_VECTOR_LEN); | |
247 | |
248 /* Process the input data */ | |
249 /* Skip the reset stuff at each end of the data */ | |
250 for (i = 0; i < len_data; i++) | |
251 { | |
252 if ((itu_data[i] & 1) == 0) | |
253 break; | |
254 } | |
255 for (j = i; j < len_data; j++) | |
256 { | |
257 if ((itu_data[j] & 1)) | |
258 break; | |
259 } | |
260 len = j - i; | |
261 g722_encode_init(&enc_state, 64000, 0); | |
262 enc_state.itu_test_mode = TRUE; | |
263 len2 = g722_encode(&enc_state, compressed, itu_data + i, len); | |
264 | |
265 /* Check the result against the ITU's reference output data */ | |
266 j = 0; | |
267 for (k = 0; k < len2; k++) | |
268 { | |
269 if ((compressed[k] & 0xFF) != ((itu_ref[k + i] >> 8) & 0xFF)) | |
270 { | |
271 printf(">>> %6d %4x %4x\n", k, compressed[k] & 0xFF, itu_ref[k + i] & 0xFFFF); | |
272 j++; | |
273 } | |
274 } | |
275 printf("%d bad samples, out of %d/%d samples\n", j, len, len_data); | |
276 if (j) | |
277 { | |
278 printf("Test failed\n"); | |
279 exit(2); | |
280 } | |
281 printf("Test passed\n"); | |
282 } | |
283 #endif | |
284 #if 1 | |
285 /* ITU G.722 decode tests, using configuration 2. The QMF is bypassed */ | |
286 /* Run each of the tests for each of the modes - 48kbps, 56kbps and 64kbps. */ | |
287 for (mode = 1; mode <= 3; mode++) | |
288 { | |
289 for (file = 0; decode_test_files[file]; file += 5) | |
290 { | |
291 printf("Testing mode %d, %s -> %s + %s\n", | |
292 mode, | |
293 decode_test_files[file], | |
294 decode_test_files[file + mode], | |
295 decode_test_files[file + 4]); | |
296 | |
297 /* Get the input data */ | |
298 len_data = get_test_vector(decode_test_files[file], (uint16_t *) itu_data, MAX_TEST_VECTOR_LEN); | |
299 | |
300 /* Get the lower reference output data */ | |
301 len_comp = get_test_vector(decode_test_files[file + mode], itu_ref, MAX_TEST_VECTOR_LEN); | |
302 | |
303 /* Get the upper reference output data */ | |
304 len_comp_upper = get_test_vector(decode_test_files[file + 4], itu_ref_upper, MAX_TEST_VECTOR_LEN); | |
305 | |
306 /* Process the input data */ | |
307 /* Skip the reset stuff at each end of the data */ | |
308 for (i = 0; i < len_data; i++) | |
309 { | |
310 if ((itu_data[i] & 1) == 0) | |
311 break; | |
312 } | |
313 for (j = i; j < len_data; j++) | |
314 { | |
315 if ((itu_data[j] & 1)) | |
316 break; | |
317 } | |
318 len = j - i; | |
319 for (k = 0; k < len; k++) | |
320 compressed[k] = itu_data[k + i] >> ((mode == 3) ? 10 : (mode == 2) ? 9 : 8); | |
321 | |
322 g722_decode_init(&dec_state, (mode == 3) ? 48000 : (mode == 2) ? 56000 : 64000, 0); | |
323 dec_state.itu_test_mode = TRUE; | |
324 len2 = g722_decode(&dec_state, decompressed, compressed, len); | |
325 | |
326 /* Check the result against the ITU's reference output data */ | |
327 j = 0; | |
328 for (k = 0; k < len2; k += 2) | |
329 { | |
330 if ((decompressed[k] & 0xFFFF) != (itu_ref[(k >> 1) + i] & 0xFFFF) | |
331 || | |
332 (decompressed[k + 1] & 0xFFFF) != (itu_ref_upper[(k >> 1) + i] & 0xFFFF)) | |
333 { | |
334 printf(">>> %6d %4x %4x %4x %4x\n", k >> 1, decompressed[k] & 0xFFFF, decompressed[k + 1] & 0xFFFF, itu_ref[(k >> 1) + i] & 0xFFFF, itu_ref_upper[(k >> 1) + i] & 0xFFFF); | |
335 j++; | |
336 } | |
337 } | |
338 printf("%d bad samples, out of %d/%d samples\n", j, len, len_data); | |
339 if (j) | |
340 { | |
341 printf("Test failed\n"); | |
342 exit(2); | |
343 } | |
344 printf("Test passed\n"); | |
345 } | |
346 } | |
347 #endif | |
348 printf("Tests passed.\n"); | |
349 } | |
350 /*- End of function --------------------------------------------------------*/ | |
351 | |
352 int main(int argc, char *argv[]) | |
353 { | |
354 g722_encode_state_t enc_state; | |
355 g722_decode_state_t dec_state; | |
356 int len2; | |
357 int len3; | |
358 int i; | |
359 int file; | |
360 SNDFILE *inhandle; | |
361 SNDFILE *outhandle; | |
362 SF_INFO info; | |
363 int outframes; | |
364 int samples; | |
365 int opt; | |
366 int itutests; | |
367 int bit_rate; | |
368 int eight_k_in; | |
369 int eight_k_out; | |
370 int encode; | |
371 int decode; | |
372 int tone_test; | |
373 const char *in_file; | |
374 const char *out_file; | |
375 int16_t indata[BLOCK_LEN]; | |
376 int16_t outdata[BLOCK_LEN]; | |
377 uint8_t adpcmdata[BLOCK_LEN]; | |
378 float tone_level; | |
379 uint32_t tone_phase; | |
380 int32_t tone_phase_rate; | |
381 | |
382 bit_rate = 64000; | |
383 eight_k_in = FALSE; | |
384 eight_k_out = FALSE; | |
385 itutests = TRUE; | |
386 encode = FALSE; | |
387 decode = FALSE; | |
388 tone_test = FALSE; | |
389 in_file = NULL; | |
390 out_file = NULL; | |
391 while ((opt = getopt(argc, argv, "b:d:e:i:l:o:t")) != -1) | |
392 { | |
393 switch (opt) | |
394 { | |
395 case 'b': | |
396 bit_rate = atoi(optarg); | |
397 if (bit_rate != 48000 && bit_rate != 56000 && bit_rate != 64000) | |
398 { | |
399 fprintf(stderr, "Invalid bit rate selected. Only 48000, 56000 and 64000 are valid.\n"); | |
400 exit(2); | |
401 } | |
402 itutests = FALSE; | |
403 break; | |
404 case 'd': | |
405 in_file = optarg; | |
406 decode = TRUE; | |
407 itutests = FALSE; | |
408 break; | |
409 case 'e': | |
410 in_file = optarg; | |
411 encode = TRUE; | |
412 itutests = FALSE; | |
413 break; | |
414 case 'i': | |
415 i = atoi(optarg); | |
416 if (i != 8000 && i != 16000) | |
417 { | |
418 fprintf(stderr, "Invalid incoming sample rate. Only 8000 and 16000 are valid.\n"); | |
419 exit(2); | |
420 } | |
421 eight_k_in = (i == 8000); | |
422 if (eight_k_in) | |
423 in_file = EIGHTK_IN_FILE_NAME; | |
424 break; | |
425 case 'l': | |
426 out_file = optarg; | |
427 break; | |
428 case 'o': | |
429 i = atoi(optarg); | |
430 if (i != 8000 && i != 16000) | |
431 { | |
432 fprintf(stderr, "Invalid outgoing sample rate. Only 8000 and 16000 are valid.\n"); | |
433 exit(2); | |
434 } | |
435 eight_k_out = (i == 8000); | |
436 break; | |
437 case 't': | |
438 tone_test = TRUE; | |
439 itutests = FALSE; | |
440 break; | |
441 default: | |
442 //usage(); | |
443 exit(2); | |
444 } | |
445 } | |
446 | |
447 if (itutests) | |
448 { | |
449 itu_compliance_tests(); | |
450 } | |
451 else | |
452 { | |
453 tone_level = dds_scaling_dbm0f(2.5f); | |
454 tone_phase = 0; | |
455 tone_phase_rate = dds_phase_ratef(1500.0f/2.0f); | |
456 if (!decode && !encode) | |
457 { | |
458 decode = | |
459 encode = TRUE; | |
460 } | |
461 if (in_file == NULL) | |
462 { | |
463 if (encode) | |
464 { | |
465 if (eight_k_in) | |
466 in_file = EIGHTK_IN_FILE_NAME; | |
467 else | |
468 in_file = IN_FILE_NAME; | |
469 } | |
470 else | |
471 { | |
472 in_file = ENCODED_FILE_NAME; | |
473 } | |
474 } | |
475 if (out_file == NULL) | |
476 { | |
477 out_file = (decode) ? OUT_FILE_NAME : ENCODED_FILE_NAME; | |
478 } | |
479 inhandle = NULL; | |
480 outhandle = NULL; | |
481 file = -1; | |
482 if (encode) | |
483 { | |
484 if (eight_k_in) | |
485 { | |
486 if ((inhandle = sf_open(in_file, SFM_READ, &info)) == NULL) | |
487 { | |
488 fprintf(stderr, " Cannot open audio file '%s'\n", in_file); | |
489 exit(2); | |
490 } | |
491 if (info.samplerate != SAMPLE_RATE) | |
492 { | |
493 fprintf(stderr, " Unexpected sample rate %d in audio file '%s'\n", info.samplerate, in_file); | |
494 exit(2); | |
495 } | |
496 if (info.channels != 1) | |
497 { | |
498 fprintf(stderr, " Unexpected number of channels in audio file '%s'\n", in_file); | |
499 exit(2); | |
500 } | |
501 } | |
502 else | |
503 { | |
504 if ((inhandle = sf_open(in_file, SFM_READ, &info)) == NULL) | |
505 { | |
506 fprintf(stderr, " Cannot open audio file '%s'\n", in_file); | |
507 exit(2); | |
508 } | |
509 if (info.samplerate != G722_SAMPLE_RATE) | |
510 { | |
511 fprintf(stderr, " Unexpected sample rate %d in audio file '%s'\n", info.samplerate, in_file); | |
512 exit(2); | |
513 } | |
514 if (info.channels != 1) | |
515 { | |
516 fprintf(stderr, " Unexpected number of channels in audio file '%s'\n", in_file); | |
517 exit(2); | |
518 } | |
519 } | |
520 if (eight_k_in) | |
521 g722_encode_init(&enc_state, bit_rate, G722_PACKED | G722_SAMPLE_RATE_8000); | |
522 else | |
523 g722_encode_init(&enc_state, bit_rate, G722_PACKED); | |
524 } | |
525 else | |
526 { | |
527 if ((file = open(in_file, O_RDONLY)) < 0) | |
528 { | |
529 fprintf(stderr, " Failed to open '%s'\n", in_file); | |
530 exit(2); | |
531 } | |
532 } | |
533 if (decode) | |
534 { | |
535 memset(&info, 0, sizeof(info)); | |
536 info.frames = 0; | |
537 info.samplerate = (eight_k_out) ? SAMPLE_RATE : G722_SAMPLE_RATE; | |
538 info.channels = 1; | |
539 info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16; | |
540 info.sections = 1; | |
541 info.seekable = 1; | |
542 if ((outhandle = sf_open(out_file, SFM_WRITE, &info)) == NULL) | |
543 { | |
544 fprintf(stderr, " Cannot create audio file '%s'\n", out_file); | |
545 exit(2); | |
546 } | |
547 if (eight_k_out) | |
548 g722_decode_init(&dec_state, bit_rate, G722_PACKED | G722_SAMPLE_RATE_8000); | |
549 else | |
550 g722_decode_init(&dec_state, bit_rate, G722_PACKED); | |
551 } | |
552 else | |
553 { | |
554 if ((file = open(out_file, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) | |
555 { | |
556 fprintf(stderr, " Failed to open '%s'\n", out_file); | |
557 exit(2); | |
558 } | |
559 } | |
560 for (;;) | |
561 { | |
562 if (encode) | |
563 { | |
564 samples = sf_readf_short(inhandle, indata, BLOCK_LEN); | |
565 if (samples <= 0) | |
566 break; | |
567 if (tone_test) | |
568 { | |
569 for (i = 0; i < samples; i++) | |
570 indata[i] = dds_modf(&tone_phase, tone_phase_rate, tone_level, 0); | |
571 } | |
572 len2 = g722_encode(&enc_state, adpcmdata, indata, samples); | |
573 } | |
574 else | |
575 { | |
576 len2 = read(file, adpcmdata, BLOCK_LEN); | |
577 if (len2 <= 0) | |
578 break; | |
579 } | |
580 if (decode) | |
581 { | |
582 len3 = g722_decode(&dec_state, outdata, adpcmdata, len2); | |
583 outframes = sf_writef_short(outhandle, outdata, len3); | |
584 if (outframes != len3) | |
585 { | |
586 fprintf(stderr, " Error writing audio file\n"); | |
587 exit(2); | |
588 } | |
589 } | |
590 else | |
591 { | |
592 len3 = write(file, adpcmdata, len2); | |
593 if (len3 <= 0) | |
594 break; | |
595 } | |
596 } | |
597 if (encode) | |
598 { | |
599 if (sf_close(inhandle)) | |
600 { | |
601 fprintf(stderr, " Cannot close audio file '%s'\n", IN_FILE_NAME); | |
602 exit(2); | |
603 } | |
604 } | |
605 else | |
606 { | |
607 close(file); | |
608 } | |
609 if (decode) | |
610 { | |
611 if (sf_close(outhandle)) | |
612 { | |
613 fprintf(stderr, " Cannot close audio file '%s'\n", OUT_FILE_NAME); | |
614 exit(2); | |
615 } | |
616 } | |
617 else | |
618 { | |
619 close(file); | |
620 } | |
621 printf("'%s' translated to '%s' at %dbps.\n", in_file, out_file, bit_rate); | |
622 } | |
623 return 0; | |
624 } | |
625 /*- End of function --------------------------------------------------------*/ | |
626 /*- End of file ------------------------------------------------------------*/ |