test_utils.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. /*
  2. * SpanDSP - a series of DSP components for telephony
  3. *
  4. * test_utils.c - Utility routines for module tests.
  5. *
  6. * Written by Steve Underwood <steveu@coppice.org>
  7. *
  8. * Copyright (C) 2006 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. #if defined(HAVE_CONFIG_H)
  27. #include "config.h"
  28. #endif
  29. #include <stdlib.h>
  30. #include <inttypes.h>
  31. #include <string.h>
  32. #include <stdio.h>
  33. #if defined(HAVE_TGMATH_H)
  34. #include <tgmath.h>
  35. #endif
  36. #if defined(HAVE_MATH_H)
  37. #include <math.h>
  38. #endif
  39. #if defined(HAVE_STDBOOL_H)
  40. #include <stdbool.h>
  41. #else
  42. #include "spandsp/stdbool.h"
  43. #endif
  44. #include "floating_fudge.h"
  45. #include <time.h>
  46. #include <fcntl.h>
  47. #include <sndfile.h>
  48. #define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
  49. #include "spandsp.h"
  50. #include "spandsp-sim.h"
  51. #define MAX_FFT_LEN 8192
  52. struct codec_munge_state_s
  53. {
  54. int munging_codec;
  55. g726_state_t g726_enc_state;
  56. g726_state_t g726_dec_state;
  57. int rbs_pattern;
  58. int sequence;
  59. };
  60. struct complexify_state_s
  61. {
  62. float history[128];
  63. int ptr;
  64. };
  65. static complex_t circle[MAX_FFT_LEN/2];
  66. static int circle_init = false;
  67. static complex_t icircle[MAX_FFT_LEN/2];
  68. static int icircle_init = false;
  69. #define SF_MAX_HANDLE 32
  70. static int sf_close_at_exit_registered = false;
  71. static SNDFILE *sf_close_at_exit_list[SF_MAX_HANDLE] =
  72. {
  73. NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  74. NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  75. NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  76. NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
  77. };
  78. SPAN_DECLARE(complexify_state_t *) complexify_init(void)
  79. {
  80. complexify_state_t *s;
  81. int i;
  82. if ((s = (complexify_state_t *) malloc(sizeof(*s))))
  83. {
  84. s->ptr = 0;
  85. for (i = 0; i < 128; i++)
  86. s->history[i] = 0.0f;
  87. }
  88. return s;
  89. }
  90. /*- End of function --------------------------------------------------------*/
  91. SPAN_DECLARE(int) complexify_free(complexify_state_t *s)
  92. {
  93. free(s);
  94. return 0;
  95. }
  96. /*- End of function --------------------------------------------------------*/
  97. SPAN_DECLARE(complexf_t) complexify(complexify_state_t *s, int16_t amp)
  98. {
  99. #define HILBERT_GAIN 1.569546344
  100. static const float hilbert_coeffs[] =
  101. {
  102. +0.0012698413f, +0.0013489483f,
  103. +0.0015105196f, +0.0017620440f,
  104. +0.0021112899f, +0.0025663788f,
  105. +0.0031358856f, +0.0038289705f,
  106. +0.0046555545f, +0.0056265487f,
  107. +0.0067541562f, +0.0080522707f,
  108. +0.0095370033f, +0.0112273888f,
  109. +0.0131463382f, +0.0153219442f,
  110. +0.0177892941f, +0.0205930381f,
  111. +0.0237910974f, +0.0274601544f,
  112. +0.0317040029f, +0.0366666667f,
  113. +0.0425537942f, +0.0496691462f,
  114. +0.0584802574f, +0.0697446887f,
  115. +0.0847739823f, +0.1060495199f,
  116. +0.1388940865f, +0.1971551103f,
  117. +0.3316207267f, +0.9994281838f
  118. };
  119. float famp;
  120. int i;
  121. int j;
  122. int k;
  123. complexf_t res;
  124. s->history[s->ptr] = amp;
  125. i = s->ptr - 63;
  126. if (i < 0)
  127. i += 128;
  128. res.re = s->history[i];
  129. famp = 0.0f;
  130. j = s->ptr - 126;
  131. if (j < 0)
  132. j += 128;
  133. for (i = 0, k = s->ptr; i < 32; i++)
  134. {
  135. famp += (s->history[k] - s->history[j])*hilbert_coeffs[i];
  136. j += 2;
  137. if (j >= 128)
  138. j -= 128;
  139. k -= 2;
  140. if (k < 0)
  141. k += 128;
  142. }
  143. res.im = famp/HILBERT_GAIN;
  144. if (++s->ptr >= 128)
  145. s->ptr = 0;
  146. return res;
  147. }
  148. /*- End of function --------------------------------------------------------*/
  149. static __inline__ complex_t expj(double theta)
  150. {
  151. return complex_set(cos(theta), sin(theta));
  152. }
  153. /*- End of function --------------------------------------------------------*/
  154. static void fftx(complex_t data[], complex_t temp[], int n)
  155. {
  156. int i;
  157. int h;
  158. int p;
  159. int t;
  160. int i2;
  161. complex_t wkt;
  162. if (n > 1)
  163. {
  164. h = n/2;
  165. for (i = 0; i < h; i++)
  166. {
  167. i2 = i*2;
  168. temp[i] = data[i2]; /* Even */
  169. temp[h + i] = data[i2 + 1]; /* Odd */
  170. }
  171. fftx(&temp[0], &data[0], h);
  172. fftx(&temp[h], &data[h], h);
  173. p = 0;
  174. t = MAX_FFT_LEN/n;
  175. for (i = 0; i < h; i++)
  176. {
  177. wkt = complex_mul(&circle[p], &temp[h + i]);
  178. data[i] = complex_add(&temp[i], &wkt);
  179. data[h + i] = complex_sub(&temp[i], &wkt);
  180. p += t;
  181. }
  182. }
  183. }
  184. /*- End of function --------------------------------------------------------*/
  185. static void ifftx(complex_t data[], complex_t temp[], int n)
  186. {
  187. int i;
  188. int h;
  189. int p;
  190. int t;
  191. int i2;
  192. complex_t wkt;
  193. if (n > 1)
  194. {
  195. h = n/2;
  196. for (i = 0; i < h; i++)
  197. {
  198. i2 = i*2;
  199. temp[i] = data[i2]; /* Even */
  200. temp[h + i] = data[i2 + 1]; /* Odd */
  201. }
  202. fftx(&temp[0], &data[0], h);
  203. fftx(&temp[h], &data[h], h);
  204. p = 0;
  205. t = MAX_FFT_LEN/n;
  206. for (i = 0; i < h; i++)
  207. {
  208. wkt = complex_mul(&icircle[p], &temp[h + i]);
  209. data[i] = complex_add(&temp[i], &wkt);
  210. data[h + i] = complex_sub(&temp[i], &wkt);
  211. p += t;
  212. }
  213. }
  214. }
  215. /*- End of function --------------------------------------------------------*/
  216. SPAN_DECLARE(void) fft(complex_t data[], int len)
  217. {
  218. int i;
  219. double x;
  220. complex_t temp[MAX_FFT_LEN];
  221. /* A very slow and clunky FFT, that's just fine for tests. */
  222. if (!circle_init)
  223. {
  224. for (i = 0; i < MAX_FFT_LEN/2; i++)
  225. {
  226. x = -(2.0*3.1415926535*i)/(double) MAX_FFT_LEN;
  227. circle[i] = expj(x);
  228. }
  229. circle_init = true;
  230. }
  231. fftx(data, temp, len);
  232. }
  233. /*- End of function --------------------------------------------------------*/
  234. SPAN_DECLARE(void) ifft(complex_t data[], int len)
  235. {
  236. int i;
  237. double x;
  238. complex_t temp[MAX_FFT_LEN];
  239. /* A very slow and clunky FFT, that's just fine for tests. */
  240. if (!icircle_init)
  241. {
  242. for (i = 0; i < MAX_FFT_LEN/2; i++)
  243. {
  244. x = (2.0*3.1415926535*i)/(double) MAX_FFT_LEN;
  245. icircle[i] = expj(x);
  246. }
  247. icircle_init = true;
  248. }
  249. ifftx(data, temp, len);
  250. }
  251. /*- End of function --------------------------------------------------------*/
  252. SPAN_DECLARE(codec_munge_state_t *) codec_munge_init(int codec, int info)
  253. {
  254. codec_munge_state_t *s;
  255. if ((s = (codec_munge_state_t *) malloc(sizeof(*s))))
  256. {
  257. switch (codec)
  258. {
  259. case MUNGE_CODEC_G726_40K:
  260. g726_init(&s->g726_enc_state, 40000, G726_ENCODING_LINEAR, G726_PACKING_NONE);
  261. g726_init(&s->g726_dec_state, 40000, G726_ENCODING_LINEAR, G726_PACKING_NONE);
  262. s->munging_codec = MUNGE_CODEC_G726_32K;
  263. break;
  264. case MUNGE_CODEC_G726_32K:
  265. g726_init(&s->g726_enc_state, 32000, G726_ENCODING_LINEAR, G726_PACKING_NONE);
  266. g726_init(&s->g726_dec_state, 32000, G726_ENCODING_LINEAR, G726_PACKING_NONE);
  267. s->munging_codec = MUNGE_CODEC_G726_32K;
  268. break;
  269. case MUNGE_CODEC_G726_24K:
  270. g726_init(&s->g726_enc_state, 24000, G726_ENCODING_LINEAR, G726_PACKING_NONE);
  271. g726_init(&s->g726_dec_state, 24000, G726_ENCODING_LINEAR, G726_PACKING_NONE);
  272. s->munging_codec = MUNGE_CODEC_G726_32K;
  273. break;
  274. case MUNGE_CODEC_G726_16K:
  275. g726_init(&s->g726_enc_state, 16000, G726_ENCODING_LINEAR, G726_PACKING_NONE);
  276. g726_init(&s->g726_dec_state, 16000, G726_ENCODING_LINEAR, G726_PACKING_NONE);
  277. s->munging_codec = MUNGE_CODEC_G726_32K;
  278. break;
  279. default:
  280. s->munging_codec = codec;
  281. break;
  282. }
  283. s->sequence = 0;
  284. s->rbs_pattern = info;
  285. }
  286. return s;
  287. }
  288. /*- End of function --------------------------------------------------------*/
  289. SPAN_DECLARE(int) codec_munge_free(codec_munge_state_t *s)
  290. {
  291. free(s);
  292. return 0;
  293. }
  294. /*- End of function --------------------------------------------------------*/
  295. SPAN_DECLARE(void) codec_munge(codec_munge_state_t *s, int16_t amp[], int len)
  296. {
  297. uint8_t law;
  298. uint8_t adpcmdata[160];
  299. int i;
  300. int adpcm;
  301. int x;
  302. switch (s->munging_codec)
  303. {
  304. case MUNGE_CODEC_NONE:
  305. /* Do nothing */
  306. break;
  307. case MUNGE_CODEC_ALAW:
  308. for (i = 0; i < len; i++)
  309. {
  310. law = linear_to_alaw(amp[i]);
  311. amp[i] = alaw_to_linear(law);
  312. }
  313. break;
  314. case MUNGE_CODEC_ULAW:
  315. for (i = 0; i < len; i++)
  316. {
  317. law = linear_to_ulaw(amp[i]);
  318. if (s->rbs_pattern & (1 << s->sequence))
  319. {
  320. /* Strip the bottom bit at the RBS rate */
  321. law &= 0xFE;
  322. }
  323. amp[i] = ulaw_to_linear(law);
  324. }
  325. break;
  326. case MUNGE_CODEC_G726_32K:
  327. /* This could actually be any of the G.726 rates */
  328. for (i = 0; i < len; i += x)
  329. {
  330. x = (len - i >= 160) ? 160 : (len - i);
  331. adpcm = g726_encode(&s->g726_enc_state, adpcmdata, amp + i, x);
  332. g726_decode(&s->g726_dec_state, amp + i, adpcmdata, adpcm);
  333. }
  334. break;
  335. }
  336. }
  337. /*- End of function --------------------------------------------------------*/
  338. static void sf_close_at_exit(void)
  339. {
  340. int i;
  341. for (i = 0; i < SF_MAX_HANDLE; i++)
  342. {
  343. if (sf_close_at_exit_list[i])
  344. {
  345. sf_close(sf_close_at_exit_list[i]);
  346. sf_close_at_exit_list[i] = NULL;
  347. }
  348. }
  349. }
  350. /*- End of function --------------------------------------------------------*/
  351. static int sf_record_handle(SNDFILE *handle)
  352. {
  353. int i;
  354. for (i = 0; i < SF_MAX_HANDLE; i++)
  355. {
  356. if (sf_close_at_exit_list[i] == NULL)
  357. break;
  358. }
  359. if (i >= SF_MAX_HANDLE)
  360. return -1;
  361. sf_close_at_exit_list[i] = handle;
  362. if (!sf_close_at_exit_registered)
  363. {
  364. atexit(sf_close_at_exit);
  365. sf_close_at_exit_registered = true;
  366. }
  367. return 0;
  368. }
  369. /*- End of function --------------------------------------------------------*/
  370. SPAN_DECLARE(SNDFILE *) sf_open_telephony_read(const char *name, int channels)
  371. {
  372. SNDFILE *handle;
  373. SF_INFO info;
  374. memset(&info, 0, sizeof(info));
  375. if ((handle = sf_open(name, SFM_READ, &info)) == NULL)
  376. {
  377. fprintf(stderr, " Cannot open audio file '%s' for reading\n", name);
  378. exit(2);
  379. }
  380. if (info.samplerate != SAMPLE_RATE)
  381. {
  382. printf(" Unexpected sample rate in audio file '%s'\n", name);
  383. exit(2);
  384. }
  385. if (info.channels != channels)
  386. {
  387. printf(" Unexpected number of channels in audio file '%s'\n", name);
  388. exit(2);
  389. }
  390. sf_record_handle(handle);
  391. return handle;
  392. }
  393. /*- End of function --------------------------------------------------------*/
  394. SPAN_DECLARE(SNDFILE *) sf_open_telephony_write(const char *name, int channels)
  395. {
  396. SNDFILE *handle;
  397. SF_INFO info;
  398. memset(&info, 0, sizeof(info));
  399. info.frames = 0;
  400. info.samplerate = SAMPLE_RATE;
  401. info.channels = channels;
  402. info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
  403. info.sections = 1;
  404. info.seekable = 1;
  405. if ((handle = sf_open(name, SFM_WRITE, &info)) == NULL)
  406. {
  407. fprintf(stderr, " Cannot open audio file '%s' for writing\n", name);
  408. exit(2);
  409. }
  410. sf_record_handle(handle);
  411. return handle;
  412. }
  413. /*- End of function --------------------------------------------------------*/
  414. SPAN_DECLARE(int) sf_close_telephony(SNDFILE *handle)
  415. {
  416. int res;
  417. int i;
  418. if ((res = sf_close(handle)) == 0)
  419. {
  420. for (i = 0; i < SF_MAX_HANDLE; i++)
  421. {
  422. if (sf_close_at_exit_list[i] == handle)
  423. {
  424. sf_close_at_exit_list[i] = NULL;
  425. break;
  426. }
  427. }
  428. }
  429. return res;
  430. }
  431. /*- End of function --------------------------------------------------------*/
  432. /*- End of file ------------------------------------------------------------*/