Mercurial > hg > audiostuff
comparison spandsp-0.0.6pre17/tests/r2_mf_rx_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 * r2_mf_tests.c - Test the R2 MF detector against the spec., whatever the | |
| 5 * spec. may be :) | |
| 6 * | |
| 7 * Written by Steve Underwood <steveu@coppice.org> | |
| 8 * | |
| 9 * Copyright (C) 2003 Steve Underwood | |
| 10 * | |
| 11 * All rights reserved. | |
| 12 * | |
| 13 * This program is free software; you can redistribute it and/or modify | |
| 14 * it under the terms of the GNU General Public License version 2, as | |
| 15 * published by the Free Software Foundation. | |
| 16 * | |
| 17 * This program is distributed in the hope that it will be useful, | |
| 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 20 * GNU General Public License for more details. | |
| 21 * | |
| 22 * You should have received a copy of the GNU General Public License | |
| 23 * along with this program; if not, write to the Free Software | |
| 24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
| 25 * | |
| 26 * $Id: r2_mf_rx_tests.c,v 1.14 2009/05/30 15:23:14 steveu Exp $ | |
| 27 */ | |
| 28 | |
| 29 /*! \file */ | |
| 30 | |
| 31 /*! \page r2_mf_tests_page R2 MF tone generation and detection tests | |
| 32 \section r2_mf_tests_page_sec_1 What does it do? | |
| 33 These tests are fashioned after those on the CM7291 test tape from | |
| 34 Mitel. Those tests are for DTMF, rather than R2 MF, but make a | |
| 35 fair starting point for a set of meaningful tests of R2 MF. | |
| 36 | |
| 37 These tests include conversion to and from A-law. It is assumed the | |
| 38 distortion this produces is comparable to u-law, so it should be | |
| 39 a fair test of performance in a real PSTN channel. | |
| 40 */ | |
| 41 | |
| 42 /* Enable the following definition to enable direct probing into the FAX structures */ | |
| 43 //#define WITH_SPANDSP_INTERNALS | |
| 44 | |
| 45 #if defined(HAVE_CONFIG_H) | |
| 46 #include "config.h" | |
| 47 #endif | |
| 48 | |
| 49 #include <stdlib.h> | |
| 50 #include <stdio.h> | |
| 51 #include <fcntl.h> | |
| 52 #include <string.h> | |
| 53 #include <time.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 | |
| 62 /* R2 tone generation specs. | |
| 63 * Power: -11.5dBm +- 1dB | |
| 64 * Frequency: within +-4Hz | |
| 65 * Mismatch between the start time of a pair of tones: <=1ms. | |
| 66 * Mismatch between the end time of a pair of tones: <=1ms. | |
| 67 */ | |
| 68 /* Basic MFC/R2 tone detection specs: | |
| 69 * Receiver response range: -5dBm to -35dBm | |
| 70 * Difference in level for a pair of frequencies | |
| 71 * Adjacent tones: <5dB | |
| 72 * Non-adjacent tones: <7dB | |
| 73 * Receiver not to detect a signal of 2 frequencies of level -5dB and | |
| 74 * duration <7ms. | |
| 75 * Receiver not to recognise a signal of 2 frequencies having a difference | |
| 76 * in level >=20dB. | |
| 77 * Max received signal frequency error: +-10Hz | |
| 78 * The sum of the operate and release times of a 2 frequency signal not to | |
| 79 * exceed 80ms (there are no individual specs for the operate and release | |
| 80 * times). | |
| 81 * Receiver not to release for signal interruptions <=7ms. | |
| 82 * System malfunction due to signal interruptions >7ms (typically 20ms) is | |
| 83 * prevented by further logic elements. | |
| 84 */ | |
| 85 | |
| 86 #define MF_DURATION (68*8) | |
| 87 #define MF_PAUSE (68*8) | |
| 88 #define MF_CYCLE (MF_DURATION + MF_PAUSE) | |
| 89 | |
| 90 /*! | |
| 91 MF tone generator descriptor for tests. | |
| 92 */ | |
| 93 typedef struct | |
| 94 { | |
| 95 float f1; /* First freq */ | |
| 96 float f2; /* Second freq */ | |
| 97 int8_t level1; /* Level of the first freq (dB) */ | |
| 98 int8_t level2; /* Level of the second freq (dB) */ | |
| 99 uint8_t on_time; /* Tone on time (ms) */ | |
| 100 uint8_t off_time; /* Minimum post tone silence (ms) */ | |
| 101 } mf_digit_tones_t; | |
| 102 | |
| 103 static const mf_digit_tones_t r2_mf_fwd_tones[] = | |
| 104 { | |
| 105 {1380.0, 1500.0, -11, -11, 1, 0}, | |
| 106 {1380.0, 1620.0, -11, -11, 1, 0}, | |
| 107 {1500.0, 1620.0, -11, -11, 1, 0}, | |
| 108 {1380.0, 1740.0, -11, -11, 1, 0}, | |
| 109 {1500.0, 1740.0, -11, -11, 1, 0}, | |
| 110 {1620.0, 1740.0, -11, -11, 1, 0}, | |
| 111 {1380.0, 1860.0, -11, -11, 1, 0}, | |
| 112 {1500.0, 1860.0, -11, -11, 1, 0}, | |
| 113 {1620.0, 1860.0, -11, -11, 1, 0}, | |
| 114 {1740.0, 1860.0, -11, -11, 1, 0}, | |
| 115 {1380.0, 1980.0, -11, -11, 1, 0}, | |
| 116 {1500.0, 1980.0, -11, -11, 1, 0}, | |
| 117 {1620.0, 1980.0, -11, -11, 1, 0}, | |
| 118 {1740.0, 1980.0, -11, -11, 1, 0}, | |
| 119 {1860.0, 1980.0, -11, -11, 1, 0}, | |
| 120 {0.0, 0.0, 0, 0, 0, 0} | |
| 121 }; | |
| 122 | |
| 123 static const mf_digit_tones_t r2_mf_back_tones[] = | |
| 124 { | |
| 125 {1140.0, 1020.0, -11, -11, 1, 0}, | |
| 126 {1140.0, 900.0, -11, -11, 1, 0}, | |
| 127 {1020.0, 900.0, -11, -11, 1, 0}, | |
| 128 {1140.0, 780.0, -11, -11, 1, 0}, | |
| 129 {1020.0, 780.0, -11, -11, 1, 0}, | |
| 130 { 900.0, 780.0, -11, -11, 1, 0}, | |
| 131 {1140.0, 660.0, -11, -11, 1, 0}, | |
| 132 {1020.0, 660.0, -11, -11, 1, 0}, | |
| 133 { 900.0, 660.0, -11, -11, 1, 0}, | |
| 134 { 780.0, 660.0, -11, -11, 1, 0}, | |
| 135 {1140.0, 540.0, -11, -11, 1, 0}, | |
| 136 {1020.0, 540.0, -11, -11, 1, 0}, | |
| 137 { 900.0, 540.0, -11, -11, 1, 0}, | |
| 138 { 780.0, 540.0, -11, -11, 1, 0}, | |
| 139 { 660.0, 540.0, -11, -11, 1, 0}, | |
| 140 {0.0, 0.0, 0, 0, 0, 0} | |
| 141 }; | |
| 142 | |
| 143 static tone_gen_descriptor_t my_mf_digit_tones[16]; | |
| 144 | |
| 145 static char r2_mf_tone_codes[] = "1234567890BCDEF"; | |
| 146 | |
| 147 int callback_ok; | |
| 148 int callback_roll; | |
| 149 | |
| 150 static void my_mf_gen_init(float low_fudge, | |
| 151 int low_level, | |
| 152 float high_fudge, | |
| 153 int high_level, | |
| 154 int duration, | |
| 155 int fwd) | |
| 156 { | |
| 157 const mf_digit_tones_t *tone; | |
| 158 int i; | |
| 159 | |
| 160 for (i = 0; i < 15; i++) | |
| 161 { | |
| 162 if (fwd) | |
| 163 tone = &r2_mf_fwd_tones[i]; | |
| 164 else | |
| 165 tone = &r2_mf_back_tones[i]; | |
| 166 make_tone_gen_descriptor(&my_mf_digit_tones[i], | |
| 167 tone->f1*(1.0 + low_fudge), | |
| 168 low_level, | |
| 169 tone->f2*(1.0 + high_fudge), | |
| 170 high_level, | |
| 171 duration, | |
| 172 0, | |
| 173 0, | |
| 174 0, | |
| 175 FALSE); | |
| 176 } | |
| 177 } | |
| 178 /*- End of function --------------------------------------------------------*/ | |
| 179 | |
| 180 static int my_mf_generate(int16_t amp[], char digit) | |
| 181 { | |
| 182 int len; | |
| 183 char *cp; | |
| 184 tone_gen_state_t tone; | |
| 185 | |
| 186 len = 0; | |
| 187 if ((cp = strchr(r2_mf_tone_codes, digit))) | |
| 188 { | |
| 189 tone_gen_init(&tone, &my_mf_digit_tones[cp - r2_mf_tone_codes]); | |
| 190 len += tone_gen(&tone, amp + len, 9999); | |
| 191 } | |
| 192 return len; | |
| 193 } | |
| 194 /*- End of function --------------------------------------------------------*/ | |
| 195 | |
| 196 static void codec_munge(int16_t amp[], int len) | |
| 197 { | |
| 198 int i; | |
| 199 uint8_t alaw; | |
| 200 | |
| 201 for (i = 0; i < len; i++) | |
| 202 { | |
| 203 alaw = linear_to_alaw (amp[i]); | |
| 204 amp[i] = alaw_to_linear (alaw); | |
| 205 } | |
| 206 } | |
| 207 /*- End of function --------------------------------------------------------*/ | |
| 208 | |
| 209 static void digit_delivery(void *data, int digit, int level, int delay) | |
| 210 { | |
| 211 char ch; | |
| 212 | |
| 213 if (data != (void *) 0x12345678) | |
| 214 { | |
| 215 callback_ok = FALSE; | |
| 216 return; | |
| 217 } | |
| 218 if ((callback_roll & 1)) | |
| 219 ch = 0; | |
| 220 else | |
| 221 ch = r2_mf_tone_codes[callback_roll >> 1]; | |
| 222 if (ch == digit) | |
| 223 callback_ok = TRUE; | |
| 224 else | |
| 225 callback_ok = FALSE; | |
| 226 if (r2_mf_tone_codes[callback_roll >> 1]) | |
| 227 callback_roll++; | |
| 228 else | |
| 229 callback_ok = FALSE; | |
| 230 } | |
| 231 /*- End of function --------------------------------------------------------*/ | |
| 232 | |
| 233 static int test_a_tone_set(int fwd) | |
| 234 { | |
| 235 int i; | |
| 236 int j; | |
| 237 int len; | |
| 238 int sample; | |
| 239 const char *s; | |
| 240 char digit; | |
| 241 int actual; | |
| 242 int nplus; | |
| 243 int nminus; | |
| 244 float rrb; | |
| 245 float rcfo; | |
| 246 int16_t amp[100000]; | |
| 247 r2_mf_rx_state_t mf_state; | |
| 248 awgn_state_t noise_source; | |
| 249 const mf_digit_tones_t *tone; | |
| 250 | |
| 251 if (fwd) | |
| 252 tone = &r2_mf_fwd_tones[0]; | |
| 253 else | |
| 254 tone = &r2_mf_back_tones[0]; | |
| 255 r2_mf_rx_init(&mf_state, fwd, NULL, NULL); | |
| 256 | |
| 257 /* Test 1: Mitel's test 1 isn't really a test. Its a calibration step, | |
| 258 which has no meaning here. */ | |
| 259 | |
| 260 printf ("Test 1: Calibration\n"); | |
| 261 printf (" Passed\n"); | |
| 262 | |
| 263 /* Test 2: Decode check | |
| 264 This is a sanity check, that all digits are reliably detected | |
| 265 under ideal conditions. Each possible digit is repeated 10 times, | |
| 266 with 68ms bursts. The level of each tone is about 6dB down from clip */ | |
| 267 | |
| 268 printf ("Test 2: Decode check\n"); | |
| 269 my_mf_gen_init(0.0, -3, 0.0, -3, 68, fwd); | |
| 270 s = r2_mf_tone_codes; | |
| 271 while (*s) | |
| 272 { | |
| 273 digit = *s++; | |
| 274 for (i = 0; i < 10; i++) | |
| 275 { | |
| 276 len = my_mf_generate(amp, digit); | |
| 277 codec_munge (amp, len); | |
| 278 r2_mf_rx(&mf_state, amp, len); | |
| 279 actual = r2_mf_rx_get(&mf_state); | |
| 280 if (actual != digit) | |
| 281 { | |
| 282 printf (" Sent '%c'\n", digit); | |
| 283 printf (" Received 0x%X\n", actual); | |
| 284 printf (" Failed\n"); | |
| 285 exit (2); | |
| 286 } | |
| 287 } | |
| 288 } | |
| 289 printf (" Passed\n"); | |
| 290 | |
| 291 /* Test 3: Recognition bandwidth and channel centre frequency check. | |
| 292 Use all digits. Each digit types requires four tests to complete | |
| 293 the check. Each section contains 40 pulses of 68ms duration, | |
| 294 with an amplitude of -20dB from clip per frequency. | |
| 295 | |
| 296 Four sections covering the tests for one tone (1 digit) are: | |
| 297 a. H frequency at 0% deviation from center, L frequency at +0.1%. | |
| 298 L frequency is then increments in +01.% steps up to +4%. The | |
| 299 number of tone bursts is noted and designated N+. | |
| 300 b. H frequency at 0% deviation, L frequency at -0.1%. L frequency | |
| 301 is then incremental in -0.1% steps, up to -4%. The number of | |
| 302 tone bursts is noted and designated N-. | |
| 303 c. The test in (a) is repeated with the L frequency at 0% and the | |
| 304 H frequency varied up to +4%. | |
| 305 d. The test in (b) is repeated with the L frequency and 0% and the | |
| 306 H frequency varied to -4%. | |
| 307 | |
| 308 Receiver Recognition Bandwidth (RRB) is calculated as follows: | |
| 309 RRB% = (N+ + N-)/10 | |
| 310 Receiver Center Frequency Offset (RCFO) is calculated as follows: | |
| 311 RCFO% = X + (N+ - N-)/20 | |
| 312 | |
| 313 Note that this test doesn't test what it says it is testing at all, | |
| 314 and the results are quite inaccurate, if not a downright lie! However, | |
| 315 it follows the Mitel procedure, so how can it be bad? :) | |
| 316 | |
| 317 The spec calls for +-4 +-10Hz (ie +-14Hz) of bandwidth. */ | |
| 318 | |
| 319 printf ("Test 3: Recognition bandwidth and channel centre frequency check\n"); | |
| 320 s = r2_mf_tone_codes; | |
| 321 j = 0; | |
| 322 while (*s) | |
| 323 { | |
| 324 digit = *s++; | |
| 325 for (nplus = 0, i = 1; i <= 60; i++) | |
| 326 { | |
| 327 my_mf_gen_init((float) i/1000.0, -17, 0.0, -17, 68, fwd); | |
| 328 len = my_mf_generate(amp, digit); | |
| 329 codec_munge(amp, len); | |
| 330 r2_mf_rx(&mf_state, amp, len); | |
| 331 if (r2_mf_rx_get(&mf_state) == digit) | |
| 332 nplus++; | |
| 333 } | |
| 334 for (nminus = 0, i = -1; i >= -60; i--) | |
| 335 { | |
| 336 my_mf_gen_init((float) i/1000.0, -17, 0.0, -17, 68, fwd); | |
| 337 len = my_mf_generate(amp, digit); | |
| 338 codec_munge(amp, len); | |
| 339 r2_mf_rx(&mf_state, amp, len); | |
| 340 if (r2_mf_rx_get(&mf_state) == digit) | |
| 341 nminus++; | |
| 342 } | |
| 343 rrb = (float) (nplus + nminus)/10.0; | |
| 344 rcfo = (float) (nplus - nminus)/10.0; | |
| 345 printf (" %c (low) rrb = %5.2f%%, rcfo = %5.2f%%, max -ve = %5.2f, max +ve = %5.2f\n", | |
| 346 digit, | |
| 347 rrb, | |
| 348 rcfo, | |
| 349 (float) nminus/10.0, | |
| 350 (float) nplus/10.0); | |
| 351 | |
| 352 if (rrb < rcfo + (2.0*100.0*14.0/r2_mf_fwd_tones[j].f1) || rrb >= 15.0 + rcfo) | |
| 353 { | |
| 354 printf (" Failed\n"); | |
| 355 exit (2); | |
| 356 } | |
| 357 | |
| 358 for (nplus = 0, i = 1; i <= 60; i++) | |
| 359 { | |
| 360 my_mf_gen_init(0.0, -17, (float) i/1000.0, -17, 68, fwd); | |
| 361 len = my_mf_generate(amp, digit); | |
| 362 codec_munge(amp, len); | |
| 363 r2_mf_rx(&mf_state, amp, len); | |
| 364 if (r2_mf_rx_get(&mf_state) == digit) | |
| 365 nplus++; | |
| 366 } | |
| 367 for (nminus = 0, i = -1; i >= -60; i--) | |
| 368 { | |
| 369 my_mf_gen_init(0.0, -17, (float) i/1000.0, -17, 68, fwd); | |
| 370 len = my_mf_generate(amp, digit); | |
| 371 codec_munge(amp, len); | |
| 372 r2_mf_rx(&mf_state, amp, len); | |
| 373 if (r2_mf_rx_get(&mf_state) == digit) | |
| 374 nminus++; | |
| 375 } | |
| 376 rrb = (float) (nplus + nminus)/10.0; | |
| 377 rcfo = (float) (nplus - nminus)/10.0; | |
| 378 printf (" %c (high) rrb = %5.2f%%, rcfo = %5.2f%%, max -ve = %5.2f, max +ve = %5.2f\n", | |
| 379 digit, | |
| 380 rrb, | |
| 381 rcfo, | |
| 382 (float) nminus/10.0, | |
| 383 (float) nplus/10.0); | |
| 384 if (rrb < rcfo + (2.0*100.0*14.0/r2_mf_fwd_tones[j].f2) || rrb >= 15.0 + rcfo) | |
| 385 { | |
| 386 printf (" Failed\n"); | |
| 387 exit (2); | |
| 388 } | |
| 389 j++; | |
| 390 } | |
| 391 printf (" Passed\n"); | |
| 392 | |
| 393 /* Test 4: Acceptable amplitude ratio (twist). | |
| 394 Twist all digits in both directions, and check the maximum twist | |
| 395 we can accept. The way this is done is styled after the Mitel DTMF | |
| 396 test, and has good and bad points. */ | |
| 397 | |
| 398 printf ("Test 4: Acceptable amplitude ratio (twist)\n"); | |
| 399 s = r2_mf_tone_codes; | |
| 400 while (*s) | |
| 401 { | |
| 402 digit = *s++; | |
| 403 for (nplus = 0, i = -50; i >= -250; i--) | |
| 404 { | |
| 405 my_mf_gen_init(0.0, -5, 0.0, i/10, 68, fwd); | |
| 406 | |
| 407 len = my_mf_generate(amp, digit); | |
| 408 codec_munge (amp, len); | |
| 409 r2_mf_rx(&mf_state, amp, len); | |
| 410 if (r2_mf_rx_get(&mf_state) == digit) | |
| 411 nplus++; | |
| 412 } | |
| 413 printf (" %c normal twist = %.2fdB\n", digit, (float) nplus/10.0); | |
| 414 if (nplus < 70) | |
| 415 { | |
| 416 printf (" Failed\n"); | |
| 417 exit (2); | |
| 418 } | |
| 419 for (nminus = 0, i = -50; i >= -250; i--) | |
| 420 { | |
| 421 my_mf_gen_init(0.0, i/10, 0.0, -5, 68, fwd); | |
| 422 | |
| 423 len = my_mf_generate(amp, digit); | |
| 424 codec_munge(amp, len); | |
| 425 r2_mf_rx(&mf_state, amp, len); | |
| 426 if (r2_mf_rx_get(&mf_state) == digit) | |
| 427 nminus++; | |
| 428 } | |
| 429 printf (" %c reverse twist = %.2fdB\n", digit, (float) nminus/10.0); | |
| 430 if (nminus < 70) | |
| 431 { | |
| 432 printf (" Failed\n"); | |
| 433 exit (2); | |
| 434 } | |
| 435 } | |
| 436 printf (" Passed\n"); | |
| 437 | |
| 438 /* Test 5: Dynamic range | |
| 439 This test sends all possible digits, with gradually increasing | |
| 440 amplitude. We determine the span over which we achieve reliable | |
| 441 detection. */ | |
| 442 | |
| 443 printf ("Test 5: Dynamic range\n"); | |
| 444 for (nplus = nminus = -1000, i = -50; i <= 3; i++) | |
| 445 { | |
| 446 s = r2_mf_tone_codes; | |
| 447 while (*s) | |
| 448 { | |
| 449 digit = *s++; | |
| 450 my_mf_gen_init(0.0, i, 0.0, i, 68, fwd); | |
| 451 for (j = 0; j < 100; j++) | |
| 452 { | |
| 453 len = my_mf_generate(amp, digit); | |
| 454 codec_munge(amp, len); | |
| 455 r2_mf_rx(&mf_state, amp, len); | |
| 456 if (r2_mf_rx_get(&mf_state) != digit) | |
| 457 break; | |
| 458 } | |
| 459 if (j < 100) | |
| 460 break; | |
| 461 } | |
| 462 if (j == 100) | |
| 463 { | |
| 464 if (nplus == -1000) | |
| 465 nplus = i; | |
| 466 } | |
| 467 else | |
| 468 { | |
| 469 if (nplus != -1000 && nminus == -1000) | |
| 470 nminus = i; | |
| 471 } | |
| 472 } | |
| 473 printf (" Dynamic range = %ddB to %ddB\n", nplus, nminus - 1); | |
| 474 if (nplus > -35 || nminus <= -5) | |
| 475 { | |
| 476 printf(" Failed\n"); | |
| 477 exit(2); | |
| 478 } | |
| 479 printf (" Passed\n"); | |
| 480 | |
| 481 /* Test 6: Guard time | |
| 482 This test sends all possible digits, with a gradually reducing | |
| 483 duration. */ | |
| 484 | |
| 485 printf ("Test 6: Guard time\n"); | |
| 486 for (i = 30; i < 62; i++) | |
| 487 { | |
| 488 s = r2_mf_tone_codes; | |
| 489 j = 0; | |
| 490 while (*s) | |
| 491 { | |
| 492 digit = *s++; | |
| 493 my_mf_gen_init(0.0, -5, 0.0, -3, i, fwd); | |
| 494 for (j = 0; j < 500; j++) | |
| 495 { | |
| 496 len = my_mf_generate(amp, digit); | |
| 497 codec_munge(amp, len); | |
| 498 r2_mf_rx(&mf_state, amp, len); | |
| 499 if (r2_mf_rx_get(&mf_state) != digit) | |
| 500 break; | |
| 501 } | |
| 502 if (j < 500) | |
| 503 break; | |
| 504 } | |
| 505 if (j == 500) | |
| 506 break; | |
| 507 } | |
| 508 printf (" Guard time = %dms\n", i); | |
| 509 if (i > 61) | |
| 510 { | |
| 511 printf(" Failed\n"); | |
| 512 exit(2); | |
| 513 } | |
| 514 printf (" Passed\n"); | |
| 515 | |
| 516 /* Test 7: Acceptable signal to noise ratio | |
| 517 We send all possible digits at -6dBm from clip, mixed with AWGN. | |
| 518 We gradually reduce the noise until we get clean detection. */ | |
| 519 | |
| 520 printf ("Test 7: Acceptable signal to noise ratio\n"); | |
| 521 my_mf_gen_init(0.0, -3, 0.0, -3, 68, fwd); | |
| 522 for (i = -3; i > -50; i--) | |
| 523 { | |
| 524 s = r2_mf_tone_codes; | |
| 525 while (*s) | |
| 526 { | |
| 527 digit = *s++; | |
| 528 awgn_init_dbm0(&noise_source, 1234567, (float) i); | |
| 529 for (j = 0; j < 500; j++) | |
| 530 { | |
| 531 len = my_mf_generate(amp, digit); | |
| 532 for (sample = 0; sample < len; sample++) | |
| 533 amp[sample] = saturate(amp[sample] + awgn(&noise_source)); | |
| 534 codec_munge(amp, len); | |
| 535 r2_mf_rx(&mf_state, amp, len); | |
| 536 if (r2_mf_rx_get(&mf_state) != digit) | |
| 537 break; | |
| 538 } | |
| 539 if (j < 500) | |
| 540 break; | |
| 541 } | |
| 542 if (j == 500) | |
| 543 break; | |
| 544 } | |
| 545 printf(" Acceptable S/N ratio is %ddB\n", -3 - i); | |
| 546 if (-3 - i > 26) | |
| 547 { | |
| 548 printf(" Failed\n"); | |
| 549 exit(2); | |
| 550 } | |
| 551 printf(" Passed\n"); | |
| 552 | |
| 553 printf("Test 8: Callback digit delivery mode.\n"); | |
| 554 callback_ok = FALSE; | |
| 555 callback_roll = 0; | |
| 556 r2_mf_rx_init(&mf_state, fwd, digit_delivery, (void *) 0x12345678); | |
| 557 my_mf_gen_init(0.0, -3, 0.0, -3, 68, fwd); | |
| 558 s = r2_mf_tone_codes; | |
| 559 awgn_init_dbm0(&noise_source, 1234567, -40.0f); | |
| 560 while (*s) | |
| 561 { | |
| 562 digit = *s++; | |
| 563 len = my_mf_generate(amp, digit); | |
| 564 for (sample = 0; sample < len; sample++) | |
| 565 amp[sample] = saturate(amp[sample] + awgn(&noise_source)); | |
| 566 codec_munge(amp, len); | |
| 567 r2_mf_rx(&mf_state, amp, len); | |
| 568 len = 160; | |
| 569 memset(amp, '\0', len*sizeof(int16_t)); | |
| 570 for (sample = 0; sample < len; sample++) | |
| 571 amp[sample] = saturate(amp[sample] + awgn(&noise_source)); | |
| 572 codec_munge(amp, len); | |
| 573 r2_mf_rx(&mf_state, amp, len); | |
| 574 } | |
| 575 if (!callback_ok) | |
| 576 { | |
| 577 printf(" Failed\n"); | |
| 578 exit (2); | |
| 579 } | |
| 580 printf(" Passed\n"); | |
| 581 | |
| 582 /* The remainder of the Mitel tape is the talk-off test. This is | |
| 583 meaningless for R2 MF. However the decoder's tolerance of | |
| 584 out of band noise is significant. */ | |
| 585 /* TODO: add a OOB tolerance test. */ | |
| 586 | |
| 587 return 0; | |
| 588 } | |
| 589 /*- End of function --------------------------------------------------------*/ | |
| 590 | |
| 591 int main(int argc, char *argv[]) | |
| 592 { | |
| 593 time_t now; | |
| 594 time_t duration; | |
| 595 | |
| 596 now = time(NULL); | |
| 597 printf("R2 forward tones\n"); | |
| 598 test_a_tone_set(TRUE); | |
| 599 printf("R2 backward tones\n"); | |
| 600 test_a_tone_set(FALSE); | |
| 601 duration = time(NULL) - now; | |
| 602 printf ("Tests passed in %lds\n", duration); | |
| 603 return 0; | |
| 604 } | |
| 605 /*- End of function --------------------------------------------------------*/ | |
| 606 /*- End of file ------------------------------------------------------------*/ |
