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