echo_tests.c 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722
  1. /*
  2. * SpanDSP - a series of DSP components for telephony
  3. *
  4. * echo_tests.c
  5. *
  6. * Written by Steve Underwood <steveu@coppice.org>
  7. *
  8. * Copyright (C) 2001 Steve Underwood
  9. *
  10. * Based on a bit from here, a bit from there, eye of toad,
  11. * ear of bat, etc - plus, of course, my own 2 cents.
  12. *
  13. * All rights reserved.
  14. *
  15. * This program is free software; you can redistribute it and/or modify
  16. * it under the terms of the GNU General Public License version 2, as
  17. * published by the Free Software Foundation.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program; if not, write to the Free Software
  26. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  27. */
  28. /*! \page echo_can_tests_page Line echo cancellation for voice tests
  29. \section echo_can_tests_page_sec_1 What does it do?
  30. The echo cancellation tests test the echo cancellor against the G.168 spec. Not
  31. all the tests in G.168 are fully implemented at this time.
  32. \section echo_can_tests_page_sec_2 How does it work?
  33. \section echo_can_tests_page_sec_2 How do I use it?
  34. */
  35. #if defined(HAVE_CONFIG_H)
  36. #include "config.h"
  37. #endif
  38. #if defined(HAVE_FL_FL_H) && defined(HAVE_FL_FL_CARTESIAN_H) && defined(HAVE_FL_FL_AUDIO_METER_H)
  39. #define ENABLE_GUI
  40. #endif
  41. #include <stdlib.h>
  42. #include <stdio.h>
  43. #include <unistd.h>
  44. #include <string.h>
  45. #include <strings.h>
  46. #include <assert.h>
  47. #include <sndfile.h>
  48. #define GEN_CONST
  49. #include <math.h>
  50. #include "spandsp.h"
  51. #include "spandsp/g168models.h"
  52. #include "spandsp-sim.h"
  53. #if defined(ENABLE_GUI)
  54. #include "echo_monitor.h"
  55. #endif
  56. #if !defined(NULL)
  57. #define NULL (void *) 0
  58. #endif
  59. #define TEST_EC_TAPS 256
  60. #define RESIDUE_FILE_NAME "residue_sound.wav"
  61. /*
  62. The key signal names, as defined in G.168
  63. +--------------+ +------------+
  64. | | Sin | |
  65. Sgen -->--| Echoey |--->---| Echo |-->-- Sout
  66. | | | |
  67. | World | Rout | Canceller |
  68. --<--| |---<---| |--<-- Rin
  69. | | | |
  70. +--------------+ +------------+
  71. Echoey world model. Munge means linear->PCM->linear distortion.
  72. +-------------------------+
  73. | | Sin
  74. Sgen -->--|-->munge--->sum-->munge--|--->---
  75. | +--> |
  76. | FIR | Rout
  77. --<--|--------+--------munge<--|---<---
  78. | |
  79. +-------------------------+
  80. */
  81. typedef struct
  82. {
  83. const char *name;
  84. int max;
  85. int cur;
  86. float gain;
  87. SNDFILE *handle;
  88. int16_t signal[SAMPLE_RATE];
  89. } signal_source_t;
  90. /* Level measurement device, specified in G.168 section 6.4.1.2.1 */
  91. typedef struct
  92. {
  93. int type;
  94. fir_float_state_t *fir;
  95. float history[35*8];
  96. int pos;
  97. float factor;
  98. float power;
  99. float peak;
  100. } level_measurement_device_t;
  101. typedef struct
  102. {
  103. int model_no;
  104. float erl;
  105. fir32_state_t impulse;
  106. float gain;
  107. int munging_codec;
  108. } channel_model_state_t;
  109. channel_model_state_t chan_model;
  110. signal_source_t local_css;
  111. signal_source_t far_css;
  112. awgn_state_t local_noise_source;
  113. awgn_state_t far_noise_source;
  114. SNDFILE *residue_handle;
  115. int16_t residue_sound[SAMPLE_RATE];
  116. int residue_cur = 0;
  117. level_measurement_device_t *power_meter_1;
  118. level_measurement_device_t *power_meter_2;
  119. int line_model_no;
  120. int supp_line_model_no;
  121. int munger;
  122. level_measurement_device_t *rin_power_meter; /* Also known as Lrin */
  123. level_measurement_device_t *rout_power_meter;
  124. level_measurement_device_t *sin_power_meter;
  125. level_measurement_device_t *sout_power_meter; /* Also known as Lret (pre NLP value is known as Lres) */
  126. level_measurement_device_t *sgen_power_meter;
  127. #define RESULT_CHANNELS 7
  128. SNDFILE *result_handle;
  129. int16_t result_sound[SAMPLE_RATE*RESULT_CHANNELS];
  130. int result_cur;
  131. const char *test_name;
  132. int quiet;
  133. int use_gui;
  134. float erl;
  135. /* Dump estimated echo response */
  136. static void dump_ec_state(echo_can_state_t *ctx)
  137. {
  138. int i;
  139. FILE *f;
  140. if ((f = fopen("echo_tests_state.txt", "wt")) == NULL)
  141. return;
  142. for (i = 0; i < TEST_EC_TAPS; i++)
  143. fprintf(f, "%f\n", (float) ctx->fir_taps16[0][i]/(1 << 15));
  144. fclose(f);
  145. }
  146. /*- End of function --------------------------------------------------------*/
  147. static inline void put_residue(int16_t amp)
  148. {
  149. int outframes;
  150. residue_sound[residue_cur++] = amp;
  151. if (residue_cur >= SAMPLE_RATE)
  152. {
  153. outframes = sf_writef_short(residue_handle, residue_sound, residue_cur);
  154. if (outframes != residue_cur)
  155. {
  156. fprintf(stderr, " Error writing residue sound\n");
  157. exit(2);
  158. }
  159. residue_cur = 0;
  160. }
  161. }
  162. /*- End of function --------------------------------------------------------*/
  163. static void signal_load(signal_source_t *sig, const char *name)
  164. {
  165. sig->handle = sf_open_telephony_read(name, 1);
  166. sig->name = name;
  167. sig->max = sf_readf_short(sig->handle, sig->signal, SAMPLE_RATE);
  168. if (sig->max < 0)
  169. {
  170. fprintf(stderr, " Error reading sound file '%s'\n", sig->name);
  171. exit(2);
  172. }
  173. }
  174. /*- End of function --------------------------------------------------------*/
  175. static void signal_free(signal_source_t *sig)
  176. {
  177. if (sf_close_telephony(sig->handle))
  178. {
  179. fprintf(stderr, " Cannot close sound file '%s'\n", sig->name);
  180. exit(2);
  181. }
  182. }
  183. /*- End of function --------------------------------------------------------*/
  184. static void signal_restart(signal_source_t *sig, float gain)
  185. {
  186. sig->cur = 0;
  187. sig->gain = powf(10.0f, gain/20.0f);
  188. }
  189. /*- End of function --------------------------------------------------------*/
  190. static int16_t signal_amp(signal_source_t *sig)
  191. {
  192. int16_t tx;
  193. tx = sig->signal[sig->cur++]*sig->gain;
  194. if (sig->cur >= sig->max)
  195. sig->cur = 0;
  196. return tx;
  197. }
  198. /*- End of function --------------------------------------------------------*/
  199. static level_measurement_device_t *level_measurement_device_create(int type)
  200. {
  201. level_measurement_device_t *dev;
  202. int i;
  203. dev = (level_measurement_device_t *) malloc(sizeof(level_measurement_device_t));
  204. dev->fir = (fir_float_state_t *) malloc(sizeof(fir_float_state_t));
  205. fir_float_create(dev->fir,
  206. level_measurement_bp_coeffs,
  207. sizeof(level_measurement_bp_coeffs)/sizeof(float));
  208. for (i = 0; i < 35*8; i++)
  209. dev->history[i] = 0.0f;
  210. dev->pos = 0;
  211. dev->factor = expf(-1.0f/((float) SAMPLE_RATE*0.035f));
  212. dev->power = 0;
  213. dev->type = type;
  214. return dev;
  215. }
  216. /*- End of function --------------------------------------------------------*/
  217. #if 0
  218. static void level_measurement_device_reset(level_measurement_device_t *dev)
  219. {
  220. int i;
  221. for (i = 0; i < 35*8; i++)
  222. dev->history[i] = 0.0f;
  223. dev->pos = 0;
  224. dev->power = 0;
  225. dev->peak = 0.0f;
  226. }
  227. /*- End of function --------------------------------------------------------*/
  228. static int level_measurement_device_release(level_measurement_device_t *s)
  229. {
  230. fir_float_free(s->fir);
  231. free(s->fir);
  232. free(s);
  233. return 0;
  234. }
  235. /*- End of function --------------------------------------------------------*/
  236. #endif
  237. static float level_measurement_device_get_peak(level_measurement_device_t *dev)
  238. {
  239. return dev->peak;
  240. }
  241. /*- End of function --------------------------------------------------------*/
  242. static float level_measurement_device_reset_peak(level_measurement_device_t *dev)
  243. {
  244. float power;
  245. power = dev->peak;
  246. dev->peak = -99.0f;
  247. return power;
  248. }
  249. /*- End of function --------------------------------------------------------*/
  250. static float level_measurement_device(level_measurement_device_t *dev, int16_t amp)
  251. {
  252. float signal;
  253. float power;
  254. /* Level measurement device(s), specified in G.168 section 6.4.1.2.1 and 6.4.1.2.2 */
  255. signal = fir_float(dev->fir, amp);
  256. signal *= signal;
  257. if (dev->type == 0)
  258. {
  259. /* Level measurement device, specified in G.168 section 6.4.1.2.1 -
  260. level measurement device. This version uses a single pole
  261. estimator.*/
  262. dev->power = dev->power*dev->factor + signal*(1.0f - dev->factor);
  263. signal = sqrtf(dev->power);
  264. }
  265. else
  266. {
  267. /* Level measurement device, specified in G.168 section 6.4.1.2.2 -
  268. level measurement device for peaks. This version uses a sliding
  269. window estimator. */
  270. dev->power += (signal - dev->history[dev->pos]);
  271. dev->history[dev->pos++] = signal;
  272. signal = sqrtf(dev->power/(35.8f*8.0f));
  273. }
  274. if (signal <= 0.0f)
  275. return -99.0f;
  276. power = DBM0_MAX_POWER + 20.0f*log10f(signal/32767.0f + 1.0e-10f);
  277. if (power > dev->peak)
  278. dev->peak = power;
  279. return power;
  280. }
  281. /*- End of function --------------------------------------------------------*/
  282. static void level_measurements_create(int type)
  283. {
  284. rin_power_meter = level_measurement_device_create(type);
  285. rout_power_meter = level_measurement_device_create(type);
  286. sin_power_meter = level_measurement_device_create(type);
  287. sout_power_meter = level_measurement_device_create(type);
  288. sgen_power_meter = level_measurement_device_create(type);
  289. }
  290. /*- End of function --------------------------------------------------------*/
  291. static void level_measurements_update(int16_t rin, int16_t sin, int16_t rout, int16_t sout, int16_t sgen)
  292. {
  293. level_measurement_device(rin_power_meter, rin);
  294. level_measurement_device(rout_power_meter, rout);
  295. level_measurement_device(sin_power_meter, sin);
  296. level_measurement_device(sout_power_meter, sout);
  297. level_measurement_device(sgen_power_meter, sgen);
  298. }
  299. /*- End of function --------------------------------------------------------*/
  300. static void level_measurements_reset_peaks(void)
  301. {
  302. level_measurement_device_reset_peak(rin_power_meter);
  303. level_measurement_device_reset_peak(rout_power_meter);
  304. level_measurement_device_reset_peak(sin_power_meter);
  305. level_measurement_device_reset_peak(sout_power_meter);
  306. level_measurement_device_reset_peak(sgen_power_meter);
  307. }
  308. /*- End of function --------------------------------------------------------*/
  309. static void print_results(void)
  310. {
  311. if (!quiet)
  312. printf("test model ERL time Max Rin Max Rout Max Sgen Max Sin Max Sout\n");
  313. printf("%-4s %-1d %-5.1f%6.2fs%9.2f%9.2f%9.2f%9.2f%9.2f\n",
  314. test_name,
  315. chan_model.model_no,
  316. 20.0f*log10f(-chan_model.erl + 1.0e-10f),
  317. 0.0f, //test_clock,
  318. level_measurement_device_get_peak(rin_power_meter),
  319. level_measurement_device_get_peak(rout_power_meter),
  320. level_measurement_device_get_peak(sgen_power_meter),
  321. level_measurement_device_get_peak(sin_power_meter),
  322. level_measurement_device_get_peak(sout_power_meter));
  323. }
  324. /*- End of function --------------------------------------------------------*/
  325. static int channel_model_create(channel_model_state_t *chan, int model, float erl, int codec)
  326. {
  327. static const int32_t line_model_clear_coeffs[] =
  328. {
  329. 32768
  330. };
  331. static const int32_t *line_models[] =
  332. {
  333. line_model_clear_coeffs,
  334. line_model_d2_coeffs,
  335. line_model_d3_coeffs,
  336. line_model_d4_coeffs,
  337. line_model_d5_coeffs,
  338. line_model_d6_coeffs,
  339. line_model_d7_coeffs,
  340. line_model_d8_coeffs,
  341. line_model_d9_coeffs
  342. };
  343. static const int line_model_sizes[] =
  344. {
  345. sizeof(line_model_clear_coeffs)/sizeof(line_model_clear_coeffs[0]),
  346. sizeof(line_model_d2_coeffs)/sizeof(line_model_d2_coeffs[0]),
  347. sizeof(line_model_d3_coeffs)/sizeof(line_model_d3_coeffs[0]),
  348. sizeof(line_model_d4_coeffs)/sizeof(line_model_d4_coeffs[0]),
  349. sizeof(line_model_d5_coeffs)/sizeof(line_model_d5_coeffs[0]),
  350. sizeof(line_model_d6_coeffs)/sizeof(line_model_d6_coeffs[0]),
  351. sizeof(line_model_d7_coeffs)/sizeof(line_model_d7_coeffs[0]),
  352. sizeof(line_model_d8_coeffs)/sizeof(line_model_d8_coeffs[0]),
  353. sizeof(line_model_d9_coeffs)/sizeof(line_model_d9_coeffs[0])
  354. };
  355. static const float ki[] =
  356. {
  357. 3.05e-5f,
  358. LINE_MODEL_D2_GAIN,
  359. LINE_MODEL_D3_GAIN,
  360. LINE_MODEL_D4_GAIN,
  361. LINE_MODEL_D5_GAIN,
  362. LINE_MODEL_D6_GAIN,
  363. LINE_MODEL_D7_GAIN,
  364. LINE_MODEL_D8_GAIN,
  365. LINE_MODEL_D9_GAIN
  366. };
  367. if (model < 0 || model >= (int) (sizeof(line_model_sizes)/sizeof(line_model_sizes[0])))
  368. return -1;
  369. fir32_create(&chan->impulse, line_models[model], line_model_sizes[model]);
  370. chan->gain = 32768.0f*powf(10.0f, erl/20.0f)*ki[model];
  371. chan->munging_codec = codec;
  372. chan->model_no = model;
  373. chan->erl = erl;
  374. return 0;
  375. }
  376. /*- End of function --------------------------------------------------------*/
  377. static int16_t channel_model(channel_model_state_t *chan, int16_t rout, int16_t sgen)
  378. {
  379. int16_t echo;
  380. int16_t sin;
  381. /* Channel modelling is merely simulating the effects of A-law or u-law distortion
  382. and using one of the echo models from G.168. Simulating the codec is very important,
  383. as this is usually the limiting factor in how much echo reduction is achieved. */
  384. /* The far end signal will have been through codec munging. */
  385. switch (chan->munging_codec)
  386. {
  387. case G711_ALAW:
  388. sgen = alaw_to_linear(linear_to_alaw(sgen));
  389. break;
  390. case G711_ULAW:
  391. sgen = ulaw_to_linear(linear_to_ulaw(sgen));
  392. break;
  393. }
  394. /* The local tx signal will usually have gone through codec munging before
  395. it reached the line's analogue area, where the echo occurs. */
  396. switch (chan->munging_codec)
  397. {
  398. case G711_ALAW:
  399. rout = alaw_to_linear(linear_to_alaw(rout));
  400. break;
  401. case G711_ULAW:
  402. rout = ulaw_to_linear(linear_to_ulaw(rout));
  403. break;
  404. }
  405. /* Now we need to model the echo. We only model a single analogue segment, as per
  406. the G.168 spec. However, there will generally be near end and far end analogue/echoey
  407. segments in the real world, unless an end is purely digital. */
  408. echo = fir32(&chan->impulse, rout*chan->gain);
  409. sin = sat_add16(echo, sgen);
  410. /* This mixed echo and far end signal will have been through codec munging
  411. when it came back into the digital network. */
  412. switch (chan->munging_codec)
  413. {
  414. case G711_ALAW:
  415. sin = alaw_to_linear(linear_to_alaw(sin));
  416. break;
  417. case G711_ULAW:
  418. sin = ulaw_to_linear(linear_to_ulaw(sin));
  419. break;
  420. }
  421. return sin;
  422. }
  423. /*- End of function --------------------------------------------------------*/
  424. static void write_log_files(int16_t rout, int16_t sin)
  425. {
  426. #if 0
  427. fprintf(flevel, "%f\t%f\t%f\t%f\n", LRin, LSin, LSout, LSgen);
  428. fprintf(fdump, "%d %d %d", ctx->tx, ctx->rx, ctx->clean);
  429. fprintf(fdump,
  430. " %d %d %d %d %d %d %d %d %d %d\n",
  431. ctx->clean_nlp,
  432. ctx->Ltx,
  433. ctx->Lrx,
  434. ctx->Lclean,
  435. (ctx->nonupdate_dwell > 0),
  436. ctx->adapt,
  437. ctx->Lclean_bg,
  438. ctx->Pstates,
  439. ctx->Lbgn_upper,
  440. ctx->Lbgn);
  441. #endif
  442. }
  443. /*- End of function --------------------------------------------------------*/
  444. static int16_t silence(void)
  445. {
  446. return 0;
  447. }
  448. /*- End of function --------------------------------------------------------*/
  449. static int16_t local_css_signal(void)
  450. {
  451. return signal_amp(&local_css);
  452. }
  453. /*- End of function --------------------------------------------------------*/
  454. static int16_t far_css_signal(void)
  455. {
  456. return signal_amp(&far_css);
  457. }
  458. /*- End of function --------------------------------------------------------*/
  459. static int16_t local_noise_signal(void)
  460. {
  461. return awgn(&local_noise_source);
  462. }
  463. /*- End of function --------------------------------------------------------*/
  464. static int16_t far_noise_signal(void)
  465. {
  466. return awgn(&far_noise_source);
  467. }
  468. /*- End of function --------------------------------------------------------*/
  469. #if 0
  470. static int16_t local_hoth_noise_signal(void)
  471. {
  472. static float hoth_noise = 0.0;
  473. hoth_noise = hoth_noise*0.625 + awgn(&local_noise_source)*0.375;
  474. return (int16_t) hoth_noise;
  475. }
  476. /*- End of function --------------------------------------------------------*/
  477. #endif
  478. static int16_t far_hoth_noise_signal(void)
  479. {
  480. static float hoth_noise = 0.0;
  481. hoth_noise = hoth_noise*0.625 + awgn(&far_noise_source)*0.375;
  482. return (int16_t) hoth_noise;
  483. }
  484. /*- End of function --------------------------------------------------------*/
  485. static void run_test(echo_can_state_t *ctx, int16_t (*tx_source)(void), int16_t (*rx_source)(void), int period)
  486. {
  487. int i;
  488. int16_t rin;
  489. int16_t rout;
  490. int16_t sin;
  491. int16_t sout;
  492. int16_t sgen;
  493. int outframes;
  494. for (i = 0; i < period*SAMPLE_RATE/1000; i++)
  495. {
  496. rin = tx_source();
  497. sgen = rx_source();
  498. rout = echo_can_hpf_tx(ctx, rin);
  499. sin = channel_model(&chan_model, rout, sgen);
  500. sout = echo_can_update(ctx, rout, sin);
  501. level_measurements_update(rin, sin, rout, sout, sgen);
  502. //residue = 100.0f*pp1/pp2;
  503. //put_residue(residue);
  504. //put_residue(clean - rx);
  505. #if defined(ENABLE_GUI)
  506. if (use_gui)
  507. echo_can_monitor_can_update(ctx->fir_taps16[0], TEST_EC_TAPS);
  508. #endif
  509. result_sound[result_cur++] = rin;
  510. result_sound[result_cur++] = sgen;
  511. result_sound[result_cur++] = sin;
  512. result_sound[result_cur++] = rout;
  513. result_sound[result_cur++] = sout;
  514. result_sound[result_cur++] = sout - sgen;
  515. result_sound[result_cur++] = 0; // TODO: insert the EC's internal status here
  516. if (result_cur >= RESULT_CHANNELS*SAMPLE_RATE)
  517. {
  518. outframes = sf_writef_short(result_handle, result_sound, result_cur/RESULT_CHANNELS);
  519. if (outframes != result_cur/RESULT_CHANNELS)
  520. {
  521. fprintf(stderr, " Error writing result sound\n");
  522. exit(2);
  523. }
  524. result_cur = 0;
  525. }
  526. }
  527. #if defined(ENABLE_GUI)
  528. if (use_gui)
  529. echo_can_monitor_can_update(ctx->fir_taps16[0], TEST_EC_TAPS);
  530. #endif
  531. if (result_cur >= 0)
  532. {
  533. outframes = sf_writef_short(result_handle, result_sound, result_cur/RESULT_CHANNELS);
  534. if (outframes != result_cur/RESULT_CHANNELS)
  535. {
  536. fprintf(stderr, " Error writing result sound\n");
  537. exit(2);
  538. }
  539. result_cur = 0;
  540. }
  541. }
  542. /*- End of function --------------------------------------------------------*/
  543. static void print_test_title(const char *title)
  544. {
  545. if (quiet == false)
  546. printf("%s", title);
  547. }
  548. /*- End of function --------------------------------------------------------*/
  549. static int perform_test_sanity(void)
  550. {
  551. echo_can_state_t *ctx;
  552. int i;
  553. int16_t rx;
  554. int16_t tx;
  555. int16_t clean;
  556. int far_tx;
  557. //int16_t far_sound[SAMPLE_RATE];
  558. int16_t result_sound[64000];
  559. int result_cur;
  560. int outframes;
  561. //int local_cur;
  562. //int far_cur;
  563. //int32_t coeffs[200][128];
  564. //int coeff_index;
  565. print_test_title("Performing basic sanity test\n");
  566. ctx = echo_can_init(TEST_EC_TAPS, 0);
  567. //local_cur = 0;
  568. //far_cur = 0;
  569. result_cur = 0;
  570. echo_can_flush(ctx);
  571. /* Converge the canceller */
  572. signal_restart(&local_css, 0.0f);
  573. run_test(ctx, silence, silence, 200);
  574. run_test(ctx, local_css_signal, silence, 5000);
  575. echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION | ECHO_CAN_USE_NLP | ECHO_CAN_USE_CNG);
  576. run_test(ctx, local_css_signal, silence, 5000);
  577. echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
  578. for (i = 0; i < SAMPLE_RATE*10; i++)
  579. {
  580. tx = local_css_signal();
  581. #if 0
  582. if ((i/10000)%10 == 9)
  583. {
  584. /* Inject a burst of far sound */
  585. if (far_cur >= far_max)
  586. {
  587. far_max = sf_readf_short(farhandle, far_sound, SAMPLE_RATE);
  588. if (far_max < 0)
  589. {
  590. fprintf(stderr, " Error reading far sound\n");
  591. exit(2);
  592. }
  593. if (far_max == 0)
  594. break;
  595. far_cur = 0;
  596. }
  597. far_tx = far_sound[far_cur++];
  598. }
  599. else
  600. {
  601. far_tx = 0;
  602. }
  603. #else
  604. //far_sound[0] = 0;
  605. far_tx = 0;
  606. #endif
  607. rx = channel_model(&chan_model, tx, far_tx);
  608. //rx += awgn(&far_noise_source);
  609. //tx += awgn(&far_noise_source);
  610. clean = echo_can_update(ctx, tx, rx);
  611. #if defined(XYZZY)
  612. if (i%SAMPLE_RATE == 0)
  613. {
  614. if (coeff_index < 200)
  615. {
  616. for (j = 0; j < ctx->taps; j++)
  617. coeffs[coeff_index][j] = ctx->fir_taps32[j];
  618. coeff_index++;
  619. }
  620. }
  621. #endif
  622. result_sound[result_cur++] = tx;
  623. result_sound[result_cur++] = rx;
  624. result_sound[result_cur++] = clean - far_tx;
  625. //result_sound[result_cur++] = ctx->tx_power[2];
  626. //result_sound[result_cur++] = ctx->tx_power[1];
  627. ////result_sound[result_cur++] = (ctx->tx_power[1] > 64) ? SAMPLE_RATE : -SAMPLE_RATE;
  628. //result_sound[result_cur++] = ctx->tap_set*SAMPLE_RATE;
  629. //result_sound[result_cur++] = (ctx->nonupdate_dwell > 0) ? SAMPLE_RATE : -SAMPLE_RATE;
  630. //result_sound[result_cur++] = ctx->latest_correction >> 8;
  631. //result_sound[result_cur++] = level_measurement_device(tx)/(16.0*65536.0);
  632. //result_sound[result_cur++] = level_measurement_device(tx)/4096.0;
  633. ////result_sound[result_cur++] = (ctx->tx_power[1] > ctx->rx_power[0]) ? SAMPLE_RATE : -SAMPLE_RATE;
  634. //result_sound[result_cur++] = (ctx->tx_power[1] > ctx->rx_power[0]) ? SAMPLE_RATE : -SAMPLE_RATE;
  635. //result_sound[result_cur++] = (ctx->narrowband_score)*5; // ? SAMPLE_RATE : -SAMPLE_RATE;
  636. //result_sound[result_cur++] = ctx->tap_rotate_counter*10;
  637. ////result_sound[result_cur++] = ctx->vad;
  638. put_residue(clean - far_tx);
  639. if (result_cur >= RESULT_CHANNELS*SAMPLE_RATE)
  640. {
  641. outframes = sf_writef_short(result_handle, result_sound, result_cur/RESULT_CHANNELS);
  642. if (outframes != result_cur/RESULT_CHANNELS)
  643. {
  644. fprintf(stderr, " Error writing result sound\n");
  645. exit(2);
  646. }
  647. result_cur = 0;
  648. }
  649. }
  650. if (result_cur > 0)
  651. {
  652. outframes = sf_writef_short(result_handle, result_sound, result_cur/RESULT_CHANNELS);
  653. if (outframes != result_cur/RESULT_CHANNELS)
  654. {
  655. fprintf(stderr, " Error writing result sound\n");
  656. exit(2);
  657. }
  658. }
  659. #if defined(XYZZY)
  660. for (j = 0; j < ctx->taps; j++)
  661. {
  662. for (i = 0; i < coeff_index; i++)
  663. fprintf(stderr, "%d ", coeffs[i][j]);
  664. fprintf(stderr, "\n");
  665. }
  666. #endif
  667. echo_can_free(ctx);
  668. return 0;
  669. }
  670. /*- End of function --------------------------------------------------------*/
  671. static int perform_test_2a(void)
  672. {
  673. echo_can_state_t *ctx;
  674. /* Test 2 - Convergence and steady state residual and returned echo level test */
  675. /* Test 2A - Convergence and reconvergence test with NLP enabled */
  676. print_test_title("Performing test 2A - Convergence and reconvergence test with NLP enabled\n");
  677. ctx = echo_can_init(TEST_EC_TAPS, 0);
  678. echo_can_flush(ctx);
  679. echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION | ECHO_CAN_USE_NLP);
  680. /* Test 2A (a) - Convergence test with NLP enabled */
  681. /* Converge the canceller. */
  682. run_test(ctx, silence, silence, 200);
  683. signal_restart(&local_css, 0.0f);
  684. run_test(ctx, local_css_signal, silence, 1000);
  685. level_measurements_reset_peaks();
  686. run_test(ctx, local_css_signal, silence, 9000);
  687. print_results();
  688. if (level_measurement_device_get_peak(sout_power_meter) > -65.0f)
  689. printf("Test failed\n");
  690. else
  691. printf("Test passed\n");
  692. /* Test 2A (b) - Reconvergence test with NLP enabled */
  693. /* Make an abrupt change of channel characteristic, to another of the channel echo models. */
  694. if (channel_model_create(&chan_model, supp_line_model_no, erl, munger))
  695. {
  696. fprintf(stderr, " Failed to create line model\n");
  697. exit(2);
  698. }
  699. signal_restart(&local_css, 0.0f);
  700. run_test(ctx, local_css_signal, silence, 1000);
  701. level_measurements_reset_peaks();
  702. run_test(ctx, local_css_signal, silence, 9000);
  703. print_results();
  704. if (level_measurement_device_get_peak(sout_power_meter) > -65.0f)
  705. printf("Test failed\n");
  706. else
  707. printf("Test passed\n");
  708. echo_can_free(ctx);
  709. return 0;
  710. }
  711. /*- End of function --------------------------------------------------------*/
  712. static int perform_test_2b(void)
  713. {
  714. echo_can_state_t *ctx;
  715. /* Test 2 - Convergence and steady state residual and returned echo level test */
  716. /* Test 2B - Convergence and reconverge with NLP disabled */
  717. print_test_title("Performing test 2B - Convergence and reconverge with NLP disabled\n");
  718. ctx = echo_can_init(TEST_EC_TAPS, 0);
  719. echo_can_flush(ctx);
  720. echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
  721. signal_restart(&local_css, 0.0f);
  722. /* Test 2B (a) - Convergence test with NLP disabled */
  723. /* Converge the canceller */
  724. run_test(ctx, silence, silence, 200);
  725. run_test(ctx, local_css_signal, silence, 1000);
  726. level_measurements_reset_peaks();
  727. run_test(ctx, local_css_signal, silence, 9000);
  728. print_results();
  729. level_measurements_reset_peaks();
  730. run_test(ctx, local_css_signal, silence, 170000);
  731. print_results();
  732. if (level_measurement_device_get_peak(sout_power_meter) > -65.0)
  733. printf("Test failed\n");
  734. else
  735. printf("Test passed\n");
  736. /* Test 2B (b) - Reconvergence test with NLP disabled */
  737. /* Make an abrupt change of channel characteristic, to another of the channel echo models. */
  738. if (channel_model_create(&chan_model, supp_line_model_no, erl, munger))
  739. {
  740. fprintf(stderr, " Failed to create line model\n");
  741. exit(2);
  742. }
  743. run_test(ctx, local_css_signal, silence, 1000);
  744. level_measurements_reset_peaks();
  745. run_test(ctx, local_css_signal, silence, 9000);
  746. print_results();
  747. level_measurements_reset_peaks();
  748. run_test(ctx, local_css_signal, silence, 170000);
  749. print_results();
  750. if (level_measurement_device_get_peak(sout_power_meter) > -65.0)
  751. printf("Test failed\n");
  752. else
  753. printf("Test passed\n");
  754. echo_can_free(ctx);
  755. return 0;
  756. }
  757. /*- End of function --------------------------------------------------------*/
  758. static int perform_test_2ca(void)
  759. {
  760. echo_can_state_t *ctx;
  761. /* Test 2 - Convergence and steady state residual and returned echo level test */
  762. /* Test 2C(a) - Convergence with background noise present */
  763. print_test_title("Performing test 2C(a) - Convergence with background noise present\n");
  764. ctx = echo_can_init(TEST_EC_TAPS, 0);
  765. awgn_init_dbm0(&far_noise_source, 7162534, -50.0f);
  766. echo_can_flush(ctx);
  767. echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
  768. /* Converge a canceller */
  769. signal_restart(&local_css, 0.0f);
  770. run_test(ctx, silence, silence, 200);
  771. awgn_init_dbm0(&far_noise_source, 7162534, -40.0f);
  772. run_test(ctx, local_css_signal, far_hoth_noise_signal, 5000);
  773. /* Now freeze adaption, and measure the echo. */
  774. echo_can_adaption_mode(ctx, 0);
  775. level_measurements_reset_peaks();
  776. run_test(ctx, local_css_signal, silence, 5000);
  777. print_results();
  778. if (level_measurement_device_get_peak(sout_power_meter) > level_measurement_device_get_peak(sgen_power_meter))
  779. printf("Test failed\n");
  780. else
  781. printf("Test passed\n");
  782. echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
  783. echo_can_free(ctx);
  784. return 0;
  785. }
  786. /*- End of function --------------------------------------------------------*/
  787. static int perform_test_3a(void)
  788. {
  789. echo_can_state_t *ctx;
  790. /* Test 3 - Performance under double talk conditions */
  791. /* Test 3A - Double talk test with low cancelled-end levels */
  792. print_test_title("Performing test 3A - Double talk test with low cancelled-end levels\n");
  793. ctx = echo_can_init(TEST_EC_TAPS, 0);
  794. echo_can_flush(ctx);
  795. echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
  796. run_test(ctx, silence, silence, 200);
  797. signal_restart(&local_css, 0.0f);
  798. signal_restart(&far_css, -20.0f);
  799. /* Apply double talk, with a weak far end signal */
  800. run_test(ctx, local_css_signal, far_css_signal, 5000);
  801. /* Now freeze adaption. */
  802. echo_can_adaption_mode(ctx, 0);
  803. run_test(ctx, local_css_signal, silence, 500);
  804. /* Now measure the echo */
  805. level_measurements_reset_peaks();
  806. run_test(ctx, local_css_signal, silence, 5000);
  807. print_results();
  808. if (level_measurement_device_get_peak(sout_power_meter) > level_measurement_device_get_peak(sgen_power_meter))
  809. printf("Test failed\n");
  810. else
  811. printf("Test passed\n");
  812. echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
  813. echo_can_free(ctx);
  814. return 0;
  815. }
  816. /*- End of function --------------------------------------------------------*/
  817. static int perform_test_3ba(void)
  818. {
  819. echo_can_state_t *ctx;
  820. /* Test 3 - Performance under double talk conditions */
  821. /* Test 3B(a) - Double talk stability test with high cancelled-end levels */
  822. print_test_title("Performing test 3B(b) - Double talk stability test with high cancelled-end levels\n");
  823. ctx = echo_can_init(TEST_EC_TAPS, 0);
  824. echo_can_flush(ctx);
  825. echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
  826. run_test(ctx, silence, silence, 200);
  827. signal_restart(&local_css, 0.0f);
  828. signal_restart(&far_css, 0.0f);
  829. /* Converge the canceller */
  830. run_test(ctx, local_css_signal, silence, 5000);
  831. /* Apply double talk */
  832. run_test(ctx, local_css_signal, far_css_signal, 5000);
  833. /* Now freeze adaption. */
  834. echo_can_adaption_mode(ctx, 0);
  835. run_test(ctx, local_css_signal, far_css_signal, 1000);
  836. /* Turn off the double talk. */
  837. run_test(ctx, local_css_signal, silence, 500);
  838. /* Now measure the echo */
  839. level_measurements_reset_peaks();
  840. run_test(ctx, local_css_signal, silence, 5000);
  841. print_results();
  842. echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
  843. echo_can_free(ctx);
  844. return 0;
  845. }
  846. /*- End of function --------------------------------------------------------*/
  847. static int perform_test_3bb(void)
  848. {
  849. echo_can_state_t *ctx;
  850. /* Test 3 - Performance under double talk conditions */
  851. /* Test 3B(b) - Double talk stability test with low cancelled-end levels */
  852. print_test_title("Performing test 3B(b) - Double talk stability test with low cancelled-end levels\n");
  853. ctx = echo_can_init(TEST_EC_TAPS, 0);
  854. echo_can_flush(ctx);
  855. echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
  856. run_test(ctx, silence, silence, 200);
  857. signal_restart(&local_css, 0.0f);
  858. signal_restart(&far_css, -15.0f);
  859. /* Converge the canceller */
  860. run_test(ctx, local_css_signal, silence, 5000);
  861. /* Apply double talk */
  862. run_test(ctx, local_css_signal, far_css_signal, 5000);
  863. /* Now freeze adaption. */
  864. echo_can_adaption_mode(ctx, 0);
  865. run_test(ctx, local_css_signal, silence, 1000);
  866. /* Turn off the double talk. */
  867. run_test(ctx, local_css_signal, silence, 500);
  868. /* Now measure the echo */
  869. level_measurements_reset_peaks();
  870. run_test(ctx, local_css_signal, silence, 5000);
  871. print_results();
  872. echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
  873. echo_can_free(ctx);
  874. return 0;
  875. }
  876. /*- End of function --------------------------------------------------------*/
  877. static int perform_test_3c(void)
  878. {
  879. echo_can_state_t *ctx;
  880. /* Test 3 - Performance under double talk conditions */
  881. /* Test 3C - Double talk test with simulated conversation */
  882. print_test_title("Performing test 3C - Double talk test with simulated conversation\n");
  883. ctx = echo_can_init(TEST_EC_TAPS, 0);
  884. echo_can_flush(ctx);
  885. echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
  886. run_test(ctx, silence, silence, 200);
  887. signal_restart(&local_css, 0.0f);
  888. signal_restart(&far_css, -15.0f);
  889. /* Apply double talk */
  890. run_test(ctx, local_css_signal, far_css_signal, 5600);
  891. /* Stop the far signal, and measure the echo. */
  892. level_measurements_reset_peaks();
  893. run_test(ctx, local_css_signal, silence, 1400);
  894. print_results();
  895. /* Continue measuring the resulting echo */
  896. run_test(ctx, local_css_signal, silence, 5000);
  897. /* Reapply double talk */
  898. signal_restart(&far_css, 0.0f);
  899. run_test(ctx, local_css_signal, far_css_signal, 5600);
  900. /* Now the far signal only */
  901. run_test(ctx, silence, far_css_signal, 5600);
  902. echo_can_free(ctx);
  903. return 0;
  904. }
  905. /*- End of function --------------------------------------------------------*/
  906. static int perform_test_4(void)
  907. {
  908. echo_can_state_t *ctx;
  909. /* Test 4 - Leak rate test */
  910. print_test_title("Performing test 4 - Leak rate test\n");
  911. ctx = echo_can_init(TEST_EC_TAPS, 0);
  912. echo_can_flush(ctx);
  913. echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
  914. run_test(ctx, silence, silence, 200);
  915. /* Converge the canceller */
  916. signal_restart(&local_css, 0.0f);
  917. run_test(ctx, local_css_signal, silence, 5000);
  918. /* Put 2 minutes of silence through it */
  919. run_test(ctx, silence, silence, 120000);
  920. /* Now freeze it, and check if it is still well adapted. */
  921. echo_can_adaption_mode(ctx, 0);
  922. level_measurements_reset_peaks();
  923. run_test(ctx, local_css_signal, silence, 5000);
  924. print_results();
  925. echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
  926. echo_can_free(ctx);
  927. return 0;
  928. }
  929. /*- End of function --------------------------------------------------------*/
  930. static int perform_test_5(void)
  931. {
  932. echo_can_state_t *ctx;
  933. /* Test 5 - Infinite return loss convergence test */
  934. print_test_title("Performing test 5 - Infinite return loss convergence test\n");
  935. ctx = echo_can_init(TEST_EC_TAPS, 0);
  936. echo_can_flush(ctx);
  937. echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
  938. /* Converge the canceller */
  939. signal_restart(&local_css, 0.0f);
  940. run_test(ctx, local_css_signal, silence, 5000);
  941. /* Now stop echoing, and see we don't do anything unpleasant as the
  942. echo path is open looped. */
  943. run_test(ctx, local_css_signal, silence, 5000);
  944. print_results();
  945. echo_can_free(ctx);
  946. return 0;
  947. }
  948. /*- End of function --------------------------------------------------------*/
  949. static int perform_test_6(void)
  950. {
  951. echo_can_state_t *ctx;
  952. int i;
  953. int j;
  954. int k;
  955. int16_t rx;
  956. int16_t tx;
  957. int16_t clean;
  958. tone_gen_descriptor_t tone_desc;
  959. tone_gen_state_t tone_state;
  960. int16_t local_sound[40000];
  961. /* Test 6 - Non-divergence on narrow-band signals */
  962. print_test_title("Performing test 6 - Non-divergence on narrow-band signals\n");
  963. ctx = echo_can_init(TEST_EC_TAPS, 0);
  964. echo_can_flush(ctx);
  965. echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
  966. /* Converge the canceller */
  967. signal_restart(&local_css, 0.0f);
  968. run_test(ctx, local_css_signal, silence, 5000);
  969. /* Now put 5s bursts of a list of tones through the converged canceller, and check
  970. that nothing unpleasant happens. */
  971. for (k = 0; tones_6_4_2_7[k][0]; k++)
  972. {
  973. tone_gen_descriptor_init(&tone_desc,
  974. tones_6_4_2_7[k][0],
  975. -11,
  976. tones_6_4_2_7[k][1],
  977. -9,
  978. 1,
  979. 0,
  980. 0,
  981. 0,
  982. 1);
  983. tone_gen_init(&tone_state, &tone_desc);
  984. j = 0;
  985. for (i = 0; i < 5; i++)
  986. {
  987. tone_gen(&tone_state, local_sound, SAMPLE_RATE);
  988. for (j = 0; j < SAMPLE_RATE; j++)
  989. {
  990. tx = local_sound[j];
  991. rx = channel_model(&chan_model, tx, 0);
  992. clean = echo_can_update(ctx, tx, rx);
  993. put_residue(clean);
  994. }
  995. #if defined(ENABLE_GUI)
  996. if (use_gui)
  997. {
  998. echo_can_monitor_can_update(ctx->fir_taps16[0], TEST_EC_TAPS);
  999. echo_can_monitor_update_display();
  1000. usleep(100000);
  1001. }
  1002. #endif
  1003. }
  1004. }
  1005. #if defined(ENABLE_GUI)
  1006. if (use_gui)
  1007. echo_can_monitor_can_update(ctx->fir_taps16[0], TEST_EC_TAPS);
  1008. #endif
  1009. echo_can_free(ctx);
  1010. return 0;
  1011. }
  1012. /*- End of function --------------------------------------------------------*/
  1013. static int perform_test_7(void)
  1014. {
  1015. echo_can_state_t *ctx;
  1016. int i;
  1017. int j;
  1018. int16_t rx;
  1019. int16_t tx;
  1020. int16_t clean;
  1021. tone_gen_descriptor_t tone_desc;
  1022. tone_gen_state_t tone_state;
  1023. int16_t local_sound[40000];
  1024. /* Test 7 - Stability */
  1025. print_test_title("Performing test 7 - Stability\n");
  1026. ctx = echo_can_init(TEST_EC_TAPS, 0);
  1027. /* Put tones through an unconverged canceller, and check nothing unpleasant
  1028. happens. */
  1029. echo_can_flush(ctx);
  1030. echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
  1031. tone_gen_descriptor_init(&tone_desc,
  1032. tones_6_4_2_7[0][0],
  1033. -11,
  1034. tones_6_4_2_7[0][1],
  1035. -9,
  1036. 1,
  1037. 0,
  1038. 0,
  1039. 0,
  1040. 1);
  1041. tone_gen_init(&tone_state, &tone_desc);
  1042. j = 0;
  1043. for (i = 0; i < 120; i++)
  1044. {
  1045. tone_gen(&tone_state, local_sound, SAMPLE_RATE);
  1046. for (j = 0; j < SAMPLE_RATE; j++)
  1047. {
  1048. tx = local_sound[j];
  1049. rx = channel_model(&chan_model, tx, 0);
  1050. clean = echo_can_update(ctx, tx, rx);
  1051. put_residue(clean);
  1052. }
  1053. #if defined(ENABLE_GUI)
  1054. if (use_gui)
  1055. {
  1056. echo_can_monitor_can_update(ctx->fir_taps16[0], TEST_EC_TAPS);
  1057. echo_can_monitor_update_display();
  1058. usleep(100000);
  1059. }
  1060. #endif
  1061. }
  1062. #if defined(ENABLE_GUI)
  1063. if (use_gui)
  1064. echo_can_monitor_can_update(ctx->fir_taps16[0], TEST_EC_TAPS);
  1065. #endif
  1066. echo_can_free(ctx);
  1067. return 0;
  1068. }
  1069. /*- End of function --------------------------------------------------------*/
  1070. static int perform_test_8(void)
  1071. {
  1072. echo_can_state_t *ctx;
  1073. /* Test 8 - Non-convergence on No 5, 6, and 7 in-band signalling */
  1074. print_test_title("Performing test 8 - Non-convergence on No 5, 6, and 7 in-band signalling\n");
  1075. ctx = echo_can_init(TEST_EC_TAPS, 0);
  1076. fprintf(stderr, "Test 8 not yet implemented\n");
  1077. echo_can_free(ctx);
  1078. return 0;
  1079. }
  1080. /*- End of function --------------------------------------------------------*/
  1081. static int perform_test_9(void)
  1082. {
  1083. echo_can_state_t *ctx;
  1084. awgn_state_t local_noise_source;
  1085. awgn_state_t far_noise_source;
  1086. /* Test 9 - Comfort noise test */
  1087. print_test_title("Performing test 9 - Comfort noise test\n");
  1088. ctx = echo_can_init(TEST_EC_TAPS, 0);
  1089. awgn_init_dbm0(&far_noise_source, 7162534, -50.0f);
  1090. echo_can_flush(ctx);
  1091. echo_can_adaption_mode(ctx,
  1092. ECHO_CAN_USE_ADAPTION
  1093. | ECHO_CAN_USE_NLP
  1094. | ECHO_CAN_USE_CNG);
  1095. /* Test 9 part 1 - matching */
  1096. /* Converge the canceller */
  1097. signal_restart(&local_css, 0.0f);
  1098. run_test(ctx, local_css_signal, silence, 5000);
  1099. echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION | ECHO_CAN_USE_NLP | ECHO_CAN_USE_CNG);
  1100. awgn_init_dbm0(&far_noise_source, 7162534, -45.0f);
  1101. run_test(ctx, silence, far_noise_signal, 30000);
  1102. awgn_init_dbm0(&local_noise_source, 1234567, -10.0f);
  1103. run_test(ctx, local_noise_signal, far_noise_signal, 2000);
  1104. /* Test 9 part 2 - adjust down */
  1105. awgn_init_dbm0(&far_noise_source, 7162534, -55.0f);
  1106. run_test(ctx, silence, far_noise_signal, 10000);
  1107. run_test(ctx, local_noise_signal, far_noise_signal, 2000);
  1108. echo_can_free(ctx);
  1109. return 0;
  1110. }
  1111. /*- End of function --------------------------------------------------------*/
  1112. static int perform_test_10a(void)
  1113. {
  1114. echo_can_state_t *ctx;
  1115. /* Test 10 - FAX test during call establishment phase */
  1116. /* Test 10A - Canceller operation on the calling station side */
  1117. print_test_title("Performing test 10A - Canceller operation on the calling station side\n");
  1118. ctx = echo_can_init(TEST_EC_TAPS, 0);
  1119. fprintf(stderr, "Test 10A not yet implemented\n");
  1120. echo_can_free(ctx);
  1121. return 0;
  1122. }
  1123. /*- End of function --------------------------------------------------------*/
  1124. static int perform_test_10b(void)
  1125. {
  1126. echo_can_state_t *ctx;
  1127. /* Test 10 - FAX test during call establishment phase */
  1128. /* Test 10B - Canceller operation on the called station side */
  1129. print_test_title("Performing test 10B - Canceller operation on the called station side\n");
  1130. ctx = echo_can_init(TEST_EC_TAPS, 0);
  1131. fprintf(stderr, "Test 10B not yet implemented\n");
  1132. echo_can_free(ctx);
  1133. return 0;
  1134. }
  1135. /*- End of function --------------------------------------------------------*/
  1136. static int perform_test_10c(void)
  1137. {
  1138. echo_can_state_t *ctx;
  1139. /* Test 10 - FAX test during call establishment phase */
  1140. /* Test 10C - Canceller operation on the calling station side during page
  1141. transmission and page breaks (for further study) */
  1142. print_test_title("Performing test 10C - Canceller operation on the calling station side during page\n"
  1143. "transmission and page breaks (for further study)\n");
  1144. ctx = echo_can_init(TEST_EC_TAPS, 0);
  1145. fprintf(stderr, "Test 10C not yet implemented\n");
  1146. echo_can_free(ctx);
  1147. return 0;
  1148. }
  1149. /*- End of function --------------------------------------------------------*/
  1150. static int perform_test_11(void)
  1151. {
  1152. echo_can_state_t *ctx;
  1153. /* Test 11 - Tandem echo canceller test (for further study) */
  1154. print_test_title("Performing test 11 - Tandem echo canceller test (for further study)\n");
  1155. ctx = echo_can_init(TEST_EC_TAPS, 0);
  1156. fprintf(stderr, "Test 11 not yet implemented\n");
  1157. echo_can_free(ctx);
  1158. return 0;
  1159. }
  1160. /*- End of function --------------------------------------------------------*/
  1161. static int perform_test_12(void)
  1162. {
  1163. echo_can_state_t *ctx;
  1164. /* Test 12 - Residual acoustic echo test (for further study) */
  1165. print_test_title("Performing test 12 - Residual acoustic echo test (for further study)\n");
  1166. ctx = echo_can_init(TEST_EC_TAPS, 0);
  1167. fprintf(stderr, "Test 12 not yet implemented\n");
  1168. echo_can_free(ctx);
  1169. return 0;
  1170. }
  1171. /*- End of function --------------------------------------------------------*/
  1172. static int perform_test_13(void)
  1173. {
  1174. echo_can_state_t *ctx;
  1175. /* Test 13 - Performance with ITU-T low-bit rate coders in echo path
  1176. (Optional, under study) */
  1177. print_test_title("Performing test 13 - Performance with ITU-T low-bit rate coders in echo path (Optional, under study)\n");
  1178. ctx = echo_can_init(TEST_EC_TAPS, 0);
  1179. fprintf(stderr, "Test 13 not yet implemented\n");
  1180. echo_can_free(ctx);
  1181. return 0;
  1182. }
  1183. /*- End of function --------------------------------------------------------*/
  1184. static int perform_test_14(void)
  1185. {
  1186. echo_can_state_t *ctx;
  1187. /* Test 14 - Performance with V-series low-speed data modems */
  1188. print_test_title("Performing test 14 - Performance with V-series low-speed data modems\n");
  1189. ctx = echo_can_init(TEST_EC_TAPS, 0);
  1190. fprintf(stderr, "Test 14 not yet implemented\n");
  1191. echo_can_free(ctx);
  1192. return 0;
  1193. }
  1194. /*- End of function --------------------------------------------------------*/
  1195. static int perform_test_15(void)
  1196. {
  1197. echo_can_state_t *ctx;
  1198. /* Test 15 - PCM offset test (Optional) */
  1199. print_test_title("Performing test 15 - PCM offset test (Optional)\n");
  1200. ctx = echo_can_init(TEST_EC_TAPS, 0);
  1201. fprintf(stderr, "Test 15 not yet implemented\n");
  1202. echo_can_free(ctx);
  1203. return 0;
  1204. }
  1205. /*- End of function --------------------------------------------------------*/
  1206. static int match_test_name(const char *name)
  1207. {
  1208. const struct
  1209. {
  1210. const char *name;
  1211. int (*func)(void);
  1212. } tests[] =
  1213. {
  1214. {"sanity", perform_test_sanity},
  1215. {"2a", perform_test_2a},
  1216. {"2b", perform_test_2b},
  1217. {"2ca", perform_test_2ca},
  1218. {"3a", perform_test_3a},
  1219. {"3ba", perform_test_3ba},
  1220. {"3bb", perform_test_3bb},
  1221. {"3c", perform_test_3c},
  1222. {"4", perform_test_4},
  1223. {"5", perform_test_5},
  1224. {"6", perform_test_6},
  1225. {"7", perform_test_7},
  1226. {"8", perform_test_8},
  1227. {"9", perform_test_9},
  1228. {"10a", perform_test_10a},
  1229. {"10b", perform_test_10b},
  1230. {"10c", perform_test_10c},
  1231. {"11", perform_test_11},
  1232. {"12", perform_test_12},
  1233. {"13", perform_test_13},
  1234. {"14", perform_test_14},
  1235. {"15", perform_test_15},
  1236. {NULL, NULL}
  1237. };
  1238. int i;
  1239. for (i = 0; tests[i].name; i++)
  1240. {
  1241. if (strcasecmp(name, tests[i].name) == 0)
  1242. {
  1243. test_name = name;
  1244. tests[i].func();
  1245. return 0;
  1246. }
  1247. }
  1248. printf("Unknown test name '%s' specified. The known test names are ", name);
  1249. for (i = 0; tests[i].name; i++)
  1250. {
  1251. printf("%s", tests[i].name);
  1252. if (tests[i + 1].name)
  1253. printf(", ");
  1254. }
  1255. printf("\n");
  1256. return -1;
  1257. }
  1258. /*- End of function --------------------------------------------------------*/
  1259. static void simulate_ec(char *argv[], int two_channel_file, int mode)
  1260. {
  1261. echo_can_state_t *ctx;
  1262. SNDFILE *txfile;
  1263. SNDFILE *rxfile;
  1264. SNDFILE *rxtxfile;
  1265. SNDFILE *ecfile;
  1266. int ntx;
  1267. int nrx;
  1268. int nec;
  1269. int16_t buf[2];
  1270. int16_t rin;
  1271. int16_t rout;
  1272. int16_t sin;
  1273. int16_t sout;
  1274. mode |= ECHO_CAN_USE_ADAPTION;
  1275. txfile = NULL;
  1276. rxfile = NULL;
  1277. rxtxfile = NULL;
  1278. ecfile = NULL;
  1279. if (two_channel_file)
  1280. {
  1281. txfile = sf_open_telephony_read(argv[0], 1);
  1282. rxfile = sf_open_telephony_read(argv[1], 1);
  1283. ecfile = sf_open_telephony_write(argv[2], 1);
  1284. }
  1285. else
  1286. {
  1287. rxtxfile = sf_open_telephony_read(argv[0], 2);
  1288. ecfile = sf_open_telephony_write(argv[1], 1);
  1289. }
  1290. ctx = echo_can_init(TEST_EC_TAPS, 0);
  1291. echo_can_adaption_mode(ctx, mode);
  1292. do
  1293. {
  1294. if (two_channel_file)
  1295. {
  1296. if ((ntx = sf_readf_short(rxtxfile, buf, 1)) < 0)
  1297. {
  1298. fprintf(stderr, " Error reading tx sound file\n");
  1299. exit(2);
  1300. }
  1301. rin = buf[0];
  1302. sin = buf[1];
  1303. nrx = ntx;
  1304. }
  1305. else
  1306. {
  1307. if ((ntx = sf_readf_short(txfile, &rin, 1)) < 0)
  1308. {
  1309. fprintf(stderr, " Error reading tx sound file\n");
  1310. exit(2);
  1311. }
  1312. if ((nrx = sf_readf_short(rxfile, &sin, 1)) < 0)
  1313. {
  1314. fprintf(stderr, " Error reading rx sound file\n");
  1315. exit(2);
  1316. }
  1317. }
  1318. rout = echo_can_hpf_tx(ctx, rin);
  1319. sout = echo_can_update(ctx, rout, sin);
  1320. if ((nec = sf_writef_short(ecfile, &sout, 1)) != 1)
  1321. {
  1322. fprintf(stderr, " Error writing ec sound file\n");
  1323. exit(2);
  1324. }
  1325. level_measurements_update(rin, sin, rout, sout, 0);
  1326. write_log_files(rin, sin);
  1327. #if defined(ENABLE_GUI)
  1328. if (use_gui)
  1329. echo_can_monitor_can_update(ctx->fir_taps16[0], TEST_EC_TAPS);
  1330. #endif
  1331. }
  1332. while (ntx && nrx);
  1333. dump_ec_state(ctx);
  1334. echo_can_free(ctx);
  1335. if (two_channel_file)
  1336. {
  1337. sf_close_telephony(rxtxfile);
  1338. }
  1339. else
  1340. {
  1341. sf_close_telephony(txfile);
  1342. sf_close_telephony(rxfile);
  1343. }
  1344. sf_close_telephony(ecfile);
  1345. }
  1346. /*- End of function --------------------------------------------------------*/
  1347. int main(int argc, char *argv[])
  1348. {
  1349. int i;
  1350. time_t now;
  1351. int simulate;
  1352. int opt;
  1353. int mode;
  1354. bool cng;
  1355. bool hpf;
  1356. bool two_channel_file;
  1357. /* Check which tests we should run */
  1358. if (argc < 2)
  1359. fprintf(stderr, "Usage: echo tests [-g] [-m <model number>] [-s] <list of test numbers>\n");
  1360. line_model_no = 0;
  1361. supp_line_model_no = 0;
  1362. cng = false;
  1363. hpf = false;
  1364. use_gui = false;
  1365. simulate = false;
  1366. munger = -1;
  1367. two_channel_file = false;
  1368. erl = -12.0f;
  1369. while ((opt = getopt(argc, argv, "2ace:ghm:M:su")) != -1)
  1370. {
  1371. switch (opt)
  1372. {
  1373. case '2':
  1374. two_channel_file = true;
  1375. break;
  1376. case 'a':
  1377. munger = G711_ALAW;
  1378. break;
  1379. case 'c':
  1380. cng = true;
  1381. break;
  1382. case 'e':
  1383. /* Allow for ERL being entered as x or -x */
  1384. erl = -fabs(atof(optarg));
  1385. break;
  1386. case 'g':
  1387. #if defined(ENABLE_GUI)
  1388. use_gui = true;
  1389. #else
  1390. fprintf(stderr, "Graphical monitoring not available\n");
  1391. exit(2);
  1392. #endif
  1393. break;
  1394. case 'h':
  1395. hpf = true;
  1396. break;
  1397. case 'm':
  1398. line_model_no = atoi(optarg);
  1399. break;
  1400. case 'M':
  1401. supp_line_model_no = atoi(optarg);
  1402. break;
  1403. case 's':
  1404. simulate = true;
  1405. break;
  1406. case 'u':
  1407. munger = G711_ULAW;
  1408. break;
  1409. default:
  1410. //usage();
  1411. exit(2);
  1412. break;
  1413. }
  1414. }
  1415. argc -= optind;
  1416. argv += optind;
  1417. #if defined(ENABLE_GUI)
  1418. if (use_gui)
  1419. start_echo_can_monitor(TEST_EC_TAPS);
  1420. #endif
  1421. if (simulate)
  1422. {
  1423. /* Process a pair of transmitted and received audio files, and produce
  1424. an echo cancelled audio file. */
  1425. if (argc < ((two_channel_file) ? 2 : 3))
  1426. {
  1427. printf("not enough arguments for a simulation\n");
  1428. exit(2);
  1429. }
  1430. mode = ECHO_CAN_USE_NLP;
  1431. mode |= ((cng) ? ECHO_CAN_USE_CNG : ECHO_CAN_USE_CLIP);
  1432. if (hpf)
  1433. {
  1434. mode |= ECHO_CAN_USE_TX_HPF;
  1435. mode |= ECHO_CAN_USE_RX_HPF;
  1436. }
  1437. simulate_ec(argv, two_channel_file, mode);
  1438. }
  1439. else
  1440. {
  1441. /* Run some G.168 tests */
  1442. #if defined(ENABLE_GUI)
  1443. if (use_gui)
  1444. echo_can_monitor_line_model_update(chan_model.impulse.coeffs, chan_model.impulse.taps);
  1445. #endif
  1446. signal_load(&local_css, "sound_c1_8k.wav");
  1447. signal_load(&far_css, "sound_c3_8k.wav");
  1448. if ((residue_handle = sf_open_telephony_write(RESIDUE_FILE_NAME, 1)) == NULL)
  1449. {
  1450. fprintf(stderr, " Failed to open '%s'\n", RESIDUE_FILE_NAME);
  1451. exit(2);
  1452. }
  1453. if (argc <= 0)
  1454. {
  1455. printf("No tests specified\n");
  1456. }
  1457. else
  1458. {
  1459. time(&now);
  1460. if ((result_handle = sf_open_telephony_write("echo_tests_result.wav", RESULT_CHANNELS)) == NULL)
  1461. {
  1462. fprintf(stderr, " Failed to open result file\n");
  1463. exit(2);
  1464. }
  1465. result_cur = 0;
  1466. level_measurements_create(0);
  1467. for (i = 0; i < argc; i++)
  1468. {
  1469. if (channel_model_create(&chan_model, line_model_no, erl, munger))
  1470. {
  1471. fprintf(stderr, " Failed to create line model\n");
  1472. exit(2);
  1473. }
  1474. match_test_name(argv[i]);
  1475. }
  1476. if (sf_close_telephony(result_handle))
  1477. {
  1478. fprintf(stderr, " Cannot close speech file '%s'\n", "result_sound.wav");
  1479. exit(2);
  1480. }
  1481. printf("Run time %lds\n", time(NULL) - now);
  1482. }
  1483. signal_free(&local_css);
  1484. signal_free(&far_css);
  1485. if (sf_close_telephony(residue_handle))
  1486. {
  1487. fprintf(stderr, " Cannot close speech file '%s'\n", RESIDUE_FILE_NAME);
  1488. exit(2);
  1489. }
  1490. }
  1491. #if defined(ENABLE_GUI)
  1492. if (use_gui)
  1493. echo_can_monitor_wait_to_end();
  1494. #endif
  1495. printf("Tests passed.\n");
  1496. return 0;
  1497. }
  1498. /*- End of function --------------------------------------------------------*/
  1499. /*- End of file ------------------------------------------------------------*/