2
0

super_tone_tx_tests.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /*
  2. * SpanDSP - a series of DSP components for telephony
  3. *
  4. * super_tone_generate_tests.c
  5. *
  6. * Written by Steve Underwood <steveu@coppice.org>
  7. *
  8. * Copyright (C) 2003 Steve Underwood
  9. *
  10. * All rights reserved.
  11. *
  12. * This program is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License version 2, as
  14. * published by the Free Software Foundation.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24. */
  25. /*! \file */
  26. /*! \page super_tone_tx_tests_page Supervisory tone generation tests
  27. \section super_tone_tx_tests_page_sec_1 What does it do?
  28. */
  29. #if defined(HAVE_CONFIG_H)
  30. #include "config.h"
  31. #endif
  32. #include <inttypes.h>
  33. #include <stdlib.h>
  34. #include <stdio.h>
  35. #include <fcntl.h>
  36. #include <string.h>
  37. #include <strings.h>
  38. #include <ctype.h>
  39. #include <time.h>
  40. #include <inttypes.h>
  41. #include <sndfile.h>
  42. #if defined(HAVE_LIBXML_XMLMEMORY_H)
  43. #include <libxml/xmlmemory.h>
  44. #endif
  45. #if defined(HAVE_LIBXML_PARSER_H)
  46. #include <libxml/parser.h>
  47. #endif
  48. #if defined(HAVE_LIBXML_XINCLUDE_H)
  49. #include <libxml/xinclude.h>
  50. #endif
  51. #include "spandsp.h"
  52. #include "spandsp-sim.h"
  53. #define OUT_FILE_NAME "super_tone.wav"
  54. SNDFILE *outhandle;
  55. super_tone_tx_step_t *tone_tree = NULL;
  56. #if defined(HAVE_LIBXML2)
  57. static void play_tones(super_tone_tx_state_t *tone, int max_samples)
  58. {
  59. int16_t amp[8000];
  60. int len;
  61. int outframes;
  62. int i;
  63. int total_length;
  64. i = 500;
  65. total_length = 0;
  66. do
  67. {
  68. len = super_tone_tx(tone, amp, 160);
  69. outframes = sf_writef_short(outhandle, amp, len);
  70. if (outframes != len)
  71. {
  72. fprintf(stderr, " Error writing audio file\n");
  73. exit(2);
  74. }
  75. total_length += len;
  76. }
  77. while (len > 0 && --i > 0);
  78. printf("Tone length = %d samples (%dms)\n", total_length, total_length/8);
  79. }
  80. /*- End of function --------------------------------------------------------*/
  81. static int parse_tone(super_tone_tx_step_t **tree, xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur)
  82. {
  83. xmlChar *x;
  84. float f1;
  85. float f2;
  86. float f_tol;
  87. float l1;
  88. float l2;
  89. float length;
  90. float length_tol;
  91. int cycles;
  92. super_tone_tx_step_t *treep;
  93. cur = cur->xmlChildrenNode;
  94. while (cur)
  95. {
  96. if (xmlStrcmp(cur->name, (const xmlChar *) "step") == 0)
  97. {
  98. printf("Step - ");
  99. /* Set some defaults */
  100. f1 = 0.0;
  101. f2 = 0.0;
  102. f_tol = 1.0;
  103. l1 = -11.0;
  104. l2 = -11.0;
  105. length = 0.0;
  106. length_tol = 10.0;
  107. cycles = 1;
  108. if ((x = xmlGetProp(cur, (const xmlChar *) "freq")))
  109. {
  110. sscanf((char *) x, "%f [%f%%]", &f1, &f_tol);
  111. sscanf((char *) x, "%f+%f [%f%%]", &f1, &f2, &f_tol);
  112. printf("Frequency=%.2f+%.2f [%.2f%%]", f1, f2, f_tol);
  113. xmlFree(x);
  114. }
  115. if ((x = xmlGetProp(cur, (const xmlChar *) "level")))
  116. {
  117. if (sscanf((char *) x, "%f+%f", &l1, &l2) < 2)
  118. l2 = l1;
  119. printf("Level=%.2f+%.2f", l1, l2);
  120. xmlFree(x);
  121. }
  122. if ((x = xmlGetProp(cur, (const xmlChar *) "length")))
  123. {
  124. sscanf((char *) x, "%f [%f%%]", &length, &length_tol);
  125. printf("Length=%.2f [%.2f%%]", length, length_tol);
  126. xmlFree(x);
  127. }
  128. if ((x = xmlGetProp(cur, (const xmlChar *) "recognition-length")))
  129. {
  130. printf("Recognition length='%s'", x);
  131. xmlFree(x);
  132. }
  133. if ((x = xmlGetProp(cur, (const xmlChar *) "cycles")))
  134. {
  135. if (strcasecmp((char *) x, "endless") == 0)
  136. cycles = 0;
  137. else
  138. cycles = atoi((char *) x);
  139. printf("Cycles=%d ", cycles);
  140. xmlFree(x);
  141. }
  142. if ((x = xmlGetProp(cur, (const xmlChar *) "recorded-announcement")))
  143. {
  144. printf("Recorded announcement='%s'", x);
  145. xmlFree(x);
  146. }
  147. printf("\n");
  148. treep = super_tone_tx_make_step(NULL,
  149. f1,
  150. l1,
  151. f2,
  152. l2,
  153. length*1000.0 + 0.5,
  154. cycles);
  155. *tree = treep;
  156. tree = &treep->next;
  157. parse_tone(&treep->nest, doc, ns, cur);
  158. }
  159. /*endif*/
  160. cur = cur->next;
  161. }
  162. /*endwhile*/
  163. return 0;
  164. }
  165. /*- End of function --------------------------------------------------------*/
  166. static void parse_tone_set(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur)
  167. {
  168. super_tone_tx_state_t tone;
  169. printf("Parsing tone set\n");
  170. cur = cur->xmlChildrenNode;
  171. while (cur)
  172. {
  173. if (strcmp((char *) cur->name + strlen((char *) cur->name) - 5, "-tone") == 0)
  174. {
  175. printf("Hit %s\n", cur->name);
  176. tone_tree = NULL;
  177. parse_tone(&tone_tree, doc, ns, cur);
  178. super_tone_tx_init(&tone, tone_tree);
  179. //printf("Len %p %p %d %d\n", (void *) tone.levels[0], (void *) tone_tree, tone_tree->length, tone_tree->tone);
  180. play_tones(&tone, 99999999);
  181. super_tone_tx_free_tone(tone_tree);
  182. }
  183. /*endif*/
  184. cur = cur->next;
  185. }
  186. /*endwhile*/
  187. }
  188. /*- End of function --------------------------------------------------------*/
  189. static void get_tone_set(const char *tone_file, const char *set_id)
  190. {
  191. xmlParserCtxtPtr ctxt;
  192. xmlDocPtr doc;
  193. xmlNsPtr ns;
  194. xmlNodePtr cur;
  195. xmlChar *x;
  196. ns = NULL;
  197. xmlKeepBlanksDefault(0);
  198. xmlCleanupParser();
  199. if ((ctxt = xmlNewParserCtxt()) == NULL)
  200. {
  201. fprintf(stderr, "Failed to allocate parser context\n");
  202. printf("Test failed\n");
  203. exit(2);
  204. }
  205. /* parse the file, activating the DTD validation option */
  206. if ((doc = xmlCtxtReadFile(ctxt, tone_file, NULL, XML_PARSE_XINCLUDE | XML_PARSE_DTDVALID)) == NULL)
  207. {
  208. fprintf(stderr, "Failed to read the XML document\n");
  209. printf("Test failed\n");
  210. exit(2);
  211. }
  212. if (ctxt->valid == 0)
  213. {
  214. fprintf(stderr, "Failed to validate the XML document\n");
  215. xmlFreeDoc(doc);
  216. xmlFreeParserCtxt(ctxt);
  217. printf("Test failed\n");
  218. exit(2);
  219. }
  220. xmlFreeParserCtxt(ctxt);
  221. /* Check the document is of the right kind */
  222. if ((cur = xmlDocGetRootElement(doc)) == NULL)
  223. {
  224. fprintf(stderr, "Empty document\n");
  225. xmlFreeDoc(doc);
  226. exit(2);
  227. }
  228. /*endif*/
  229. if (xmlStrcmp(cur->name, (const xmlChar *) "global-tones"))
  230. {
  231. fprintf(stderr, "Document of the wrong type, root node != global-tones");
  232. xmlFreeDoc(doc);
  233. exit(2);
  234. }
  235. /*endif*/
  236. cur = cur->xmlChildrenNode;
  237. while (cur && xmlIsBlankNode(cur))
  238. cur = cur->next;
  239. /*endwhile*/
  240. if (cur == NULL)
  241. exit(2);
  242. /*endif*/
  243. while (cur)
  244. {
  245. if (xmlStrcmp(cur->name, (const xmlChar *) "tone-set") == 0)
  246. {
  247. if ((x = xmlGetProp(cur, (const xmlChar *) "uncode")))
  248. {
  249. if (strcmp((char *) x, set_id) == 0)
  250. parse_tone_set(doc, ns, cur);
  251. /*endif*/
  252. xmlFree(x);
  253. }
  254. /*endif*/
  255. }
  256. /*endif*/
  257. cur = cur->next;
  258. }
  259. /*endwhile*/
  260. xmlFreeDoc(doc);
  261. }
  262. /*- End of function --------------------------------------------------------*/
  263. #endif
  264. int main(int argc, char *argv[])
  265. {
  266. if ((outhandle = sf_open_telephony_write(OUT_FILE_NAME, 1)) == NULL)
  267. {
  268. fprintf(stderr, " Cannot open audio file '%s'\n", OUT_FILE_NAME);
  269. exit(2);
  270. }
  271. #if defined(HAVE_LIBXML2)
  272. get_tone_set("../spandsp/global-tones.xml", (argc > 1) ? argv[1] : "hk");
  273. #endif
  274. if (sf_close_telephony(outhandle))
  275. {
  276. fprintf(stderr, " Cannot close audio file '%s'\n", OUT_FILE_NAME);
  277. exit(2);
  278. }
  279. printf("Done\n");
  280. return 0;
  281. }
  282. /*- End of function --------------------------------------------------------*/
  283. /*- End of file ------------------------------------------------------------*/