eSpeak NG is an open source speech synthesizer that supports more than hundred languages and accents.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

speak_lib.cpp 32KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284
  1. /***************************************************************************
  2. * Copyright (C) 2005 to 2013 by Jonathan Duddington *
  3. * email: [email protected] *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; either version 3 of the License, or *
  8. * (at your option) any later version. *
  9. * *
  10. * This program is distributed in the hope that it will be useful, *
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  13. * GNU General Public License for more details. *
  14. * *
  15. * You should have received a copy of the GNU General Public License *
  16. * along with this program; if not, write see: *
  17. * <http://www.gnu.org/licenses/>. *
  18. ***************************************************************************/
  19. #include "StdAfx.h"
  20. #include "stdio.h"
  21. #include "ctype.h"
  22. #include "string.h"
  23. #include "stdlib.h"
  24. #include "wchar.h"
  25. #include "locale.h"
  26. #include <assert.h>
  27. #include <time.h>
  28. #include "speech.h"
  29. #include <sys/stat.h>
  30. #ifndef PLATFORM_WINDOWS
  31. #include <unistd.h>
  32. #endif
  33. #include "speak_lib.h"
  34. #include "phoneme.h"
  35. #include "synthesize.h"
  36. #include "voice.h"
  37. #include "translate.h"
  38. #include "debug.h"
  39. #include "fifo.h"
  40. #include "event.h"
  41. #include "wave.h"
  42. unsigned char *outbuf=NULL;
  43. espeak_EVENT *event_list=NULL;
  44. int event_list_ix=0;
  45. int n_event_list;
  46. long count_samples;
  47. void* my_audio=NULL;
  48. static unsigned int my_unique_identifier=0;
  49. static void* my_user_data=NULL;
  50. static espeak_AUDIO_OUTPUT my_mode=AUDIO_OUTPUT_SYNCHRONOUS;
  51. static int synchronous_mode = 1;
  52. static int out_samplerate = 0;
  53. static int voice_samplerate = 22050;
  54. static espeak_ERROR err = EE_OK;
  55. t_espeak_callback* synth_callback = NULL;
  56. int (* uri_callback)(int, const char *, const char *) = NULL;
  57. int (* phoneme_callback)(const char *) = NULL;
  58. char path_home[N_PATH_HOME]; // this is the espeak-data directory
  59. extern int saved_parameters[N_SPEECH_PARAM]; //Parameters saved on synthesis start
  60. void WVoiceChanged(voice_t *wvoice)
  61. {//=================================
  62. // Voice change in wavegen
  63. voice_samplerate = wvoice->samplerate;
  64. }
  65. #ifdef USE_ASYNC
  66. static int dispatch_audio(short* outbuf, int length, espeak_EVENT* event)
  67. {//======================================================================
  68. ENTER("dispatch_audio");
  69. int a_wave_can_be_played = fifo_is_command_enabled();
  70. #ifdef DEBUG_ENABLED
  71. SHOW("*** dispatch_audio > uid=%d, [write=%p (%d bytes)], sample=%d, a_wave_can_be_played = %d\n",
  72. (event) ? event->unique_identifier : 0, wave_test_get_write_buffer(), 2*length,
  73. (event) ? event->sample : 0,
  74. a_wave_can_be_played);
  75. #endif
  76. switch(my_mode)
  77. {
  78. case AUDIO_OUTPUT_PLAYBACK:
  79. {
  80. int event_type=0;
  81. if(event)
  82. {
  83. event_type = event->type;
  84. }
  85. if(event_type == espeakEVENT_SAMPLERATE)
  86. {
  87. voice_samplerate = event->id.number;
  88. if(out_samplerate != voice_samplerate)
  89. {
  90. if(out_samplerate != 0)
  91. {
  92. // sound was previously open with a different sample rate
  93. wave_close(my_audio);
  94. sleep(1);
  95. }
  96. out_samplerate = voice_samplerate;
  97. if(!wave_init(voice_samplerate))
  98. {
  99. err = EE_INTERNAL_ERROR;
  100. return(-1);
  101. }
  102. wave_set_callback_is_output_enabled( fifo_is_command_enabled);
  103. my_audio = wave_open("alsa");
  104. event_init();
  105. }
  106. }
  107. if (outbuf && length && a_wave_can_be_played)
  108. {
  109. wave_write (my_audio, (char*)outbuf, 2*length);
  110. }
  111. while(a_wave_can_be_played) {
  112. // TBD: some event are filtered here but some insight might be given
  113. // TBD: in synthesise.cpp for avoiding to create WORDs with size=0.
  114. // TBD: For example sentence "or ALT)." returns three words
  115. // "or", "ALT" and "".
  116. // TBD: the last one has its size=0.
  117. if (event && (event->type == espeakEVENT_WORD) && (event->length==0))
  118. {
  119. break;
  120. }
  121. espeak_ERROR a_error = event_declare(event);
  122. if (a_error != EE_BUFFER_FULL)
  123. {
  124. break;
  125. }
  126. SHOW_TIME("dispatch_audio > EE_BUFFER_FULL\n");
  127. usleep(10000);
  128. a_wave_can_be_played = fifo_is_command_enabled();
  129. }
  130. }
  131. break;
  132. case AUDIO_OUTPUT_RETRIEVAL:
  133. if (synth_callback)
  134. {
  135. synth_callback(outbuf, length, event);
  136. }
  137. break;
  138. case AUDIO_OUTPUT_SYNCHRONOUS:
  139. case AUDIO_OUTPUT_SYNCH_PLAYBACK:
  140. break;
  141. }
  142. if (!a_wave_can_be_played)
  143. {
  144. SHOW_TIME("dispatch_audio > synth must be stopped!\n");
  145. }
  146. SHOW_TIME("LEAVE dispatch_audio\n");
  147. return (a_wave_can_be_played==0); // 1 = stop synthesis, -1 = error
  148. }
  149. static int create_events(short* outbuf, int length, espeak_EVENT* event, uint32_t the_write_pos)
  150. {//=====================================================================
  151. int finished;
  152. int i=0;
  153. // The audio data are written to the output device.
  154. // The list of events in event_list (index: event_list_ix) is read:
  155. // Each event is declared to the "event" object which stores them internally.
  156. // The event object is responsible of calling the external callback
  157. // as soon as the relevant audio sample is played.
  158. do
  159. { // for each event
  160. espeak_EVENT* event;
  161. if (event_list_ix == 0)
  162. {
  163. event = NULL;
  164. }
  165. else
  166. {
  167. event = event_list + i;
  168. #ifdef DEBUG_ENABLED
  169. SHOW("Synthesize: event->sample(%d) + %d = %d\n", event->sample, the_write_pos, event->sample + the_write_pos);
  170. #endif
  171. event->sample += the_write_pos;
  172. }
  173. #ifdef DEBUG_ENABLED
  174. SHOW("*** Synthesize: i=%d (event_list_ix=%d), length=%d\n",i,event_list_ix,length);
  175. #endif
  176. finished = dispatch_audio((short *)outbuf, length, event);
  177. length = 0; // the wave data are played once.
  178. i++;
  179. } while((i < event_list_ix) && !finished);
  180. return finished;
  181. }
  182. int sync_espeak_terminated_msg( uint32_t unique_identifier, void* user_data)
  183. {//=====================================================================
  184. ENTER("sync_espeak_terminated_msg");
  185. int finished=0;
  186. memset(event_list, 0, 2*sizeof(espeak_EVENT));
  187. event_list[0].type = espeakEVENT_MSG_TERMINATED;
  188. event_list[0].unique_identifier = unique_identifier;
  189. event_list[0].user_data = user_data;
  190. event_list[1].type = espeakEVENT_LIST_TERMINATED;
  191. event_list[1].unique_identifier = unique_identifier;
  192. event_list[1].user_data = user_data;
  193. if (my_mode==AUDIO_OUTPUT_PLAYBACK)
  194. {
  195. while(1)
  196. {
  197. espeak_ERROR a_error = event_declare(event_list);
  198. if (a_error != EE_BUFFER_FULL)
  199. {
  200. break;
  201. }
  202. SHOW_TIME("sync_espeak_terminated_msg > EE_BUFFER_FULL\n");
  203. usleep(10000);
  204. }
  205. }
  206. else
  207. {
  208. if (synth_callback)
  209. {
  210. finished=synth_callback(NULL,0,event_list);
  211. }
  212. }
  213. return finished;
  214. }
  215. #endif
  216. static void select_output(espeak_AUDIO_OUTPUT output_type)
  217. {//=======================================================
  218. my_mode = output_type;
  219. my_audio = NULL;
  220. synchronous_mode = 1;
  221. option_waveout = 1; // inhibit portaudio callback from wavegen.cpp
  222. out_samplerate = 0;
  223. switch(my_mode)
  224. {
  225. case AUDIO_OUTPUT_PLAYBACK:
  226. // wave_init() is now called just before the first wave_write()
  227. synchronous_mode = 0;
  228. break;
  229. case AUDIO_OUTPUT_RETRIEVAL:
  230. synchronous_mode = 0;
  231. break;
  232. case AUDIO_OUTPUT_SYNCHRONOUS:
  233. break;
  234. case AUDIO_OUTPUT_SYNCH_PLAYBACK:
  235. option_waveout = 0;
  236. WavegenInitSound();
  237. break;
  238. }
  239. } // end of select_output
  240. int GetFileLength(const char *filename)
  241. {//====================================
  242. struct stat statbuf;
  243. if(stat(filename,&statbuf) != 0)
  244. return(0);
  245. if((statbuf.st_mode & S_IFMT) == S_IFDIR)
  246. // if(S_ISDIR(statbuf.st_mode))
  247. return(-2); // a directory
  248. return(statbuf.st_size);
  249. } // end of GetFileLength
  250. char *Alloc(int size)
  251. {//==================
  252. char *p;
  253. if((p = (char *)malloc(size)) == NULL)
  254. fprintf(stderr,"Can't allocate memory\n"); // I was told that size+1 fixes a crash on 64-bit systems
  255. return(p);
  256. }
  257. void Free(void *ptr)
  258. {//=================
  259. if(ptr != NULL)
  260. free(ptr);
  261. }
  262. static void init_path(const char *path)
  263. {//====================================
  264. #ifdef PLATFORM_WINDOWS
  265. HKEY RegKey;
  266. unsigned long size;
  267. unsigned long var_type;
  268. char *env;
  269. unsigned char buf[sizeof(path_home)-13];
  270. if(path != NULL)
  271. {
  272. sprintf(path_home,"%s/espeak-data",path);
  273. return;
  274. }
  275. if((env = getenv("ESPEAK_DATA_PATH")) != NULL)
  276. {
  277. sprintf(path_home,"%s/espeak-data",env);
  278. if(GetFileLength(path_home) == -2)
  279. return; // an espeak-data directory exists
  280. }
  281. buf[0] = 0;
  282. RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Speech\\Voices\\Tokens\\eSpeak", 0, KEY_READ, &RegKey);
  283. size = sizeof(buf);
  284. var_type = REG_SZ;
  285. RegQueryValueExA(RegKey, "path", 0, &var_type, buf, &size);
  286. sprintf(path_home,"%s\\espeak-data",buf);
  287. #else
  288. char *env;
  289. if(path != NULL)
  290. {
  291. snprintf(path_home,sizeof(path_home),"%s/espeak-data",path);
  292. return;
  293. }
  294. // check for environment variable
  295. if((env = getenv("ESPEAK_DATA_PATH")) != NULL)
  296. {
  297. snprintf(path_home,sizeof(path_home),"%s/espeak-data",env);
  298. if(GetFileLength(path_home) == -2)
  299. return; // an espeak-data directory exists
  300. }
  301. snprintf(path_home,sizeof(path_home),"%s/espeak-data",getenv("HOME"));
  302. if(access(path_home,R_OK) != 0)
  303. {
  304. strcpy(path_home,PATH_ESPEAK_DATA);
  305. }
  306. #endif
  307. }
  308. static int initialise(int control)
  309. {//===============================
  310. int param;
  311. int result;
  312. int srate = 22050; // default sample rate 22050 Hz
  313. err = EE_OK;
  314. LoadConfig();
  315. if((result = LoadPhData(&srate)) != 1) // reads sample rate from espeak-data/phontab
  316. {
  317. if(result == -1)
  318. {
  319. fprintf(stderr,"Failed to load espeak-data\n");
  320. if((control & espeakINITIALIZE_DONT_EXIT) == 0)
  321. {
  322. exit(1);
  323. }
  324. }
  325. else
  326. fprintf(stderr,"Wrong version of espeak-data 0x%x (expects 0x%x) at %s\n",result,version_phdata,path_home);
  327. }
  328. WavegenInit(srate,0);
  329. memset(&current_voice_selected,0,sizeof(current_voice_selected));
  330. SetVoiceStack(NULL, "");
  331. SynthesizeInit();
  332. InitNamedata();
  333. for(param=0; param<N_SPEECH_PARAM; param++)
  334. param_stack[0].parameter[param] = param_defaults[param];
  335. return(0);
  336. }
  337. static espeak_ERROR Synthesize(unsigned int unique_identifier, const void *text, int flags)
  338. {//========================================================================================
  339. // Fill the buffer with output sound
  340. int length;
  341. int finished = 0;
  342. int count_buffers = 0;
  343. #ifdef USE_ASYNC
  344. uint32_t a_write_pos=0;
  345. #endif
  346. #ifdef DEBUG_ENABLED
  347. ENTER("Synthesize");
  348. if (text)
  349. {
  350. SHOW("Synthesize > uid=%d, flags=%d, >>>text=%s<<<\n", unique_identifier, flags, text);
  351. }
  352. #endif
  353. if((outbuf==NULL) || (event_list==NULL))
  354. return(EE_INTERNAL_ERROR); // espeak_Initialize() has not been called
  355. option_multibyte = flags & 7;
  356. option_ssml = flags & espeakSSML;
  357. option_phoneme_input = flags & espeakPHONEMES;
  358. option_endpause = flags & espeakENDPAUSE;
  359. count_samples = 0;
  360. #ifdef USE_ASYNC
  361. if(my_mode == AUDIO_OUTPUT_PLAYBACK)
  362. {
  363. a_write_pos = wave_get_write_position(my_audio);
  364. }
  365. #endif
  366. if(translator == NULL)
  367. {
  368. SetVoiceByName("default");
  369. }
  370. SpeakNextClause(NULL,text,0);
  371. if(my_mode == AUDIO_OUTPUT_SYNCH_PLAYBACK)
  372. {
  373. for(;;)
  374. {
  375. #ifdef PLATFORM_WINDOWS
  376. Sleep(300); // 0.3s
  377. #else
  378. #ifdef USE_NANOSLEEP
  379. struct timespec period;
  380. struct timespec remaining;
  381. period.tv_sec = 0;
  382. period.tv_nsec = 300000000; // 0.3 sec
  383. nanosleep(&period,&remaining);
  384. #else
  385. sleep(1);
  386. #endif
  387. #endif
  388. if(SynthOnTimer() != 0)
  389. break;
  390. }
  391. return(EE_OK);
  392. }
  393. for(;;)
  394. {
  395. #ifdef DEBUG_ENABLED
  396. SHOW("Synthesize > %s\n","for (next)");
  397. #endif
  398. out_ptr = outbuf;
  399. out_end = &outbuf[outbuf_size];
  400. event_list_ix = 0;
  401. WavegenFill(0);
  402. length = (out_ptr - outbuf)/2;
  403. count_samples += length;
  404. event_list[event_list_ix].type = espeakEVENT_LIST_TERMINATED; // indicates end of event list
  405. event_list[event_list_ix].unique_identifier = my_unique_identifier;
  406. event_list[event_list_ix].user_data = my_user_data;
  407. count_buffers++;
  408. if (my_mode==AUDIO_OUTPUT_PLAYBACK)
  409. {
  410. #ifdef USE_ASYNC
  411. finished = create_events((short *)outbuf, length, event_list, a_write_pos);
  412. if(finished < 0)
  413. return EE_INTERNAL_ERROR;
  414. length = 0; // the wave data are played once.
  415. #endif
  416. }
  417. else
  418. {
  419. finished = synth_callback((short *)outbuf, length, event_list);
  420. }
  421. if(finished)
  422. {
  423. SpeakNextClause(NULL,0,2); // stop
  424. break;
  425. }
  426. if(Generate(phoneme_list,&n_phoneme_list,1)==0)
  427. {
  428. if(WcmdqUsed() == 0)
  429. {
  430. // don't process the next clause until the previous clause has finished generating speech.
  431. // This ensures that <audio> tag (which causes end-of-clause) is at a sound buffer boundary
  432. event_list[0].type = espeakEVENT_LIST_TERMINATED;
  433. event_list[0].unique_identifier = my_unique_identifier;
  434. event_list[0].user_data = my_user_data;
  435. if(SpeakNextClause(NULL,NULL,1)==0)
  436. {
  437. #ifdef USE_ASYNC
  438. if (my_mode==AUDIO_OUTPUT_PLAYBACK)
  439. {
  440. if(dispatch_audio(NULL, 0, NULL) < 0) // TBD: test case
  441. return err = EE_INTERNAL_ERROR;
  442. }
  443. else
  444. {
  445. synth_callback(NULL, 0, event_list); // NULL buffer ptr indicates end of data
  446. }
  447. #else
  448. synth_callback(NULL, 0, event_list); // NULL buffer ptr indicates end of data
  449. #endif
  450. break;
  451. }
  452. }
  453. }
  454. }
  455. return(EE_OK);
  456. } // end of Synthesize
  457. #ifdef DEBUG_ENABLED
  458. static const char* label[] = {
  459. "END_OF_EVENT_LIST",
  460. "WORD",
  461. "SENTENCE",
  462. "MARK",
  463. "PLAY",
  464. "END"};
  465. #endif
  466. void MarkerEvent(int type, unsigned int char_position, int value, int value2, unsigned char *out_ptr)
  467. {//==================================================================================================
  468. // type: 1=word, 2=sentence, 3=named mark, 4=play audio, 5=end, 7=phoneme
  469. ENTER("MarkerEvent");
  470. espeak_EVENT *ep;
  471. double time;
  472. if((event_list == NULL) || (event_list_ix >= (n_event_list-2)))
  473. return;
  474. ep = &event_list[event_list_ix++];
  475. ep->type = (espeak_EVENT_TYPE)type;
  476. ep->unique_identifier = my_unique_identifier;
  477. ep->user_data = my_user_data;
  478. ep->text_position = char_position & 0xffffff;
  479. ep->length = char_position >> 24;
  480. time = (double(count_samples + mbrola_delay + (out_ptr - out_start)/2)*1000.0)/samplerate;
  481. ep->audio_position = int(time);
  482. ep->sample = (count_samples + mbrola_delay + (out_ptr - out_start)/2);
  483. #ifdef DEBUG_ENABLED
  484. SHOW("MarkerEvent > count_samples=%d, out_ptr=%x, out_start=0x%x\n",count_samples, out_ptr, out_start);
  485. SHOW("*** MarkerEvent > type=%s, uid=%d, text_pos=%d, length=%d, audio_position=%d, sample=%d\n",
  486. label[ep->type], ep->unique_identifier, ep->text_position, ep->length,
  487. ep->audio_position, ep->sample);
  488. #endif
  489. if((type == espeakEVENT_MARK) || (type == espeakEVENT_PLAY))
  490. ep->id.name = &namedata[value];
  491. else
  492. //#ifdef deleted
  493. // temporarily removed, don't introduce until after eSpeak version 1.46.02
  494. if(type == espeakEVENT_PHONEME)
  495. {
  496. int *p;
  497. p = (int *)(ep->id.string);
  498. p[0] = value;
  499. p[1] = value2;
  500. }
  501. else
  502. //#endif
  503. {
  504. ep->id.number = value;
  505. }
  506. } // end of MarkerEvent
  507. espeak_ERROR sync_espeak_Synth(unsigned int unique_identifier, const void *text, size_t size,
  508. unsigned int position, espeak_POSITION_TYPE position_type,
  509. unsigned int end_position, unsigned int flags, void* user_data)
  510. {//===========================================================================
  511. #ifdef DEBUG_ENABLED
  512. ENTER("sync_espeak_Synth");
  513. SHOW("sync_espeak_Synth > position=%d, position_type=%d, end_position=%d, flags=%d, user_data=0x%x, text=%s\n", position, position_type, end_position, flags, user_data, text);
  514. #endif
  515. espeak_ERROR aStatus;
  516. InitText(flags);
  517. my_unique_identifier = unique_identifier;
  518. my_user_data = user_data;
  519. for (int i=0; i < N_SPEECH_PARAM; i++)
  520. saved_parameters[i] = param_stack[0].parameter[i];
  521. switch(position_type)
  522. {
  523. case POS_CHARACTER:
  524. skip_characters = position;
  525. break;
  526. case POS_WORD:
  527. skip_words = position;
  528. break;
  529. case POS_SENTENCE:
  530. skip_sentences = position;
  531. break;
  532. }
  533. if(skip_characters || skip_words || skip_sentences)
  534. skipping_text = 1;
  535. end_character_position = end_position;
  536. aStatus = Synthesize(unique_identifier, text, flags);
  537. #ifdef USE_ASYNC
  538. wave_flush(my_audio);
  539. #endif
  540. SHOW_TIME("LEAVE sync_espeak_Synth");
  541. return aStatus;
  542. } // end of sync_espeak_Synth
  543. espeak_ERROR sync_espeak_Synth_Mark(unsigned int unique_identifier, const void *text, size_t size,
  544. const char *index_mark, unsigned int end_position,
  545. unsigned int flags, void* user_data)
  546. {//=========================================================================
  547. espeak_ERROR aStatus;
  548. InitText(flags);
  549. my_unique_identifier = unique_identifier;
  550. my_user_data = user_data;
  551. if(index_mark != NULL)
  552. {
  553. strncpy0(skip_marker, index_mark, sizeof(skip_marker));
  554. skipping_text = 1;
  555. }
  556. end_character_position = end_position;
  557. aStatus = Synthesize(unique_identifier, text, flags | espeakSSML);
  558. SHOW_TIME("LEAVE sync_espeak_Synth_Mark");
  559. return (aStatus);
  560. } // end of sync_espeak_Synth_Mark
  561. void sync_espeak_Key(const char *key)
  562. {//==================================
  563. // symbolic name, symbolicname_character - is there a system resource of symbolic names per language?
  564. int letter;
  565. int ix;
  566. ix = utf8_in(&letter,key);
  567. if(key[ix] == 0)
  568. {
  569. // a single character
  570. sync_espeak_Char(letter);
  571. return;
  572. }
  573. my_unique_identifier = 0;
  574. my_user_data = NULL;
  575. Synthesize(0, key,0); // speak key as a text string
  576. }
  577. void sync_espeak_Char(wchar_t character)
  578. {//=====================================
  579. // is there a system resource of character names per language?
  580. char buf[80];
  581. my_unique_identifier = 0;
  582. my_user_data = NULL;
  583. sprintf(buf,"<say-as interpret-as=\"tts:char\">&#%d;</say-as>",character);
  584. Synthesize(0, buf,espeakSSML);
  585. }
  586. void sync_espeak_SetPunctuationList(const wchar_t *punctlist)
  587. {//==========================================================
  588. // Set the list of punctuation which are spoken for "some".
  589. my_unique_identifier = 0;
  590. my_user_data = NULL;
  591. wcsncpy(option_punctlist, punctlist, N_PUNCTLIST);
  592. option_punctlist[N_PUNCTLIST-1] = 0;
  593. } // end of sync_espeak_SetPunctuationList
  594. #pragma GCC visibility push(default)
  595. ESPEAK_API void espeak_SetSynthCallback(t_espeak_callback* SynthCallback)
  596. {//======================================================================
  597. ENTER("espeak_SetSynthCallback");
  598. synth_callback = SynthCallback;
  599. #ifdef USE_ASYNC
  600. event_set_callback(synth_callback);
  601. #endif
  602. }
  603. ESPEAK_API void espeak_SetUriCallback(int (* UriCallback)(int, const char*, const char *))
  604. {//=======================================================================================
  605. ENTER("espeak_SetUriCallback");
  606. uri_callback = UriCallback;
  607. }
  608. ESPEAK_API void espeak_SetPhonemeCallback(int (* PhonemeCallback)(const char*))
  609. {//===========================================================================
  610. phoneme_callback = PhonemeCallback;
  611. }
  612. ESPEAK_API int espeak_Initialize(espeak_AUDIO_OUTPUT output_type, int buf_length, const char *path, int options)
  613. {//=============================================================================================================
  614. ENTER("espeak_Initialize");
  615. int param;
  616. // It seems that the wctype functions don't work until the locale has been set
  617. // to something other than the default "C". Then, not only Latin1 but also the
  618. // other characters give the correct results with iswalpha() etc.
  619. #ifdef PLATFORM_RISCOS
  620. setlocale(LC_CTYPE,"ISO8859-1");
  621. #else
  622. if(setlocale(LC_CTYPE,"en_US.UTF-8") == NULL)
  623. {
  624. if(setlocale(LC_CTYPE,"UTF-8") == NULL)
  625. setlocale(LC_CTYPE,"");
  626. }
  627. #endif
  628. init_path(path);
  629. initialise(options);
  630. select_output(output_type);
  631. if(f_logespeak)
  632. {
  633. fprintf(f_logespeak,"INIT mode %d options 0x%x\n",output_type,options);
  634. }
  635. // buflength is in mS, allocate 2 bytes per sample
  636. if(buf_length == 0)
  637. buf_length = 200;
  638. outbuf_size = (buf_length * samplerate)/500;
  639. outbuf = (unsigned char*)realloc(outbuf,outbuf_size);
  640. if((out_start = outbuf) == NULL)
  641. return(EE_INTERNAL_ERROR);
  642. // allocate space for event list. Allow 200 events per second.
  643. // Add a constant to allow for very small buf_length
  644. n_event_list = (buf_length*200)/1000 + 20;
  645. if((event_list = (espeak_EVENT *)realloc(event_list,sizeof(espeak_EVENT) * n_event_list)) == NULL)
  646. return(EE_INTERNAL_ERROR);
  647. option_phonemes = 0;
  648. option_mbrola_phonemes = 0;
  649. option_phoneme_events = (options & (espeakINITIALIZE_PHONEME_EVENTS | espeakINITIALIZE_PHONEME_IPA));
  650. VoiceReset(0);
  651. // SetVoiceByName("default");
  652. for(param=0; param<N_SPEECH_PARAM; param++)
  653. param_stack[0].parameter[param] = saved_parameters[param] = param_defaults[param];
  654. SetParameter(espeakRATE,175,0);
  655. SetParameter(espeakVOLUME,100,0);
  656. SetParameter(espeakCAPITALS,option_capitals,0);
  657. SetParameter(espeakPUNCTUATION,option_punctuation,0);
  658. SetParameter(espeakWORDGAP,0,0);
  659. // DoVoiceChange(voice);
  660. #ifdef USE_ASYNC
  661. fifo_init();
  662. #endif
  663. return(samplerate);
  664. }
  665. ESPEAK_API espeak_ERROR espeak_Synth(const void *text, size_t size,
  666. unsigned int position,
  667. espeak_POSITION_TYPE position_type,
  668. unsigned int end_position, unsigned int flags,
  669. unsigned int* unique_identifier, void* user_data)
  670. {//=====================================================================================
  671. #ifdef DEBUG_ENABLED
  672. ENTER("espeak_Synth");
  673. SHOW("espeak_Synth > position=%d, position_type=%d, end_position=%d, flags=%d, user_data=0x%x, text=%s\n", position, position_type, end_position, flags, user_data, text);
  674. #endif
  675. if(f_logespeak)
  676. {
  677. fprintf(f_logespeak,"\nSYNTH posn %d %d %d flags 0x%x\n%s\n",position,end_position,position_type,flags, (const char *)text);
  678. fflush(f_logespeak);
  679. }
  680. espeak_ERROR a_error=EE_INTERNAL_ERROR;
  681. static unsigned int temp_identifier;
  682. if (unique_identifier == NULL)
  683. {
  684. unique_identifier = &temp_identifier;
  685. }
  686. *unique_identifier = 0;
  687. if(synchronous_mode)
  688. {
  689. return(sync_espeak_Synth(0,text,size,position,position_type,end_position,flags,user_data));
  690. }
  691. #ifdef USE_ASYNC
  692. // Create the text command
  693. t_espeak_command* c1 = create_espeak_text(text, size, position, position_type, end_position, flags, user_data);
  694. // Retrieve the unique identifier
  695. *unique_identifier = c1->u.my_text.unique_identifier;
  696. // Create the "terminated msg" command (same uid)
  697. t_espeak_command* c2 = create_espeak_terminated_msg(*unique_identifier, user_data);
  698. // Try to add these 2 commands (single transaction)
  699. if (c1 && c2)
  700. {
  701. a_error = fifo_add_commands(c1, c2);
  702. if (a_error != EE_OK)
  703. {
  704. delete_espeak_command(c1);
  705. delete_espeak_command(c2);
  706. c1=c2=NULL;
  707. }
  708. }
  709. else
  710. {
  711. delete_espeak_command(c1);
  712. delete_espeak_command(c2);
  713. }
  714. #endif
  715. return a_error;
  716. } // end of espeak_Synth
  717. ESPEAK_API espeak_ERROR espeak_Synth_Mark(const void *text, size_t size,
  718. const char *index_mark,
  719. unsigned int end_position,
  720. unsigned int flags,
  721. unsigned int* unique_identifier,
  722. void* user_data)
  723. {//=========================================================================
  724. #ifdef DEBUG_ENABLED
  725. ENTER("espeak_Synth_Mark");
  726. SHOW("espeak_Synth_Mark > index_mark=%s, end_position=%d, flags=%d, text=%s\n", index_mark, end_position, flags, text);
  727. #endif
  728. espeak_ERROR a_error=EE_OK;
  729. static unsigned int temp_identifier;
  730. if(f_logespeak)
  731. {
  732. fprintf(f_logespeak,"\nSYNTH MARK %s posn %d flags 0x%x\n%s\n",index_mark,end_position,flags, (const char *)text);
  733. }
  734. if (unique_identifier == NULL)
  735. {
  736. unique_identifier = &temp_identifier;
  737. }
  738. *unique_identifier = 0;
  739. if(synchronous_mode)
  740. {
  741. return(sync_espeak_Synth_Mark(0,text,size,index_mark,end_position,flags,user_data));
  742. }
  743. #ifdef USE_ASYNC
  744. // Create the mark command
  745. t_espeak_command* c1 = create_espeak_mark(text, size, index_mark, end_position,
  746. flags, user_data);
  747. // Retrieve the unique identifier
  748. *unique_identifier = c1->u.my_mark.unique_identifier;
  749. // Create the "terminated msg" command (same uid)
  750. t_espeak_command* c2 = create_espeak_terminated_msg(*unique_identifier, user_data);
  751. // Try to add these 2 commands (single transaction)
  752. if (c1 && c2)
  753. {
  754. a_error = fifo_add_commands(c1, c2);
  755. if (a_error != EE_OK)
  756. {
  757. delete_espeak_command(c1);
  758. delete_espeak_command(c2);
  759. c1=c2=NULL;
  760. }
  761. }
  762. else
  763. {
  764. delete_espeak_command(c1);
  765. delete_espeak_command(c2);
  766. }
  767. #endif
  768. return a_error;
  769. } // end of espeak_Synth_Mark
  770. ESPEAK_API espeak_ERROR espeak_Key(const char *key)
  771. {//================================================
  772. ENTER("espeak_Key");
  773. // symbolic name, symbolicname_character - is there a system resource of symbolicnames per language
  774. if(f_logespeak)
  775. {
  776. fprintf(f_logespeak,"\nKEY %s\n",key);
  777. }
  778. espeak_ERROR a_error = EE_OK;
  779. if(synchronous_mode)
  780. {
  781. sync_espeak_Key(key);
  782. return(EE_OK);
  783. }
  784. #ifdef USE_ASYNC
  785. t_espeak_command* c = create_espeak_key( key, NULL);
  786. a_error = fifo_add_command(c);
  787. if (a_error != EE_OK)
  788. {
  789. delete_espeak_command(c);
  790. }
  791. #endif
  792. return a_error;
  793. }
  794. ESPEAK_API espeak_ERROR espeak_Char(wchar_t character)
  795. {//===========================================
  796. ENTER("espeak_Char");
  797. // is there a system resource of character names per language?
  798. if(f_logespeak)
  799. {
  800. fprintf(f_logespeak,"\nCHAR U+%x\n",character);
  801. }
  802. #ifdef USE_ASYNC
  803. espeak_ERROR a_error;
  804. if(synchronous_mode)
  805. {
  806. sync_espeak_Char(character);
  807. return(EE_OK);
  808. }
  809. t_espeak_command* c = create_espeak_char( character, NULL);
  810. a_error = fifo_add_command(c);
  811. if (a_error != EE_OK)
  812. {
  813. delete_espeak_command(c);
  814. }
  815. return a_error;
  816. #else
  817. sync_espeak_Char(character);
  818. return(EE_OK);
  819. #endif
  820. }
  821. ESPEAK_API espeak_ERROR espeak_SetVoiceByName(const char *name)
  822. {//============================================================
  823. ENTER("espeak_SetVoiceByName");
  824. //#ifdef USE_ASYNC
  825. // I don't think there's a need to queue change voice requests
  826. #ifdef deleted
  827. espeak_ERROR a_error;
  828. if(synchronous_mode)
  829. {
  830. return(SetVoiceByName(name));
  831. }
  832. t_espeak_command* c = create_espeak_voice_name(name);
  833. a_error = fifo_add_command(c);
  834. if (a_error != EE_OK)
  835. {
  836. delete_espeak_command(c);
  837. }
  838. return a_error;
  839. #else
  840. return(SetVoiceByName(name));
  841. #endif
  842. } // end of espeak_SetVoiceByName
  843. ESPEAK_API espeak_ERROR espeak_SetVoiceByProperties(espeak_VOICE *voice_selector)
  844. {//==============================================================================
  845. ENTER("espeak_SetVoiceByProperties");
  846. //#ifdef USE_ASYNC
  847. #ifdef deleted
  848. espeak_ERROR a_error;
  849. if(synchronous_mode)
  850. {
  851. return(SetVoiceByProperties(voice_selector));
  852. }
  853. t_espeak_command* c = create_espeak_voice_spec( voice_selector);
  854. a_error = fifo_add_command(c);
  855. if (a_error != EE_OK)
  856. {
  857. delete_espeak_command(c);
  858. }
  859. return a_error;
  860. #else
  861. return(SetVoiceByProperties(voice_selector));
  862. #endif
  863. } // end of espeak_SetVoiceByProperties
  864. ESPEAK_API int espeak_GetParameter(espeak_PARAMETER parameter, int current)
  865. {//========================================================================
  866. ENTER("espeak_GetParameter");
  867. // current: 0=default value, 1=current value
  868. if(current)
  869. {
  870. return(param_stack[0].parameter[parameter]);
  871. }
  872. else
  873. {
  874. return(param_defaults[parameter]);
  875. }
  876. } // end of espeak_GetParameter
  877. ESPEAK_API espeak_ERROR espeak_SetParameter(espeak_PARAMETER parameter, int value, int relative)
  878. {//=============================================================================================
  879. ENTER("espeak_SetParameter");
  880. if(f_logespeak)
  881. {
  882. fprintf(f_logespeak,"SETPARAM %d %d %d\n",parameter,value,relative);
  883. }
  884. #ifdef USE_ASYNC
  885. espeak_ERROR a_error;
  886. if(synchronous_mode)
  887. {
  888. SetParameter(parameter,value,relative);
  889. return(EE_OK);
  890. }
  891. t_espeak_command* c = create_espeak_parameter(parameter, value, relative);
  892. a_error = fifo_add_command(c);
  893. if (a_error != EE_OK)
  894. {
  895. delete_espeak_command(c);
  896. }
  897. return a_error;
  898. #else
  899. SetParameter(parameter,value,relative);
  900. return(EE_OK);
  901. #endif
  902. }
  903. ESPEAK_API espeak_ERROR espeak_SetPunctuationList(const wchar_t *punctlist)
  904. {//================================================================
  905. ENTER("espeak_SetPunctuationList");
  906. // Set the list of punctuation which are spoken for "some".
  907. #ifdef USE_ASYNC
  908. espeak_ERROR a_error;
  909. if(synchronous_mode)
  910. {
  911. sync_espeak_SetPunctuationList(punctlist);
  912. return(EE_OK);
  913. }
  914. t_espeak_command* c = create_espeak_punctuation_list( punctlist);
  915. a_error = fifo_add_command(c);
  916. if (a_error != EE_OK)
  917. {
  918. delete_espeak_command(c);
  919. }
  920. return a_error;
  921. #else
  922. sync_espeak_SetPunctuationList(punctlist);
  923. return(EE_OK);
  924. #endif
  925. } // end of espeak_SetPunctuationList
  926. ESPEAK_API void espeak_SetPhonemeTrace(int value, FILE *stream)
  927. {//============================================================
  928. ENTER("espeak_SetPhonemes");
  929. /* Controls the output of phoneme symbols for the text
  930. bits 0-3:
  931. value=0 No phoneme output (default)
  932. value=1 Output the translated phoneme symbols for the text
  933. value=2 as (1), but also output a trace of how the translation was done (matching rules and list entries)
  934. value=3 as (1), but produces IPA phoneme names rather than ascii
  935. bit 4: produce mbrola pho data
  936. */
  937. option_phonemes = value & 7;
  938. option_mbrola_phonemes = value & 16;
  939. f_trans = stream;
  940. if(stream == NULL)
  941. f_trans = stderr;
  942. } // end of espeak_SetPhonemes
  943. ESPEAK_API const char *espeak_TextToPhonemes(const void **textptr, int textmode, int phonememode)
  944. {//=================================================================================================
  945. /* phoneme_mode bits 0-3: 0=only phoneme names, 1=ties, 2=ZWJ, 3=underscore separator
  946. bits 4-7: 0=eSpeak phoneme names, 1=IPA
  947. */
  948. option_multibyte = textmode & 7;
  949. *textptr = TranslateClause(translator, NULL, *textptr, NULL, NULL);
  950. return(GetTranslatedPhonemeString(phonememode));
  951. }
  952. ESPEAK_API void espeak_CompileDictionary(const char *path, FILE *log, int flags)
  953. {//=============================================================================
  954. ENTER("espeak_CompileDictionary");
  955. CompileDictionary(path, dictionary_name, log, NULL, flags);
  956. } // end of espeak_CompileDirectory
  957. ESPEAK_API espeak_ERROR espeak_Cancel(void)
  958. {//===============================
  959. #ifdef USE_ASYNC
  960. ENTER("espeak_Cancel");
  961. fifo_stop();
  962. event_clear_all();
  963. if(my_mode == AUDIO_OUTPUT_PLAYBACK)
  964. {
  965. wave_close(my_audio);
  966. }
  967. SHOW_TIME("espeak_Cancel > LEAVE");
  968. #endif
  969. embedded_value[EMBED_T] = 0; // reset echo for pronunciation announcements
  970. for (int i=0; i < N_SPEECH_PARAM; i++)
  971. SetParameter(i, saved_parameters[i], 0);
  972. return EE_OK;
  973. } // end of espeak_Cancel
  974. ESPEAK_API int espeak_IsPlaying(void)
  975. {//==================================
  976. // ENTER("espeak_IsPlaying");
  977. #ifdef USE_ASYNC
  978. if((my_mode == AUDIO_OUTPUT_PLAYBACK) && wave_is_busy(my_audio))
  979. return(1);
  980. return(fifo_is_busy());
  981. #else
  982. return(0);
  983. #endif
  984. } // end of espeak_IsPlaying
  985. ESPEAK_API espeak_ERROR espeak_Synchronize(void)
  986. {//=============================================
  987. espeak_ERROR berr = err;
  988. #ifdef USE_ASYNC
  989. SHOW_TIME("espeak_Synchronize > ENTER");
  990. while (espeak_IsPlaying())
  991. {
  992. usleep(20000);
  993. }
  994. #endif
  995. err = EE_OK;
  996. SHOW_TIME("espeak_Synchronize > LEAVE");
  997. return berr;
  998. } // end of espeak_Synchronize
  999. extern void FreePhData(void);
  1000. extern void FreeVoiceList(void);
  1001. ESPEAK_API espeak_ERROR espeak_Terminate(void)
  1002. {//===========================================
  1003. ENTER("espeak_Terminate");
  1004. #ifdef USE_ASYNC
  1005. fifo_stop();
  1006. fifo_terminate();
  1007. event_terminate();
  1008. if(my_mode == AUDIO_OUTPUT_PLAYBACK)
  1009. {
  1010. wave_close(my_audio);
  1011. wave_terminate();
  1012. out_samplerate = 0;
  1013. }
  1014. #endif
  1015. Free(event_list);
  1016. event_list = NULL;
  1017. Free(outbuf);
  1018. outbuf = NULL;
  1019. FreePhData();
  1020. FreeVoiceList();
  1021. if(f_logespeak)
  1022. {
  1023. fclose(f_logespeak);
  1024. f_logespeak = NULL;
  1025. }
  1026. return EE_OK;
  1027. } // end of espeak_Terminate
  1028. ESPEAK_API const char *espeak_Info(const char **ptr)
  1029. {//=================================================
  1030. if(ptr != NULL)
  1031. {
  1032. *ptr = path_home;
  1033. }
  1034. return(version_string);
  1035. }
  1036. #pragma GCC visibility pop