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 * $Id: super_tone_tx_tests.c,v 1.22 2008/05/13 13:17:26 steveu Exp $
26 */
27
28 /*! \file */
29
30 /*! \page super_tone_tx_tests_page Supervisory tone generation tests
31 \section super_tone_tx_tests_page_sec_1 What does it do?
32 */
33
34 #if defined(HAVE_CONFIG_H)
35 #include "config.h"
36 #endif
37
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include <fcntl.h>
41 #include <string.h>
42 #include <strings.h>
43 #include <ctype.h>
44 #include <time.h>
45 #include <inttypes.h>
46 #include <sys/socket.h>
47 #include <audiofile.h>
48
49 #if defined(HAVE_LIBXML_XMLMEMORY_H)
50 #include <libxml/xmlmemory.h>
51 #endif
52 #if defined(HAVE_LIBXML_PARSER_H)
53 #include <libxml/parser.h>
54 #endif
55 #if defined(HAVE_LIBXML_XINCLUDE_H)
56 #include <libxml/xinclude.h>
57 #endif
58
59 #include "spandsp.h"
60
61 #define OUT_FILE_NAME "super_tone.wav"
62
63 AFfilehandle outhandle;
64 AFfilesetup filesetup;
65
66 super_tone_tx_step_t *tone_tree = NULL;
67
play_tones(super_tone_tx_state_t * tone,int max_samples)68 static void play_tones(super_tone_tx_state_t *tone, int max_samples)
69 {
70 int16_t amp[8000];
71 int len;
72 int outframes;
73 int i;
74 int total_length;
75
76 i = 500;
77 total_length = 0;
78 do
79 {
80 len = super_tone_tx(tone, amp, 160);
81 outframes = afWriteFrames(outhandle,
82 AF_DEFAULT_TRACK,
83 amp,
84 len);
85 if (outframes != len)
86 {
87 fprintf(stderr, " Error writing wave file\n");
88 exit(2);
89 }
90 total_length += len;
91 }
92 while (len > 0 && --i > 0);
93 printf("Tone length = %d samples (%dms)\n", total_length, total_length/8);
94 }
95 /*- End of function --------------------------------------------------------*/
96
97 #if defined(HAVE_LIBXML2)
parse_tone(super_tone_tx_step_t ** tree,xmlDocPtr doc,xmlNsPtr ns,xmlNodePtr cur)98 static int parse_tone(super_tone_tx_step_t **tree, xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur)
99 {
100 xmlChar *x;
101 float f1;
102 float f2;
103 float f_tol;
104 float l1;
105 float l2;
106 float length;
107 float length_tol;
108 int cycles;
109 super_tone_tx_step_t *treep;
110
111 cur = cur->xmlChildrenNode;
112 while (cur)
113 {
114 if (xmlStrcmp(cur->name, (const xmlChar *) "step") == 0)
115 {
116 printf("Step - ");
117 /* Set some defaults */
118 f1 = 0.0;
119 f2 = 0.0;
120 f_tol = 1.0;
121 l1 = -11.0;
122 l2 = -11.0;
123 length = 0.0;
124 length_tol = 10.0;
125 cycles = 1;
126 if ((x = xmlGetProp(cur, (const xmlChar *) "freq")))
127 {
128 sscanf((char *) x, "%f [%f%%]", &f1, &f_tol);
129 sscanf((char *) x, "%f+%f [%f%%]", &f1, &f2, &f_tol);
130 printf("Frequency=%.2f+%.2f [%.2f%%]", f1, f2, f_tol);
131 xmlFree(x);
132 }
133 if ((x = xmlGetProp(cur, (const xmlChar *) "level")))
134 {
135 if (sscanf((char *) x, "%f+%f", &l1, &l2) < 2)
136 l2 = l1;
137 printf("Level=%.2f+%.2f", l1, l2);
138 xmlFree(x);
139 }
140 if ((x = xmlGetProp(cur, (const xmlChar *) "length")))
141 {
142 sscanf((char *) x, "%f [%f%%]", &length, &length_tol);
143 printf("Length=%.2f [%.2f%%]", length, length_tol);
144 xmlFree(x);
145 }
146 if ((x = xmlGetProp(cur, (const xmlChar *) "recognition-length")))
147 {
148 printf("Recognition length='%s'", x);
149 xmlFree(x);
150 }
151 if ((x = xmlGetProp(cur, (const xmlChar *) "cycles")))
152 {
153 if (strcasecmp((char *) x, "endless") == 0)
154 cycles = 0;
155 else
156 cycles = atoi((char *) x);
157 printf("Cycles=%d ", cycles);
158 xmlFree(x);
159 }
160 if ((x = xmlGetProp(cur, (const xmlChar *) "recorded-announcement")))
161 {
162 printf("Recorded announcement='%s'", x);
163 xmlFree(x);
164 }
165 printf("\n");
166 treep = super_tone_tx_make_step(NULL,
167 f1,
168 l1,
169 f2,
170 l2,
171 length*1000.0 + 0.5,
172 cycles);
173 *tree = treep;
174 tree = &(treep->next);
175 parse_tone(&(treep->nest), doc, ns, cur);
176 }
177 /*endif*/
178 cur = cur->next;
179 }
180 /*endwhile*/
181 return 0;
182 }
183 /*- End of function --------------------------------------------------------*/
184
parse_tone_set(xmlDocPtr doc,xmlNsPtr ns,xmlNodePtr cur)185 static void parse_tone_set(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur)
186 {
187 super_tone_tx_state_t tone;
188
189 printf("Parsing tone set\n");
190 cur = cur->xmlChildrenNode;
191 while (cur)
192 {
193 if (strcmp((char *) cur->name + strlen((char *) cur->name) - 5, "-tone") == 0)
194 {
195 printf("Hit %s\n", cur->name);
196 tone_tree = NULL;
197 parse_tone(&tone_tree, doc, ns, cur);
198 super_tone_tx_init(&tone, tone_tree);
199 //printf("Len %p %p %d %d\n", (void *) tone.levels[0], (void *) tone_tree, tone_tree->length, tone_tree->tone);
200 play_tones(&tone, 99999999);
201 super_tone_tx_free(tone_tree);
202 }
203 /*endif*/
204 cur = cur->next;
205 }
206 /*endwhile*/
207 }
208 /*- End of function --------------------------------------------------------*/
209
get_tone_set(const char * tone_file,const char * set_id)210 static void get_tone_set(const char *tone_file, const char *set_id)
211 {
212 xmlDocPtr doc;
213 xmlNsPtr ns;
214 xmlNodePtr cur;
215 #if 0
216 xmlValidCtxt valid;
217 #endif
218 xmlChar *x;
219
220 ns = NULL;
221 xmlKeepBlanksDefault(0);
222 xmlCleanupParser();
223 doc = xmlParseFile(tone_file);
224 if (doc == NULL)
225 {
226 fprintf(stderr, "No document\n");
227 exit(2);
228 }
229 /*endif*/
230 xmlXIncludeProcess(doc);
231 #if 0
232 if (!xmlValidateDocument(&valid, doc))
233 {
234 fprintf(stderr, "Invalid document\n");
235 exit(2);
236 }
237 /*endif*/
238 #endif
239 /* Check the document is of the right kind */
240 if ((cur = xmlDocGetRootElement(doc)) == NULL)
241 {
242 fprintf(stderr, "Empty document\n");
243 xmlFreeDoc(doc);
244 exit(2);
245 }
246 /*endif*/
247 if (xmlStrcmp(cur->name, (const xmlChar *) "global-tones"))
248 {
249 fprintf(stderr, "Document of the wrong type, root node != global-tones");
250 xmlFreeDoc(doc);
251 exit(2);
252 }
253 /*endif*/
254 cur = cur->xmlChildrenNode;
255 while (cur && xmlIsBlankNode(cur))
256 cur = cur->next;
257 /*endwhile*/
258 if (cur == NULL)
259 exit(2);
260 /*endif*/
261 while (cur)
262 {
263 if (xmlStrcmp(cur->name, (const xmlChar *) "tone-set") == 0)
264 {
265 if ((x = xmlGetProp(cur, (const xmlChar *) "uncode")))
266 {
267 if (strcmp((char *) x, set_id) == 0)
268 parse_tone_set(doc, ns, cur);
269 /*endif*/
270 xmlFree(x);
271 }
272 /*endif*/
273 }
274 /*endif*/
275 cur = cur->next;
276 }
277 /*endwhile*/
278 xmlFreeDoc(doc);
279 }
280 /*- End of function --------------------------------------------------------*/
281 #endif
282
main(int argc,char * argv[])283 int main(int argc, char *argv[])
284 {
285 if ((filesetup = afNewFileSetup ()) == AF_NULL_FILESETUP)
286 {
287 fprintf(stderr, " Failed to create file setup\n");
288 exit(2);
289 }
290 afInitSampleFormat(filesetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16);
291 afInitRate(filesetup, AF_DEFAULT_TRACK, 8000.0);
292 afInitFileFormat(filesetup, AF_FILE_WAVE);
293 afInitChannels(filesetup, AF_DEFAULT_TRACK, 1);
294
295 if ((outhandle = afOpenFile(OUT_FILE_NAME, "w", filesetup)) == AF_NULL_FILEHANDLE)
296 {
297 fprintf(stderr, " Cannot open audio file '%s'\n", OUT_FILE_NAME);
298 exit(2);
299 }
300 #if defined(HAVE_LIBXML2)
301 get_tone_set("../spandsp/global-tones.xml", (argc > 1) ? argv[1] : "hk");
302 #endif
303 if (afCloseFile (outhandle) != 0)
304 {
305 fprintf(stderr, " Cannot close audio file '%s'\n", OUT_FILE_NAME);
306 exit(2);
307 }
308 afFreeFileSetup(filesetup);
309 printf("Done\n");
310 return 0;
311 }
312 /*- End of function --------------------------------------------------------*/
313 /*- End of file ------------------------------------------------------------*/
314