/[zanavi_public1]/navit/navit/speech/cmdline/speech_cmdline.c
ZANavi

Contents of /navit/navit/speech/cmdline/speech_cmdline.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (show annotations) (download)
Fri Oct 28 21:19:04 2011 UTC (12 years, 5 months ago) by zoff99
File MIME type: text/plain
File size: 5174 byte(s)
import files
1 /**
2 * Navit, a modular navigation system.
3 * Copyright (C) 2005-2008 Navit Team
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 #include <stdlib.h>
21 #include <string.h>
22 #include <glib.h>
23 #include "config.h"
24 #include "debug.h"
25 #include "item.h"
26 #include "plugin.h"
27 #include "file.h"
28 #include "speech.h"
29 #include "util.h"
30 #ifdef HAVE_API_WIN32_BASE
31 #include <windows.h>
32 #endif
33 #ifdef USE_EXEC
34 #include <sys/types.h>
35 #include <unistd.h>
36 #include <string.h>
37 #endif
38
39
40 static GList *
41 speech_cmdline_search(GList *l, int suffix_len, const char *s)
42 {
43 GList *li=l,*ret=NULL,*tmp;
44 int len=0;
45 while (li) {
46 char *snd=li->data;
47 int snd_len;
48 snd_len=strlen(snd)-suffix_len;
49 if (!strncasecmp(s, snd, snd_len)) {
50 const char *ss=s+snd_len;
51 while (*ss == ' ' || *ss == ',')
52 ss++;
53 dbg(1,"found %s remaining %s\n",snd,ss);
54 if (*ss)
55 tmp=speech_cmdline_search(l, suffix_len, ss);
56 else
57 tmp=NULL;
58 if (!ret || g_list_length(tmp) < len) {
59 len=g_list_length(tmp);
60 g_list_free(ret);
61 ret=tmp;
62 if (!*ss || tmp)
63 ret=g_list_prepend(ret, snd);
64 } else
65 g_list_free(tmp);
66 }
67 li=g_list_next(li);
68 }
69 return ret;
70 }
71 #if 0
72
73 r=search(l, strlen(path)+1, suffix_len, argv[1]);
74 while (r) {
75 printf("%s/%s\n",path,r->data);
76 r=g_list_next(r);
77 }
78 return 0;
79 #endif
80
81 struct speech_priv {
82 char *cmdline;
83 char *sample_dir;
84 char *sample_suffix;
85 GList *samples;
86 struct spawn_process_info *spi;
87 };
88
89 static int
90 speechd_say(struct speech_priv *this, const char *text)
91 {
92 char **cmdv=g_strsplit(this->cmdline," ", -1);
93 int variable_arg_no=-1;
94 GList *argl=NULL;
95 guint listlen;
96 int samplesmode=0;
97 int i;
98
99 for(i=0;cmdv[i];i++)
100 if(strchr(cmdv[i],'%')) {
101 variable_arg_no=i;
102 break;
103 }
104
105 if (this->sample_dir && this->sample_suffix) {
106 argl=speech_cmdline_search(this->samples, strlen(this->sample_suffix), text);
107 samplesmode=1;
108 listlen=g_list_length(argl);
109 } else {
110 listlen=1;
111 }
112 dbg(0,"text '%s'\n",text);
113 if(listlen>0) {
114 int argc;
115 char**argv;
116 int j;
117 int cmdvlen=g_strv_length(cmdv);
118 argc=cmdvlen + listlen - (variable_arg_no>0?1:0);
119 argv=g_new(char *,argc+1);
120 if(variable_arg_no==-1) {
121 argv[cmdvlen]=g_strdup("%s");
122 variable_arg_no=cmdvlen;
123 }
124
125 for(i=0,j=0;j<argc;) {
126 if( i==variable_arg_no ) {
127 if (samplesmode) {
128 GList *l=argl;
129 while(l) {
130 char *new_arg;
131 new_arg=g_strdup_printf("%s/%s",this->sample_dir,(char *)l->data);
132 dbg(0,"new_arg %s\n",new_arg);
133 argv[j++]=g_strdup_printf(cmdv[i],new_arg);
134 g_free(new_arg);
135 l=g_list_next(l);
136 }
137 } else {
138 argv[j++]=g_strdup_printf(cmdv[i],text);
139 }
140 i++;
141 } else {
142 argv[j++]=g_strdup(cmdv[i++]);
143 }
144 }
145 argv[j]=NULL;
146 if (argl)
147 // No need to free data elements here as they are
148 // still referenced from this->samples
149 g_list_free(argl);
150
151 if(this->spi) {
152 spawn_process_check_status(this->spi,1); // Block until previous spawned speech process is terminated.
153 spawn_process_info_free(this->spi);
154 }
155 this->spi=spawn_process(argv);
156 g_strfreev(argv);
157 }
158 g_strfreev(cmdv);
159 return 0;
160 }
161
162
163 static void
164 speechd_destroy(struct speech_priv *this) {
165 GList *l=this->samples;
166 g_free(this->cmdline);
167 g_free(this->sample_dir);
168 g_free(this->sample_suffix);
169 while(l) {
170 g_free(l->data);
171 }
172 g_list_free(this->samples);
173 if(this->spi)
174 spawn_process_info_free(this->spi);
175 g_free(this);
176 }
177
178 static struct speech_methods speechd_meth = {
179 speechd_destroy,
180 speechd_say,
181 };
182
183 static struct speech_priv *
184 speechd_new(struct speech_methods *meth, struct attr **attrs, struct attr *parent) {
185 struct speech_priv *this;
186 struct attr *attr;
187 attr=attr_search(attrs, NULL, attr_data);
188 if (! attr)
189 return NULL;
190 this=g_new0(struct speech_priv,1);
191 this->cmdline=g_strdup(attr->u.str);
192 if ((attr=attr_search(attrs, NULL, attr_sample_dir)))
193 this->sample_dir=g_strdup(attr->u.str);
194 if ((attr=attr_search(attrs, NULL, attr_sample_suffix)))
195 this->sample_suffix=g_strdup(attr->u.str);
196 if (this->sample_dir && this->sample_suffix) {
197 void *handle=file_opendir(this->sample_dir);
198 char *name;
199 int suffix_len=strlen(this->sample_suffix);
200 while((name=file_readdir(handle))) {
201 int len=strlen(name);
202 if (len > suffix_len) {
203 if (!strcmp(name+len-suffix_len, this->sample_suffix)) {
204 dbg(0,"found %s\n",name);
205 this->samples=g_list_prepend(this->samples, g_strdup(name));
206 }
207 }
208 }
209 file_closedir(handle);
210 }
211 *meth=speechd_meth;
212 return this;
213 }
214
215
216 void
217 plugin_init(void)
218 {
219 plugin_register_speech_type("cmdline", speechd_new);
220 }

   
Visit the ZANavi Wiki