PageRenderTime 70ms CodeModel.GetById 7ms app.highlight 59ms RepoModel.GetById 1ms app.codeStats 0ms

/native/external/espeak/src/espeak_command.cpp

http://eyes-free.googlecode.com/
C++ | 703 lines | 540 code | 119 blank | 44 comment | 60 complexity | c7670c59eb5ead7f5b0362f5d0b36f60 MD5 | raw file
  1/***************************************************************************
  2 *   Copyright (C) 2007, Gilles Casse <gcasse@oralux.org>                  *
  3 *                                                                         *
  4 *   This program is free software; you can redistribute it and/or modify  *
  5 *   it under the terms of the GNU General Public License as published by  *
  6 *   the Free Software Foundation; either version 3 of the License, or     *
  7 *   (at your option) any later version.                                   *
  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.,                                       *
 17 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 18 ***************************************************************************/
 19#include "speech.h"
 20
 21#ifdef USE_ASYNC
 22// This source file is only used for asynchronious modes
 23
 24#include "espeak_command.h"
 25#include <stdlib.h>
 26#include <string.h>
 27#include <assert.h>
 28////#include <wchar.h>
 29
 30#include "debug.h"
 31
 32
 33static unsigned int my_current_text_id=0;
 34
 35
 36//<create_espeak_text
 37t_espeak_command* create_espeak_text(const void *text, size_t size, unsigned int position, espeak_POSITION_TYPE position_type, unsigned int end_position, unsigned int flags, void* user_data)
 38{
 39  ENTER("create_espeak_text");
 40  int a_error=1;
 41  void* a_text = NULL;
 42  t_espeak_text* data = NULL;
 43  t_espeak_command* a_command = (t_espeak_command*)malloc(sizeof(t_espeak_command));
 44
 45  if (!text || !size || !a_command)
 46    {
 47      goto text_error;
 48    }
 49 
 50  a_text = malloc( size );
 51  if (!a_text)
 52    {
 53      goto text_error;
 54    }
 55  memcpy(a_text, text, size);
 56  
 57  a_command->type = ET_TEXT;
 58  a_command->state = CS_UNDEFINED;
 59  data = &(a_command->u.my_text);
 60  data->unique_identifier = ++my_current_text_id;
 61  data->text = a_text;
 62  data->size = size;
 63  data->position = position;
 64  data->position_type = position_type;
 65  data->end_position = end_position;
 66  data->flags = flags;
 67  data->user_data = user_data;
 68  a_error=0;
 69
 70  SHOW("ET_TEXT malloc text=%x, command=%x (uid=%d)\n", a_text, a_command, data->unique_identifier);
 71
 72 text_error:
 73  if (a_error)
 74    {
 75      if (a_text)
 76	{
 77	  free (a_text);
 78	}
 79      if (a_command)
 80	{
 81	  free (a_command);
 82	}
 83      a_command = NULL;
 84    }
 85
 86  SHOW("command=0x%x\n", a_command);
 87
 88  return a_command;
 89}
 90
 91//>
 92
 93
 94t_espeak_command* create_espeak_terminated_msg(unsigned int unique_identifier, void* user_data)
 95{
 96  ENTER("create_espeak_terminated_msg");
 97  int a_error=1;
 98  t_espeak_terminated_msg* data = NULL;
 99  t_espeak_command* a_command = (t_espeak_command*)malloc(sizeof(t_espeak_command));
100
101  if (!a_command)
102    {
103      goto msg_error;
104    }
105   
106  a_command->type = ET_TERMINATED_MSG;
107  a_command->state = CS_UNDEFINED;
108  data = &(a_command->u.my_terminated_msg);
109  data->unique_identifier = unique_identifier;
110  data->user_data = user_data;
111  a_error=0;
112
113  SHOW("ET_TERMINATED_MSG command=%x (uid=%d, user_data=0x%x)\n", a_command, unique_identifier, (int)user_data);
114
115 msg_error:
116  if (a_error)
117    {
118      if (a_command)
119	{
120	  free (a_command);
121	}
122      a_command = NULL;
123    }
124
125  SHOW("command=0x%x\n", a_command);
126
127  return a_command;
128
129}
130
131
132
133
134//<create_espeak_mark
135t_espeak_command* create_espeak_mark(const void *text, size_t size, const char *index_mark, unsigned int end_position, unsigned int flags, void* user_data)
136{
137  ENTER("create_espeak_mark");
138  int a_error=1;
139  void* a_text = NULL;
140  char *a_index_mark = NULL;
141  t_espeak_mark* data = NULL;
142  t_espeak_command* a_command = (t_espeak_command*)malloc(sizeof(t_espeak_command));
143
144  if (!text || !size || !index_mark || !a_command)
145    {
146      goto mark_error;
147    }
148
149  a_text = malloc( size );
150  if (!a_text)
151    {
152      goto mark_error;
153    }
154  memcpy(a_text, text, size);
155
156  a_index_mark = strdup( index_mark);
157
158  a_command->type = ET_MARK;
159  a_command->state = CS_UNDEFINED;
160  data = &(a_command->u.my_mark);
161  data->unique_identifier = ++my_current_text_id;
162  data->text = a_text;
163  data->size = size;
164  data->index_mark = a_index_mark;
165  data->end_position = end_position;
166  data->flags = flags;
167  data->user_data = user_data;
168  a_error=0;
169
170 mark_error:
171  if (a_error)
172    {
173      if (a_text)
174	{
175	  free (a_text);
176	}
177      if (a_command)
178	{
179	  free (a_command);
180	}
181      a_command = NULL;
182      if (a_index_mark)
183	{
184	  free (a_index_mark);
185	}
186    }
187
188  SHOW("ET_MARK malloc text=%x, command=%x (uid=%d)\n", a_text, a_command, data->unique_identifier);
189
190  return a_command;
191}
192//>
193//< create_espeak_key, create_espeak_char
194
195t_espeak_command* create_espeak_key(const char *key_name)
196{
197  ENTER("create_espeak_key");
198  int a_error=1;
199  t_espeak_command* a_command = (t_espeak_command*)malloc(sizeof(t_espeak_command));
200
201  if (!key_name || !a_command)
202    {
203      goto key_error;
204    }
205
206  a_command->type = ET_KEY;
207  a_command->state = CS_UNDEFINED;
208  a_command->u.my_key = strdup( key_name);
209  a_error=0;
210
211 key_error:
212  if (a_error)
213    {
214      if (a_command)
215	{
216	  free (a_command);
217	}
218      a_command = NULL;
219    }
220
221  SHOW("command=0x%x\n", a_command);
222
223  return a_command;
224}
225
226t_espeak_command* create_espeak_char(wchar_t character)
227{
228  ENTER("create_espeak_char");
229  int a_error=1;
230  t_espeak_command* a_command = (t_espeak_command*)malloc(sizeof(t_espeak_command));
231  if (!a_command)
232    {
233      goto char_error;
234    }
235 
236  a_command->type = ET_CHAR;
237  a_command->state = CS_UNDEFINED;
238  a_command->u.my_char = character;
239  a_error=0;
240
241 char_error:
242  if (a_error)
243    {
244      if (a_command)
245	{
246	  free (a_command);
247	}
248      a_command = NULL;
249    }
250
251  SHOW("command=0x%x\n", a_command);
252
253  return a_command;
254}
255
256//>
257//< create_espeak_parameter
258
259t_espeak_command* create_espeak_parameter(espeak_PARAMETER parameter, int value, int relative)
260{
261  ENTER("create_espeak_parameter");
262  int a_error=1;
263  t_espeak_parameter* data = NULL;
264  t_espeak_command* a_command = (t_espeak_command*)malloc(sizeof(t_espeak_command));
265  if (!a_command)
266    {
267      goto param_error;
268    }
269 
270  a_command->type = ET_PARAMETER;
271  a_command->state = CS_UNDEFINED;
272  data = &(a_command->u.my_param);
273  data->parameter = parameter; 
274  data->value = value;
275  data->relative = relative;
276  a_error=0;
277
278 param_error:
279  if (a_error)
280    {
281      if (a_command)
282	{
283	  free (a_command);
284	}
285      a_command = NULL;
286    }
287
288  SHOW("command=0x%x\n", a_command);
289
290  return a_command;
291}
292
293//>
294//< create_espeak_punctuation_list
295
296t_espeak_command* create_espeak_punctuation_list(const wchar_t *punctlist)
297{
298  ENTER("create_espeak_punctuation_list");
299  int a_error=1;
300  //  wchar_t *a_list = NULL;
301  t_espeak_command* a_command = (t_espeak_command*)malloc(sizeof(t_espeak_command));
302
303  if (!punctlist || !a_command)
304    {
305      goto list_error;
306    }
307 
308  a_command->type = ET_PUNCTUATION_LIST;
309  a_command->state = CS_UNDEFINED;
310
311  {
312    size_t len = (wcslen(punctlist) + 1)*sizeof(wchar_t);
313    wchar_t* a_list = (wchar_t*)malloc(len);
314    memcpy(a_list, punctlist, len);
315    a_command->u.my_punctuation_list = a_list;
316  }
317
318  a_error=0;
319
320 list_error:
321  if (a_error)
322    {
323      if (a_command)
324	{
325	  free (a_command);
326	}
327      a_command = NULL;
328    }
329
330  SHOW("command=0x%x\n", a_command);
331
332  return a_command;
333}
334
335//>
336//< create_espeak_voice_name, create_espeak_voice_spec
337
338t_espeak_command* create_espeak_voice_name(const char *name)
339{
340  ENTER("create_espeak_voice_name");
341
342  int a_error=1;
343  t_espeak_command* a_command = (t_espeak_command*)malloc(sizeof(t_espeak_command));
344
345  if (!name || !a_command)
346    {
347      goto name_error;
348    }
349 
350  a_command->type = ET_VOICE_NAME;
351  a_command->state = CS_UNDEFINED;
352  a_command->u.my_voice_name = strdup( name);
353  a_error=0;
354
355 name_error:
356  if (a_error)
357    {
358      if (a_command)
359	{
360	  free (a_command);
361	}
362      a_command = NULL;
363    }
364
365  SHOW("command=0x%x\n", a_command);
366
367  return a_command;
368}
369
370t_espeak_command* create_espeak_voice_spec(espeak_VOICE *voice)
371{
372  ENTER("create_espeak_voice_spec");
373  int a_error=1;
374  t_espeak_command* a_command = (t_espeak_command*)malloc(sizeof(t_espeak_command));
375
376  if (!voice || !a_command)
377    {
378      goto spec_error;
379    }
380 
381  a_command->type = ET_VOICE_SPEC;
382  a_command->state = CS_UNDEFINED;
383  {
384    espeak_VOICE* data = &(a_command->u.my_voice_spec);
385    memcpy(data, voice, sizeof(espeak_VOICE));
386
387    if (voice->name)
388      {
389	data->name = strdup(voice->name);
390      }
391
392    if (voice->languages)
393      {
394	data->languages = strdup(voice->languages);
395      }
396
397    if (voice->identifier)
398      {
399	data->identifier = strdup(voice->identifier);
400      }
401
402    a_error=0;
403  }
404
405 spec_error:
406  if (a_error)
407    {
408      if (a_command)
409	{
410	  free (a_command);
411	}
412      a_command = NULL;
413    }
414
415  SHOW("command=0x%x\n", a_command);
416
417  return a_command;
418}
419
420//>
421//< delete_espeak_command
422int delete_espeak_command( t_espeak_command* the_command)
423{
424  ENTER("delete_espeak_command");
425  int a_status = 0;
426  if (the_command)
427    {
428      switch(the_command->type)
429	{
430	case ET_TEXT:
431	  if (the_command->u.my_text.text)
432	    {
433	      SHOW("delete_espeak_command > ET_TEXT free text=%x, command=%x, uid=%d\n", the_command->u.my_text.text, the_command, the_command->u.my_text.unique_identifier);
434	      free(the_command->u.my_text.text);
435	    }
436	  break;
437
438	case ET_MARK:
439	  if (the_command->u.my_mark.text)
440	    {
441	      free(the_command->u.my_mark.text);
442	    }
443	  if (the_command->u.my_mark.index_mark)
444	    {
445	      free((void*)(the_command->u.my_mark.index_mark));
446	    }
447	  break;
448
449	case ET_TERMINATED_MSG:
450	  { 
451	    // if the terminated msg is pending,
452	    // it must be processed here for informing the calling program 
453	    // that its message is finished.
454	    // This can be important for cleaning the related user data.	    
455	    t_espeak_terminated_msg* data = &(the_command->u.my_terminated_msg);
456	    if (the_command->state == CS_PENDING)
457	      {
458		the_command->state = CS_PROCESSED;
459		SHOW("delete_espeak_command > ET_TERMINATED_MSG callback (command=0x%x, uid=%d) \n", the_command, data->unique_identifier);
460		sync_espeak_terminated_msg( data->unique_identifier, data->user_data);
461	      }
462	  }
463	  break;
464
465	case ET_KEY:
466	  if (the_command->u.my_key)
467	    {
468	      free((void*)(the_command->u.my_key));
469	    }
470	  break;
471
472	case ET_CHAR:
473	case ET_PARAMETER:
474	  // No allocation
475	  break;
476
477	case ET_PUNCTUATION_LIST:
478	  if (the_command->u.my_punctuation_list)
479	    {
480	      free((void*)(the_command->u.my_punctuation_list));
481	    }
482	  break;
483
484	case ET_VOICE_NAME:
485	  if (the_command->u.my_voice_name)
486	  {
487	    free((void*)(the_command->u.my_voice_name));
488	  }
489	  break;
490	  
491	case ET_VOICE_SPEC:
492	  {
493		espeak_VOICE* data = &(the_command->u.my_voice_spec);
494
495		if (data->name)
496		{
497			free((void *)data->name);
498		}
499
500		if (data->languages)
501		{
502			free((void *)data->languages);
503		}
504
505		if (data->identifier)
506		{
507			free((void *)data->identifier);
508		}
509	  }
510	  break;
511
512	default:
513	  assert(0);
514	}
515      SHOW("delete_espeak_command > free command=0x%x\n", the_command);
516      free(the_command);
517      a_status = 1;
518    }
519  return a_status;
520}
521//>
522//< process_espeak_command
523void process_espeak_command( t_espeak_command* the_command)
524{
525  ENTER("process_espeak_command");
526
527  SHOW("command=0x%x\n", the_command);
528
529  if (the_command == NULL)
530    {
531      return;
532    }
533
534  the_command->state = CS_PROCESSED;
535
536  switch(the_command->type)
537    {
538    case ET_TEXT:
539      {
540	t_espeak_text* data = &(the_command->u.my_text);
541	sync_espeak_Synth( data->unique_identifier, data->text, data->size, 
542			   data->position, data->position_type, 
543			   data->end_position, data->flags, data->user_data);	
544      }
545      break;
546
547    case ET_MARK:
548      {
549	t_espeak_mark* data = &(the_command->u.my_mark);
550	sync_espeak_Synth_Mark( data->unique_identifier, data->text, data->size, 
551				data->index_mark, data->end_position, data->flags, 
552				data->user_data);
553      }
554      break;
555
556    case ET_TERMINATED_MSG:
557      { 
558	t_espeak_terminated_msg* data = &(the_command->u.my_terminated_msg);
559	sync_espeak_terminated_msg( data->unique_identifier, data->user_data);
560      }
561      break;
562
563    case ET_KEY:
564      {
565	const char* data = the_command->u.my_key;
566	sync_espeak_Key(data);
567      }
568      break;
569
570    case ET_CHAR:
571      {
572	const wchar_t data = the_command->u.my_char;
573	sync_espeak_Char( data);
574      }
575      break;
576
577    case ET_PARAMETER:
578      {
579	t_espeak_parameter* data = &(the_command->u.my_param);
580	SetParameter( data->parameter, data->value, data->relative);
581      }
582      break;
583
584    case ET_PUNCTUATION_LIST:
585      {
586	const wchar_t* data = the_command->u.my_punctuation_list;
587	sync_espeak_SetPunctuationList( data);
588      }
589      break;
590
591    case ET_VOICE_NAME:
592      {
593	const char* data = the_command->u.my_voice_name;
594	SetVoiceByName( data);
595      }
596      break;
597
598    case ET_VOICE_SPEC:
599      {
600	espeak_VOICE* data = &(the_command->u.my_voice_spec);
601	SetVoiceByProperties(data);
602      }
603      break;
604
605    default:
606      assert(0);
607      break;
608    }
609}
610
611//>
612
613//< process_espeak_command
614void display_espeak_command( t_espeak_command* the_command)
615{
616  ENTER("display_espeak_command");
617#ifdef DEBUG_ENABLED
618  if (the_command == NULL)
619    {
620      SHOW("display_espeak_command > command=%s\n","NULL");
621      return;
622    }
623
624  SHOW("display_espeak_command > state=%d\n",the_command->state);
625
626  switch(the_command->type)
627    {
628    case ET_TEXT:
629      {
630	t_espeak_text* data = &(the_command->u.my_text);
631	SHOW("display_espeak_command > (0x%x) uid=%d, TEXT=%s, user_data=0x%x\n", the_command, data->unique_identifier, (char*)data->text, (int)(data->user_data));
632      }
633      break;
634
635    case ET_MARK:
636      {
637	t_espeak_mark* data = &(the_command->u.my_mark);
638	SHOW("display_espeak_command > (0x%x) uid=%d, MARK=%s, user_data=0x%x\n", the_command, data->unique_identifier, (char*)data->text, (int)(data->user_data));
639      }
640      break;
641
642    case ET_KEY:
643      {
644	const char* data = the_command->u.my_key;
645	SHOW("display_espeak_command > (0x%x) KEY=%c\n", the_command, data);
646      }
647      break;
648
649    case ET_TERMINATED_MSG:
650      {
651	t_espeak_terminated_msg* data = &(the_command->u.my_terminated_msg);
652
653	SHOW("display_espeak_command > (0x%x) TERMINATED_MSG uid=%d, user_data=0x%x, state=%d\n", 
654	     the_command, data->unique_identifier, data->user_data, 
655	     the_command->state);
656      }
657      break;
658
659    case ET_CHAR:
660      {
661	const wchar_t data = the_command->u.my_char;
662	SHOW("display_espeak_command > (0x%x) CHAR=%c\n", the_command, (char)data);
663      }
664      break;
665
666    case ET_PARAMETER:
667      {
668	t_espeak_parameter* data = &(the_command->u.my_param);
669	SHOW("display_espeak_command > (0x%x) PARAMETER=%d, value=%d, relative=%d\n", 
670	     the_command, data->parameter, data->value, data->relative);
671      }
672      break;
673
674    case ET_PUNCTUATION_LIST:
675      {
676	const wchar_t* data = the_command->u.my_punctuation_list;
677	sync_espeak_SetPunctuationList( data);
678	SHOW("display_espeak_command > (0x%x) PUNCTLIST=%s\n", the_command, (char*)data);
679      }
680      break;
681
682    case ET_VOICE_NAME:
683      {
684	const char* data = the_command->u.my_voice_name;
685	SHOW("display_espeak_command > (0x%x) VOICE_NAME=%s\n", the_command, data);
686      }
687      break;
688
689    case ET_VOICE_SPEC:
690      {
691	SHOW("display_espeak_command > (0x%x) VOICE_SPEC", the_command);
692      }
693      break;
694
695    default:
696      assert(0);
697      break;
698    }
699#endif
700}
701
702#endif
703//>