comparison spandsp-0.0.6pre17/tests/v8_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 * v8_tests.c
5 *
6 * Written by Steve Underwood <steveu@coppice.org>
7 *
8 * Copyright (C) 2004 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: v8_tests.c,v 1.36.4.1 2009/12/28 12:32:53 steveu Exp $
26 */
27
28 /*! \page v8_tests_page V.8 tests
29 \section v8_tests_page_sec_1 What does it do?
30 */
31
32 #if defined(HAVE_CONFIG_H)
33 #include "config.h"
34 #endif
35
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <fcntl.h>
39 #include <unistd.h>
40 #include <string.h>
41 #include <sndfile.h>
42
43 //#if defined(WITH_SPANDSP_INTERNALS)
44 #define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
45 //#endif
46
47 #include "spandsp.h"
48 #include "spandsp-sim.h"
49
50 #define FALSE 0
51 #define TRUE (!FALSE)
52
53 #define SAMPLES_PER_CHUNK 160
54
55 #define OUTPUT_FILE_NAME "v8.wav"
56
57 int negotiations_ok = 0;
58
59 static int select_modulation(int mask)
60 {
61 /* Select the fastest data modem available */
62 if (mask & V8_MOD_V90)
63 return V8_MOD_V90;
64 if (mask & V8_MOD_V34)
65 return V8_MOD_V34;
66 if (mask & V8_MOD_V32)
67 return V8_MOD_V32;
68 if (mask & V8_MOD_V23)
69 return V8_MOD_V23;
70 if (mask & V8_MOD_V21)
71 return V8_MOD_V21;
72 return V8_MOD_FAILED;
73 }
74 /*- End of function --------------------------------------------------------*/
75
76 static void handler(void *user_data, v8_parms_t *result)
77 {
78 const char *s;
79
80 s = (const char *) user_data;
81
82 if (result == NULL)
83 {
84 printf("%s V.8 negotiation failed\n", s);
85 return;
86 }
87 if (result->modem_connect_tone == MODEM_CONNECT_TONES_ANSAM
88 ||
89 result->modem_connect_tone == MODEM_CONNECT_TONES_ANSAM_PR
90 ||
91 result->modem_connect_tone == MODEM_CONNECT_TONES_NONE)
92 {
93 printf("%s V.8 negotiation result:\n", s);
94 printf(" Modem connect tone '%s' (%d)\n", modem_connect_tone_to_str(result->modem_connect_tone), result->modem_connect_tone);
95 printf(" Call function '%s' (%d)\n", v8_call_function_to_str(result->call_function), result->call_function);
96 printf(" Far end modulations 0x%X\n", result->modulations);
97 printf(" Protocol '%s' (%d)\n", v8_protocol_to_str(result->protocol), result->protocol);
98 printf(" PSTN access '%s' (%d)\n", v8_pstn_access_to_str(result->pstn_access), result->pstn_access);
99 printf(" PCM modem availability '%s' (%d)\n", v8_pcm_modem_availability_to_str(result->pcm_modem_availability), result->pcm_modem_availability);
100 if (result->t66 >= 0)
101 printf(" T.66 '%s' (%d)\n", v8_t66_to_str(result->t66), result->t66);
102 if (result->nsf >= 0)
103 printf(" NSF %d\n", result->nsf);
104 if (result->call_function == V8_CALL_V_SERIES
105 &&
106 result->protocol == V8_PROTOCOL_LAPM_V42)
107 {
108 negotiations_ok++;
109 }
110 }
111 else
112 {
113 printf("%s V.8 negotiation result:\n", s);
114 printf(" Modem connect tone '%s' (%d)\n", modem_connect_tone_to_str(result->modem_connect_tone), result->modem_connect_tone);
115 }
116 }
117 /*- End of function --------------------------------------------------------*/
118
119 static int v8_calls_v8_tests(SNDFILE *outhandle)
120 {
121 v8_state_t *v8_caller;
122 v8_state_t *v8_answerer;
123 logging_state_t *caller_logging;
124 logging_state_t *answerer_logging;
125 int caller_available_modulations;
126 int answerer_available_modulations;
127 int i;
128 int samples;
129 int remnant;
130 int outframes;
131 int16_t amp[SAMPLES_PER_CHUNK];
132 int16_t out_amp[2*SAMPLES_PER_CHUNK];
133 v8_parms_t v8_call_parms;
134 v8_parms_t v8_answer_parms;
135
136 caller_available_modulations = V8_MOD_V17
137 | V8_MOD_V21
138 | V8_MOD_V22
139 | V8_MOD_V23HALF
140 | V8_MOD_V23
141 | V8_MOD_V26BIS
142 | V8_MOD_V26TER
143 | V8_MOD_V27TER
144 | V8_MOD_V29
145 | V8_MOD_V32
146 | V8_MOD_V34HALF
147 | V8_MOD_V34
148 | V8_MOD_V90
149 | V8_MOD_V92;
150 answerer_available_modulations = V8_MOD_V17
151 | V8_MOD_V21
152 | V8_MOD_V22
153 | V8_MOD_V23HALF
154 | V8_MOD_V23
155 | V8_MOD_V26BIS
156 | V8_MOD_V26TER
157 | V8_MOD_V27TER
158 | V8_MOD_V29
159 | V8_MOD_V32
160 | V8_MOD_V34HALF
161 | V8_MOD_V34
162 | V8_MOD_V90
163 | V8_MOD_V92;
164 negotiations_ok = 0;
165
166 v8_call_parms.modem_connect_tone = MODEM_CONNECT_TONES_NONE;
167 v8_call_parms.call_function = V8_CALL_V_SERIES;
168 v8_call_parms.modulations = caller_available_modulations;
169 v8_call_parms.protocol = V8_PROTOCOL_LAPM_V42;
170 v8_call_parms.pcm_modem_availability = 0;
171 v8_call_parms.pstn_access = 0;
172 v8_call_parms.nsf = -1;
173 v8_call_parms.t66 = -1;
174 v8_caller = v8_init(NULL,
175 TRUE,
176 &v8_call_parms,
177 handler,
178 (void *) "caller");
179 v8_answer_parms.modem_connect_tone = MODEM_CONNECT_TONES_ANSAM_PR;
180 v8_answer_parms.call_function = V8_CALL_V_SERIES;
181 v8_answer_parms.modulations = answerer_available_modulations;
182 v8_answer_parms.protocol = V8_PROTOCOL_LAPM_V42;
183 v8_answer_parms.pcm_modem_availability = 0;
184 v8_answer_parms.pstn_access = 0;
185 v8_answer_parms.nsf = -1;
186 v8_answer_parms.t66 = -1;
187 v8_answerer = v8_init(NULL,
188 FALSE,
189 &v8_answer_parms,
190 handler,
191 (void *) "answerer");
192 caller_logging = v8_get_logging_state(v8_caller);
193 span_log_set_level(caller_logging, SPAN_LOG_FLOW | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
194 span_log_set_tag(caller_logging, "caller");
195 answerer_logging = v8_get_logging_state(v8_answerer);
196 span_log_set_level(answerer_logging, SPAN_LOG_FLOW | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
197 span_log_set_tag(answerer_logging, "answerer");
198 for (i = 0; i < 1000; i++)
199 {
200 samples = v8_tx(v8_caller, amp, SAMPLES_PER_CHUNK);
201 if (samples < SAMPLES_PER_CHUNK)
202 {
203 memset(amp + samples, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - samples));
204 samples = SAMPLES_PER_CHUNK;
205 }
206 span_log_bump_samples(caller_logging, samples);
207 remnant = v8_rx(v8_answerer, amp, samples);
208 for (i = 0; i < samples; i++)
209 out_amp[2*i] = amp[i];
210
211 samples = v8_tx(v8_answerer, amp, SAMPLES_PER_CHUNK);
212 if (samples < SAMPLES_PER_CHUNK)
213 {
214 memset(amp + samples, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - samples));
215 samples = SAMPLES_PER_CHUNK;
216 }
217 span_log_bump_samples(answerer_logging, samples);
218 if (v8_rx(v8_caller, amp, samples) && remnant)
219 break;
220 for (i = 0; i < samples; i++)
221 out_amp[2*i + 1] = amp[i];
222
223 outframes = sf_writef_short(outhandle, out_amp, samples);
224 if (outframes != samples)
225 {
226 fprintf(stderr, " Error writing audio file\n");
227 exit(2);
228 }
229 }
230 v8_free(v8_caller);
231 v8_free(v8_answerer);
232
233 if (negotiations_ok != 2)
234 {
235 printf("Tests failed.\n");
236 exit(2);
237 }
238 return 0;
239 }
240 /*- End of function --------------------------------------------------------*/
241
242 static int non_v8_calls_v8_tests(SNDFILE *outhandle)
243 {
244 silence_gen_state_t *non_v8_caller_tx;
245 modem_connect_tones_rx_state_t *non_v8_caller_rx;
246 v8_state_t *v8_answerer;
247 logging_state_t *answerer_logging;
248 int answerer_available_modulations;
249 int i;
250 int samples;
251 int remnant;
252 int outframes;
253 int tone;
254 int16_t amp[SAMPLES_PER_CHUNK];
255 int16_t out_amp[2*SAMPLES_PER_CHUNK];
256 v8_parms_t v8_answer_parms;
257
258 answerer_available_modulations = V8_MOD_V17
259 | V8_MOD_V21
260 | V8_MOD_V22
261 | V8_MOD_V23HALF
262 | V8_MOD_V23
263 | V8_MOD_V26BIS
264 | V8_MOD_V26TER
265 | V8_MOD_V27TER
266 | V8_MOD_V29
267 | V8_MOD_V32
268 | V8_MOD_V34HALF
269 | V8_MOD_V34
270 | V8_MOD_V90
271 | V8_MOD_V92;
272 negotiations_ok = 0;
273
274 non_v8_caller_tx = silence_gen_init(NULL, 10*SAMPLE_RATE);
275 non_v8_caller_rx = modem_connect_tones_rx_init(NULL, MODEM_CONNECT_TONES_ANS_PR, NULL, NULL);
276
277 v8_answer_parms.modem_connect_tone = MODEM_CONNECT_TONES_ANSAM_PR;
278 v8_answer_parms.call_function = V8_CALL_V_SERIES;
279 v8_answer_parms.modulations = answerer_available_modulations;
280 v8_answer_parms.protocol = V8_PROTOCOL_LAPM_V42;
281 v8_answer_parms.pcm_modem_availability = 0;
282 v8_answer_parms.pstn_access = 0;
283 v8_answer_parms.nsf = -1;
284 v8_answer_parms.t66 = -1;
285 v8_answerer = v8_init(NULL,
286 FALSE,
287 &v8_answer_parms,
288 handler,
289 (void *) "answerer");
290 answerer_logging = v8_get_logging_state(v8_answerer);
291 span_log_set_level(answerer_logging, SPAN_LOG_FLOW | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
292 span_log_set_tag(answerer_logging, "answerer");
293 for (i = 0; i < 1000; i++)
294 {
295 samples = silence_gen(non_v8_caller_tx, amp, SAMPLES_PER_CHUNK);
296 if (samples < SAMPLES_PER_CHUNK)
297 {
298 memset(amp + samples, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - samples));
299 samples = SAMPLES_PER_CHUNK;
300 }
301 remnant = v8_rx(v8_answerer, amp, samples);
302 if (remnant)
303 break;
304 for (i = 0; i < samples; i++)
305 out_amp[2*i] = amp[i];
306
307 samples = v8_tx(v8_answerer, amp, SAMPLES_PER_CHUNK);
308 if (samples < SAMPLES_PER_CHUNK)
309 {
310 memset(amp + samples, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - samples));
311 samples = SAMPLES_PER_CHUNK;
312 }
313 span_log_bump_samples(answerer_logging, samples);
314 modem_connect_tones_rx(non_v8_caller_rx, amp, samples);
315 if ((tone = modem_connect_tones_rx_get(non_v8_caller_rx)) != MODEM_CONNECT_TONES_NONE)
316 {
317 printf("Detected %s (%d)\n", modem_connect_tone_to_str(tone), tone);
318 if (tone == MODEM_CONNECT_TONES_ANSAM_PR)
319 negotiations_ok++;
320 }
321 for (i = 0; i < samples; i++)
322 out_amp[2*i + 1] = amp[i];
323
324 outframes = sf_writef_short(outhandle, out_amp, samples);
325 if (outframes != samples)
326 {
327 fprintf(stderr, " Error writing audio file\n");
328 exit(2);
329 }
330 }
331 silence_gen_free(non_v8_caller_tx);
332 modem_connect_tones_rx_free(non_v8_caller_rx);
333 v8_free(v8_answerer);
334
335 if (negotiations_ok != 1)
336 {
337 printf("Tests failed.\n");
338 exit(2);
339 }
340 return 0;
341 }
342 /*- End of function --------------------------------------------------------*/
343
344 static int v8_calls_non_v8_tests(SNDFILE *outhandle)
345 {
346 v8_state_t *v8_caller;
347 modem_connect_tones_tx_state_t *non_v8_answerer_tx;
348 logging_state_t *caller_logging;
349 int caller_available_modulations;
350 int i;
351 int samples;
352 int outframes;
353 int16_t amp[SAMPLES_PER_CHUNK];
354 int16_t out_amp[2*SAMPLES_PER_CHUNK];
355 v8_parms_t v8_call_parms;
356
357 caller_available_modulations = V8_MOD_V17
358 | V8_MOD_V21
359 | V8_MOD_V22
360 | V8_MOD_V23HALF
361 | V8_MOD_V23
362 | V8_MOD_V26BIS
363 | V8_MOD_V26TER
364 | V8_MOD_V27TER
365 | V8_MOD_V29
366 | V8_MOD_V32
367 | V8_MOD_V34HALF
368 | V8_MOD_V34
369 | V8_MOD_V90
370 | V8_MOD_V92;
371 negotiations_ok = 0;
372
373 v8_call_parms.modem_connect_tone = MODEM_CONNECT_TONES_NONE;
374 v8_call_parms.call_function = V8_CALL_V_SERIES;
375 v8_call_parms.modulations = caller_available_modulations;
376 v8_call_parms.protocol = V8_PROTOCOL_LAPM_V42;
377 v8_call_parms.pcm_modem_availability = 0;
378 v8_call_parms.pstn_access = 0;
379 v8_call_parms.nsf = -1;
380 v8_call_parms.t66 = -1;
381 v8_caller = v8_init(NULL,
382 TRUE,
383 &v8_call_parms,
384 handler,
385 (void *) "caller");
386 non_v8_answerer_tx = modem_connect_tones_tx_init(NULL, MODEM_CONNECT_TONES_ANS_PR);
387 caller_logging = v8_get_logging_state(v8_caller);
388 span_log_set_level(caller_logging, SPAN_LOG_FLOW | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
389 span_log_set_tag(caller_logging, "caller");
390 for (i = 0; i < 1000; i++)
391 {
392 samples = v8_tx(v8_caller, amp, SAMPLES_PER_CHUNK);
393 if (samples < SAMPLES_PER_CHUNK)
394 {
395 memset(amp + samples, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - samples));
396 samples = SAMPLES_PER_CHUNK;
397 }
398 span_log_bump_samples(caller_logging, samples);
399 for (i = 0; i < samples; i++)
400 out_amp[2*i] = amp[i];
401
402 samples = modem_connect_tones_tx(non_v8_answerer_tx, amp, SAMPLES_PER_CHUNK);
403 if (samples < SAMPLES_PER_CHUNK)
404 {
405 memset(amp + samples, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - samples));
406 samples = SAMPLES_PER_CHUNK;
407 }
408 if (v8_rx(v8_caller, amp, samples))
409 break;
410 for (i = 0; i < samples; i++)
411 out_amp[2*i + 1] = amp[i];
412
413 outframes = sf_writef_short(outhandle, out_amp, samples);
414 if (outframes != samples)
415 {
416 fprintf(stderr, " Error writing audio file\n");
417 exit(2);
418 }
419 }
420 v8_free(v8_caller);
421 modem_connect_tones_tx_free(non_v8_answerer_tx);
422
423 #if 0
424 if (negotiations_ok != 1)
425 {
426 printf("Tests failed.\n");
427 exit(2);
428 }
429 #endif
430 return 0;
431 }
432 /*- End of function --------------------------------------------------------*/
433
434 int main(int argc, char *argv[])
435 {
436 int16_t amp[SAMPLES_PER_CHUNK];
437 int samples;
438 int remnant;
439 int caller_available_modulations;
440 int answerer_available_modulations;
441 SNDFILE *inhandle;
442 SNDFILE *outhandle;
443 int opt;
444 char *decode_test_file;
445 v8_state_t *v8_caller;
446 v8_state_t *v8_answerer;
447 v8_parms_t v8_call_parms;
448 v8_parms_t v8_answer_parms;
449 logging_state_t *logging;
450
451 decode_test_file = NULL;
452 while ((opt = getopt(argc, argv, "d:")) != -1)
453 {
454 switch (opt)
455 {
456 case 'd':
457 decode_test_file = optarg;
458 break;
459 default:
460 //usage();
461 exit(2);
462 break;
463 }
464 }
465
466 caller_available_modulations = V8_MOD_V17
467 | V8_MOD_V21
468 | V8_MOD_V22
469 | V8_MOD_V23HALF
470 | V8_MOD_V23
471 | V8_MOD_V26BIS
472 | V8_MOD_V26TER
473 | V8_MOD_V27TER
474 | V8_MOD_V29
475 | V8_MOD_V32
476 | V8_MOD_V34HALF
477 | V8_MOD_V34
478 | V8_MOD_V90
479 | V8_MOD_V92;
480 answerer_available_modulations = V8_MOD_V17
481 | V8_MOD_V21
482 | V8_MOD_V22
483 | V8_MOD_V23HALF
484 | V8_MOD_V23
485 | V8_MOD_V26BIS
486 | V8_MOD_V26TER
487 | V8_MOD_V27TER
488 | V8_MOD_V29
489 | V8_MOD_V32
490 | V8_MOD_V34HALF
491 | V8_MOD_V34
492 | V8_MOD_V90
493 | V8_MOD_V92;
494
495 if (decode_test_file == NULL)
496 {
497 if ((outhandle = sf_open_telephony_write(OUTPUT_FILE_NAME, 2)) == NULL)
498 {
499 fprintf(stderr, " Cannot create audio file '%s'\n", OUTPUT_FILE_NAME);
500 exit(2);
501 }
502
503 printf("Test 1: V.8 terminal calls V.8 terminal\n");
504 v8_calls_v8_tests(outhandle);
505
506 printf("Test 2: non-V.8 terminal calls V.8 terminal\n");
507 non_v8_calls_v8_tests(outhandle);
508
509 printf("Test 3: V.8 terminal calls non-V.8 terminal\n");
510 v8_calls_non_v8_tests(outhandle);
511
512 if (sf_close(outhandle))
513 {
514 fprintf(stderr, " Cannot close audio file '%s'\n", OUTPUT_FILE_NAME);
515 exit(2);
516 }
517
518 printf("Tests passed.\n");
519 }
520 else
521 {
522 printf("Decode file '%s'\n", decode_test_file);
523 v8_call_parms.modem_connect_tone = MODEM_CONNECT_TONES_NONE;
524 v8_call_parms.call_function = V8_CALL_V_SERIES;
525 v8_call_parms.modulations = caller_available_modulations;
526 v8_call_parms.protocol = V8_PROTOCOL_LAPM_V42;
527 v8_call_parms.pcm_modem_availability = 0;
528 v8_call_parms.pstn_access = 0;
529 v8_call_parms.nsf = -1;
530 v8_call_parms.t66 = -1;
531 v8_caller = v8_init(NULL,
532 TRUE,
533 &v8_call_parms,
534 handler,
535 (void *) "caller");
536 logging = v8_get_logging_state(v8_caller);
537 span_log_set_level(logging, SPAN_LOG_FLOW | SPAN_LOG_SHOW_TAG);
538 span_log_set_tag(logging, "caller");
539
540 v8_answer_parms.modem_connect_tone = MODEM_CONNECT_TONES_ANSAM_PR;
541 v8_answer_parms.call_function = V8_CALL_V_SERIES;
542 v8_answer_parms.modulations = answerer_available_modulations;
543 v8_answer_parms.protocol = V8_PROTOCOL_LAPM_V42;
544 v8_answer_parms.pcm_modem_availability = 0;
545 v8_answer_parms.pstn_access = 0;
546 v8_answer_parms.nsf = -1;
547 v8_answer_parms.t66 = -1;
548 v8_answerer = v8_init(NULL,
549 FALSE,
550 &v8_answer_parms,
551 handler,
552 (void *) "answerer");
553 logging = v8_get_logging_state(v8_answerer);
554 span_log_set_level(logging, SPAN_LOG_FLOW | SPAN_LOG_SHOW_TAG);
555 span_log_set_tag(logging, "answerer");
556
557 if ((inhandle = sf_open_telephony_read(decode_test_file, 1)) == NULL)
558 {
559 fprintf(stderr, " Cannot open speech file '%s'\n", decode_test_file);
560 exit (2);
561 }
562 /*endif*/
563
564 while ((samples = sf_readf_short(inhandle, amp, SAMPLES_PER_CHUNK)))
565 {
566 remnant = v8_rx(v8_caller, amp, samples);
567 remnant = v8_rx(v8_answerer, amp, samples);
568 remnant = v8_tx(v8_caller, amp, samples);
569 remnant = v8_tx(v8_answerer, amp, samples);
570 }
571 /*endwhile*/
572
573 v8_free(v8_caller);
574 v8_free(v8_answerer);
575 if (sf_close(inhandle) != 0)
576 {
577 fprintf(stderr, " Cannot close speech file '%s'\n", decode_test_file);
578 exit(2);
579 }
580 /*endif*/
581 }
582 return 0;
583 }
584 /*- End of function --------------------------------------------------------*/
585 /*- End of file ------------------------------------------------------------*/

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