sig_tone_tests.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  1. /*
  2. * SpanDSP - a series of DSP components for telephony
  3. *
  4. * sig_tone_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. /*! \file */
  26. /*! \page sig_tone_tests_page The 2280/2400/2600Hz signalling tone Rx/Tx tests
  27. \section sig_tone_tests_sec_1 What does it do?
  28. ???.
  29. \section sig_tone_tests_sec_2 How does it work?
  30. ???.
  31. */
  32. #if defined(HAVE_CONFIG_H)
  33. #include "config.h"
  34. #endif
  35. #include <stdlib.h>
  36. #include <unistd.h>
  37. #include <stdio.h>
  38. #include <memory.h>
  39. #include <sndfile.h>
  40. #include "spandsp.h"
  41. #include "spandsp-sim.h"
  42. #define OUT_FILE_NAME "sig_tone.wav"
  43. #define SAMPLES_PER_CHUNK 160
  44. #define MITEL_DIR "../test-data/mitel/"
  45. #define BELLCORE_DIR "../test-data/bellcore/"
  46. const char *bellcore_files[] =
  47. {
  48. MITEL_DIR "mitel-cm7291-talkoff.wav",
  49. BELLCORE_DIR "tr-tsy-00763-1.wav",
  50. BELLCORE_DIR "tr-tsy-00763-2.wav",
  51. BELLCORE_DIR "tr-tsy-00763-3.wav",
  52. BELLCORE_DIR "tr-tsy-00763-4.wav",
  53. BELLCORE_DIR "tr-tsy-00763-5.wav",
  54. BELLCORE_DIR "tr-tsy-00763-6.wav",
  55. ""
  56. };
  57. typedef struct
  58. {
  59. double freq;
  60. double min_level;
  61. double max_level;
  62. } template_t;
  63. static int number_of_tones = 1;
  64. static int sampleno = 0;
  65. static int tone_1_present = 0;
  66. static int tone_2_present = 0;
  67. static int tx_section = 0;
  68. static int dial_pulses = 0;
  69. static int rx_handler_callbacks = 0;
  70. static int tx_handler_callbacks = 0;
  71. static bool use_gui = false;
  72. static void plot_frequency_response(void)
  73. {
  74. FILE *gnucmd;
  75. if ((gnucmd = popen("gnuplot", "w")) == NULL)
  76. {
  77. exit(2);
  78. }
  79. fprintf(gnucmd, "set autoscale\n");
  80. fprintf(gnucmd, "unset log\n");
  81. fprintf(gnucmd, "unset label\n");
  82. fprintf(gnucmd, "set xtic auto\n");
  83. fprintf(gnucmd, "set ytic auto\n");
  84. fprintf(gnucmd, "set title 'Notch filter frequency response'\n");
  85. fprintf(gnucmd, "set xlabel 'Frequency (Hz)'\n");
  86. fprintf(gnucmd, "set ylabel 'Gain (dB)'\n");
  87. fprintf(gnucmd, "plot 'sig_tone_notch' using 1:3 title 'min' with lines,"
  88. "'sig_tone_notch' using 1:6 title 'actual' with lines,"
  89. "'sig_tone_notch' using 1:9 title 'max' with lines\n");
  90. fflush(gnucmd);
  91. getchar();
  92. if (pclose(gnucmd) == -1)
  93. {
  94. exit(2);
  95. }
  96. }
  97. /*- End of function --------------------------------------------------------*/
  98. static void tx_handler(void *user_data, int what, int level, int duration)
  99. {
  100. sig_tone_tx_state_t *s;
  101. int tone;
  102. int time;
  103. static const int pattern_1_tone[][2] =
  104. {
  105. {33, SIG_TONE_1_PRESENT},
  106. {67, 0},
  107. {33, SIG_TONE_1_PRESENT},
  108. {67, 0},
  109. {33, SIG_TONE_1_PRESENT},
  110. {67, 0},
  111. {33, SIG_TONE_1_PRESENT},
  112. {67, 0},
  113. {33, SIG_TONE_1_PRESENT},
  114. {67, 0},
  115. {33, SIG_TONE_1_PRESENT},
  116. {67, 0},
  117. {33, SIG_TONE_1_PRESENT},
  118. {67, 0},
  119. {33, SIG_TONE_1_PRESENT},
  120. {67, 0},
  121. {33, SIG_TONE_1_PRESENT},
  122. {67, 0},
  123. {600, SIG_TONE_1_PRESENT},
  124. {0, 0}
  125. };
  126. static const int pattern_2_tones[][2] =
  127. {
  128. #if 0
  129. {33, SIG_TONE_1_PRESENT},
  130. {67, 0},
  131. {33, SIG_TONE_1_PRESENT},
  132. {67, 0},
  133. {33, SIG_TONE_1_PRESENT},
  134. {67, 0},
  135. {33, SIG_TONE_1_PRESENT},
  136. {67, 0},
  137. {33, SIG_TONE_1_PRESENT},
  138. {67, 0},
  139. {33, SIG_TONE_1_PRESENT},
  140. {67, 0},
  141. {33, SIG_TONE_1_PRESENT},
  142. {67, 0},
  143. {33, SIG_TONE_1_PRESENT},
  144. {67, 0},
  145. {33, SIG_TONE_1_PRESENT},
  146. {67, 0},
  147. #endif
  148. {100, SIG_TONE_1_PRESENT},
  149. {100, SIG_TONE_1_PRESENT | SIG_TONE_2_PRESENT},
  150. {100, SIG_TONE_2_PRESENT},
  151. #if 0
  152. {100, 0},
  153. {100, SIG_TONE_2_PRESENT},
  154. {100, SIG_TONE_1_PRESENT | SIG_TONE_2_PRESENT},
  155. {100, SIG_TONE_1_PRESENT},
  156. #endif
  157. {0, 0}
  158. };
  159. s = (sig_tone_tx_state_t *) user_data;
  160. tx_handler_callbacks++;
  161. //printf("What - %d, duration - %d\n", what, duration);
  162. if ((what & SIG_TONE_TX_UPDATE_REQUEST))
  163. {
  164. /* The sig tone transmit side wants to know what to do next */
  165. printf("Tx: update request\n");
  166. if (number_of_tones == 1)
  167. {
  168. time = pattern_1_tone[tx_section][0];
  169. tone = pattern_1_tone[tx_section][1];
  170. }
  171. else
  172. {
  173. time = pattern_2_tones[tx_section][0];
  174. tone = pattern_2_tones[tx_section][1];
  175. }
  176. if (time)
  177. {
  178. printf("Tx: [%04x] %s %s for %d samples (%dms)\n",
  179. tone,
  180. (tone & SIG_TONE_1_PRESENT) ? "on " : "off",
  181. (tone & SIG_TONE_2_PRESENT) ? "on " : "off",
  182. ms_to_samples(time),
  183. time);
  184. sig_tone_tx_set_mode(s, tone, ms_to_samples(time));
  185. tx_section++;
  186. }
  187. else
  188. {
  189. printf("End of sequence\n");
  190. }
  191. }
  192. /*endif*/
  193. }
  194. /*- End of function --------------------------------------------------------*/
  195. static void rx_handler(void *user_data, int what, int level, int duration)
  196. {
  197. float ms;
  198. int x;
  199. rx_handler_callbacks++;
  200. ms = 1000.0f*(float) duration/(float) SAMPLE_RATE;
  201. printf("Rx: [%04x]", what);
  202. x = what & SIG_TONE_1_PRESENT;
  203. if ((what & SIG_TONE_1_CHANGE))
  204. {
  205. printf(" %s", (x) ? "on " : "off");
  206. if (x == tone_1_present)
  207. exit(2);
  208. tone_1_present = x;
  209. }
  210. else
  211. {
  212. printf(" ---");
  213. if (x != tone_1_present)
  214. exit(2);
  215. }
  216. /*endif*/
  217. x = what & SIG_TONE_2_PRESENT;
  218. if ((what & SIG_TONE_2_CHANGE))
  219. {
  220. printf(" %s", (x) ? "on " : "off");
  221. if (x == tone_2_present)
  222. exit(2);
  223. tone_2_present = x;
  224. }
  225. else
  226. {
  227. if (x != tone_2_present)
  228. exit(2);
  229. printf(" ---");
  230. }
  231. /*endif*/
  232. printf(" after %d samples (%.3fms)\n", duration, ms);
  233. }
  234. /*- End of function --------------------------------------------------------*/
  235. static void map_frequency_response(sig_tone_rx_state_t *s, template_t template[])
  236. {
  237. int16_t buf[SAMPLES_PER_CHUNK];
  238. int i;
  239. int len;
  240. double sumin;
  241. double sumout;
  242. swept_tone_state_t *swept;
  243. double freq;
  244. double gain;
  245. int template_entry;
  246. FILE *file;
  247. /* Things like noise don't highlight the frequency response of the high Q notch
  248. very well. We use a slowly swept frequency to check it. */
  249. printf("Frequency response test\n");
  250. sig_tone_rx_set_mode(s, SIG_TONE_RX_PASSTHROUGH | SIG_TONE_RX_FILTER_TONE, 0);
  251. swept = swept_tone_init(NULL, 200.0f, 3900.0f, -10.0f, 120*SAMPLE_RATE, 0);
  252. template_entry = 0;
  253. file = fopen("sig_tone_notch", "wb");
  254. for (;;)
  255. {
  256. if ((len = swept_tone(swept, buf, SAMPLES_PER_CHUNK)) <= 0)
  257. break;
  258. /*endif*/
  259. sumin = 0.0;
  260. for (i = 0; i < len; i++)
  261. sumin += (double) buf[i]*(double) buf[i];
  262. /*endfor*/
  263. sig_tone_rx(s, buf, len);
  264. sumout = 0.0;
  265. for (i = 0; i < len; i++)
  266. sumout += (double) buf[i]*(double) buf[i];
  267. /*endfor*/
  268. freq = swept_tone_current_frequency(swept);
  269. gain = (sumin != 0.0) ? 10.0*log10(sumout/sumin + 1.0e-10) : 0.0;
  270. printf("%7.1f Hz %.3f dBm0 < %.3f dBm0 < %.3f dBm0\n",
  271. freq,
  272. template[template_entry].min_level,
  273. gain,
  274. template[template_entry].max_level);
  275. if (file)
  276. {
  277. fprintf(file,
  278. "%7.1f Hz %.3f dBm0 < %.3f dBm0 < %.3f dBm0\n",
  279. freq,
  280. template[template_entry].min_level,
  281. gain,
  282. template[template_entry].max_level);
  283. }
  284. /*endif*/
  285. if (gain < template[template_entry].min_level || gain > template[template_entry].max_level)
  286. {
  287. printf("Expected: %.3f dBm0 to %.3f dBm0\n",
  288. template[template_entry].min_level,
  289. template[template_entry].max_level);
  290. printf(" Failed\n");
  291. exit(2);
  292. }
  293. /*endif*/
  294. if (freq > template[template_entry].freq)
  295. template_entry++;
  296. }
  297. /*endfor*/
  298. swept_tone_free(swept);
  299. if (file)
  300. {
  301. fclose(file);
  302. if (use_gui)
  303. plot_frequency_response();
  304. /*endif*/
  305. }
  306. /*endif*/
  307. printf(" Passed\n");
  308. }
  309. /*- End of function --------------------------------------------------------*/
  310. static void speech_immunity_tests(sig_tone_rx_state_t *s)
  311. {
  312. int j;
  313. int total_hits;
  314. SNDFILE *inhandle;
  315. int16_t amp[SAMPLE_RATE];
  316. int frames;
  317. printf("Speech immunity test\n");
  318. total_hits = 0;
  319. for (j = 0; bellcore_files[j][0]; j++)
  320. {
  321. /* Push some silence through, so we should be in the tone off state */
  322. vec_zeroi16(amp, SAMPLE_RATE);
  323. sig_tone_rx(s, amp, SAMPLE_RATE);
  324. rx_handler_callbacks = 0;
  325. if ((inhandle = sf_open_telephony_read(bellcore_files[j], 1)) == NULL)
  326. {
  327. printf(" Cannot open speech file '%s'\n", bellcore_files[j]);
  328. exit(2);
  329. }
  330. /*endif*/
  331. while ((frames = sf_readf_short(inhandle, amp, SAMPLE_RATE)))
  332. {
  333. sig_tone_rx(s, amp, frames);
  334. }
  335. /*endwhile*/
  336. if (sf_close_telephony(inhandle))
  337. {
  338. printf(" Cannot close speech file '%s'\n", bellcore_files[j]);
  339. exit(2);
  340. }
  341. /*endif*/
  342. printf(" File %d gave %d false hits.\n", j + 1, rx_handler_callbacks);
  343. total_hits += rx_handler_callbacks;
  344. }
  345. /*endfor*/
  346. printf(" %d hits in total\n", total_hits);
  347. if (total_hits > 0)
  348. {
  349. printf(" Failed\n");
  350. exit(2);
  351. }
  352. /*endif*/
  353. printf(" Passed\n");
  354. }
  355. /*- End of function --------------------------------------------------------*/
  356. static void level_and_ratio_tests(sig_tone_rx_state_t *s, double pitch[2])
  357. {
  358. awgn_state_t noise_source;
  359. int32_t phase_rate[2];
  360. uint32_t phase[2];
  361. int16_t gain;
  362. int16_t amp[SAMPLE_RATE];
  363. int i;
  364. int j;
  365. int k;
  366. int l;
  367. float noise_level;
  368. float tone_level;
  369. power_meter_t noise_meter;
  370. power_meter_t tone_meter;
  371. int16_t noise;
  372. int16_t tone;
  373. printf("Acceptable level and ratio test - %.2f Hz + %.2f Hz\n", pitch[0], pitch[1]);
  374. for (l = 0; l < 2; l++)
  375. {
  376. phase[l] = 0;
  377. phase_rate[l] = (pitch[l] != 0.0) ? dds_phase_rate(pitch[l]) : 0;
  378. }
  379. for (k = -25; k > -60; k--)
  380. {
  381. noise_level = k;
  382. awgn_init_dbm0(&noise_source, 1234567, noise_level);
  383. tone_level = noise_level;
  384. /* Push some silence through, so we should be in the tone off state */
  385. vec_zeroi16(amp, SAMPLE_RATE);
  386. sig_tone_rx(s, amp, SAMPLE_RATE);
  387. power_meter_init(&noise_meter, 6);
  388. power_meter_init(&tone_meter, 6);
  389. for (j = 0; j < 20; j++)
  390. {
  391. rx_handler_callbacks = 0;
  392. gain = dds_scaling_dbm0(tone_level);
  393. for (i = 0; i < SAMPLES_PER_CHUNK; i++)
  394. {
  395. noise = awgn(&noise_source);
  396. tone = dds_mod(&phase[0], phase_rate[0], gain, 0);
  397. if (phase_rate[1])
  398. tone += dds_mod(&phase[1], phase_rate[1], gain, 0);
  399. power_meter_update(&noise_meter, noise);
  400. power_meter_update(&tone_meter, tone);
  401. amp[i] = noise + tone;
  402. }
  403. /*endfor*/
  404. sig_tone_rx(s, amp, SAMPLES_PER_CHUNK);
  405. if (rx_handler_callbacks)
  406. {
  407. printf("Hit at tone = %.2fdBm0, noise = %.2fdBm0\n", tone_level, noise_level);
  408. printf("Measured tone = %.2fdBm0, noise = %.2fdBm0\n", power_meter_current_dbm0(&tone_meter), power_meter_current_dbm0(&noise_meter));
  409. if (rx_handler_callbacks != 1)
  410. printf("Callbacks = %d\n", rx_handler_callbacks);
  411. }
  412. /*endif*/
  413. tone_level += 1.0f;
  414. }
  415. /*endfor*/
  416. }
  417. /*endfor*/
  418. printf(" Passed\n");
  419. }
  420. /*- End of function --------------------------------------------------------*/
  421. static void sequence_tests(sig_tone_tx_state_t *tx_state, sig_tone_rx_state_t *rx_state, codec_munge_state_t *munge)
  422. {
  423. int i;
  424. awgn_state_t noise_source;
  425. SNDFILE *outhandle;
  426. int16_t amp[SAMPLES_PER_CHUNK];
  427. int16_t out_amp[2*SAMPLES_PER_CHUNK];
  428. int outframes;
  429. int rx_samples;
  430. int tx_samples;
  431. printf("Signalling sequence test\n");
  432. tx_section = 0;
  433. if ((outhandle = sf_open_telephony_write(OUT_FILE_NAME, 2)) == NULL)
  434. {
  435. fprintf(stderr, " Cannot create audio file '%s'\n", OUT_FILE_NAME);
  436. exit(2);
  437. }
  438. /*endif*/
  439. awgn_init_dbm0(&noise_source, 1234567, -20.0f);
  440. sig_tone_tx_set_mode(tx_state, SIG_TONE_1_PRESENT | SIG_TONE_2_PRESENT | SIG_TONE_TX_PASSTHROUGH, 0);
  441. sig_tone_rx_set_mode(rx_state, SIG_TONE_RX_PASSTHROUGH, 0);
  442. for (sampleno = 0; sampleno < 4000; sampleno += SAMPLES_PER_CHUNK)
  443. {
  444. if (sampleno == 800)
  445. {
  446. /* 100ms seize */
  447. printf("Tx: [0000] off off for %d samples (%dms)\n", ms_to_samples(100), 100);
  448. dial_pulses = 0;
  449. sig_tone_tx_set_mode(tx_state, 0, ms_to_samples(100));
  450. }
  451. /*endif*/
  452. for (i = 0; i < SAMPLES_PER_CHUNK; i++)
  453. amp[i] = awgn(&noise_source);
  454. /*endfor*/
  455. tx_samples = sig_tone_tx(tx_state, amp, SAMPLES_PER_CHUNK);
  456. for (i = 0; i < tx_samples; i++)
  457. out_amp[2*i] = amp[i];
  458. /*endfor*/
  459. codec_munge(munge, amp, tx_samples);
  460. rx_samples = sig_tone_rx(rx_state, amp, tx_samples);
  461. for (i = 0; i < rx_samples; i++)
  462. out_amp[2*i + 1] = amp[i];
  463. /*endfor*/
  464. outframes = sf_writef_short(outhandle, out_amp, rx_samples);
  465. if (outframes != rx_samples)
  466. {
  467. fprintf(stderr, " Error writing audio file\n");
  468. exit(2);
  469. }
  470. /*endif*/
  471. }
  472. /*endfor*/
  473. if (sf_close_telephony(outhandle))
  474. {
  475. fprintf(stderr, " Cannot close audio file '%s'\n", OUT_FILE_NAME);
  476. exit(2);
  477. }
  478. /*endif*/
  479. }
  480. /*- End of function --------------------------------------------------------*/
  481. int main(int argc, char *argv[])
  482. {
  483. int type;
  484. sig_tone_tx_state_t tx_state;
  485. sig_tone_rx_state_t rx_state;
  486. codec_munge_state_t *munge;
  487. double fc[2];
  488. int i;
  489. template_t template[10];
  490. int opt;
  491. use_gui = false;
  492. while ((opt = getopt(argc, argv, "g")) != -1)
  493. {
  494. switch (opt)
  495. {
  496. case 'g':
  497. use_gui = true;
  498. break;
  499. default:
  500. //usage();
  501. exit(2);
  502. break;
  503. }
  504. }
  505. for (type = 1; type <= 3; type++)
  506. {
  507. sampleno = 0;
  508. tone_1_present = 0;
  509. tone_2_present = 0;
  510. munge = NULL;
  511. for (i = 0; i < 10; i++)
  512. {
  513. template[i].freq = 0.0;
  514. template[i].min_level = 0.0;
  515. template[i].max_level = 0.0;
  516. }
  517. fc[0] =
  518. fc[1] = 0.0;
  519. switch (type)
  520. {
  521. case 1:
  522. printf("2280Hz tests.\n");
  523. munge = codec_munge_init(MUNGE_CODEC_ALAW, 0);
  524. sig_tone_tx_init(&tx_state, SIG_TONE_2280HZ, tx_handler, &tx_state);
  525. sig_tone_rx_init(&rx_state, SIG_TONE_2280HZ, rx_handler, &rx_state);
  526. number_of_tones = 1;
  527. fc[0] = 2280.0;
  528. /* From BTNR 181 2.3.3.1 */
  529. template[0].freq = 1150.0;
  530. template[0].min_level = -0.2;
  531. template[0].max_level = 0.0;
  532. template[1].freq = 1880.0;
  533. template[1].min_level = -0.5;
  534. template[1].max_level = 0.0;
  535. template[2].freq = 2080.0;
  536. template[2].min_level = -5.0;
  537. template[2].max_level = 0.0;
  538. template[3].freq = 2280.0 - 20.0;
  539. template[3].min_level = -99.0;
  540. template[3].max_level = 0.0;
  541. template[4].freq = 2280.0 + 20.0;
  542. template[4].min_level = -99.0;
  543. template[4].max_level = -30.0;
  544. template[5].freq = 2480.0;
  545. template[5].min_level = -99.0;
  546. template[5].max_level = 0.0;
  547. template[6].freq = 2680.0;
  548. template[6].min_level = -5.0;
  549. template[6].max_level = 0.0;
  550. template[7].freq = 4000.0;
  551. template[7].min_level = -0.5;
  552. template[7].max_level = 0.0;
  553. break;
  554. case 2:
  555. printf("2600Hz tests.\n");
  556. munge = codec_munge_init(MUNGE_CODEC_ULAW, 0);
  557. sig_tone_tx_init(&tx_state, SIG_TONE_2600HZ, tx_handler, &tx_state);
  558. sig_tone_rx_init(&rx_state, SIG_TONE_2600HZ, rx_handler, &rx_state);
  559. number_of_tones = 1;
  560. fc[0] = 2600.0;
  561. template[0].freq = 2600.0 - 200.0;
  562. template[0].min_level = -1.0;
  563. template[0].max_level = 0.0;
  564. template[1].freq = 2600.0 - 20.0;
  565. template[1].min_level = -99.0;
  566. template[1].max_level = 0.0;
  567. template[2].freq = 2600.0 + 20.0;
  568. template[2].min_level = -99.0;
  569. template[2].max_level = -30.0;
  570. template[3].freq = 2600.0 + 200.0;
  571. template[3].min_level = -99.0;
  572. template[3].max_level = 0.0;
  573. template[4].freq = 4000.0;
  574. template[4].min_level = -1.0;
  575. template[4].max_level = 0.0;
  576. break;
  577. case 3:
  578. printf("2400Hz/2600Hz tests.\n");
  579. munge = codec_munge_init(MUNGE_CODEC_ULAW, 0);
  580. sig_tone_tx_init(&tx_state, SIG_TONE_2400HZ_2600HZ, tx_handler, &tx_state);
  581. sig_tone_rx_init(&rx_state, SIG_TONE_2400HZ_2600HZ, rx_handler, &rx_state);
  582. number_of_tones = 2;
  583. fc[0] = 2400.0;
  584. fc[1] = 2600.0;
  585. template[0].freq = 2400.0 - 200.0;
  586. template[0].min_level = -1.0;
  587. template[0].max_level = 0.0;
  588. template[1].freq = 2400.0 - 20.0;
  589. template[1].min_level = -99.0;
  590. template[1].max_level = 0.0;
  591. template[2].freq = 2400.0 + 20.0;
  592. template[2].min_level = -99.0;
  593. template[2].max_level = -30.0;
  594. template[3].freq = 2600.0 - 20.0;
  595. template[3].min_level = -99.0;
  596. template[3].max_level = 0.0;
  597. template[4].freq = 2600.0 + 20.0;
  598. template[4].min_level = -99.0;
  599. template[4].max_level = -30.0;
  600. template[5].freq = 2600.0 + 200.0;
  601. template[5].min_level = -99.0;
  602. template[5].max_level = 0.0;
  603. template[6].freq = 4000.0;
  604. template[6].min_level = -1.0;
  605. template[6].max_level = 0.0;
  606. break;
  607. }
  608. /*endswitch*/
  609. map_frequency_response(&rx_state, template);
  610. speech_immunity_tests(&rx_state);
  611. level_and_ratio_tests(&rx_state, fc);
  612. sequence_tests(&tx_state, &rx_state, munge);
  613. if (munge)
  614. codec_munge_free(munge);
  615. }
  616. /*endfor*/
  617. printf("Tests completed.\n");
  618. return 0;
  619. }
  620. /*- End of function --------------------------------------------------------*/
  621. /*- End of file ------------------------------------------------------------*/