Mercurial > hg > audiostuff
comparison spandsp-0.0.6pre17/tests/fsk_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 * fsk_tests.c - Tests for the low speed FSK modem code (V.21, V.23, etc.). | |
| 5 * | |
| 6 * Written by Steve Underwood <steveu@coppice.org> | |
| 7 * | |
| 8 * Copyright (C) 2003 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: fsk_tests.c,v 1.59 2009/11/02 13:25:20 steveu Exp $ | |
| 26 */ | |
| 27 | |
| 28 /*! \page fsk_tests_page FSK modem tests | |
| 29 \section fsk_tests_page_sec_1 What does it do? | |
| 30 These tests allow either: | |
| 31 | |
| 32 - An FSK transmit modem to feed an FSK receive modem, of the same type, | |
| 33 through a telephone line model. BER testing is then used to evaluate | |
| 34 performance under various line conditions. This is effective for testing | |
| 35 the basic performance of the receive modem. It is also the only test mode | |
| 36 provided for evaluating the transmit modem. | |
| 37 | |
| 38 - An FSK receive modem is used to decode FSK audio, stored in a file. | |
| 39 This is good way to evaluate performance with audio recorded from other | |
| 40 models of modem, and with real world problematic telephone lines. | |
| 41 | |
| 42 \section fsk_tests_page_sec_2 How does it work? | |
| 43 */ | |
| 44 | |
| 45 #if defined(HAVE_CONFIG_H) | |
| 46 #include "config.h" | |
| 47 #endif | |
| 48 | |
| 49 #include <stdlib.h> | |
| 50 #include <stdio.h> | |
| 51 #include <unistd.h> | |
| 52 #include <string.h> | |
| 53 #include <assert.h> | |
| 54 #include <sndfile.h> | |
| 55 | |
| 56 //#if defined(WITH_SPANDSP_INTERNALS) | |
| 57 #define SPANDSP_EXPOSE_INTERNAL_STRUCTURES | |
| 58 //#endif | |
| 59 | |
| 60 #include "spandsp.h" | |
| 61 #include "spandsp-sim.h" | |
| 62 | |
| 63 #define BLOCK_LEN 160 | |
| 64 | |
| 65 #define OUTPUT_FILE_NAME "fsk.wav" | |
| 66 | |
| 67 char *decode_test_file = NULL; | |
| 68 both_ways_line_model_state_t *model; | |
| 69 int rx_bits = 0; | |
| 70 int cutoff_test_carrier = FALSE; | |
| 71 | |
| 72 static void rx_status(void *user_data, int status) | |
| 73 { | |
| 74 printf("FSK rx status is %s (%d)\n", signal_status_to_str(status), status); | |
| 75 } | |
| 76 /*- End of function --------------------------------------------------------*/ | |
| 77 | |
| 78 static void tx_status(void *user_data, int status) | |
| 79 { | |
| 80 printf("FSK tx status is %s (%d)\n", signal_status_to_str(status), status); | |
| 81 } | |
| 82 /*- End of function --------------------------------------------------------*/ | |
| 83 | |
| 84 static void put_bit(void *user_data, int bit) | |
| 85 { | |
| 86 if (bit < 0) | |
| 87 { | |
| 88 rx_status(user_data, bit); | |
| 89 return; | |
| 90 } | |
| 91 | |
| 92 printf("Rx bit %d - %d\n", rx_bits++, bit); | |
| 93 } | |
| 94 /*- End of function --------------------------------------------------------*/ | |
| 95 | |
| 96 static void cutoff_test_rx_status(void *user_data, int status) | |
| 97 { | |
| 98 printf("FSK rx status is %s (%d)\n", signal_status_to_str(status), status); | |
| 99 switch (status) | |
| 100 { | |
| 101 case SIG_STATUS_CARRIER_UP: | |
| 102 cutoff_test_carrier = TRUE; | |
| 103 break; | |
| 104 case SIG_STATUS_CARRIER_DOWN: | |
| 105 cutoff_test_carrier = FALSE; | |
| 106 break; | |
| 107 } | |
| 108 } | |
| 109 /*- End of function --------------------------------------------------------*/ | |
| 110 | |
| 111 static void cutoff_test_put_bit(void *user_data, int bit) | |
| 112 { | |
| 113 if (bit < 0) | |
| 114 { | |
| 115 cutoff_test_rx_status(user_data, bit); | |
| 116 return; | |
| 117 } | |
| 118 } | |
| 119 /*- End of function --------------------------------------------------------*/ | |
| 120 | |
| 121 static void reporter(void *user_data, int reason, bert_results_t *results) | |
| 122 { | |
| 123 int channel; | |
| 124 | |
| 125 channel = (int) (intptr_t) user_data; | |
| 126 switch (reason) | |
| 127 { | |
| 128 case BERT_REPORT_SYNCED: | |
| 129 fprintf(stderr, "%d: BERT report synced\n", channel); | |
| 130 break; | |
| 131 case BERT_REPORT_UNSYNCED: | |
| 132 fprintf(stderr, "%d: BERT report unsync'ed\n", channel); | |
| 133 break; | |
| 134 case BERT_REPORT_REGULAR: | |
| 135 fprintf(stderr, "%d: BERT report regular - %d bits, %d bad bits, %d resyncs\n", channel, results->total_bits, results->bad_bits, results->resyncs); | |
| 136 break; | |
| 137 case BERT_REPORT_GT_10_2: | |
| 138 fprintf(stderr, "%d: BERT report > 1 in 10^2\n", channel); | |
| 139 break; | |
| 140 case BERT_REPORT_LT_10_2: | |
| 141 fprintf(stderr, "%d: BERT report < 1 in 10^2\n", channel); | |
| 142 break; | |
| 143 case BERT_REPORT_LT_10_3: | |
| 144 fprintf(stderr, "%d: BERT report < 1 in 10^3\n", channel); | |
| 145 break; | |
| 146 case BERT_REPORT_LT_10_4: | |
| 147 fprintf(stderr, "%d: BERT report < 1 in 10^4\n", channel); | |
| 148 break; | |
| 149 case BERT_REPORT_LT_10_5: | |
| 150 fprintf(stderr, "%d: BERT report < 1 in 10^5\n", channel); | |
| 151 break; | |
| 152 case BERT_REPORT_LT_10_6: | |
| 153 fprintf(stderr, "%d: BERT report < 1 in 10^6\n", channel); | |
| 154 break; | |
| 155 case BERT_REPORT_LT_10_7: | |
| 156 fprintf(stderr, "%d: BERT report < 1 in 10^7\n", channel); | |
| 157 break; | |
| 158 default: | |
| 159 fprintf(stderr, "%d: BERT report reason %d\n", channel, reason); | |
| 160 break; | |
| 161 } | |
| 162 } | |
| 163 /*- End of function --------------------------------------------------------*/ | |
| 164 | |
| 165 int main(int argc, char *argv[]) | |
| 166 { | |
| 167 fsk_tx_state_t *caller_tx; | |
| 168 fsk_rx_state_t *caller_rx; | |
| 169 fsk_tx_state_t *answerer_tx; | |
| 170 fsk_rx_state_t *answerer_rx; | |
| 171 bert_state_t caller_bert; | |
| 172 bert_state_t answerer_bert; | |
| 173 bert_results_t bert_results; | |
| 174 power_meter_t caller_meter; | |
| 175 power_meter_t answerer_meter; | |
| 176 int16_t caller_amp[BLOCK_LEN]; | |
| 177 int16_t answerer_amp[BLOCK_LEN]; | |
| 178 int16_t caller_model_amp[BLOCK_LEN]; | |
| 179 int16_t answerer_model_amp[BLOCK_LEN]; | |
| 180 int16_t out_amp[2*BLOCK_LEN]; | |
| 181 SNDFILE *inhandle; | |
| 182 SNDFILE *outhandle; | |
| 183 int outframes; | |
| 184 int i; | |
| 185 int j; | |
| 186 int samples; | |
| 187 int test_bps; | |
| 188 int noise_level; | |
| 189 int noise_sweep; | |
| 190 int bits_per_test; | |
| 191 int line_model_no; | |
| 192 int modem_under_test_1; | |
| 193 int modem_under_test_2; | |
| 194 int modems_set; | |
| 195 int log_audio; | |
| 196 int channel_codec; | |
| 197 int rbs_pattern; | |
| 198 int on_at; | |
| 199 int off_at; | |
| 200 tone_gen_descriptor_t tone_desc; | |
| 201 tone_gen_state_t tone_tx; | |
| 202 int opt; | |
| 203 | |
| 204 channel_codec = MUNGE_CODEC_NONE; | |
| 205 rbs_pattern = 0; | |
| 206 line_model_no = 0; | |
| 207 decode_test_file = NULL; | |
| 208 noise_sweep = FALSE; | |
| 209 modem_under_test_1 = FSK_V21CH1; | |
| 210 modem_under_test_2 = FSK_V21CH2; | |
| 211 log_audio = FALSE; | |
| 212 modems_set = 0; | |
| 213 while ((opt = getopt(argc, argv, "c:dlm:nr:s:")) != -1) | |
| 214 { | |
| 215 switch (opt) | |
| 216 { | |
| 217 case 'c': | |
| 218 channel_codec = atoi(optarg); | |
| 219 break; | |
| 220 case 'd': | |
| 221 decode_test_file = optarg; | |
| 222 break; | |
| 223 case 'l': | |
| 224 log_audio = TRUE; | |
| 225 break; | |
| 226 case 'm': | |
| 227 line_model_no = atoi(optarg); | |
| 228 break; | |
| 229 case 'n': | |
| 230 noise_sweep = TRUE; | |
| 231 break; | |
| 232 case 'r': | |
| 233 rbs_pattern = atoi(optarg); | |
| 234 break; | |
| 235 case 's': | |
| 236 switch (modems_set++) | |
| 237 { | |
| 238 case 0: | |
| 239 modem_under_test_1 = atoi(optarg); | |
| 240 break; | |
| 241 case 1: | |
| 242 modem_under_test_2 = atoi(optarg); | |
| 243 break; | |
| 244 } | |
| 245 break; | |
| 246 default: | |
| 247 //usage(); | |
| 248 exit(2); | |
| 249 break; | |
| 250 } | |
| 251 } | |
| 252 | |
| 253 if (modem_under_test_1 >= 0) | |
| 254 printf("Modem channel 1 is '%s'\n", preset_fsk_specs[modem_under_test_1].name); | |
| 255 if (modem_under_test_2 >= 0) | |
| 256 printf("Modem channel 2 is '%s'\n", preset_fsk_specs[modem_under_test_2].name); | |
| 257 | |
| 258 outhandle = NULL; | |
| 259 | |
| 260 if (log_audio) | |
| 261 { | |
| 262 if ((outhandle = sf_open_telephony_write(OUTPUT_FILE_NAME, 2)) == NULL) | |
| 263 { | |
| 264 fprintf(stderr, " Cannot create audio file '%s'\n", OUTPUT_FILE_NAME); | |
| 265 exit(2); | |
| 266 } | |
| 267 } | |
| 268 noise_level = -200; | |
| 269 bits_per_test = 0; | |
| 270 inhandle = NULL; | |
| 271 | |
| 272 memset(caller_amp, 0, sizeof(*caller_amp)); | |
| 273 memset(answerer_amp, 0, sizeof(*answerer_amp)); | |
| 274 memset(caller_model_amp, 0, sizeof(*caller_model_amp)); | |
| 275 memset(answerer_model_amp, 0, sizeof(*answerer_model_amp)); | |
| 276 power_meter_init(&caller_meter, 7); | |
| 277 power_meter_init(&answerer_meter, 7); | |
| 278 | |
| 279 if (decode_test_file) | |
| 280 { | |
| 281 if ((inhandle = sf_open_telephony_read(decode_test_file, 1)) == NULL) | |
| 282 { | |
| 283 fprintf(stderr, " Cannot open audio file '%s'\n", decode_test_file); | |
| 284 exit(2); | |
| 285 } | |
| 286 caller_rx = fsk_rx_init(NULL, &preset_fsk_specs[modem_under_test_1], FSK_FRAME_MODE_SYNC, put_bit, NULL); | |
| 287 fsk_rx_set_modem_status_handler(caller_rx, rx_status, (void *) &caller_rx); | |
| 288 test_bps = preset_fsk_specs[modem_under_test_1].baud_rate; | |
| 289 | |
| 290 for (;;) | |
| 291 { | |
| 292 samples = sf_readf_short(inhandle, caller_model_amp, BLOCK_LEN); | |
| 293 if (samples < BLOCK_LEN) | |
| 294 break; | |
| 295 for (i = 0; i < samples; i++) | |
| 296 power_meter_update(&caller_meter, caller_model_amp[i]); | |
| 297 fsk_rx(caller_rx, caller_model_amp, samples); | |
| 298 } | |
| 299 | |
| 300 if (sf_close(inhandle) != 0) | |
| 301 { | |
| 302 fprintf(stderr, " Cannot close audio file '%s'\n", decode_test_file); | |
| 303 exit(2); | |
| 304 } | |
| 305 } | |
| 306 else | |
| 307 { | |
| 308 printf("Test cutoff level\n"); | |
| 309 caller_rx = fsk_rx_init(NULL, &preset_fsk_specs[modem_under_test_1], FSK_FRAME_MODE_SYNC, cutoff_test_put_bit, NULL); | |
| 310 fsk_rx_signal_cutoff(caller_rx, -30.0f); | |
| 311 fsk_rx_set_modem_status_handler(caller_rx, cutoff_test_rx_status, (void *) &caller_rx); | |
| 312 on_at = 0; | |
| 313 for (i = -40; i < -25; i++) | |
| 314 { | |
| 315 make_tone_gen_descriptor(&tone_desc, | |
| 316 1500, | |
| 317 i, | |
| 318 0, | |
| 319 0, | |
| 320 1, | |
| 321 0, | |
| 322 0, | |
| 323 0, | |
| 324 TRUE); | |
| 325 tone_gen_init(&tone_tx, &tone_desc); | |
| 326 for (j = 0; j < 10; j++) | |
| 327 { | |
| 328 samples = tone_gen(&tone_tx, caller_model_amp, 160); | |
| 329 fsk_rx(caller_rx, caller_model_amp, samples); | |
| 330 } | |
| 331 if (cutoff_test_carrier) | |
| 332 break; | |
| 333 } | |
| 334 on_at = i; | |
| 335 off_at = 0; | |
| 336 for ( ; i > -40; i--) | |
| 337 { | |
| 338 make_tone_gen_descriptor(&tone_desc, | |
| 339 1500, | |
| 340 i, | |
| 341 0, | |
| 342 0, | |
| 343 1, | |
| 344 0, | |
| 345 0, | |
| 346 0, | |
| 347 TRUE); | |
| 348 tone_gen_init(&tone_tx, &tone_desc); | |
| 349 for (j = 0; j < 10; j++) | |
| 350 { | |
| 351 samples = tone_gen(&tone_tx, caller_model_amp, 160); | |
| 352 fsk_rx(caller_rx, caller_model_amp, samples); | |
| 353 } | |
| 354 if (!cutoff_test_carrier) | |
| 355 break; | |
| 356 } | |
| 357 off_at = i; | |
| 358 printf("Carrier on at %d, off at %d\n", on_at, off_at); | |
| 359 if (on_at < -29 || on_at > -26 | |
| 360 || | |
| 361 off_at < -35 || off_at > -31) | |
| 362 { | |
| 363 printf("Tests failed.\n"); | |
| 364 exit(2); | |
| 365 } | |
| 366 | |
| 367 printf("Test with BERT\n"); | |
| 368 test_bps = preset_fsk_specs[modem_under_test_1].baud_rate; | |
| 369 if (modem_under_test_1 >= 0) | |
| 370 { | |
| 371 caller_tx = fsk_tx_init(NULL, &preset_fsk_specs[modem_under_test_1], (get_bit_func_t) bert_get_bit, &caller_bert); | |
| 372 fsk_tx_set_modem_status_handler(caller_tx, tx_status, (void *) &caller_tx); | |
| 373 answerer_rx = fsk_rx_init(NULL, &preset_fsk_specs[modem_under_test_1], FSK_FRAME_MODE_SYNC, (put_bit_func_t) bert_put_bit, &answerer_bert); | |
| 374 fsk_rx_set_modem_status_handler(answerer_rx, rx_status, (void *) &answerer_rx); | |
| 375 } | |
| 376 if (modem_under_test_2 >= 0) | |
| 377 { | |
| 378 answerer_tx = fsk_tx_init(NULL, &preset_fsk_specs[modem_under_test_2], (get_bit_func_t) bert_get_bit, &answerer_bert); | |
| 379 fsk_tx_set_modem_status_handler(answerer_tx, tx_status, (void *) &answerer_tx); | |
| 380 caller_rx = fsk_rx_init(NULL, &preset_fsk_specs[modem_under_test_2], FSK_FRAME_MODE_SYNC, (put_bit_func_t) bert_put_bit, &caller_bert); | |
| 381 fsk_rx_set_modem_status_handler(caller_rx, rx_status, (void *) &caller_rx); | |
| 382 } | |
| 383 test_bps = preset_fsk_specs[modem_under_test_1].baud_rate; | |
| 384 | |
| 385 bits_per_test = 500000; | |
| 386 noise_level = -24; | |
| 387 | |
| 388 bert_init(&caller_bert, bits_per_test, BERT_PATTERN_ITU_O152_11, test_bps, 20); | |
| 389 bert_set_report(&caller_bert, 100000, reporter, (void *) (intptr_t) 1); | |
| 390 bert_init(&answerer_bert, bits_per_test, BERT_PATTERN_ITU_O152_11, test_bps, 20); | |
| 391 bert_set_report(&answerer_bert, 100000, reporter, (void *) (intptr_t) 2); | |
| 392 if ((model = both_ways_line_model_init(line_model_no, (float) noise_level, line_model_no, (float) noise_level, channel_codec, rbs_pattern)) == NULL) | |
| 393 { | |
| 394 fprintf(stderr, " Failed to create line model\n"); | |
| 395 exit(2); | |
| 396 } | |
| 397 | |
| 398 for (;;) | |
| 399 { | |
| 400 samples = fsk_tx(caller_tx, caller_amp, BLOCK_LEN); | |
| 401 for (i = 0; i < samples; i++) | |
| 402 power_meter_update(&caller_meter, caller_amp[i]); | |
| 403 samples = fsk_tx(answerer_tx, answerer_amp, BLOCK_LEN); | |
| 404 for (i = 0; i < samples; i++) | |
| 405 power_meter_update(&answerer_meter, answerer_amp[i]); | |
| 406 both_ways_line_model(model, | |
| 407 caller_model_amp, | |
| 408 caller_amp, | |
| 409 answerer_model_amp, | |
| 410 answerer_amp, | |
| 411 samples); | |
| 412 | |
| 413 //printf("Powers %10.5fdBm0 %10.5fdBm0\n", power_meter_current_dbm0(&caller_meter), power_meter_current_dbm0(&answerer_meter)); | |
| 414 | |
| 415 fsk_rx(answerer_rx, caller_model_amp, samples); | |
| 416 for (i = 0; i < samples; i++) | |
| 417 out_amp[2*i] = caller_model_amp[i]; | |
| 418 for ( ; i < BLOCK_LEN; i++) | |
| 419 out_amp[2*i] = 0; | |
| 420 | |
| 421 fsk_rx(caller_rx, answerer_model_amp, samples); | |
| 422 for (i = 0; i < samples; i++) | |
| 423 out_amp[2*i + 1] = answerer_model_amp[i]; | |
| 424 for ( ; i < BLOCK_LEN; i++) | |
| 425 out_amp[2*i + 1] = 0; | |
| 426 | |
| 427 if (log_audio) | |
| 428 { | |
| 429 outframes = sf_writef_short(outhandle, out_amp, BLOCK_LEN); | |
| 430 if (outframes != BLOCK_LEN) | |
| 431 { | |
| 432 fprintf(stderr, " Error writing audio file\n"); | |
| 433 exit(2); | |
| 434 } | |
| 435 } | |
| 436 | |
| 437 if (samples < BLOCK_LEN) | |
| 438 { | |
| 439 bert_result(&caller_bert, &bert_results); | |
| 440 fprintf(stderr, "%ddB AWGN, %d bits, %d bad bits, %d resyncs\n", noise_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs); | |
| 441 if (!noise_sweep) | |
| 442 { | |
| 443 if (bert_results.total_bits != bits_per_test - 43 | |
| 444 || | |
| 445 bert_results.bad_bits != 0 | |
| 446 || | |
| 447 bert_results.resyncs != 0) | |
| 448 { | |
| 449 printf("Tests failed.\n"); | |
| 450 exit(2); | |
| 451 } | |
| 452 } | |
| 453 bert_result(&answerer_bert, &bert_results); | |
| 454 fprintf(stderr, "%ddB AWGN, %d bits, %d bad bits, %d resyncs\n", noise_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs); | |
| 455 if (!noise_sweep) | |
| 456 { | |
| 457 if (bert_results.total_bits != bits_per_test - 43 | |
| 458 || | |
| 459 bert_results.bad_bits != 0 | |
| 460 || | |
| 461 bert_results.resyncs != 0) | |
| 462 { | |
| 463 printf("Tests failed.\n"); | |
| 464 exit(2); | |
| 465 } | |
| 466 break; | |
| 467 } | |
| 468 | |
| 469 /* Put a little silence between the chunks in the file. */ | |
| 470 memset(out_amp, 0, sizeof(out_amp)); | |
| 471 if (log_audio) | |
| 472 { | |
| 473 for (i = 0; i < 200; i++) | |
| 474 outframes = sf_writef_short(outhandle, out_amp, BLOCK_LEN); | |
| 475 } | |
| 476 if (modem_under_test_1 >= 0) | |
| 477 { | |
| 478 caller_tx = fsk_tx_init(NULL, &preset_fsk_specs[modem_under_test_1], (get_bit_func_t) bert_get_bit, &caller_bert); | |
| 479 fsk_tx_set_modem_status_handler(caller_tx, tx_status, (void *) &caller_tx); | |
| 480 answerer_rx = fsk_rx_init(NULL, &preset_fsk_specs[modem_under_test_1], FSK_FRAME_MODE_SYNC, (put_bit_func_t) bert_put_bit, &answerer_bert); | |
| 481 fsk_rx_set_modem_status_handler(answerer_rx, rx_status, (void *) &answerer_rx); | |
| 482 } | |
| 483 if (modem_under_test_2 >= 0) | |
| 484 { | |
| 485 answerer_tx = fsk_tx_init(NULL, &preset_fsk_specs[modem_under_test_2], (get_bit_func_t) bert_get_bit, &answerer_bert); | |
| 486 fsk_tx_set_modem_status_handler(answerer_tx, tx_status, (void *) &answerer_tx); | |
| 487 caller_rx = fsk_rx_init(NULL, &preset_fsk_specs[modem_under_test_2], FSK_FRAME_MODE_SYNC, (put_bit_func_t) bert_put_bit, &caller_bert); | |
| 488 fsk_rx_set_modem_status_handler(caller_rx, rx_status, (void *) &caller_rx); | |
| 489 } | |
| 490 noise_level++; | |
| 491 if ((model = both_ways_line_model_init(line_model_no, (float) noise_level, line_model_no, noise_level, channel_codec, 0)) == NULL) | |
| 492 { | |
| 493 fprintf(stderr, " Failed to create line model\n"); | |
| 494 exit(2); | |
| 495 } | |
| 496 bert_init(&caller_bert, bits_per_test, BERT_PATTERN_ITU_O152_11, test_bps, 20); | |
| 497 bert_set_report(&caller_bert, 100000, reporter, (void *) (intptr_t) 1); | |
| 498 bert_init(&answerer_bert, bits_per_test, BERT_PATTERN_ITU_O152_11, test_bps, 20); | |
| 499 bert_set_report(&answerer_bert, 100000, reporter, (void *) (intptr_t) 2); | |
| 500 } | |
| 501 } | |
| 502 printf("Tests passed.\n"); | |
| 503 } | |
| 504 if (log_audio) | |
| 505 { | |
| 506 if (sf_close(outhandle) != 0) | |
| 507 { | |
| 508 fprintf(stderr, " Cannot close audio file '%s'\n", OUTPUT_FILE_NAME); | |
| 509 exit(2); | |
| 510 } | |
| 511 } | |
| 512 return 0; | |
| 513 } | |
| 514 /*- End of function --------------------------------------------------------*/ | |
| 515 /*- End of file ------------------------------------------------------------*/ |
