summaryrefslogtreecommitdiff
path: root/navit/support/espeak
diff options
context:
space:
mode:
Diffstat (limited to 'navit/support/espeak')
-rw-r--r--navit/support/espeak/CMakeLists.txt9
-rw-r--r--navit/support/espeak/StdAfx.h3
-rwxr-xr-xnavit/support/espeak/compiledict.c1671
-rw-r--r--navit/support/espeak/debug.c74
-rw-r--r--navit/support/espeak/debug.h26
-rwxr-xr-xnavit/support/espeak/dictionary.c3490
-rw-r--r--navit/support/espeak/espeak-data/af_dictbin74925 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/ca_dictbin4212 -> 0 bytes
-rwxr-xr-xnavit/support/espeak/espeak-data/config9
-rw-r--r--navit/support/espeak/espeak-data/cs_dictbin7798 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/cy_dictbin3541 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/da_dictbin5327 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/de_dictbin19322 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/el_dictbin4585 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/en_dictbin87069 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/eo_dictbin4746 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/es_dictbin5309 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/fi_dictbin4567 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/fr_dictbin19363 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/grc_dictbin3390 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/hbs_dictbin7404 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/hi_dictbin5696 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/hu_dictbin5916 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/hy_dictbin2469 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/id_dictbin3083 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/is_dictbin5566 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/it_dictbin48870 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/jbo_dictbin2051 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/ku_dictbin2277 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/la_dictbin3911 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/lv_dictbin12558 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/af1_phtransbin1636 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/ca1_phtransbin1372 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/cr1_phtransbin2164 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/cs_phtransbin580 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/de2_phtransbin1444 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/de4_phtransbin1588 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/de6_phtransbin1204 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/en1_phtransbin796 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/es_phtransbin1708 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/fr1_phtransbin1852 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/gr2_phtransbin2212 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/grc-de6_phtransbin484 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/hu1_phtransbin1420 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/id1_phtransbin868 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/in1_phtransbin1252 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/it3_phtransbin892 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/la1_phtransbin748 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/nl_phtransbin1612 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/pl1_phtransbin1540 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/pt1_phtransbin2092 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/pt_phtransbin2092 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/ptbr4_phtransbin2356 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/ptbr_phtransbin2500 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/ro1_phtransbin2116 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/sv2_phtransbin1564 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/sv_phtransbin1564 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/us3_phtransbin1012 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mbrola_ph/us_phtransbin1084 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/mk_dictbin4948 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/nl_dictbin4124 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/no_dictbin3735 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/pap_dictbin2148 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/phondatabin355256 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/phondata-manifest729
-rw-r--r--navit/support/espeak/espeak-data/phonindexbin30256 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/phontabbin36460 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/pl_dictbin40458 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/pt_dictbin14970 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/ro_dictbin24961 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/ru_dictbin5519 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/sk_dictbin8898 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/sq_dictbin3222 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/sv_dictbin9508 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/sw_dictbin3072 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/ta_dictbin2527 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/tr_dictbin4783 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/vi_dictbin4855 -> 0 bytes
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/!v/croak11
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/!v/f118
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/!v/f220
-rw-r--r--navit/support/espeak/espeak-data/voices/!v/f322
-rw-r--r--navit/support/espeak/espeak-data/voices/!v/f418
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/!v/fast11
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/!v/m119
-rw-r--r--navit/support/espeak/espeak-data/voices/!v/m215
-rw-r--r--navit/support/espeak/espeak-data/voices/!v/m316
-rw-r--r--navit/support/espeak/espeak-data/voices/!v/m417
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/!v/m515
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/!v/m613
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/!v/m718
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/!v/whisper13
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/af8
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/bs16
-rw-r--r--navit/support/espeak/espeak-data/voices/ca4
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/cs4
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/cy5
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/da3
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/de5
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/default4
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/el5
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/en/en9
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/en/en-n14
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/en/en-rp12
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/en/en-sc16
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/en/en-us17
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/en/en-wi19
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/en/en-wm12
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/eo3
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/es7
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/es-la11
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/fi4
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/fr7
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/fr-be7
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/hi9
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/hr18
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/hu3
-rw-r--r--navit/support/espeak/espeak-data/voices/hy3
-rw-r--r--navit/support/espeak/espeak-data/voices/hy-west19
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/id8
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/is4
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/it6
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/ku6
-rw-r--r--navit/support/espeak/espeak-data/voices/la13
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/lv6
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-af17
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-af1-en7
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-br19
-rw-r--r--navit/support/espeak/espeak-data/voices/mb/mb-br39
-rw-r--r--navit/support/espeak/espeak-data/voices/mb/mb-br49
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-cr19
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-cz26
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-de26
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-de46
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-de4-en6
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-de510
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-de5-en7
-rw-r--r--navit/support/espeak/espeak-data/voices/mb/mb-de66
-rw-r--r--navit/support/espeak/espeak-data/voices/mb/mb-de6-grc6
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-de77
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-en17
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-es17
-rw-r--r--navit/support/espeak/espeak-data/voices/mb/mb-es27
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-fr19
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-fr1-en8
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-fr48
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-fr4-en8
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-gr26
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-gr2-en6
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-hu16
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-hu1-en6
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-id17
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-it38
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-it48
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-la16
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-nl27
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-nl2-en7
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-pl16
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-pl1-en6
-rw-r--r--navit/support/espeak/espeak-data/voices/mb/mb-pt19
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-ro17
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-ro1-en7
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-sw17
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-sw1-en7
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-sw27
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-sw2-en7
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-us112
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-us212
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mb/mb-us312
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/mk4
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/nl3
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/no6
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/pl5
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/pt7
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/pt-pt7
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/ro5
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/ru6
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/sk4
-rw-r--r--navit/support/espeak/espeak-data/voices/sq6
-rw-r--r--navit/support/espeak/espeak-data/voices/sr15
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/sv4
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/sw4
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/ta6
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/test/grc8
-rw-r--r--navit/support/espeak/espeak-data/voices/test/jbo3
-rw-r--r--navit/support/espeak/espeak-data/voices/test/pap5
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/tr4
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/vi6
-rw-r--r--navit/support/espeak/espeak-data/voices/zh30
-rwxr-xr-xnavit/support/espeak/espeak-data/voices/zh-yue14
-rw-r--r--navit/support/espeak/espeak-data/zh_dictbin41834 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak-data/zhy_dictbin1556 -> 0 bytes
-rw-r--r--navit/support/espeak/espeak.c665
-rw-r--r--navit/support/espeak/espeak_command.c707
-rw-r--r--navit/support/espeak/espeak_command.h145
-rw-r--r--navit/support/espeak/event.c725
-rw-r--r--navit/support/espeak/event.h51
-rw-r--r--navit/support/espeak/fifo.c593
-rw-r--r--navit/support/espeak/fifo.h58
-rwxr-xr-xnavit/support/espeak/intonation.c1104
-rw-r--r--navit/support/espeak/klatt.c1303
-rw-r--r--navit/support/espeak/klatt.h153
-rw-r--r--navit/support/espeak/mbrolib.h205
-rw-r--r--navit/support/espeak/numbers.c1507
-rwxr-xr-xnavit/support/espeak/phoneme.h168
-rwxr-xr-xnavit/support/espeak/phonemelist.c686
-rwxr-xr-xnavit/support/espeak/portaudio.h466
-rwxr-xr-xnavit/support/espeak/portaudio18.h466
-rw-r--r--navit/support/espeak/portaudio19.h1127
-rw-r--r--navit/support/espeak/readclause.c2440
-rwxr-xr-xnavit/support/espeak/setlengths.c673
-rwxr-xr-xnavit/support/espeak/sintab.h258
-rwxr-xr-xnavit/support/espeak/speak.c898
-rw-r--r--navit/support/espeak/speak_init.c6
-rw-r--r--navit/support/espeak/speak_lib.c1156
-rw-r--r--navit/support/espeak/speak_lib.h601
-rwxr-xr-xnavit/support/espeak/speech.h86
-rwxr-xr-xnavit/support/espeak/synth_mbrola.c760
-rwxr-xr-xnavit/support/espeak/synthdata.c682
-rwxr-xr-xnavit/support/espeak/synthesize.c1658
-rwxr-xr-xnavit/support/espeak/synthesize.h377
-rw-r--r--navit/support/espeak/tr_languages.c1335
-rwxr-xr-xnavit/support/espeak/translate.c2800
-rwxr-xr-xnavit/support/espeak/translate.h584
-rw-r--r--navit/support/espeak/voice.h81
-rwxr-xr-xnavit/support/espeak/voices.c1746
-rwxr-xr-xnavit/support/espeak/wave.c1112
-rw-r--r--navit/support/espeak/wave.h52
-rwxr-xr-xnavit/support/espeak/wave_pulse.c935
-rwxr-xr-xnavit/support/espeak/wave_sada.c588
-rwxr-xr-xnavit/support/espeak/wavegen.c1941
231 files changed, 0 insertions, 37904 deletions
diff --git a/navit/support/espeak/CMakeLists.txt b/navit/support/espeak/CMakeLists.txt
deleted file mode 100644
index 6a20511e7..000000000
--- a/navit/support/espeak/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-
-if(INTERNAL_ESPEAK_COMPLETE)
- set(ESPEAK_LIBRARY_ADDITIONAL speak_lib.c)
-endif()
-supportlib_add_library(support_espeak compiledict.c dictionary.c intonation.c readclause.c setlengths.c
- numbers.c synth_mbrola.c synthdata.c synthesize.c translate.c tr_languages.c voices.c wavegen.c
- phonemelist.c klatt.c speak_init.c ${ESPEAK_LIBRARY_ADDITIONAL})
-
-install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/espeak-data DESTINATION ${SHARE_DIR} PATTERN ".svn" EXCLUDE)
diff --git a/navit/support/espeak/StdAfx.h b/navit/support/espeak/StdAfx.h
deleted file mode 100644
index c9a526fdf..000000000
--- a/navit/support/espeak/StdAfx.h
+++ /dev/null
@@ -1,3 +0,0 @@
-// This is a dummy file.
-// A file of this name is needed on Windows
-
diff --git a/navit/support/espeak/compiledict.c b/navit/support/espeak/compiledict.c
deleted file mode 100755
index a2b7865f9..000000000
--- a/navit/support/espeak/compiledict.c
+++ /dev/null
@@ -1,1671 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2005 to 2007 by Jonathan Duddington *
- * email: jonsd@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write see: *
- * <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-#include "StdAfx.h"
-
-#include <stdio.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-#include <wctype.h>
-
-#include "speak_lib.h"
-#include "speech.h"
-#include "phoneme.h"
-#include "synthesize.h"
-#include "translate.h"
-
-//#define OPT_FORMAT // format the text and write formatted copy to Log file
-//#define OUTPUT_FORMAT
-
-extern void Write4Bytes(FILE *f, int value);
-int HashDictionary(const char *string);
-
-static FILE *f_log = NULL;
-extern char *dir_dictionary;
-
-static int linenum;
-static int error_count;
-static int transpose_offset; // transpose character range for LookupDictList()
-static int transpose_min;
-static int transpose_max;
-static int text_mode = 0;
-static int debug_flag = 0;
-
-static int hash_counts[N_HASH_DICT];
-static char *hash_chains[N_HASH_DICT];
-static char letterGroupsDefined[N_LETTER_GROUPS];
-
-#define __cdecl
-
-MNEM_TAB mnem_flags[] = {
- // these in the first group put a value in bits0-3 of dictionary_flags
- {"$1", 0x41}, // stress on 1st syllable
- {"$2", 0x42}, // stress on 2nd syllable
- {"$3", 0x43},
- {"$4", 0x44},
- {"$5", 0x45},
- {"$6", 0x46},
- {"$7", 0x47},
- {"$u", 0x48}, // reduce to unstressed
- {"$u1", 0x49},
- {"$u2", 0x4a},
- {"$u3", 0x4b},
- {"$u+", 0x4c}, // reduce to unstressed, but stress at end of clause
- {"$u1+", 0x4d},
- {"$u2+", 0x4e},
- {"$u3+", 0x4f},
-
-
- // these set the corresponding numbered bit if dictionary_flags
- {"$pause", 8}, /* ensure pause before this word */
- {"$only", 9}, /* only match on this word without suffix */
- {"$onlys", 10}, /* only match with none, or with 's' suffix */
- {"$strend", 11}, /* full stress if at end of clause */
- {"$strend2", 12}, /* full stress if at end of clause, or only followed by unstressed */
- {"$unstressend",13}, /* reduce stress at end of clause */
- {"$atend", 14}, /* use this pronunciation if at end of clause */
-
- {"$dot", 16}, /* ignore '.' after this word (abbreviation) */
- {"$abbrev", 17}, /* use this pronuciation rather than split into letters */
- {"$stem", 18}, // must have a suffix
-
-// language specific
- {"$double", 19}, // IT double the initial consonant of next word
- {"$alt", 20}, // use alternative pronunciation
- {"$alt2", 21},
-
-
- {"$max3", 27}, // limit to 3 repetitions
- {"$brk", 28}, // a shorter $pause
- {"$text", 29}, // word translates to replcement text, not phonemes
-
-// flags in dictionary word 2
- {"$verbf", 0x20}, /* verb follows */
- {"$verbsf", 0x21}, /* verb follows, allow -s suffix */
- {"$nounf", 0x22}, /* noun follows */
- {"$pastf", 0x23}, /* past tense follows */
- {"$verb", 0x24}, /* use this pronunciation when its a verb */
- {"$noun", 0x25}, /* use this pronunciation when its a noun */
- {"$past", 0x26}, /* use this pronunciation when its past tense */
- {"$verbextend",0x28}, /* extend influence of 'verb follows' */
- {"$capital", 0x29}, /* use this pronunciation if initial letter is upper case */
- {"$allcaps", 0x2a}, /* use this pronunciation if initial letter is upper case */
- {"$accent", 0x2b}, // character name is base-character name + accent name
-
- // doesn't set dictionary_flags
- {"$?", 100}, // conditional rule, followed by byte giving the condition number
-
- {"$textmode", 200},
- {"$phonememode", 201},
- {NULL, -1}
-};
-
-
-#define LEN_GROUP_NAME 12
-
-typedef struct {
- char name[LEN_GROUP_NAME+1];
- unsigned int start;
- unsigned int length;
-} RGROUP;
-
-
-int isspace2(unsigned int c)
-{//=========================
-// can't use isspace() because on Windows, isspace(0xe1) gives TRUE !
- int c2;
-
- if(((c2 = (c & 0xff)) == 0) || (c > ' '))
- return(0);
- return(1);
-}
-
-
-static const char *LookupMnem2(MNEM_TAB *table, int value)
-{//=======================================================
- while(table->mnem != NULL)
- {
- if(table->value == value)
- return(table->mnem);
- table++;
- }
- return("");
-}
-
-
-char *print_dictionary_flags(unsigned int *flags)
-{//==============================================
- static char buf[20];
-
- sprintf(buf,"%s 0x%x/%x",LookupMnem2(mnem_flags,(flags[0] & 0xf)+0x40), flags[0], flags[1]);
- return(buf);
-}
-
-
-
-static FILE *fopen_log(const char *fname,const char *access)
-{//==================================================
-// performs fopen, but produces error message to f_log if it fails
- FILE *f;
-
- if((f = fopen(fname,access)) == NULL)
- {
- if(f_log != NULL)
- fprintf(f_log,"Can't access (%s) file '%s'\n",access,fname);
- }
- return(f);
-}
-
-
-#ifdef OPT_FORMAT
-static const char *lookup_mnem(MNEM_TAB *table, int value)
-//========================================================
-/* Lookup a mnemonic string in a table, return its name */
-{
- while(table->mnem != NULL)
- {
- if(table->value==value)
- return(table->mnem);
- table++;
- }
- return("??"); /* not found */
-} /* end of mnem */
-#endif
-
-
-
-
-static int compile_line(char *linebuf, char *dict_line, int *hash)
-{//===============================================================
-// Compile a line in the language_list file
- unsigned char c;
- char *p;
- char *word;
- char *phonetic;
- unsigned int ix;
- int step;
- unsigned int n_flag_codes = 0;
- int flag_offset;
- int length;
- int multiple_words = 0;
- int multiple_numeric_hyphen = 0;
- char *multiple_string = NULL;
- char *multiple_string_end = NULL;
-
- int len_word;
- int len_phonetic;
- int text_not_phonemes; // this word specifies replacement text, not phonemes
- unsigned int wc;
- int all_upper_case;
-
- char *mnemptr;
- char *comment;
- unsigned char flag_codes[100];
- char encoded_ph[200];
- unsigned char bad_phoneme[4];
-static char nullstring[] = {0};
-
- comment = NULL;
- text_not_phonemes = 0;
- phonetic = word = nullstring;
-
-if(memcmp(linebuf,"_-",2)==0)
-{
-step=1; // TEST
-}
- p = linebuf;
-// while(isspace2(*p)) p++;
-
-#ifdef deleted
- if(*p == '$')
- {
- if(memcmp(p,"$textmode",9) == 0)
- {
- text_mode = 1;
- return(0);
- }
- if(memcmp(p,"$phonememode",12) == 0)
- {
- text_mode = 0;
- return(0);
- }
- }
-#endif
-
- step = 0;
-
- c = 0;
- while(c != '\n')
- {
- c = *p;
-
- if((c == '?') && (step==0))
- {
- // conditional rule, allow only if the numbered condition is set for the voice
- flag_offset = 100;
-
- p++;
- if(*p == '!')
- {
- // allow only if the numbered condition is NOT set
- flag_offset = 132;
- p++;
- }
-
- ix = 0;
- if(isdigit(*p))
- {
- ix += (*p-'0');
- p++;
- }
- if(isdigit(*p))
- {
- ix = ix*10 + (*p-'0');
- p++;
- }
- flag_codes[n_flag_codes++] = ix + flag_offset;
- c = *p;
- }
-
- if((c == '$') && isalnum(p[1]))
- {
- /* read keyword parameter */
- mnemptr = p;
- while(!isspace2(c = *p)) p++;
- *p = 0;
-
- ix = LookupMnem(mnem_flags,mnemptr);
- if(ix > 0)
- {
- if(ix == 200)
- {
- text_mode = 1;
- }
- else
- if(ix == 201)
- {
- text_mode = 0;
- }
- else
- if(ix == BITNUM_FLAG_TEXTMODE)
- {
- text_not_phonemes = 1;
- }
- else
- {
- flag_codes[n_flag_codes++] = ix;
- }
- }
- else
- {
- fprintf(f_log,"%5d: Unknown keyword: %s\n",linenum,mnemptr);
- error_count++;
- }
- }
-
- if((c == '/') && (p[1] == '/') && (multiple_words==0))
- {
- c = '\n'; /* "//" treat comment as end of line */
- comment = p;
- }
-
- switch(step)
- {
- case 0:
- if(c == '(')
- {
- multiple_words = 1;
- word = p+1;
- step = 1;
- }
- else
- if(!isspace2(c))
- {
- word = p;
- step = 1;
- }
- break;
-
- case 1:
- if((c == '-') && (word[0] != '_'))
- {
- if(isdigit(word[0]))
- {
- multiple_numeric_hyphen = 1;
- }
- else
- {
- flag_codes[n_flag_codes++] = BITNUM_FLAG_HYPHENATED;
- }
- c = ' ';
- }
- if(isspace2(c))
- {
- p[0] = 0; /* terminate english word */
-
- if(multiple_words)
- {
- multiple_string = multiple_string_end = p+1;
- step = 2;
- }
- else
- {
- step = 3;
- }
- }
- else
- if((c == ')') && multiple_words)
- {
- p[0] = 0;
- step = 3;
- multiple_words = 0;
- }
- break;
-
- case 2:
- if(isspace2(c))
- {
- multiple_words++;
- }
- else
- if(c == ')')
- {
- p[0] = ' '; // terminate extra string
- multiple_string_end = p+1;
- step = 3;
- }
- break;
-
- case 3:
- if(!isspace2(c))
- {
- phonetic = p;
- step = 4;
- }
- break;
-
- case 4:
- if(isspace2(c))
- {
- p[0] = 0; /* terminate phonetic */
- step = 5;
- }
- break;
-
- case 5:
- break;
- }
- p++;
- }
-
- if(word[0] == 0)
- {
-#ifdef OPT_FORMAT
- if(comment != NULL)
- fprintf(f_log,"%s",comment);
- else
- fputc('\n',f_log);
-#endif
- return(0); /* blank line */
- }
-
- if(text_mode)
- text_not_phonemes = 1;
-
- if(text_not_phonemes != translator->langopts.textmode)
- {
- flag_codes[n_flag_codes++] = BITNUM_FLAG_TEXTMODE;
- }
-
- if(text_not_phonemes)
- {
- // this is replacement text, so don't encode as phonemes. Restrict the length of the replacement word
- strncpy0(encoded_ph,phonetic,N_WORD_BYTES-4);
- }
- else
- {
- EncodePhonemes(phonetic,encoded_ph,bad_phoneme);
- if(strchr(encoded_ph,phonSWITCH) != 0)
- {
- flag_codes[n_flag_codes++] = BITNUM_FLAG_ONLY_S; // don't match on suffixes (except 's') when switching languages
- }
-
- // check for errors in the phonemes codes
- for(ix=0; ix<sizeof(encoded_ph); ix++)
- {
- c = encoded_ph[ix];
- if(c == 0) break;
-
- if(c == 255)
- {
- /* unrecognised phoneme, report error */
- fprintf(f_log,"%5d: Bad phoneme [%c] (0x%x) in: %s %s\n",linenum,bad_phoneme[0],bad_phoneme[0],word,phonetic);
- error_count++;
- }
- }
- }
-
- if(sscanf(word,"U+%x",&wc) == 1)
- {
- // Character code
- ix = utf8_out(wc, word);
- word[ix] = 0;
- }
- else
- if(word[0] != '_')
- {
- // convert to lower case, and note if the word is all-capitals
- int c2;
-
- all_upper_case = 1;
- p = word;
- for(p=word;;)
- {
- // this assumes that the lower case char is the same length as the upper case char
- // OK, except for Turkish "I", but use towlower() rather than towlower2()
- ix = utf8_in(&c2,p);
- if(c2 == 0)
- break;
- if(iswupper(c2))
- {
- utf8_out(towlower(c2),p);
- }
- else
- {
- all_upper_case = 0;
- }
- p += ix;
- }
- if(all_upper_case)
- {
- flag_codes[n_flag_codes++] = BITNUM_FLAG_ALLCAPS;
- }
- }
-
- len_word = strlen(word);
-
- if(transpose_offset > 0)
- {
- len_word = TransposeAlphabet(word, transpose_offset, transpose_min, transpose_max);
- }
-
- *hash = HashDictionary(word);
- len_phonetic = strlen(encoded_ph);
-
- dict_line[1] = len_word; // bit 6 indicates whether the word has been compressed
- len_word &= 0x3f;
-
- memcpy(&dict_line[2],word,len_word);
-
- if(len_phonetic == 0)
- {
- // no phonemes specified. set bit 7
- dict_line[1] |= 0x80;
- length = len_word + 2;
- }
- else
- {
- length = len_word + len_phonetic + 3;
- strcpy(&dict_line[(len_word)+2],encoded_ph);
- }
-
- for(ix=0; ix<n_flag_codes; ix++)
- {
- dict_line[ix+length] = flag_codes[ix];
- }
- length += n_flag_codes;
-
- if((multiple_string != NULL) && (multiple_words > 0))
- {
- if(multiple_words > 10)
- {
- fprintf(f_log,"%5d: Two many parts in a multi-word entry: %d\n",linenum,multiple_words);
- }
- else
- {
- dict_line[length++] = 80 + multiple_words + multiple_numeric_hyphen; // if numeric, count a hyphen as an extra word
- ix = multiple_string_end - multiple_string;
- if(multiple_numeric_hyphen)
- {
- // the first part is numeric, so keep the hyphen to match on
- dict_line[length++] = '-';
- dict_line[length++] = ' ';
- }
- memcpy(&dict_line[length],multiple_string,ix);
- length += ix;
- }
- }
- dict_line[0] = length;
-
-#ifdef OPT_FORMAT
- spaces = 16;
- for(ix=0; ix<n_flag_codes; ix++)
- {
- if(flag_codes[ix] >= 100)
- {
- fprintf(f_log,"?%d ",flag_codes[ix]-100);
- spaces -= 3;
- }
- }
-
- fprintf(f_log,"%s",word);
- spaces -= strlen(word);
- DecodePhonemes(encoded_ph,decoded_ph);
- while(spaces-- > 0) fputc(' ',f_log);
- spaces += (14 - strlen(decoded_ph));
-
- fprintf(f_log," %s",decoded_ph);
- while(spaces-- > 0) fputc(' ',f_log);
- for(ix=0; ix<n_flag_codes; ix++)
- {
- if(flag_codes[ix] < 100)
- fprintf(f_log," %s",lookup_mnem(mnem_flags,flag_codes[ix]));
- }
- if(comment != NULL)
- fprintf(f_log," %s",comment);
- else
- fputc('\n',f_log);
-#endif
-
- return(length);
-} /* end of compile_line */
-
-
-
-static void compile_dictlist_start(void)
-{//=====================================
-// initialise dictionary list
- int ix;
- char *p;
- char *p2;
-
- for(ix=0; ix<N_HASH_DICT; ix++)
- {
- p = hash_chains[ix];
- while(p != NULL)
- {
- memcpy(&p2,p,sizeof(char *));
- free(p);
- p = p2;
- }
- hash_chains[ix] = NULL;
- hash_counts[ix]=0;
- }
-}
-
-
-static void compile_dictlist_end(FILE *f_out)
-{//==========================================
-// Write out the compiled dictionary list
- int hash;
- int length;
- char *p;
-
- if(f_log != NULL)
- {
-#ifdef OUTPUT_FORMAT
- for(hash=0; hash<N_HASH_DICT; hash++)
- {
- fprintf(f_log,"%8d",hash_counts[hash]);
- if((hash & 7) == 7)
- fputc('\n',f_log);
- }
- fflush(f_log);
-#endif
- }
-
- for(hash=0; hash<N_HASH_DICT; hash++)
- {
- p = hash_chains[hash];
- hash_counts[hash] = (int)ftell(f_out);
-
- while(p != NULL)
- {
- length = *(p+sizeof(char *));
- fwrite(p+sizeof(char *),length,1,f_out);
- memcpy(&p,p,sizeof(char *));
- }
- fputc(0,f_out);
- }
-}
-
-
-
-static int compile_dictlist_file(const char *path, const char* filename)
-{//=====================================================================
- int length;
- int hash;
- char *p;
- int count=0;
- FILE *f_in;
- char buf[200];
- char fname[sizeof(path_home)+45];
- char dict_line[128];
-
- text_mode = 0;
-
- sprintf(fname,"%s%s",path,filename);
- if((f_in = fopen(fname,"r")) == NULL)
- return(-1);
-
- fprintf(f_log,"Compiling: '%s'\n",fname);
-
- linenum=0;
-
- while(fgets(buf,sizeof(buf),f_in) != NULL)
- {
- linenum++;
-
- length = compile_line(buf,dict_line,&hash);
- if(length == 0) continue; /* blank line */
-
- hash_counts[hash]++;
-
- p = (char *)malloc(length+sizeof(char *));
- if(p == NULL)
- {
- if(f_log != NULL)
- {
- fprintf(f_log,"Can't allocate memory\n");
- error_count++;
- }
- break;
- }
-
- memcpy(p,&hash_chains[hash],sizeof(char *));
- hash_chains[hash] = p;
- memcpy(p+sizeof(char *),dict_line,length);
- count++;
- }
-
- fprintf(f_log,"\t%d entries\n",count);
- fclose(f_in);
- return(0);
-} /* end of compile_dictlist_file */
-
-
-
-static char rule_cond[80];
-static char rule_pre[80];
-static char rule_post[80];
-static char rule_match[80];
-static char rule_phonemes[80];
-static char group_name[LEN_GROUP_NAME+1];
-
-#define N_RULES 2000 // max rules for each group
-
-
-
-static void copy_rule_string(char *string, int *state)
-{//===================================================
-// state 0: conditional, 1=pre, 2=match, 3=post, 4=phonemes
- static char *outbuf[5] = {rule_cond, rule_pre, rule_match, rule_post, rule_phonemes};
- static int next_state[5] = {2,2,4,4,4};
- char *output;
- char *p;
- int ix;
- int len;
- char c;
- int sxflags;
- int value;
- int literal;
-
- if(string[0] == 0) return;
-
- output = outbuf[*state];
- if(*state==4)
- {
- // append to any previous phoneme string, i.e. allow spaces in the phoneme string
- len = strlen(rule_phonemes);
- if(len > 0)
- rule_phonemes[len++] = ' ';
- output = &rule_phonemes[len];
- }
- sxflags = 0x808000; // to ensure non-zero bytes
-
- for(p=string,ix=0;;)
- {
- literal = 0;
- c = *p++;
- if(c == '\\')
- {
- c = *p++; // treat next character literally
- if((c >= '0') && (c <= '3') && (p[0] >= '0') && (p[0] <= '7') && (p[1] >= '0') && (p[1] <= '7'))
- {
- // character code given by 3 digit octal value;
- c = (c-'0')*64 + (p[0]-'0')*8 + (p[1]-'0');
- p += 2;
- }
- literal = 1;
- }
-
- if(((*state)==1) || ((*state)==3))
- {
- // replace special characters (note: 'E' is reserved for a replaced silent 'e')
- if(literal == 0)
- {
- static const char lettergp_letters[9] = {LETTERGP_A,LETTERGP_B,LETTERGP_C,0,0,LETTERGP_F,LETTERGP_G,LETTERGP_H,LETTERGP_Y};
- switch(c)
- {
- case '_':
- c = RULE_SPACE;
- break;
-
- case 'Y':
- c = 'I'; // drop through to next case
- case 'A': // vowel
- case 'B':
- case 'C':
- case 'H':
- case 'F':
- case 'G':
- if((*state) == 1)
- {
- // pre-rule, put the number before the RULE_LETTERGP;
- output[ix++] = lettergp_letters[c-'A'] + 'A';
- c = RULE_LETTERGP;
- }
- else
- {
- output[ix++] = RULE_LETTERGP;
- c = lettergp_letters[c-'A'] + 'A';
- }
- break;
- case 'D':
- c = RULE_DIGIT;
- break;
- case 'K':
- c = RULE_NOTVOWEL;
- break;
- case 'N':
- c = RULE_NO_SUFFIX;
- break;
- case 'V':
- c = RULE_IFVERB;
- break;
- case 'Z':
- c = RULE_NONALPHA;
- break;
- case '+':
- c = RULE_INC_SCORE;
- break;
- case '@':
- c = RULE_SYLLABLE;
- break;
- case '&':
- c = RULE_STRESSED;
- break;
- case '%':
- c = RULE_DOUBLE;
- break;
- case '#':
- c = RULE_DEL_FWD;
- break;
- case '!':
- c = RULE_CAPITAL;
- break;
- case 'T':
- c = RULE_ALT1;
- break;
- case 'W':
- c = RULE_SPELLING;
- break;
- case 'X':
- c = RULE_NOVOWELS;
- break;
- case 'L':
- // expect two digits
- c = *p++ - '0';
- value = *p++ - '0';
- c = c * 10 + value;
- if((value < 0) || (value > 9))
- {
- c = 0;
- fprintf(f_log,"%5d: Expected 2 digits after 'L'\n",linenum);
- error_count++;
- }
- else
- if((c <= 0) || (c >= N_LETTER_GROUPS) || (letterGroupsDefined[(int)c] == 0))
- {
- fprintf(f_log,"%5d: Letter group L%.2d not defined\n",linenum,c);
- error_count++;
- }
- c += 'A';
- if((*state) == 1)
- {
- // pre-rule, put the group number before the RULE_LETTERGP command
- output[ix++] = c;
- c = RULE_LETTERGP2;
- }
- else
- {
- output[ix++] = RULE_LETTERGP2;
- }
- break;
-
- case '$': // obsolete, replaced by S
- fprintf(f_log,"%5d: $ now not allowed, use S for suffix",linenum);
- error_count++;
- break;
- case 'P':
- sxflags |= SUFX_P; // Prefix, now drop through to Suffix
- case 'S':
- output[ix++] = RULE_ENDING;
- value = 0;
- while(!isspace2(c = *p++) && (c != 0))
- {
- switch(c)
- {
- case 'e':
- sxflags |= SUFX_E;
- break;
- case 'i':
- sxflags |= SUFX_I;
- break;
- case 'p': // obsolete, replaced by 'P' above
- sxflags |= SUFX_P;
- break;
- case 'v':
- sxflags |= SUFX_V;
- break;
- case 'd':
- sxflags |= SUFX_D;
- break;
- case 'f':
- sxflags |= SUFX_F;
- break;
- case 'q':
- sxflags |= SUFX_Q;
- break;
- case 't':
- sxflags |= SUFX_T;
- break;
- case 'b':
- sxflags |= SUFX_B;
- break;
- default:
- if(isdigit(c))
- value = (value*10) + (c - '0');
- break;
- }
- }
- p--;
- output[ix++] = sxflags >> 16;
- output[ix++] = sxflags >> 8;
- c = value | 0x80;
- break;
- }
- }
- }
- output[ix++] = c;
- if(c == 0) break;
- }
-
- *state = next_state[*state];
-} // end of copy_rule_string
-
-
-
-static char *compile_rule(char *input)
-{//===================================
- int ix;
- unsigned char c;
- int wc;
- char *p;
- char *prule;
- int len;
- int len_name;
- int state=2;
- int finish=0;
- int pre_bracket=0;
- char buf[80];
- char output[150];
- unsigned char bad_phoneme[4];
-
- buf[0]=0;
- rule_cond[0]=0;
- rule_pre[0]=0;
- rule_post[0]=0;
- rule_match[0]=0;
- rule_phonemes[0]=0;
-
- p = buf;
-
- for(ix=0; finish==0; ix++)
- {
- c = input[ix];
-
- switch(c = input[ix])
- {
- case ')': // end of prefix section
- *p = 0;
- state = 1;
- pre_bracket = 1;
- copy_rule_string(buf,&state);
- p = buf;
- break;
-
- case '(': // start of suffix section
- *p = 0;
- state = 2;
- copy_rule_string(buf,&state);
- state = 3;
- p = buf;
- break;
-
- case '\n': // end of line
- case '\r':
- case 0: // end of line
- *p = 0;
- copy_rule_string(buf,&state);
- finish=1;
- break;
-
- case '\t': // end of section section
- case ' ':
- *p = 0;
- copy_rule_string(buf,&state);
- p = buf;
- break;
-
- case '?':
- if(state==2)
- state=0;
- else
- *p++ = c;
- break;
-
- default:
- *p++ = c;
- break;
- }
- }
-
- if(strcmp(rule_match,"$group")==0)
- strcpy(rule_match,group_name);
-
- if(rule_match[0]==0)
- return(NULL);
-
- EncodePhonemes(rule_phonemes,buf,bad_phoneme);
- for(ix=0;; ix++)
- {
- if((c = buf[ix])==0) break;
- if(c==255)
- {
- fprintf(f_log,"%5d: Bad phoneme [%c] in %s",linenum,bad_phoneme[0],input);
- error_count++;
- break;
- }
- }
- strcpy(output,buf);
- len = strlen(buf)+1;
-
- len_name = strlen(group_name);
- if((len_name > 0) && (memcmp(rule_match,group_name,len_name) != 0))
- {
- utf8_in(&wc,rule_match);
- if((group_name[0] == '9') && IsDigit(wc))
- {
- // numeric group, rule_match starts with a digit, so OK
- }
- else
- {
- fprintf(f_log,"%5d: Wrong initial letters '%s' for group '%s'\n",linenum,rule_match,group_name);
- error_count++;
- }
- }
- strcpy(&output[len],rule_match);
- len += strlen(rule_match);
-
- if(debug_flag)
- {
- output[len] = RULE_LINENUM;
- output[len+1] = (linenum % 255) + 1;
- output[len+2] = (linenum / 255) + 1;
- len+=3;
- }
-
- if(rule_cond[0] != 0)
- {
- ix = -1;
- if(rule_cond[0] == '!')
- {
- // allow the rule only if the condition number is NOT set for the voice
- ix = atoi(&rule_cond[1]) + 32;
- }
- else
- {
- // allow the rule only if the condition number is set for the voice
- ix = atoi(rule_cond);
- }
-
- if((ix > 0) && (ix < 255))
- {
- output[len++] = RULE_CONDITION;
- output[len++] = ix;
- }
- else
- {
- fprintf(f_log,"%5d: bad condition number ?%d\n",linenum,ix);
- error_count++;
- }
- }
- if(rule_pre[0] != 0)
- {
- output[len++] = RULE_PRE;
- // output PRE string in reverse order
- for(ix = strlen(rule_pre)-1; ix>=0; ix--)
- output[len++] = rule_pre[ix];
- }
-
- if(rule_post[0] != 0)
- {
- sprintf(&output[len],"%c%s",RULE_POST,rule_post);
- len += (strlen(rule_post)+1);
- }
- output[len++]=0;
- prule = (char *)malloc(len);
- memcpy(prule,output,len);
- return(prule);
-} // end of compile_rule
-
-
-static int __cdecl string_sorter(char **a, char **b)
-{//=================================================
- char *pa, *pb;
- int ix;
-
- if((ix = strcmp(pa = *a,pb = *b)) != 0)
- return(ix);
- pa += (strlen(pa)+1);
- pb += (strlen(pb)+1);
- return(strcmp(pa,pb));
-} /* end of string_sorter */
-
-
-static int __cdecl rgroup_sorter(RGROUP *a, RGROUP *b)
-{//===================================================
- int ix;
- ix = strcmp(a->name,b->name);
- if(ix != 0) return(ix);
- return(a->start-b->start);
-}
-
-
-#ifdef OUTPUT_FORMAT
-static void print_rule_group(FILE *f_out, int n_rules, char **rules, char *name)
-{//=============================================================================
- int rule;
- int ix;
- unsigned char c;
- int len1;
- int len2;
- int spaces;
- char *p;
- char *pout;
- int condition;
- char buf[80];
- char suffix[12];
-
- static unsigned char symbols[] = {'@','&','%','+','#','$','D','Z','A','B','C','F'};
-
- fprintf(f_out,"\n$group %s\n",name);
-
- for(rule=0; rule<n_rules; rule++)
- {
- p = rules[rule];
- len1 = strlen(p) + 1;
- p = &p[len1];
- len2 = strlen(p);
-
- rule_match[0]=0;
- rule_pre[0]=0;
- rule_post[0]=0;
- condition = 0;
-
- pout = rule_match;
- for(ix=0; ix<len2; ix++)
- {
- switch(c = p[ix])
- {
- case RULE_PRE:
- *pout = 0;
- pout = rule_pre;
- break;
- case RULE_POST:
- *pout = 0;
- pout = rule_post;
- break;
- case RULE_CONDITION:
- condition = p[++ix];
- break;
- case RULE_ENDING:
- sprintf(suffix,"$%d[%x]",(p[ix+2]),p[ix+1] & 0x7f);
- ix += 2;
- strcpy(pout,suffix);
- pout += strlen(suffix);
- break;
- default:
- if(c <= RULE_LETTER7)
- c = symbols[c-RULE_SYLLABLE];
- if(c == ' ')
- c = '_';
- *pout++ = c;
- break;
- }
- }
- *pout = 0;
-
- spaces = 12;
- if(condition > 0)
- {
- sprintf(buf,"?%d ",condition);
- spaces -= strlen(buf);
- fprintf(f_out,"%s",buf);
- }
-
- if(rule_pre[0] != 0)
- {
- p = buf;
- for(ix=strlen(rule_pre)-1;ix>=0;ix--)
- *p++ = rule_pre[ix];
- sprintf(p,") ");
- spaces -= strlen(buf);
- for(ix=0; ix<spaces; ix++)
- fputc(' ',f_out);
- fprintf(f_out,"%s",buf);
- spaces = 0;
- }
-
- for(ix=0; ix<spaces; ix++)
- fputc(' ',f_out);
-
- spaces = 14;
- sprintf(buf," %s ",rule_match);
- if(rule_post[0] != 0)
- {
- p = &buf[strlen(buf)];
- sprintf(p,"(%s ",rule_post);
- }
- fprintf(f_out,"%s",buf);
- spaces -= strlen(buf);
-
- for(ix=0; ix<spaces; ix++)
- fputc(' ',f_out);
- DecodePhonemes(rules[rule],buf);
- fprintf(f_out,"%s\n",buf); // phonemes
- }
-}
-#endif
-
-
-//#define LIST_GROUP_INFO
-static void output_rule_group(FILE *f_out, int n_rules, char **rules, char *name)
-{//==============================================================================
- int ix;
- int len1;
- int len2;
- int len_name;
- char *p;
- char *p2, *p3;
- const char *common;
-
- short nextchar_count[256];
- memset(nextchar_count,0,sizeof(nextchar_count));
-
- len_name = strlen(name);
-
-#ifdef OUTPUT_FORMAT
- print_rule_group(f_log,n_rules,rules,name);
-#endif
-
- // sort the rules in this group by their phoneme string
- common = "";
- qsort((void *)rules,n_rules,sizeof(char *),(int (__cdecl *)(const void *,const void *))string_sorter);
-
- if(strcmp(name,"9")==0)
- len_name = 0; // don't remove characters from numeric match strings
-
- for(ix=0; ix<n_rules; ix++)
- {
- p = rules[ix];
- len1 = strlen(p) + 1; // phoneme string
- p3 = &p[len1];
- p2 = p3 + len_name; // remove group name from start of match string
- len2 = strlen(p2);
-
- nextchar_count[(unsigned char)(p2[0])]++; // the next byte after the group name
-
- if((common[0] != 0) && (strcmp(p,common)==0))
- {
- fwrite(p2,len2,1,f_out);
- fputc(0,f_out); // no phoneme string, it's the same as previous rule
- }
- else
- {
- if((ix < n_rules-1) && (strcmp(p,rules[ix+1])==0))
- {
- common = rules[ix]; // phoneme string is same as next, set as common
- fputc(RULE_PH_COMMON,f_out);
- }
-
- fwrite(p2,len2,1,f_out);
- fputc(RULE_PHONEMES,f_out);
- fwrite(p,len1,1,f_out);
- }
- }
-
-#ifdef LIST_GROUP_INFO
- for(ix=32; ix<256; ix++)
- {
- if(nextchar_count[ix] > 30)
- printf("Group %s %c %d\n",name,ix,nextchar_count[ix]);
- }
-#endif
-} // end of output_rule_group
-
-
-
-static int compile_lettergroup(char *input, FILE *f_out)
-{//=====================================================
- char *p;
- char *p_start;
- int group;
- int ix;
- int n_items;
- int length;
- int max_length = 0;
-
- #define N_LETTERGP_ITEMS 200
- char *items[N_LETTERGP_ITEMS];
- char item_length[N_LETTERGP_ITEMS];
-
- p = input;
- if(!isdigit(p[0]) || !isdigit(p[1]))
- {
- fprintf(f_log,"%5d: Expected 2 digits after '.L'\n",linenum);
- error_count++;
- return(1);
- }
-
- group = atoi(&p[0]);
- if(group >= N_LETTER_GROUPS)
- {
- fprintf(f_log,"%5d: lettergroup out of range (01-%.2d)\n",linenum,N_LETTER_GROUPS-1);
- error_count++;
- return(1);
- }
-
- while(!isspace2(*p)) p++;
-
- fputc(RULE_GROUP_START,f_out);
- fputc(RULE_LETTERGP2,f_out);
- fputc(group + 'A', f_out);
- if(letterGroupsDefined[group] != 0)
- {
- fprintf(f_log,"%5d: lettergroup L%.2d is already defined\n",linenum,group);
- error_count++;
- }
- letterGroupsDefined[group] = 1;
-
- n_items = 0;
- while(n_items < N_LETTERGP_ITEMS)
- {
- while(isspace2(*p)) p++;
- if(*p == 0)
- break;
-
- items[n_items] = p_start = p;
- while((*p & 0xff) > ' ')
- {
- p++;
- }
- *p++ = 0;
- length = p - p_start;
- if(length > max_length)
- max_length = length;
- item_length[n_items++] = length;
- }
-
- // write out the items, longest first
- while(max_length > 1)
- {
- for(ix=0; ix < n_items; ix++)
- {
- if(item_length[ix] == max_length)
- {
- fwrite(items[ix],1,max_length,f_out);
- }
- }
- max_length--;
- }
-
- fputc(RULE_GROUP_END,f_out);
-
- return(0);
-}
-
-
-static int compile_dictrules(FILE *f_in, FILE *f_out, char *fname_temp)
-{//====================================================================
- char *prule;
- unsigned char *p;
- int ix;
- int c;
- int gp;
- FILE *f_temp;
- int n_rules=0;
- int count=0;
- int different;
- const char *prev_rgroup_name;
- unsigned int char_code;
- int compile_mode=0;
- char *buf;
- char buf1[200];
- char *rules[N_RULES];
-
- int n_rgroups = 0;
- RGROUP rgroup[N_RULE_GROUP2];
-
- linenum = 0;
- group_name[0] = 0;
-
- if((f_temp = fopen_log(fname_temp,"wb")) == NULL)
- return(1);
-
- for(;;)
- {
- linenum++;
- buf = fgets(buf1,sizeof(buf1),f_in);
- if(buf != NULL)
- {
- if((p = (unsigned char *)strstr(buf,"//")) != NULL)
- *p = 0;
-
- if(buf[0] == '\r') buf++; // ignore extra \r in \r\n
- }
-
- if((buf == NULL) || (buf[0] == '.'))
- {
- // next .group or end of file, write out the previous group
-
- if(n_rules > 0)
- {
- strcpy(rgroup[n_rgroups].name,group_name);
- rgroup[n_rgroups].start = ftell(f_temp);
- output_rule_group(f_temp,n_rules,rules,group_name);
- rgroup[n_rgroups].length = ftell(f_temp) - rgroup[n_rgroups].start;
- n_rgroups++;
-
- count += n_rules;
- }
- n_rules = 0;
-
- if(compile_mode == 2)
- {
- // end of the character replacements section
- fwrite(&n_rules,1,4,f_out); // write a zero word to terminate the replacemenmt list
- compile_mode = 0;
- }
-
- if(buf == NULL) break; // end of file
-
- if(memcmp(buf,".L",2)==0)
- {
- compile_lettergroup(&buf[2], f_out);
- continue;
- }
-
- if(memcmp(buf,".replace",8)==0)
- {
- compile_mode = 2;
- fputc(RULE_GROUP_START,f_out);
- fputc(RULE_REPLACEMENTS,f_out);
-
- // advance to next word boundary
- while((ftell(f_out) & 3) != 0)
- fputc(0,f_out);
- }
-
- if(memcmp(buf,".group",6)==0)
- {
- compile_mode = 1;
-
- p = (unsigned char *)&buf[6];
- while((p[0]==' ') || (p[0]=='\t')) p++; // Note: Windows isspace(0xe1) gives TRUE !
- ix = 0;
- while((*p > ' ') && (ix < LEN_GROUP_NAME))
- group_name[ix++] = *p++;
- group_name[ix]=0;
-
- if(sscanf(group_name,"0x%x",&char_code)==1)
- {
- // group character is given as a character code (max 16 bits)
- p = (unsigned char *)group_name;
-
- if(char_code > 0x100)
- {
- *p++ = (char_code >> 8);
- }
- *p++ = char_code;
- *p = 0;
- }
-
- if(strlen(group_name) > 2)
- {
- if(utf8_in(&c,group_name) < 2)
- {
- fprintf(f_log,"%5d: Group name longer than 2 bytes (UTF8)",linenum);
- error_count++;
- }
-
- group_name[2] = 0;
- }
- }
-
- continue;
- }
-
- switch(compile_mode)
- {
- case 1: // .group
- prule = compile_rule(buf);
- if((prule != NULL) && (n_rules < N_RULES))
- {
- rules[n_rules++] = prule;
- }
- break;
-
- case 2: // .replace
- {
- int replace1;
- int replace2;
- char *p;
-
- p = buf;
- replace1 = 0;
- replace2 = 0;
- while(isspace2(*p)) p++;
- ix = 0;
- while((unsigned char)(*p) > 0x20) // not space or zero-byte
- {
- p += utf8_in(&c,p);
- replace1 += (c << ix);
- ix += 16;
- }
- while(isspace2(*p)) p++;
- ix = 0;
- while((unsigned char)(*p) > 0x20)
- {
- p += utf8_in(&c,p);
- replace2 += (c << ix);
- ix += 16;
- }
- if(replace1 != 0)
- {
- Write4Bytes(f_out,replace1); // write as little-endian
- Write4Bytes(f_out,replace2); // if big-endian, reverse the bytes in LoadDictionary()
- }
- }
- break;
- }
- }
- fclose(f_temp);
-
- qsort((void *)rgroup,n_rgroups,sizeof(rgroup[0]),(int (__cdecl *)(const void *,const void *))rgroup_sorter);
-
- if((f_temp = fopen(fname_temp,"rb"))==NULL)
- return(2);
-
- prev_rgroup_name = "\n";
-
- for(gp = 0; gp < n_rgroups; gp++)
- {
- fseek(f_temp,rgroup[gp].start,SEEK_SET);
-
- if((different = strcmp(rgroup[gp].name, prev_rgroup_name)) != 0)
- {
- // not the same as the previous group
- if(gp > 0)
- fputc(RULE_GROUP_END,f_out);
- fputc(RULE_GROUP_START,f_out);
- fprintf(f_out, prev_rgroup_name = rgroup[gp].name);
- fputc(0,f_out);
- }
-
- for(ix=rgroup[gp].length; ix>0; ix--)
- {
- c = fgetc(f_temp);
- fputc(c,f_out);
- }
-
- if(different)
- {
- }
- }
- fputc(RULE_GROUP_END,f_out);
- fputc(0,f_out);
-
- fclose(f_temp);
-#if 0
- remove(fname_temp);
-#endif
-
- fprintf(f_log,"\t%d rules, %d groups\n\n",count,n_rgroups);
- return(0);
-} // end of compile_dictrules
-
-
-
-int CompileDictionary(const char *dsource, const char *dict_name, FILE *log, char *fname_err, int flags)
-{//=====================================================================================================
-// fname: space to write the filename in case of error
-// flags: bit 0: include source line number information, for debug purposes.
-
- FILE *f_in;
- FILE *f_out;
- int offset_rules=0;
- int value;
- char fname_in[sizeof(path_home)+45];
- char fname_out[sizeof(path_home)+15];
- char fname_temp[sizeof(path_home)+15];
- char path[sizeof(path_home)+40]; // path_dsource+20
-
- error_count = 0;
- memset(letterGroupsDefined,0,sizeof(letterGroupsDefined));
-
- debug_flag = flags & 1;
-
- if(dsource == NULL)
- dsource = "";
-
- f_log = log;
-//f_log = fopen("log2.txt","w");
- if(f_log == NULL)
- f_log = stderr;
-
- sprintf(path,"%s%s_",dsource,dict_name);
- sprintf(fname_in,"%srules",path);
- f_in = fopen_log(fname_in,"r");
- if(f_in == NULL)
- {
- if(fname_err)
- strcpy(fname_err,fname_in);
- return(-1);
- }
-
- sprintf(fname_out,"%s%c%s_dict",path_home,PATHSEP,dict_name);
- if((f_out = fopen_log(fname_out,"wb+")) == NULL)
- {
- if(fname_err)
- strcpy(fname_err,fname_in);
- return(-1);
- }
- sprintf(fname_temp,"%s%ctemp",path_home,PATHSEP);
-
- transpose_offset = 0;
-
- if(strcmp(dict_name,"ru") == 0)
- {
- // transpose cyrillic alphabet from unicode to iso8859-5
-// transpose_offset = 0x430-0xd0;
- transpose_offset = 0x42f; // range 0x01 to 0x22
- transpose_min = 0x430;
- transpose_max = 0x451;
- }
-
- value = N_HASH_DICT;
- Write4Bytes(f_out,value);
- Write4Bytes(f_out,offset_rules);
-
- compile_dictlist_start();
-
- fprintf(f_log,"Using phonemetable: '%s'\n",phoneme_tab_list[phoneme_tab_number].name);
- compile_dictlist_file(path,"roots");
- if(translator->langopts.listx)
- {
- compile_dictlist_file(path,"list");
- compile_dictlist_file(path,"listx");
- }
- else
- {
- compile_dictlist_file(path,"listx");
- compile_dictlist_file(path,"list");
- }
- compile_dictlist_file(path,"extra");
-
- compile_dictlist_end(f_out);
- offset_rules = ftell(f_out);
-
- fprintf(f_log,"Compiling: '%s'\n",fname_in);
-
- compile_dictrules(f_in,f_out,fname_temp);
- fclose(f_in);
-
- fseek(f_out,4,SEEK_SET);
- Write4Bytes(f_out,offset_rules);
- fclose(f_out);
-
- LoadDictionary(translator, dict_name, 0);
-
- return(error_count);
-} // end of compile_dictionary
-
diff --git a/navit/support/espeak/debug.c b/navit/support/espeak/debug.c
deleted file mode 100644
index 38ea57c99..000000000
--- a/navit/support/espeak/debug.c
+++ /dev/null
@@ -1,74 +0,0 @@
-#include <stdio.h>
-#include <stdarg.h>
-#include "speech.h"
-#include "debug.h"
-
-#ifdef DEBUG_ENABLED
-#include <sys/time.h>
-#include <unistd.h>
-
-static FILE* fd_log=NULL;
-static const char* FILENAME="/tmp/espeak.log";
-
-void debug_init()
-{
- if((fd_log = fopen(FILENAME,"a")) != NULL)
- setvbuf(fd_log, NULL, _IONBF, 0);
-}
-
-void debug_enter(const char* text)
-{
- struct timeval tv;
-
- gettimeofday(&tv, NULL);
-
- // fd_log = fopen(FILENAME,"a");
- if (!fd_log)
- {
- debug_init();
- }
-
- if (fd_log)
- {
- fprintf(fd_log, "%03d.%03dms > ENTER %s\n",(int)(tv.tv_sec%1000), (int)(tv.tv_usec/1000), text);
- // fclose(fd_log);
- }
-}
-
-
-void debug_show(const char *format, ...)
-{
- va_list args;
- va_start(args, format);
- // fd_log = fopen(FILENAME,"a");
- if (!fd_log)
- {
- debug_init();
- }
- if (fd_log)
- {
- vfprintf(fd_log, format, args);
- // fclose(fd_log);
- }
- va_end(args);
-}
-
-void debug_time(const char* text)
-{
- struct timeval tv;
-
- gettimeofday(&tv, NULL);
-
- // fd_log = fopen(FILENAME,"a");
- if (!fd_log)
- {
- debug_init();
- }
- if (fd_log)
- {
- fprintf(fd_log, "%03d.%03dms > %s\n",(int)(tv.tv_sec%1000), (int)(tv.tv_usec/1000), text);
- // fclose(fd_log);
- }
-}
-
-#endif
diff --git a/navit/support/espeak/debug.h b/navit/support/espeak/debug.h
deleted file mode 100644
index c3fb9c920..000000000
--- a/navit/support/espeak/debug.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef DEBUG_H
-#define DEBUG_H
-
-//#define DEBUG_ENABLED
-
-#ifdef DEBUG_ENABLED
-#define ENTER(text) debug_enter(text)
-#define SHOW(format,...) debug_show(format,__VA_ARGS__);
-#define SHOW_TIME(text) debug_time(text);
-extern void debug_enter(const char* text);
-extern void debug_show(const char* format,...);
-extern void debug_time(const char* text);
-
-#else
-
-#ifdef PLATFORM_WINDOWS
-#define SHOW(format) // VC6 doesn't allow "..."
-#else
-#define SHOW(format,...)
-#endif
-#define SHOW_TIME(text)
-#define ENTER(text)
-#endif
-
-
-#endif
diff --git a/navit/support/espeak/dictionary.c b/navit/support/espeak/dictionary.c
deleted file mode 100755
index d7dd3dc65..000000000
--- a/navit/support/espeak/dictionary.c
+++ /dev/null
@@ -1,3490 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2005 to 2007 by Jonathan Duddington *
- * email: jonsd@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write see: *
- * <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-#include "StdAfx.h"
-
-#define LOG_TRANSLATE
-
-#include <stdio.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <wctype.h>
-#include <wchar.h>
-
-#include "speak_lib.h"
-#include "speech.h"
-#include "phoneme.h"
-#include "synthesize.h"
-#include "translate.h"
-
-
-int dictionary_skipwords;
-char dictionary_name[40];
-
-extern char *print_dictionary_flags(unsigned int *flags);
-
-// accented characters which indicate (in some languages) the start of a separate syllable
-//static const unsigned short diereses_list[7] = {L'ä',L'ë',L'ï',L'ö',L'ü',L'ÿ',0};
-static const unsigned short diereses_list[7] = {0xe4,0xeb,0xef,0xf6,0xfc,0xff,0};
-
-// convert characters to an approximate 7 bit ascii equivalent
-// used for checking for vowels
-static unsigned char remove_accent[] = {
-'a','a','a','a','a','a','a','c','e','e','e','e','i','i','i','i', // 0c0
-'d','n','o','o','o','o','o', 0, 'o','u','u','u','u','y','t','s', // 0d0
-'a','a','a','a','a','a','a','c','e','e','e','e','i','i','i','i', // 0e0
-'d','n','o','o','o','o','o', 0 ,'o','u','u','u','u','y','t','y', // 0f0
-
-'a','a','a','a','a','a','c','c','c','c','c','c','c','c','d','d', // 100
-'d','d','e','e','e','e','e','e','e','e','e','e','g','g','g','g', // 110
-'g','g','g','g','h','h','h','h','i','i','i','i','i','i','i','i', // 120
-'i','i','i','i','j','j','k','k','k','l','l','l','l','l','l','l', // 130
-'l','l','l','n','n','n','n','n','n','n','n','n','o','o','o','o', // 140
-'o','o','o','o','r','r','r','r','r','r','s','s','s','s','s','s', // 150
-'s','s','t','t','t','t','t','t','u','u','u','u','u','u','u','u', // 160
-'u','u','u','u','w','w','y','y','y','z','z','z','z','z','z','s', // 170
-'b','b','b','b', 0, 0, 'o','c','c','d','d','d','d','d','e','e', // 180
-'e','f','f','g','g','h','i','i','k','k','l','l','m','n','n','o', // 190
-'o','o','o','o','p','p','y', 0, 0, 's','s','t','t','t','t','u', // 1a0
-'u','u','v','y','y','z','z','z','z','z','z','z', 0, 0, 0, 'w', // 1b0
-'t','t','t','k','d','d','d','l','l','l','n','n','n','a','a','i', // 1c0
-'i','o','o','u','u','u','u','u','u','u','u','u','u','e','a','a', // 1d0
-'a','a','a','a','g','g','g','g','k','k','o','o','o','o','z','z', // 1e0
-'j','d','d','d','g','g','w','w','n','n','a','a','a','a','o','o', // 1f0
-
-'a','a','a','a','e','e','e','e','i','i','i','i','o','o','o','o', // 200
-'r','r','r','r','u','u','u','u','s','s','t','t','y','y','h','h', // 210
-'n','d','o','o','z','z','a','a','e','e','o','o','o','o','o','o', // 220
-'o','o','y','y','l','n','t','j','d','q','a','c','c','l','t','s', // 230
-'z', 0 };
-
-
-
-
-void strncpy0(char *to,const char *from, int size)
-{//===============================================
- // strcpy with limit, ensures a zero terminator
- strncpy(to,from,size);
- to[size-1] = 0;
-}
-
-
-static int reverse_word_bytes(int word)
-{//=============================
- // reverse the order of bytes from little-endian to big-endian
-#ifdef ARCH_BIG
- int ix;
- int word2 = 0;
-
- for(ix=0; ix<=24; ix+=8)
- {
- word2 = word2 << 8;
- word2 |= (word >> ix) & 0xff;
- }
- return(word2);
-#else
- return(word);
-#endif
-}
-
-
-int LookupMnem(MNEM_TAB *table, char *string)
-{//==========================================
- while(table->mnem != NULL)
- {
- if(strcmp(string,table->mnem)==0)
- return(table->value);
- table++;
- }
- return(table->value);
-}
-
-
-
-//=============================================================================================
-// Read pronunciation rules and pronunciation lookup dictionary
-//
-//=============================================================================================
-
-
-static void InitGroups(Translator *tr)
-{//===================================
-/* Called after dictionary 1 is loaded, to set up table of entry points for translation rule chains
- for single-letters and two-letter combinations
-*/
-
- int ix;
- char *p;
- char *p_name;
- unsigned int *pw;
- unsigned char c, c2;
- int len;
-
- tr->n_groups2 = 0;
- for(ix=0; ix<256; ix++)
- {
- tr->groups1[ix]=NULL;
- tr->groups2_count[ix]=0;
- tr->groups2_start[ix]=255; // indicates "not set"
- }
- memset(tr->letterGroups,0,sizeof(tr->letterGroups));
-
- p = tr->data_dictrules;
- while(*p != 0)
- {
- if(*p != RULE_GROUP_START)
- {
- fprintf(stderr,"Bad rules data in '%s_dict' at 0x%x\n",dictionary_name,(unsigned int)(p - tr->data_dictrules));
- break;
- }
- p++;
-
- if(p[0] == RULE_REPLACEMENTS)
- {
- pw = (unsigned int *)(((long)p+4) & ~3); // advance to next word boundary
- tr->langopts.replace_chars = pw;
- while(pw[0] != 0)
- {
- pw += 2; // find the end of the replacement list, each entry is 2 words.
- }
- p = (char *)(pw+1);
-
-#ifdef ARCH_BIG
- pw = (unsigned int *)(tr->langopts.replace_chars);
- while(*pw != 0)
- {
- *pw = reverse_word_bytes(*pw);
- pw++;
- *pw = reverse_word_bytes(*pw);
- pw++;
- }
-#endif
- continue;
- }
-
- if(p[0] == RULE_LETTERGP2)
- {
- ix = p[1] - 'A';
- p += 2;
- if((ix >= 0) && (ix < N_LETTER_GROUPS))
- {
- tr->letterGroups[ix] = p;
- }
- }
- else
- {
- len = strlen(p);
- p_name = p;
- c = p_name[0];
-
- p += (len+1);
- if(len == 1)
- {
- tr->groups1[c] = p;
- }
- else
- if(len == 0)
- {
- tr->groups1[0] = p;
- }
- else
- {
- if(tr->groups2_start[c] == 255)
- tr->groups2_start[c] = tr->n_groups2;
-
- tr->groups2_count[c]++;
- tr->groups2[tr->n_groups2] = p;
- c2 = p_name[1];
- tr->groups2_name[tr->n_groups2++] = (c + (c2 << 8));
- }
- }
-
- // skip over all the rules in this group
- while(*p != RULE_GROUP_END)
- {
- p += (strlen(p) + 1);
- }
- p++;
- }
-
-} // end of InitGroups
-
-
-
-int LoadDictionary(Translator *tr, const char *name, int no_error)
-{//===============================================================
- int hash;
- char *p;
- int *pw;
- int length;
- FILE *f;
- unsigned int size;
- char fname[sizeof(path_home)+20];
-
- strcpy(dictionary_name,name); // currently loaded dictionary name
-
- if(no_error) // don't load dictionary, just set the dictionary_name
- return(1);
-
- // Load a pronunciation data file into memory
- // bytes 0-3: offset to rules data
- // bytes 4-7: number of hash table entries
- sprintf(fname,"%s%c%s_dict",path_home,PATHSEP,name);
- size = GetFileLength(fname);
-
- f = fopen(fname,"rb");
- if((f == NULL) || (size <= 0))
- {
- if(no_error == 0)
- {
- fprintf(stderr,"Can't read dictionary file: '%s'\n",fname);
- }
- return(1);
- }
-
- if(tr->data_dictlist != NULL)
- Free(tr->data_dictlist);
-
- tr->data_dictlist = Alloc(size);
- fread(tr->data_dictlist,size,1,f);
- fclose(f);
-
-
- pw = (int *)(tr->data_dictlist);
- length = reverse_word_bytes(pw[1]);
-
- if(size <= (N_HASH_DICT + sizeof(int)*2))
- {
- fprintf(stderr,"Empty _dict file: '%s\n",fname);
- return(2);
- }
-
- if((reverse_word_bytes(pw[0]) != N_HASH_DICT) ||
- (length <= 0) || (length > 0x8000000))
- {
- fprintf(stderr,"Bad data: '%s' (%x length=%x)\n",fname,reverse_word_bytes(pw[0]),length);
- return(2);
- }
- tr->data_dictrules = &(tr->data_dictlist[length]);
-
- // set up indices into data_dictrules
- InitGroups(tr);
- if(tr->groups1[0] == NULL)
- {
- fprintf(stderr,"Error in %s_rules, no default rule group\n",name);
- }
-
- // set up hash table for data_dictlist
- p = &(tr->data_dictlist[8]);
-
- for(hash=0; hash<N_HASH_DICT; hash++)
- {
- tr->dict_hashtab[hash] = p;
- while((length = *p) != 0)
- {
- p += length;
- }
- p++; // skip over the zero which terminates the list for this hash value
- }
-
- return(0);
-} // end of LoadDictionary
-
-
-int HashDictionary(const char *string)
-//====================================
-/* Generate a hash code from the specified string
- This is used to access the dictionary_2 word-lookup dictionary
-*/
-{
- int c;
- int chars=0;
- int hash=0;
-
- while((c = (*string++ & 0xff)) != 0)
- {
- hash = hash * 8 + c;
- hash = (hash & 0x3ff) ^ (hash >> 8); /* exclusive or */
- chars++;
- }
-
- return((hash+chars) & 0x3ff); // a 10 bit hash code
-} // end of HashDictionary
-
-
-
-//=============================================================================================
-// Translate between internal representation of phonemes and a mnemonic form for display
-//
-//=============================================================================================
-
-
-
-char *EncodePhonemes(char *p, char *outptr, unsigned char *bad_phoneme)
-/*********************************************************************/
-/* Translate a phoneme string from ascii mnemonics to internal phoneme numbers,
- from 'p' up to next blank .
- Returns advanced 'p'
- outptr contains encoded phonemes, unrecognised phonemes are encoded as 255
- bad_phoneme must point to char array of length 2 of more
-*/
-{
- int ix;
- unsigned char c;
- int count; /* num. of matching characters */
- int max; /* highest num. of matching found so far */
- int max_ph; /* corresponding phoneme with highest matching */
- int consumed;
- unsigned int mnemonic_word;
-
- bad_phoneme[0] = 0;
-
- // skip initial blanks
- while(isspace(*p))
- {
- p++;
- }
-
- while(((c = *p) != 0) && !isspace(c))
- {
- consumed = 0;
-
- switch(c)
- {
- case '|':
- // used to separate phoneme mnemonics if needed, to prevent characters being treated
- // as a multi-letter mnemonic
-
- if((c = p[1]) == '|')
- {
- // treat double || as a word-break symbol, drop through
- // to the default case with c = '|'
- }
- else
- {
- p++;
- break;
- }
-
- default:
- // lookup the phoneme mnemonic, find the phoneme with the highest number of
- // matching characters
- max= -1;
- max_ph= 0;
-
- for(ix=1; ix<n_phoneme_tab; ix++)
- {
- if(phoneme_tab[ix] == NULL)
- continue;
- if(phoneme_tab[ix]->type == phINVALID)
- continue; // this phoneme is not defined for this language
-
- count = 0;
- mnemonic_word = phoneme_tab[ix]->mnemonic;
-
- while(((c = p[count]) > ' ') && (count < 4) &&
- (c == ((mnemonic_word >> (count*8)) & 0xff)))
- count++;
-
- if((count > max) &&
- ((count == 4) || (((mnemonic_word >> (count*8)) & 0xff)==0)))
- {
- max = count;
- max_ph = phoneme_tab[ix]->code;
- }
- }
-
- if(max_ph == 0)
- {
- max_ph = 255; /* not recognised */
- bad_phoneme[0] = *p;
- bad_phoneme[1] = 0;
- }
-
- if(max <= 0)
- max = 1;
- p += (consumed + max);
- *outptr++ = (char)(max_ph);
-
- if(max_ph == phonSWITCH)
- {
- // Switch Language: this phoneme is followed by a text string
- char *p_lang = outptr;
- while(!isspace(c = *p) && (c != 0))
- {
- p++;
- *outptr++ = tolower(c);
- }
- *outptr = 0;
- if(c == 0)
- {
- if(strcmp(p_lang,"en")==0)
- {
- *p_lang = 0; // don't need "en", it's assumed by default
- return(p);
- }
- }
- else
- {
- *outptr++ = '|'; // more phonemes follow, terminate language string with separator
- }
- }
- break;
- }
- }
- /* terminate the encoded string */
- *outptr = 0;
- return(p);
-} // end of EncodePhonemes
-
-
-
-void DecodePhonemes(const char *inptr, char *outptr)
-//==================================================
-// Translate from internal phoneme codes into phoneme mnemonics
-{
- unsigned char phcode;
- unsigned char c;
- unsigned int mnem;
- PHONEME_TAB *ph;
- static const char *stress_chars = "==,,'* ";
-
- while((phcode = *inptr++) > 0)
- {
- if(phcode == 255)
- continue; /* indicates unrecognised phoneme */
- if((ph = phoneme_tab[phcode]) == NULL)
- continue;
-
- if((ph->type == phSTRESS) && (ph->std_length <= 4) && (ph->spect == 0))
- {
- if(ph->std_length > 1)
- *outptr++ = stress_chars[ph->std_length];
- }
- else
- {
- mnem = ph->mnemonic;
-
- while((c = (mnem & 0xff)) != 0)
- {
- *outptr++ = c;
- mnem = mnem >> 8;
- }
- if(phcode == phonSWITCH)
- {
- while(isalpha(*inptr))
- {
- *outptr++ = *inptr++;
- }
- }
- }
- }
- *outptr = 0; /* string terminator */
-} // end of DecodePhonemes
-
-
-
-static void WriteMnemonic(char *phon_out, int *ix, int mnem)
-{//=========================================================
- unsigned char c;
-
- while((c = mnem & 0xff) != 0)
- {
- if((c == '/') && (option_phoneme_variants==0))
- break; // discard phoneme variant indicator
- phon_out[(*ix)++]= c;
- // phon_out[phon_out_ix++]= ipa1[c];
- mnem = mnem >> 8;
- }
-}
-
-
-
-void GetTranslatedPhonemeString(char *phon_out, int n_phon_out)
-{//============================================================
-/* Can be called after a clause has been translated into phonemes, in order
- to display the clause in phoneme mnemonic form.
-*/
-
- int ix;
- int phon_out_ix=0;
- int stress;
- char *p;
- PHONEME_LIST *plist;
-
- static const char *stress_chars = "==,,''";
-
- if(phon_out != NULL)
- {
- for(ix=1; ix<(n_phoneme_list-2) && (phon_out_ix < (n_phon_out - 6)); ix++)
- {
- plist = &phoneme_list[ix];
- if(plist->newword)
- phon_out[phon_out_ix++] = ' ';
-
- if(plist->synthflags & SFLAG_SYLLABLE)
- {
- if((stress = plist->stresslevel) > 1)
- {
- if(stress > 5) stress = 5;
- phon_out[phon_out_ix++] = stress_chars[stress];
- }
- }
- WriteMnemonic(phon_out, &phon_out_ix, plist->ph->mnemonic);
-
- if(plist->synthflags & SFLAG_LENGTHEN)
- {
- WriteMnemonic(phon_out, &phon_out_ix, phoneme_tab[phonLENGTHEN]->mnemonic);
- }
- if((plist->synthflags & SFLAG_SYLLABLE) && (plist->type != phVOWEL))
- {
- // syllablic consonant
- WriteMnemonic(phon_out, &phon_out_ix, phoneme_tab[phonSYLLABIC]->mnemonic);
- }
- if(plist->ph->code == phonSWITCH)
- {
- // the tone_ph field contains a phoneme table number
- p = phoneme_tab_list[plist->tone_ph].name;
- while(*p != 0)
- {
- phon_out[phon_out_ix++] = *p++;
- }
- phon_out[phon_out_ix++] = ' ';
- }
- else
- if(plist->tone_ph > 0)
- {
- WriteMnemonic(phon_out, &phon_out_ix, phoneme_tab[plist->tone_ph]->mnemonic);
- }
- }
-
- if(phon_out_ix >= n_phon_out)
- phon_out_ix = n_phon_out - 1;
- phon_out[phon_out_ix] = 0;
- }
-} // end of GetTranslatedPhonemeString
-
-
-
-//=============================================================================================
-// Is a word Unpronouncable - and so should be spoken as individual letters
-//
-//=============================================================================================
-
-
-
-static int IsLetterGroup(Translator *tr, char *word, int group, int pre)
-{//=====================================================================
- // match the word against a list of utf-8 strings
- char *p;
- char *w;
- int len=0;
-
- p = tr->letterGroups[group];
- if(p == NULL)
- return(0);
-
- while(*p != RULE_GROUP_END)
- {
- if(pre)
- {
- len = strlen(p);
- w = word - len + 1;
- }
- else
- {
- w = word;
- }
- while(*p == *w)
- {
- w++;
- p++;
- }
- if(*p == 0)
- {
- if(pre)
- return(len);
- return(w-word); // matched a complete string
- }
-
- while(*p++ != 0); // skip to end of string
- }
- return(0);
-}
-
-
-static int IsLetter(Translator *tr, int letter, int group)
-{//=======================================================
- int letter2;
-
- if(tr->letter_groups[group] != NULL)
- {
- if(wcschr(tr->letter_groups[group],letter))
- return(1);
- return(0);
- }
-
- if(group > 7)
- return(0);
-
- if(tr->letter_bits_offset > 0)
- {
- if(((letter2 = (letter - tr->letter_bits_offset)) > 0) && (letter2 < 0x80))
- letter = letter2;
- else
- return(0);
- }
- else
- {
- if((letter >= 0xc0) && (letter <= 0x241))
- return(tr->letter_bits[remove_accent[letter-0xc0]] & (1L << group));
- }
-
- if((letter >= 0) && (letter < 0x80))
- return(tr->letter_bits[letter] & (1L << group));
-
- return(0);
-}
-
-
-static int IsVowel(Translator *tr, int letter)
-{//===========================================
- return(IsLetter(tr, letter, 0));
-}
-
-
-
-
-static int Unpronouncable_en(Translator *tr, char *word)
-{//=====================================================
-/* Determines whether a word in 'unpronouncable', i.e. whether it should
- be spoken as individual letters.
-
- This function is language specific.
-*/
-
- int c;
- int vowel_posn=9;
- int index;
- int count;
- int ix;
- int apostrophe=0;
-
- static unsigned char initials_bitmap[86] = {
- 0x00, 0x00, 0x00, 0x00, 0x22, 0x08, 0x00, 0x88, // 0
- 0x20, 0x24, 0x20, 0x80, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x28, 0x08, 0x00, 0x88, 0x22, 0x04, 0x00, // 16
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x88, 0x22, 0x04, 0x00, 0x02, 0x00, 0x04, // 32
- 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x28, 0x8a, 0x03, 0x00, 0x00, 0x40, 0x00, // 48
- 0x02, 0x00, 0x41, 0xca, 0xbb, 0x06, 0x20, 0x80,
- 0x91, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x00, // 64
- 0x08, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, };
-
-
- // words which we pass through to the dictionary, even though they look unpronouncable
- static const char *exceptions[] = {
- "'s ", "st ","nd ","rd ","th ",NULL };
-
- if((*word == ' ') || (*word == 0))
- return(0);
-
- for(ix=0; exceptions[ix] != NULL; ix++)
- {
- // Seemingly uncpronouncable words, but to be looked in the dictionary rules instead
- if(memcmp(word,exceptions[ix],3)==0)
- return(0);
- }
-
- index=0;
- count=0;
- for(;;)
- {
- index += utf8_in(&c,&word[index]);
- count++;
-
- if((c==0) || (c==' '))
- break;
-
- if(IsVowel(tr, c) || (c == 'y'))
- {
- vowel_posn = count;
- break;
- }
-
- if(c == '\'')
- apostrophe = 1;
- else
- if(!IsAlpha(c))
- return(0); // letter (not vowel) outside Latin character range or apostrophe, abort test
- }
- if((vowel_posn > 5) || ((word[0]!='s') && (vowel_posn > 4)))
- return(1); // no vowel, or no vowel in first four letters
-
- /* there is at least one vowel, is the initial letter combination valid ? */
-
- if(vowel_posn < 3)
- return(0); /* vowel in first two letters, OK */
-
- if(apostrophe)
- return(0); // first two letters not a-z, abort test
-
- index = (word[0]-'a') * 26 + (word[1]-'a');
- if(initials_bitmap[index >> 3] & (1L << (index & 7)))
- return(0);
- else
- return(1); /****/
-} /* end of Unpronounceable */
-
-
-
-
-int Unpronouncable(Translator *tr, char *word)
-{//===========================================
-/* Determines whether a word in 'unpronouncable', i.e. whether it should
- be spoken as individual letters.
-
- This function may be language specific. This is a generic version.
-*/
-
- int c;
- int c1=0;
- int vowel_posn=9;
- int index;
- int count;
- int apostrophe=0;
-
- if(tr->translator_name == L('e','n'))
- {
- return(Unpronouncable_en(tr,word));
- }
-
- utf8_in(&c,word);
- if((tr->letter_bits_offset > 0) && (c < 0x241))
- {
- // Latin characters for a language with a non-latin alphabet
- return(0); // so we can re-translate the word as English
- }
-
- if(tr->langopts.param[LOPT_UNPRONOUNCABLE] == 1)
- return(0);
-
- if((*word == ' ') || (*word == 0))
- return(0);
-
- index = 0;
- count = 0;
- for(;;)
- {
- index += utf8_in(&c,&word[index]);
- if((c==0) || (c==' '))
- break;
-
- if(count==0)
- c1 = c;
- count++;
-
- if(IsVowel(tr, c))
- {
- vowel_posn = count; // position of the first vowel
- break;
- }
-
- if(c == '\'')
- apostrophe = 1;
- else
- if(!iswalpha(c))
- return(0); // letter (not vowel) outside a-z range or apostrophe, abort test
- }
-
- if((vowel_posn < 9) && (tr->langopts.param[LOPT_UNPRONOUNCABLE] == 2))
- return(0); // option means allow any word with a vowel
-
- if(c1 == tr->langopts.param[LOPT_UNPRONOUNCABLE])
- vowel_posn--; // disregard this as the initial letter when counting
-
- if(vowel_posn > (tr->langopts.max_initial_consonants+1))
- return(1); // no vowel, or no vowel in first four letters
-
-return(0);
-
-} /* end of Unpronounceable */
-
-
-
-//=============================================================================================
-// Determine the stress pattern of a word
-//
-//=============================================================================================
-
-
-
-static int GetVowelStress(Translator *tr, unsigned char *phonemes, unsigned char *vowel_stress, int *vowel_count, int *stressed_syllable, int control)
-{//====================================================================================================================================================
-// control = 1, set stress to 1 for forced unstressed vowels
- unsigned char phcode;
- PHONEME_TAB *ph;
- unsigned char *ph_out = phonemes;
- int count = 1;
- int max_stress = 0;
- int ix;
- int j;
- int stress = 0;
- int primary_posn = 0;
-
- vowel_stress[0] = 0;
- while(((phcode = *phonemes++) != 0) && (count < (N_WORD_PHONEMES/2)-1))
- {
- if((ph = phoneme_tab[phcode]) == NULL)
- continue;
-
- if((ph->type == phSTRESS) && (ph->spect == 0))
- {
- /* stress marker, use this for the following vowel */
-
- if(phcode == phonSTRESS_PREV)
- {
- /* primary stress on preceeding vowel */
- j = count - 1;
- while((j > 0) && (*stressed_syllable == 0) && (vowel_stress[j] < 4))
- {
- if(vowel_stress[j] != 1)
- {
- // don't promote a phoneme which must be unstressed
- vowel_stress[j] = 4;
-
- if(max_stress < 4)
- {
- max_stress = 4;
- primary_posn = j;
- }
-
- /* reduce any preceding primary stress markers */
- for(ix=1; ix<j; ix++)
- {
- if(vowel_stress[ix] == 4)
- vowel_stress[ix] = 3;
- }
- break;
- }
- j--;
- }
- }
- else
- {
- if((ph->std_length < 4) || (*stressed_syllable == 0))
- {
- stress = ph->std_length;
-
- if(stress > max_stress)
- max_stress = stress;
- }
- }
- continue;
- }
-
- if((ph->type == phVOWEL) && !(ph->phflags & phNONSYLLABIC))
- {
- vowel_stress[count] = (char)stress;
- if((stress >= 4) && (stress >= max_stress))
- {
- primary_posn = count;
- max_stress = stress;
- }
-
- if((stress == 0) && (control & 1) && (ph->phflags & phUNSTRESSED))
- vowel_stress[count] = 1; /* weak vowel, must be unstressed */
-
- count++;
- stress = 0;
- }
- else
- if(phcode == phonSYLLABIC)
- {
- // previous consonant phoneme is syllablic
- vowel_stress[count] = (char)stress;
- if((stress == 0) && (control & 1))
- vowel_stress[count++] = 1; // syllabic consonant, usually unstressed
- }
-
- *ph_out++ = phcode;
- }
- vowel_stress[count] = 0;
- *ph_out = 0;
-
- /* has the position of the primary stress been specified by $1, $2, etc? */
- if(*stressed_syllable > 0)
- {
- if(*stressed_syllable >= count)
- *stressed_syllable = count-1; // the final syllable
-
- vowel_stress[*stressed_syllable] = 4;
- max_stress = 4;
- primary_posn = *stressed_syllable;
- }
-
- if(max_stress == 5)
- {
- // priority stress, replaces any other primary stress marker
- for(ix=1; ix<count; ix++)
- {
- if(vowel_stress[ix] == 4)
- {
- if(tr->langopts.stress_flags & 0x20000)
- vowel_stress[ix] = 0;
- else
- vowel_stress[ix] = 3;
- }
-
- if(vowel_stress[ix] == 5)
- {
- vowel_stress[ix] = 4;
- primary_posn = ix;
- }
- }
- max_stress = 4;
- }
-
- *stressed_syllable = primary_posn;
- *vowel_count = count;
- return(max_stress);
-} // end of GetVowelStress
-
-
-
-static char stress_phonemes[] = {phonSTRESS_U, phonSTRESS_D, phonSTRESS_2, phonSTRESS_3,
- phonSTRESS_P, phonSTRESS_P2, phonSTRESS_TONIC};
-
-
-void ChangeWordStress(Translator *tr, char *word, int new_stress)
-{//==============================================================
- int ix;
- unsigned char *p;
- int max_stress;
- int vowel_count; // num of vowels + 1
- int stressed_syllable=0; // position of stressed syllable
- unsigned char phonetic[N_WORD_PHONEMES];
- unsigned char vowel_stress[N_WORD_PHONEMES/2];
-
- strcpy((char *)phonetic,word);
- max_stress = GetVowelStress(tr, phonetic, vowel_stress, &vowel_count, &stressed_syllable, 0);
-
- if(new_stress >= 4)
- {
- // promote to primary stress
- for(ix=1; ix<vowel_count; ix++)
- {
- if(vowel_stress[ix] >= max_stress)
- {
- vowel_stress[ix] = new_stress;
- break;
- }
- }
- }
- else
- {
- // remove primary stress
- for(ix=1; ix<vowel_count; ix++)
- {
- if(vowel_stress[ix] > new_stress) // >= allows for diminished stress (=1)
- vowel_stress[ix] = new_stress;
- }
- }
-
- // write out phonemes
- ix = 1;
- p = phonetic;
- while(*p != 0)
- {
- if((phoneme_tab[*p]->type == phVOWEL) && !(phoneme_tab[*p]->phflags & phNONSYLLABIC))
- {
- if(vowel_stress[ix] != 0)
- *word++ = stress_phonemes[vowel_stress[ix]];
-
- ix++;
- }
- *word++ = *p++;
- }
- *word = 0;
-} // end of ChangeWordStress
-
-
-
-void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags, int tonic, int prev_stress)
-{//=========================================================================================================
-/* Guess stress pattern of word. This is language specific
-
- 'dictionary_flags' has bits 0-3 position of stressed vowel (if > 0)
- or unstressed (if == 7) or syllables 1 and 2 (if == 6)
- bits 8... dictionary flags
-
- If 'tonic' is set (>= 0), replace highest stress by this value.
-
- Parameter used for input and output
-*/
-
- unsigned char phcode;
- unsigned char *p;
- PHONEME_TAB *ph;
- int stress;
- int max_stress;
- int vowel_count; // num of vowels + 1
- int ix;
- int v;
- int v_stress;
- int stressed_syllable; // position of stressed syllable
- int max_stress_posn;
- int unstressed_word = 0;
- char *max_output;
- int final_ph;
- int final_ph2;
- int mnem;
- int mnem2;
- int post_tonic;
- int opt_length;
- int done;
- int stressflags;
-
- unsigned char vowel_stress[N_WORD_PHONEMES/2];
- char syllable_weight[N_WORD_PHONEMES/2];
- char vowel_length[N_WORD_PHONEMES/2];
- unsigned char phonetic[N_WORD_PHONEMES];
-
- static char consonant_types[16] = {0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0};
-
-
- /* stress numbers STRESS_BASE +
- 0 diminished, unstressed within a word
- 1 unstressed, weak
- 2
- 3 secondary stress
- 4 main stress */
-
- stressflags = tr->langopts.stress_flags;
-
- /* copy input string into internal buffer */
- for(ix=0; ix<N_WORD_PHONEMES; ix++)
- {
- phonetic[ix] = output[ix];
- // check for unknown phoneme codes
- if(phonetic[ix] >= n_phoneme_tab)
- phonetic[ix] = phonSCHWA;
- if(phonetic[ix] == 0)
- break;
- }
- if(ix == 0) return;
- final_ph = phonetic[ix-1];
- final_ph2 = phonetic[ix-2];
-
- max_output = output + (N_WORD_PHONEMES-3); /* check for overrun */
-
- // any stress position marked in the xx_list dictionary ?
- stressed_syllable = (*dictionary_flags) & 0x7;
- if((*dictionary_flags) & 0x8)
- {
- // this indicates a word without a primary stress
- stressed_syllable = (*dictionary_flags) & 0x3;
- unstressed_word = 1;
- }
-
- max_stress = GetVowelStress(tr, phonetic, vowel_stress, &vowel_count, &stressed_syllable, 1);
-
- if((max_stress == 0) && (tr->langopts.stress_flags & 1) && (vowel_count == 2))
- {
- // option: don't stress monosyllables except at end-of-clause
- vowel_stress[1] = 1;
- (*dictionary_flags) |= FLAG_STRESS_END2;
- }
-
- // heavy or light syllables
- ix = 1;
- for(p = phonetic; *p != 0; p++)
- {
- if((phoneme_tab[p[0]]->type == phVOWEL) && !(phoneme_tab[p[0]]->phflags & phNONSYLLABIC))
- {
- int weight = 0;
- int lengthened = 0;
-
- if(phoneme_tab[p[1]]->code == phonLENGTHEN)
- lengthened = 1;
-
- if(lengthened || (phoneme_tab[p[0]]->phflags & phLONG))
- {
- // long vowel, increase syllable weight
- weight++;
- }
- vowel_length[ix] = weight;
-
- if(lengthened) p++; // advance over phonLENGTHEN
-
- if(consonant_types[phoneme_tab[p[1]]->type] && ((phoneme_tab[p[2]]->type != phVOWEL) || (phoneme_tab[p[1]]->phflags & phLONG)))
- {
- // followed by two consonants, a long consonant, or consonant and end-of-word
- weight++;
- }
- syllable_weight[ix] = weight;
- ix++;
- }
- }
-
- switch(tr->langopts.stress_rule)
- {
- case 8:
- // stress on first syllable, unless it is a light syllable
- if(syllable_weight[1] > 0)
- break;
- // else drop through to case 1
- case 1:
- // stress on second syllable
- if((stressed_syllable == 0) && (vowel_count > 2))
- {
- stressed_syllable = 2;
- if(max_stress == 0)
- {
- vowel_stress[stressed_syllable] = 4;
- }
- max_stress = 4;
- }
- break;
-
- case 2:
- // a language with stress on penultimate vowel
-
- if(stressed_syllable == 0)
- {
- /* no explicit stress - stress the penultimate vowel */
- max_stress = 4;
-
- if(vowel_count > 2)
- {
- stressed_syllable = vowel_count - 2;
-
- if(stressflags & 0x300)
- {
- // LANG=Spanish, stress on last vowel if the word ends in a consonant other than 'n' or 's'
- if(phoneme_tab[final_ph]->type != phVOWEL)
- {
- if(stressflags & 0x100)
- {
- stressed_syllable = vowel_count - 1;
- }
- else
- {
- mnem = phoneme_tab[final_ph]->mnemonic;
- mnem2 = phoneme_tab[final_ph2]->mnemonic;
-
- if((mnem == 's') && (mnem2 == 'n'))
- {
- // -ns stress remains on penultimate syllable
- }
- else
- if(((mnem != 'n') && (mnem != 's')) || (phoneme_tab[final_ph2]->type != phVOWEL))
- {
- stressed_syllable = vowel_count - 1;
- }
- }
- }
- }
- if(stressflags & 0x80000)
- {
- // stress on last syllable if it has a long vowel, but previous syllable has a short vowel
- if(vowel_length[vowel_count - 1] > vowel_length[vowel_count - 2])
- {
- stressed_syllable = vowel_count - 1;
- }
- }
-
- if(vowel_stress[stressed_syllable] == 1)
- {
- // but this vowel is explicitly marked as unstressed
- if(stressed_syllable > 1)
- stressed_syllable--;
- else
- stressed_syllable++;
- }
- }
- else
- {
- stressed_syllable = 1;
- }
-
- // only set the stress if it's not already marked explicitly
- if(vowel_stress[stressed_syllable] == 0)
- {
- // don't stress if next and prev syllables are stressed
- if((vowel_stress[stressed_syllable-1] < 4) || (vowel_stress[stressed_syllable+1] < 4))
- vowel_stress[stressed_syllable] = max_stress;
- }
- }
- break;
-
- case 3:
- // stress on last vowel
- if(stressed_syllable == 0)
- {
- /* no explicit stress - stress the final vowel */
- stressed_syllable = vowel_count - 1;
- if(max_stress == 0)
- {
- while(stressed_syllable > 0)
- {
- if(vowel_stress[stressed_syllable] == 0)
- {
- vowel_stress[stressed_syllable] = 4;
- break;
- }
- else
- stressed_syllable--;
- }
- }
- max_stress = 4;
- }
- break;
-
- case 4: // stress on antipenultimate vowel
- if(stressed_syllable == 0)
- {
- stressed_syllable = vowel_count - 3;
- if(stressed_syllable < 1)
- stressed_syllable = 1;
-
- if(max_stress == 0)
- {
- vowel_stress[stressed_syllable] = 4;
- }
- max_stress = 4;
- }
- break;
-
- case 5:
- // LANG=Russian
- if(stressed_syllable == 0)
- {
- /* no explicit stress - guess the stress from the number of syllables */
- static char guess_ru[16] = {0,0,1,1,2,3,3,4,5,6,7,7,8,9,10,11};
- static char guess_ru_v[16] = {0,0,1,1,2,2,3,3,4,5,6,7,7,8,9,10}; // for final phoneme is a vowel
- static char guess_ru_t[16] = {0,0,1,2,3,3,3,4,5,6,7,7,7,8,9,10}; // for final phoneme is an unvoiced stop
-
- stressed_syllable = vowel_count - 3;
- if(vowel_count < 16)
- {
- if(phoneme_tab[final_ph]->type == phVOWEL)
- stressed_syllable = guess_ru_v[vowel_count];
- else
- if(phoneme_tab[final_ph]->type == phSTOP)
- stressed_syllable = guess_ru_t[vowel_count];
- else
- stressed_syllable = guess_ru[vowel_count];
- }
- vowel_stress[stressed_syllable] = 4;
- max_stress = 4;
- }
- break;
-
- case 6: // LANG=hi stress on the last heaviest syllable
- if(stressed_syllable == 0)
- {
- int wt;
- int max_weight = -1;
- int prev_stressed;
-
- // find the heaviest syllable, excluding the final syllable
- for(ix = 1; ix < (vowel_count-1); ix++)
- {
- if(vowel_stress[ix] == 0)
- {
- if((wt = syllable_weight[ix]) >= max_weight)
- {
- max_weight = wt;
- prev_stressed = stressed_syllable;
- stressed_syllable = ix;
- }
- }
- }
-
- if((syllable_weight[vowel_count-1] == 2) && (max_weight< 2))
- {
- // the only double=heavy syllable is the final syllable, so stress this
- stressed_syllable = vowel_count-1;
- }
- else
- if(max_weight <= 0)
- {
- // all syllables, exclusing the last, are light. Stress the first syllable
- stressed_syllable = 1;
- }
-
- vowel_stress[stressed_syllable] = 4;
- max_stress = 4;
- }
- break;
-
- case 7: // LANG=tr, the last syllable for any vowel markes explicitly as unstressed
- if(stressed_syllable == 0)
- {
- stressed_syllable = vowel_count - 1;
- for(ix=1; ix < vowel_count; ix++)
- {
- if(vowel_stress[ix] == 1)
- {
- stressed_syllable = ix-1;
- break;
- }
- }
- vowel_stress[stressed_syllable] = 4;
- max_stress = 4;
- }
- break;
-
- case 9: // mark all as stressed
- for(ix=1; ix<vowel_count; ix++)
- {
- if(vowel_stress[ix] == 0)
- vowel_stress[ix] = 4;
- }
- break;
- }
-
- /* now guess the complete stress pattern */
- if(max_stress < 4)
- stress = 4; /* no primary stress marked, use for 1st syllable */
- else
- stress = 3;
-
-
- if((stressflags & 0x1000) && (vowel_count == 2))
- {
- // Two syllable word, if one syllable has primary stress, then give the other secondary stress
- if(vowel_stress[1] == 4)
- vowel_stress[2] = 3;
- if(vowel_stress[2] == 4)
- vowel_stress[1] = 3;
- }
-#if deleted
- if((stressflags & 0x2000) && (vowel_stress[1] == 0))
- {
- // If there is only one syllable before the primary stress, give it a secondary stress
- if((vowel_count > 2) && (vowel_stress[2] >= 4))
- {
- vowel_stress[1] = 3;
- }
- }
-#endif
-
- done = 0;
- for(v=1; v<vowel_count; v++)
- {
- if(vowel_stress[v] == 0)
- {
- if((stressflags & 0x10) && (stress < 4) && (v == vowel_count-1))
- {
- // flag: don't give secondary stress to final vowel
- }
- else
- if((stressflags & 0x8000) && (done == 0))
- {
- vowel_stress[v] = (char)stress;
- done =1;
- stress = 3; /* use secondary stress for remaining syllables */
- }
- else
- if((vowel_stress[v-1] <= 1) && ((vowel_stress[v+1] <= 1) || ((stress == 4) && (vowel_stress[v+1] <= 2))))
- {
- /* trochaic: give stress to vowel surrounded by unstressed vowels */
-
- if((stress == 3) && (stressflags & 0x20))
- continue; // don't use secondary stress
-
- if((v > 1) && (stressflags & 0x40) && (syllable_weight[v]==0) && (syllable_weight[v+1]>0))
- {
- // don't put secondary stress on a light syllable which is followed by a heavy syllable
- continue;
- }
-
-// should start with secondary stress on the first syllable, or should it count back from
-// the primary stress and put secondary stress on alternate syllables?
- vowel_stress[v] = (char)stress;
- done =1;
- stress = 3; /* use secondary stress for remaining syllables */
- }
- }
- }
-
- if((unstressed_word) && (tonic < 0))
- {
- if(vowel_count <= 2)
- tonic = tr->langopts.unstressed_wd1; /* monosyllable - unstressed */
- else
- tonic = tr->langopts.unstressed_wd2; /* more than one syllable, used secondary stress as the main stress */
- }
-
- max_stress = 0;
- max_stress_posn = 0;
- for(v=1; v<vowel_count; v++)
- {
- if(vowel_stress[v] >= max_stress)
- {
- max_stress = vowel_stress[v];
- max_stress_posn = v;
- }
- }
-
- if(tonic >= 0)
- {
- /* find position of highest stress, and replace it by 'tonic' */
-
- /* don't disturb an explicitly set stress by 'unstress-at-end' flag */
- if((tonic > max_stress) || (max_stress <= 4))
- vowel_stress[max_stress_posn] = (char)tonic;
- max_stress = tonic;
- }
-
-
- /* produce output phoneme string */
- p = phonetic;
- v = 1;
-
- if((ph = phoneme_tab[*p]) != NULL)
- {
-
- if(ph->type == phSTRESS)
- ph = phoneme_tab[p[1]];
-
-#ifdef deleted
- int gap = tr->langopts.word_gap & 0x700;
- if((gap) && (vowel_stress[1] >= 4) && (prev_stress >= 4))
- {
- /* two primary stresses together, insert a short pause */
- *output++ = pause_phonemes[gap >> 8];
- }
- else
-#endif
- if((tr->langopts.vowel_pause & 0x30) && (ph->type == phVOWEL))
- {
- // word starts with a vowel
-
- if((tr->langopts.vowel_pause & 0x20) && (vowel_stress[1] >= 4))
- {
- *output++ = phonPAUSE_NOLINK; // not to be replaced by link
- }
- else
- {
- *output++ = phonPAUSE_VSHORT; // break, but no pause
- }
- }
- }
-
- p = phonetic;
- post_tonic = 0;
- while(((phcode = *p++) != 0) && (output < max_output))
- {
- if((ph = phoneme_tab[phcode]) == NULL)
- continue;
-
-// if(ph->type == phSTRESS)
-// continue;
-
- if(ph->type == phPAUSE)
- {
- tr->prev_last_stress = 0;
- }
- else
- if(((ph->type == phVOWEL) && !(ph->phflags & phNONSYLLABIC)) || (*p == phonSYLLABIC))
- {
- // a vowel, or a consonant followed by a syllabic consonant marker
-
- v_stress = vowel_stress[v];
- tr->prev_last_stress = v_stress;
-
- if(vowel_stress[v-1] >= max_stress)
- post_tonic = 1;
-
- if(v_stress <= 1)
- {
- if((v > 1) && (max_stress >= 4) && (stressflags & 4) && (v == (vowel_count-1)))
- {
- // option: mark unstressed final syllable as diminished
- v_stress = 1;
- }
- else
- if((stressflags & 2) || (v == 1) || (v == (vowel_count-1)))
- {
- // first or last syllable, or option 'don't set diminished stress'
- v_stress = 0;
- }
- else
- if((v == (vowel_count-2)) && (vowel_stress[vowel_count-1] <= 1))
- {
- // penultimate syllable, followed by an unstressed final syllable
- v_stress = 0;
- }
- else
- {
- // unstressed syllable within a word
- if((vowel_stress[v-1] != 1) || ((stressflags & 0x10000) == 0))
- {
- v_stress = 1; /* change from 0 (unstressed) to 1 (diminished stress) */
- vowel_stress[v] = v_stress;
- }
- }
- }
-
- if(v_stress > 0)
- *output++ = stress_phonemes[v_stress]; // mark stress of all vowels except 0 (unstressed)
-
-
- if(vowel_stress[v] > max_stress)
- {
- max_stress = vowel_stress[v];
- }
-
- if((*p == phonLENGTHEN) && ((opt_length = tr->langopts.param[LOPT_IT_LENGTHEN]) & 1))
- {
- // remove lengthen indicator from non-stressed syllables
- int shorten=0;
-
- if(opt_length & 0x10)
- {
- // only allow lengthen indicator on the highest stress syllable in the word
- if(v != max_stress_posn)
- shorten = 1;
- }
- else
- if(v_stress < 4)
- {
- // only allow lengthen indicator if stress >= 4.
- shorten = 1;
- }
-
- if(shorten)
- p++;
- }
-
- if((v_stress >= 4) && (tr->langopts.param[LOPT_IT_LENGTHEN] == 2))
- {
- // LANG=Italian, lengthen penultimate stressed vowels, unless followed by 2 consonants
- if((v == (vowel_count - 2)) && (syllable_weight[v] == 0))
- {
- *output++ = phcode;
- phcode = phonLENGTHEN;
- }
- }
-
- v++;
- }
-
- if(phcode != 1)
- *output++ = phcode;
- }
- *output++ = 0;
-
-} /* end of SetWordStress */
-
-
-
-
-//=============================================================================================
-// Look up a word in the pronunciation rules
-//
-//=============================================================================================
-
-
-#ifdef LOG_TRANSLATE
-static char *DecodeRule(const char *group, char *rule)
-{//==================================================
-/* Convert compiled match template to ascii */
-
- unsigned char rb;
- unsigned char c;
- char *p;
- int ix;
- int match_type;
- int finished=0;
- int value;
- int linenum=0;
- int flags;
- int suffix_char;
- int condition_num=0;
- char buf[60];
- char buf_pre[60];
- char suffix[20];
- static char output[60];
-
- static char symbols[] = {' ',' ',' ',' ',' ',' ',' ',' ',' ',
- '@','&','%','+','#','S','D','Z','A','L',' ',' ',' ',' ',' ','N','K','V',' ','T','X','?','W'};
-
- static char symbols_lg[] = {'A','B','C','H','F','G','Y'};
-
- match_type = 0;
- buf_pre[0] = 0;
- strcpy(buf,group);
- p = &buf[strlen(buf)];
- while(!finished)
- {
- rb = *rule++;
-
- if(rb <= RULE_LINENUM)
- {
- switch(rb)
- {
- case 0:
- case RULE_PHONEMES:
- finished=1;
- break;
- case RULE_PRE:
- match_type = RULE_PRE;
- *p = 0;
- p = buf_pre;
- break;
- case RULE_POST:
- match_type = RULE_POST;
- *p = 0;
- strcat(buf," (");
- p = &buf[strlen(buf)];
- break;
- case RULE_PH_COMMON:
- break;
- case RULE_CONDITION:
- /* conditional rule, next byte gives condition number */
- condition_num = *rule++;
- break;
- case RULE_LINENUM:
- value = (rule[1] & 0xff) - 1;
- linenum = (rule[0] & 0xff) - 1 + (value * 255);
- rule+=2;
- break;
- }
- continue;
- }
-
- if(rb == RULE_ENDING)
- {
- static const char *flag_chars = "ei vtfq t";
- flags = ((rule[0] & 0x7f)<< 8) + (rule[1] & 0x7f);
- suffix_char = 'S';
- if(flags & (SUFX_P >> 8))
- suffix_char = 'P';
- sprintf(suffix,"%c%d",suffix_char,rule[2] & 0x7f);
- rule += 3;
- for(ix=0;ix<9;ix++)
- {
- if(flags & 1)
- sprintf(&suffix[strlen(suffix)],"%c",flag_chars[ix]);
- flags = (flags >> 1);
- }
- strcpy(p,suffix);
- p += strlen(suffix);
- c = ' ';
- }
- else
- if(rb == RULE_LETTERGP)
- {
- c = symbols_lg[*rule++ - 'A'];
- }
- else
- if(rb == RULE_LETTERGP2)
- {
- value = *rule++ - 'A';
- p[0] = 'L';
- p[1] = (value / 10) + '0';
- c = (value % 10) + '0';
-
- if(match_type == RULE_PRE)
- {
- p[0] = c;
- c = 'L';
- }
- p+=2;
- }
- else
- if(rb <= RULE_LAST_RULE)
- c = symbols[rb];
- else
- if(rb == RULE_SPACE)
- c = '_';
- else
- c = rb;
- *p++ = c;
- }
- *p = 0;
-
- p = output;
- if(linenum > 0)
- {
- sprintf(p,"%5d:\t",linenum);
- p += 7;
- }
- if(condition_num > 0)
- {
- sprintf(p,"?%d ",condition_num);
- p = &p[strlen(p)];
- }
- if((ix = strlen(buf_pre)) > 0)
- {
- while(--ix >= 0)
- *p++ = buf_pre[ix];
- *p++ = ')';
- *p++ = ' ';
- }
- *p = 0;
- strcat(p,buf);
- ix = strlen(output);
- while(ix < 8)
- output[ix++]=' ';
- output[ix]=0;
- return(output);
-} /* end of decode_match */
-#endif
-
-
-
-void AppendPhonemes(Translator *tr, char *string, int size, const char *ph)
-{//========================================================================
-/* Add new phoneme string "ph" to "string"
- Keeps count of the number of vowel phonemes in the word, and whether these
- can be stressed syllables. These values can be used in translation rules
-*/
- const char *p;
- unsigned char c;
- int unstress_mark;
- int length;
-
- length = strlen(ph) + strlen(string);
- if(length >= size)
- {
- return;
- }
-
- /* any stressable vowel ? */
- unstress_mark = 0;
- p = ph;
- while((c = *p++) != 0)
- {
- if(c >= n_phoneme_tab) continue;
-
- if(phoneme_tab[c]->type == phSTRESS)
- {
- if(phoneme_tab[c]->std_length < 4)
- unstress_mark = 1;
- }
- else
- {
- if(phoneme_tab[c]->type == phVOWEL)
- {
- if(((phoneme_tab[c]->phflags & phUNSTRESSED) == 0) &&
- (unstress_mark == 0))
- {
- tr->word_stressed_count++;
- }
- unstress_mark = 0;
- tr->word_vowel_count++;
- }
- }
- }
-
- if(string != NULL)
- strcat(string,ph);
-} /* end of AppendPhonemes */
-
-
-
-static void MatchRule(Translator *tr, char *word[], const char *group, char *rule, MatchRecord *match_out, int word_flags, int dict_flags)
-{//=======================================================================================================================================
-/* Checks a specified word against dictionary rules.
- Returns with phoneme code string, or NULL if no match found.
-
- word (indirect) points to current character group within the input word
- This is advanced by this procedure as characters are consumed
-
- group: the initial characters used to choose the rules group
-
- rule: address of dictionary rule data for this character group
-
- match_out: returns best points score
-
- word_flags: indicates whether this is a retranslation after a suffix has been removed
-*/
-
- unsigned char rb; // current instuction from rule
- unsigned char letter; // current letter from input word, single byte
- int letter_w; // current letter, wide character
- int letter_xbytes; // number of extra bytes of multibyte character (num bytes - 1)
- unsigned char last_letter;
-
- char *pre_ptr;
- char *post_ptr; /* pointer to first character after group */
-
- char *rule_start; /* start of current match template */
- char *p;
-
- int match_type; /* left, right, or consume */
- int failed;
- int consumed; /* number of letters consumed from input */
- int count; /* count through rules in the group */
- int syllable_count;
- int vowel;
- int letter_group;
- int distance_right;
- int distance_left;
- int lg_pts;
- int n_bytes;
- int add_points;
-
- MatchRecord match;
- static MatchRecord best;
-
- int total_consumed; /* letters consumed for best match */
- int group_length;
-
- unsigned char condition_num;
- char *common_phonemes; /* common to a group of entries */
-
-
-
- if(rule == NULL)
- {
- match_out->points = 0;
- (*word)++;
- return;
- }
-
-
- total_consumed = 0;
- count = 0;
- common_phonemes = NULL;
- match_type = 0;
-
- best.points = 0;
- best.phonemes = "";
- best.end_type = 0;
- best.del_fwd = NULL;
-
- group_length = strlen(group);
-
- /* search through dictionary rules */
- while(rule[0] != RULE_GROUP_END)
- {
- match_type=0;
- consumed = 0;
- letter = 0;
- distance_right= -6; /* used to reduce points for matches further away the current letter */
- distance_left= -2;
- count++;
-
- match.points = 1;
- match.end_type = 0;
- match.del_fwd = NULL;
-
- pre_ptr = *word;
- post_ptr = *word + group_length;
-
- /* work through next rule until end, or until no-match proved */
- rule_start = rule;
- failed = 0;
- while(!failed)
- {
- rb = *rule++;
-
- if(rb <= RULE_LINENUM)
- {
- switch(rb)
- {
- case 0: // no phoneme string for this rule, use previous common rule
- if(common_phonemes != NULL)
- {
- match.phonemes = common_phonemes;
- while(((rb = *match.phonemes++) != 0) && (rb != RULE_PHONEMES))
- {
- if(rb == RULE_CONDITION)
- match.phonemes++; // skip over condition number
- }
- }
- else
- {
- match.phonemes = "";
- }
- rule--; // so we are still pointing at the 0
- failed=2; // matched OK
- break;
- case RULE_PRE:
- match_type = RULE_PRE;
- break;
- case RULE_POST:
- match_type = RULE_POST;
- break;
- case RULE_PHONEMES:
- match.phonemes = rule;
- failed=2; // matched OK
- break;
- case RULE_PH_COMMON:
- common_phonemes = rule;
- break;
- case RULE_CONDITION:
- /* conditional rule, next byte gives condition number */
- condition_num = *rule++;
-
- if(condition_num >= 32)
- {
- // allow the rule only if the condition number is NOT set
- if((tr->dict_condition & (1L << (condition_num-32))) != 0)
- failed = 1;
- }
- else
- {
- // allow the rule only if the condition number is set
- if((tr->dict_condition & (1L << condition_num)) == 0)
- failed = 1;
- }
-
- if(!failed)
- match.points++; // add one point for a matched conditional rule
- break;
- case RULE_LINENUM:
- rule+=2;
- break;
- }
- continue;
- }
-
- add_points = 0;
-
- switch(match_type)
- {
- case 0:
- /* match and consume this letter */
- last_letter = letter;
- letter = *post_ptr++;
-
- if((letter == rb) || ((letter==(unsigned char)REPLACED_E) && (rb=='e')))
- {
- add_points = 21;
- consumed++;
- }
- else
- failed = 1;
- break;
-
-
- case RULE_POST:
- /* continue moving fowards */
- distance_right += 6;
- if(distance_right > 18)
- distance_right = 19;
- last_letter = letter;
- letter_xbytes = utf8_in(&letter_w,post_ptr)-1;
- letter = *post_ptr++;
-
- switch(rb)
- {
- case RULE_LETTERGP:
- letter_group = *rule++ - 'A';
- if(IsLetter(tr, letter_w, letter_group))
- {
- lg_pts = 20;
- if(letter_group==2)
- lg_pts = 19; // fewer points for C, general consonant
- add_points = (lg_pts-distance_right);
- post_ptr += letter_xbytes;
- }
- else
- failed = 1;
- break;
-
- case RULE_LETTERGP2: // match against a list of utf-8 strings
- letter_group = *rule++ - 'A';
- if((n_bytes = IsLetterGroup(tr, post_ptr-1,letter_group,0)) >0)
- {
- add_points = (20-distance_right);
- post_ptr += (n_bytes-1);
- }
- else
- failed =1;
- break;
-
- case RULE_NOTVOWEL:
- if(!IsLetter(tr, letter_w,0))
- {
- add_points = (20-distance_right);
- post_ptr += letter_xbytes;
- }
- else
- failed = 1;
- break;
-
- case RULE_DIGIT:
- if(IsDigit(letter_w))
- {
- add_points = (20-distance_right);
- post_ptr += letter_xbytes;
- }
- else
- if(tr->langopts.tone_numbers)
- {
- // also match if there is no digit
- add_points = (20-distance_right);
- post_ptr--;
- }
- else
- failed = 1;
- break;
-
- case RULE_NONALPHA:
- if(!iswalpha(letter_w))
- {
- add_points = (21-distance_right);
- post_ptr += letter_xbytes;
- }
- else
- failed = 1;
- break;
-
- case RULE_DOUBLE:
- if(letter == last_letter)
- add_points = (21-distance_right);
- else
- failed = 1;
- break;
-
- case RULE_ALT1:
- if(dict_flags & FLAG_ALT_TRANS)
- add_points = 1;
- else
- failed = 1;
- break;
-
- case '-':
- if((letter == '-') || ((letter == ' ') && (word_flags & FLAG_HYPHEN_AFTER)))
- {
- add_points = (22-distance_right); // one point more than match against space
- }
- else
- failed = 1;
- break;
-
- case RULE_SYLLABLE:
- {
- /* more than specified number of vowel letters to the right */
- char *p = post_ptr + letter_xbytes;
-
- syllable_count = 1;
- while(*rule == RULE_SYLLABLE)
- {
- rule++;
- syllable_count+=1; /* number of syllables to match */
- }
- vowel = 0;
- while(letter_w != RULE_SPACE)
- {
- if((vowel==0) && IsLetter(tr, letter_w,LETTERGP_VOWEL2))
- {
- // this is counting vowels which are separated by non-vowels
- syllable_count--;
- }
- vowel = IsLetter(tr, letter_w,LETTERGP_VOWEL2);
- p += utf8_in(&letter_w,p);
- }
- if(syllable_count <= 0)
- add_points = (19-distance_right);
- else
- failed = 1;
- }
- break;
-
- case RULE_NOVOWELS:
- {
- char *p = post_ptr + letter_xbytes;
- while(letter_w != RULE_SPACE)
- {
- if(IsLetter(tr, letter_w,LETTERGP_VOWEL2))
- {
- failed = 1;
- break;
- }
- p += utf8_in(&letter_w,p);
- }
- if(!failed)
- add_points = (19-distance_right);
- }
- break;
-
- case RULE_INC_SCORE:
- add_points = 20; // force an increase in points
- break;
-
- case RULE_DEL_FWD:
- // find the next 'e' in the word and replace by ''
- for(p = *word + group_length; *p != ' '; p++)
- {
- if(*p == 'e')
- {
- match.del_fwd = p;
- break;
- }
- }
- break;
-
- case RULE_ENDING:
- // next 3 bytes are a (non-zero) ending type. 2 bytes of flags + suffix length
- match.end_type = (rule[0] << 16) + ((rule[1] & 0x7f) << 8) + (rule[2] & 0x7f);
- rule += 3;
- break;
-
- case RULE_NO_SUFFIX:
- if(word_flags & FLAG_SUFFIX_REMOVED)
- failed = 1; // a suffix has been removed
- else
- add_points = 1;
- break;
-
- default:
- if(letter == rb)
- {
- if(letter == RULE_SPACE)
- add_points = (21-distance_right);
- else
- add_points = (21-distance_right);
- }
- else
- failed = 1;
- break;
- }
- break;
-
-
- case RULE_PRE:
- /* match backwards from start of current group */
- distance_left += 2;
- if(distance_left > 18)
- distance_left = 19;
-
- last_letter = *pre_ptr;
- pre_ptr--;
- letter_xbytes = utf8_in2(&letter_w,pre_ptr,1)-1;
- letter = *pre_ptr;
-
- switch(rb)
- {
- case RULE_LETTERGP:
- letter_group = *rule++ - 'A';
- if(IsLetter(tr, letter_w,letter_group))
- {
- lg_pts = 20;
- if(letter_group==2)
- lg_pts = 19; // fewer points for C, general consonant
- add_points = (lg_pts-distance_left);
- pre_ptr -= letter_xbytes;
- }
- else
- failed = 1;
- break;
-
- case RULE_LETTERGP2: // match against a list of utf-8 strings
- letter_group = *rule++ - 'A';
- if((n_bytes = IsLetterGroup(tr, pre_ptr,letter_group,1)) >0)
- {
- add_points = (20-distance_right);
- pre_ptr -= (n_bytes-1);
- }
- else
- failed =1;
- break;
-
- case RULE_NOTVOWEL:
- if(!IsLetter(tr, letter_w,0))
- {
- add_points = (20-distance_left);
- pre_ptr -= letter_xbytes;
- }
- else
- failed = 1;
- break;
-
- case RULE_DOUBLE:
- if(letter == last_letter)
- add_points = (21-distance_left);
- else
- failed = 1;
- break;
-
- case RULE_DIGIT:
- if(IsDigit(letter_w))
- {
- add_points = (21-distance_left);
- pre_ptr -= letter_xbytes;
- }
- else
- failed = 1;
- break;
-
- case RULE_NONALPHA:
- if(!iswalpha(letter_w))
- {
- add_points = (21-distance_right);
- pre_ptr -= letter_xbytes;
- }
- else
- failed = 1;
- break;
-
- case RULE_SYLLABLE:
- /* more than specified number of vowels to the left */
- syllable_count = 1;
- while(*rule == RULE_SYLLABLE)
- {
- rule++;
- syllable_count++; /* number of syllables to match */
- }
- if(syllable_count <= tr->word_vowel_count)
- add_points = (19-distance_left);
- else
- failed = 1;
- break;
-
- case RULE_STRESSED:
- if(tr->word_stressed_count > 0)
- add_points = 19;
- else
- failed = 1;
- break;
-
- case RULE_NOVOWELS:
- {
- char *p = pre_ptr - letter_xbytes - 1;
- while(letter_w != RULE_SPACE)
- {
- if(IsLetter(tr, letter_w,LETTERGP_VOWEL2))
- {
- failed = 1;
- break;
- }
- p -= utf8_in2(&letter_w,p,1);
- }
- if(!failed)
- add_points = 3;
- }
- break;
-
- case RULE_IFVERB:
- if(tr->expect_verb)
- add_points = 1;
- else
- failed = 1;
- break;
-
- case RULE_CAPITAL:
- if(word_flags & FLAG_FIRST_UPPER)
- add_points = 1;
- else
- failed = 1;
- break;
-
- case '.':
- // dot in pre- section, match on any dot before this point in the word
- for(p=pre_ptr; *p != ' '; p--)
- {
- if(*p == '.')
- {
- add_points = 50;
- break;
- }
- }
- if(*p == ' ')
- failed = 1;
- break;
-
- case '-':
- if((letter == '-') || ((letter == ' ') && (word_flags & FLAG_HYPHEN)))
- {
- add_points = (22-distance_right); // one point more than match against space
- }
- else
- failed = 1;
- break;
-
- default:
- if(letter == rb)
- {
- if(letter == RULE_SPACE)
- add_points = 4;
- else
- add_points = (21-distance_left);
- }
- else
- failed = 1;
- break;
- }
- break;
- }
-
- if(failed == 0)
- match.points += add_points;
- }
-
- if(failed == 2)
- {
- /* matched OK, is this better than the last best match ? */
- if(match.points >= best.points)
- {
- memcpy(&best,&match,sizeof(match));
- total_consumed = consumed;
- }
-
-#ifdef LOG_TRANSLATE
- if((option_phonemes == 2) && (match.points > 0) && ((word_flags & FLAG_NO_TRACE) == 0))
- {
- // show each rule that matches, and it's points score
- int pts;
- char decoded_phonemes[80];
-
- // note: 'count' contains the rule number, if we want to include it
- pts = match.points;
- if(group_length > 1)
- pts += 35; // to account for an extra letter matching
- DecodePhonemes(match.phonemes,decoded_phonemes);
- fprintf(f_trans,"%3d\t%s [%s]\n",pts,DecodeRule(group,rule_start),decoded_phonemes);
- }
-#endif
-
- }
-
- /* skip phoneme string to reach start of next template */
- while(*rule++ != 0);
- }
-
-#ifdef LOG_TRANSLATE
- if((option_phonemes == 2) && ((word_flags & FLAG_NO_TRACE)==0))
- {
- if(group_length <= 1)
- fprintf(f_trans,"\n");
- }
-#endif
-
- /* advance input data pointer */
- total_consumed += group_length;
- if(total_consumed == 0)
- total_consumed = 1; /* always advance over 1st letter */
-
- *word += total_consumed;
-
- if(best.points == 0)
- best.phonemes = "";
- memcpy(match_out,&best,sizeof(MatchRecord));
-} /* end of MatchRule */
-
-
-
-
-int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, char *end_phonemes, int word_flags, unsigned int *dict_flags)
-{//=====================================================================================================================================
-/* Translate a word bounded by space characters
- Append the result to 'phonemes' and any standard prefix/suffix in 'end_phonemes' */
-
- unsigned char c, c2;
- unsigned int c12;
- int wc=0;
- int wc_prev;
- int wc_bytes;
- char *p2; /* copy of p for use in double letter chain match */
- int found;
- int g; /* group chain number */
- int g1; /* first group for this letter */
- int n;
- int letter;
- int any_alpha=0;
- int ix;
- unsigned int digit_count=0;
- char *p;
- int dict_flags0=0;
- MatchRecord match1;
- MatchRecord match2;
- char ph_buf[40];
- char word_copy[N_WORD_BYTES];
- static const char str_pause[2] = {phonPAUSE_NOLINK,0};
-
- char group_name[4];
-
- if(tr->data_dictrules == NULL)
- return(0);
-
- if(dict_flags != NULL)
- dict_flags0 = dict_flags[0];
-
- for(ix=0; ix<(N_WORD_BYTES-1);)
- {
- c = p_start[ix];
- word_copy[ix++] = c;
- if(c == 0)
- break;
- }
- word_copy[ix] = 0;
-
-
-#ifdef LOG_TRANSLATE
- if((option_phonemes == 2) && ((word_flags & FLAG_NO_TRACE)==0))
- {
- char wordbuf[120];
- int ix;
-
- for(ix=0; ((c = p_start[ix]) != ' ') && (c != 0); ix++)
- {
- wordbuf[ix] = c;
- }
- wordbuf[ix] = 0;
- fprintf(f_trans,"Translate '%s'\n",wordbuf);
- }
-#endif
-
- p = p_start;
- tr->word_vowel_count = 0;
- tr->word_stressed_count = 0;
-
- if(end_phonemes != NULL)
- end_phonemes[0] = 0;
-
- while(((c = *p) != ' ') && (c != 0))
- {
- wc_prev = wc;
- wc_bytes = utf8_in(&wc,p);
- if(IsAlpha(wc))
- any_alpha++;
-
- n = tr->groups2_count[c];
- if(IsDigit(wc) && ((tr->langopts.tone_numbers == 0) || !any_alpha))
- {
- // lookup the number in *_list not *_rules
- char string[8];
- char buf[40];
- string[0] = '_';
- memcpy(&string[1],p,wc_bytes);
- string[1+wc_bytes] = 0;
- Lookup(tr, string,buf);
- if(++digit_count >= 2)
- {
- strcat(buf,str_pause);
- digit_count=0;
- }
- AppendPhonemes(tr,phonemes,ph_size,buf);
- p += wc_bytes;
- continue;
- }
- else
- {
- digit_count = 0;
- found = 0;
-
- if(n > 0)
- {
- /* there are some 2 byte chains for this initial letter */
- c2 = p[1];
- c12 = c + (c2 << 8); /* 2 characters */
-
- g1 = tr->groups2_start[c];
- for(g=g1; g < (g1+n); g++)
- {
- if(tr->groups2_name[g] == c12)
- {
- found = 1;
-
- group_name[0] = c;
- group_name[1] = c2;
- group_name[2] = 0;
- p2 = p;
- MatchRule(tr, &p2, group_name, tr->groups2[g], &match2, word_flags, dict_flags0);
- if(match2.points > 0)
- match2.points += 35; /* to acount for 2 letters matching */
-
- /* now see whether single letter chain gives a better match ? */
- group_name[1] = 0;
- MatchRule(tr, &p, group_name, tr->groups1[c], &match1, word_flags, dict_flags0);
-
- if(match2.points >= match1.points)
- {
- // use match from the 2-letter group
- memcpy(&match1,&match2,sizeof(MatchRecord));
- p = p2;
- }
- }
- }
- }
-
- if(!found)
- {
- /* alphabetic, single letter chain */
- group_name[0] = c;
- group_name[1] = 0;
-
- if(tr->groups1[c] != NULL)
- MatchRule(tr, &p, group_name, tr->groups1[c], &match1, word_flags, dict_flags0);
- else
- {
- // no group for this letter, use default group
- MatchRule(tr, &p, "", tr->groups1[0], &match1, word_flags, dict_flags0);
-
- if((match1.points == 0) && ((option_sayas & 0x10) == 0))
- {
- n = utf8_in(&letter,p-1)-1;
-
- if(tr->letter_bits_offset > 0)
- {
- // not a Latin alphabet, switch to the default Latin alphabet language
- if((letter <= 0x241) && iswalpha(letter))
- {
- sprintf(phonemes,"%c%s",phonSWITCH,tr->langopts.ascii_language);
- return(0);
- }
- }
-#ifdef deleted
-// can't switch to a tone language, because the tone-phoneme numbers are not valid for the original language
- if((letter >= 0x4e00) && (letter < 0xa000) && (tr->langopts.ideographs != 1))
- {
- // Chinese ideogram
- sprintf(phonemes,"%czh",phonSWITCH);
- return(0);
- }
-#endif
-
- // is it a bracket ?
- if(IsBracket(letter))
- {
- if(pre_pause < 4)
- pre_pause = 4;
- }
-
- // no match, try removing the accent and re-translating the word
- if((letter >= 0xc0) && (letter <= 0x241) && ((ix = remove_accent[letter-0xc0]) != 0))
- {
- // within range of the remove_accent table
- if((p[-2] != ' ') || (p[n] != ' '))
- {
- // not the only letter in the word
- p2 = p-1;
- p[-1] = ix;
- while((p[0] = p[n]) != ' ') p++;
- while(n-- > 0) *p++ = ' '; // replacement character must be no longer than original
-
- if(tr->langopts.param[LOPT_DIERESES] && (lookupwchar(diereses_list,letter) > 0))
- {
- // vowel with dieresis, replace and continue from this point
- p = p2;
- continue;
- }
-
- phonemes[0] = 0; // delete any phonemes which have been produced so far
- p = p_start;
- tr->word_vowel_count = 0;
- tr->word_stressed_count = 0;
- continue; // start again at the beginning of the word
- }
- }
- else
- if((letter >= 0x3200) && (letter < 0xa700) && (end_phonemes != NULL))
- {
- // ideograms
- // outside the range of the accent table, speak the unknown symbol sound
- Lookup(tr, "_??", ph_buf);
- match1.phonemes = ph_buf;
- match1.points = 1;
- p += (wc_bytes-1);
- }
- }
- }
-
- if(match1.points == 0)
- {
- if((wc >= 0x300) && (wc <= 0x36f))
- {
- // combining accent inside a word, ignore
- }
- else
- if(IsAlpha(wc))
- {
- if((any_alpha > 1) || (p[wc_bytes-1] > ' '))
- {
- // an unrecognised character in a word, abort and then spell the word
- phonemes[0] = 0;
- if(dict_flags != NULL)
- dict_flags[0] |= FLAG_SPELLWORD;
- break;
- }
- }
- else
- {
- LookupLetter(tr, wc, -1, ph_buf);
- if(ph_buf[0])
- {
- match1.phonemes = ph_buf;
- match1.points = 1;
- }
- }
- p += (wc_bytes-1);
- }
- else
- {
- tr->phonemes_repeat_count = 0;
- }
- }
- }
-
- if(match1.phonemes == NULL)
- match1.phonemes = "";
-
- if(match1.points > 0)
- {
- if((match1.phonemes[0] == phonSWITCH) && ((word_flags & FLAG_DONT_SWITCH_TRANSLATOR)==0))
- {
- // an instruction to switch language, return immediately so we can re-translate
- strcpy(phonemes,match1.phonemes);
- return(0);
- }
-
- if((match1.end_type != 0) && (end_phonemes != NULL))
- {
- /* a standard ending has been found, re-translate the word without it */
- if((match1.end_type & SUFX_P) && (word_flags & FLAG_NO_PREFIX))
- {
- // ignore the match on a prefix
- }
- else
- {
- if((match1.end_type & SUFX_P) && ((match1.end_type & 0x7f) == 0))
- {
- // no prefix length specified
- match1.end_type |= p - p_start;
- }
- strcpy(end_phonemes,match1.phonemes);
- memcpy(p_start,word_copy,strlen(word_copy));
- return(match1.end_type);
- }
- }
- if(match1.del_fwd != NULL)
- *match1.del_fwd = REPLACED_E;
- AppendPhonemes(tr,phonemes,ph_size,match1.phonemes);
- }
- }
-
- // any language specific changes ?
- ApplySpecialAttribute(tr,phonemes,dict_flags0);
- memcpy(p_start,word_copy,strlen(word_copy));
-
- return(0);
-} /* end of TranslateRules */
-
-
-void ApplySpecialAttribute2(Translator *tr, char *phonemes, int dict_flags)
-{//========================================================================
- // apply after the translation is complete
- int ix;
- int len;
- char *p;
-
- len = strlen(phonemes);
-
- switch(tr->translator_name)
- {
- case L('i','t'):
- for(ix=0; ix<(len-1); ix++)
- {
- if(phonemes[ix] == phonSTRESS_P)
- {
- p = &phonemes[ix+1];
- if((dict_flags & FLAG_ALT2_TRANS) != 0)
- {
- if(*p == PhonemeCode('E'))
- *p = PhonemeCode('e');
- if(*p == PhonemeCode('O'))
- *p = PhonemeCode('o');
- }
- else
- {
- if(*p == PhonemeCode('e'))
- *p = PhonemeCode('E');
- if(*p == PhonemeCode('o'))
- *p = PhonemeCode('O');
- }
- break;
- }
- }
- break;
- }
-} // end of ApplySpecialAttribute2
-
-
-void ApplySpecialAttribute(Translator *tr, char *phonemes, int dict_flags)
-{//=======================================================================
-// Amend the translated phonemes according to an attribute which is specific for the language.
- int len;
- int ix;
- char *p_end;
- int phoneme_1;
-
- if((dict_flags & (FLAG_ALT_TRANS | FLAG_ALT2_TRANS)) == 0)
- return;
-
- len = strlen(phonemes);
- p_end = &phonemes[len-1];
-
- switch(tr->translator_name)
- {
- case L('d','e'):
- if(p_end[0] == PhonemeCode2('i',':'))
- {
- // words ends in ['i:], change to [=I@]
- p_end[-1] = phonSTRESS_PREV;
- p_end[0] = PhonemeCode('I');
- p_end[1] = phonSCHWA;
- p_end[2] = 0;
- }
- break;
-
- case L('p','t'):
- phoneme_1 = PhonemeCode('o');
- for(ix=0; ix<(len-1); ix++)
- {
- if(phonemes[ix] == phoneme_1)
- {
- phonemes[ix] = PhonemeCode('O');
- break;
- }
- }
- break;
-
- case L('r','o'):
- if(p_end[0] == PhonemeCode('j'))
- {
- // word end in [j], change to ['i]
- p_end[0] = phonSTRESS_P;
- p_end[1] = PhonemeCode('i');
- p_end[2] = 0;
- }
- break;
- }
-} // end of ApplySpecialAttribute
-
-
-
-//=============================================================================================
-// Look up a word in the pronunciation dictionary list
-// - exceptions which override the usual pronunciation rules, or which give a word
-// special properties, such as pronounce as unstressed
-//=============================================================================================
-
-// common letter pairs, encode these as a single byte
-static const short pairs_ru[] = {
-0x010c, // ла 21052 0x23
-0x010e, // на 18400
-0x0113, // та 14254
-0x0301, // ав 31083
-0x030f, // ов 13420
-0x060e, // не 21798
-0x0611, // ре 19458
-0x0903, // ви 16226
-0x0b01, // ак 14456
-0x0b0f, // ок 17836
-0x0c01, // ал 13324
-0x0c09, // ил 16877
-0x0e01, // ан 15359
-0x0e06, // ен 13543 0x30
-0x0e09, // ин 17168
-0x0e0e, // нн 15973
-0x0e0f, // он 22373
-0x0e1c, // ын 15052
-0x0f03, // во 24947
-0x0f11, // ро 13552
-0x0f12, // со 16368
-0x100f, // оп 19054
-0x1011, // рп 17067
-0x1101, // ар 23967
-0x1106, // ер 18795
-0x1109, // ир 13797
-0x110f, // ор 21737
-0x1213, // тс 25076
-0x1220, // яс 14310
-0x7fff};
-//0x040f ог 12976
-//0x1306 ет 12826
-//0x0f0d мо 12688
-
-
-int TransposeAlphabet(char *text, int offset, int min, int max)
-{//============================================================
-// transpose cyrillic alphabet (for example) into ascii (single byte) character codes
-// return: number of bytes, bit 6: 1=used compression
- int c;
- int c2;
- int ix;
- char *p = text;
- char *p2 = text;
- int all_alpha=1;
- int bits;
- int acc;
-
- do {
- p += utf8_in(&c,p);
- if((c >= min) && (c <= max))
- {
- *p2++ = c - offset;
- }
- else
- if(c != 0)
- {
- p2 += utf8_out(c,p2);
- all_alpha=0;
- }
- } while (c != 0);
- *p2 = 0;
-
- if(all_alpha)
- {
- // compress to 6 bits per character
- acc=0;
- bits=0;
-
- p = text;
- p2 = text;
- while((c = *p++) != 0)
- {
- c2 = c + (*p << 8);
- for(ix=0; c2 >= pairs_ru[ix]; ix++)
- {
- if(c2 == pairs_ru[ix])
- {
- // found an encoding for a 2-character pair
- c = ix + 0x23; // 2-character codes start at 0x23
- p++;
- break;
- }
- }
- acc = (acc << 6) + (c & 0x3f);
- bits += 6;
-
- if(bits >= 8)
- {
- bits -= 8;
- *p2++ = (acc >> bits);
- }
- }
- if(bits > 0)
- {
- *p2++ = (acc << (8-bits));
- }
- *p2 = 0;
- return((p2 - text) | 0x40); // bit 6 indicates compressed characters
- }
- return(p2 - text);
-} // end of TransposeAlphabet
-
-
-
-
-static const char *LookupDict2(Translator *tr, const char *word, const char *word2,
- char *phonetic, unsigned int *flags, int end_flags, WORD_TAB *wtab)
-//=====================================================================================
-/* Find an entry in the word_dict file for a specified word.
- Returns NULL if no match, else returns 'word_end'
-
- word zero terminated word to match
- word2 pointer to next word(s) in the input text (terminated by space)
-
- flags: returns dictionary flags which are associated with a matched word
-
- end_flags: indicates whether this is a retranslation after removing a suffix
-*/
-{
- char *p;
- char *next;
- int hash;
- int phoneme_len;
- int wlen;
- unsigned char flag;
- unsigned int dictionary_flags;
- unsigned int dictionary_flags2;
- int condition_failed=0;
- int n_chars;
- int no_phonemes;
- int skipwords;
- int ix;
- const char *word_end;
- const char *word1;
- int wflags = 0;
- char word_buf[N_WORD_BYTES];
-
- if(wtab != NULL)
- {
- wflags = wtab->flags;
- }
-
- word1 = word;
- if(tr->transpose_offset > 0)
- {
- strcpy(word_buf,word);
- wlen = TransposeAlphabet(word_buf, tr->transpose_offset, tr->transpose_min, tr->transpose_max);
- word = word_buf;
- }
- else
- {
- wlen = strlen(word);
- }
-
- hash = HashDictionary(word);
- p = tr->dict_hashtab[hash];
-
- if(p == NULL)
- {
- if(flags != NULL)
- *flags = 0;
- return(0);
- }
-
- // Find the first entry in the list for this hash value which matches.
- // This corresponds to the last matching entry in the *_list file.
-
- while(*p != 0)
- {
- next = p + p[0];
-
- if(((p[1] & 0x7f) != wlen) || (memcmp(word,&p[2],wlen & 0x3f) != 0))
- {
- // bit 6 of wlen indicates whether the word has been compressed; so we need to match on this also.
- p = next;
- continue;
- }
-
- /* found matching entry. Decode the phonetic string */
- word_end = word2;
-
- dictionary_flags = 0;
- dictionary_flags2 = 0;
- no_phonemes = p[1] & 0x80;
-
- p += ((p[1] & 0x3f) + 2);
-
- if(no_phonemes)
- {
- phonetic[0] = 0;
- phoneme_len = 0;
- }
- else
- {
- strcpy(phonetic,p);
- phoneme_len = strlen(p);
- p += (phoneme_len + 1);
- }
-
- while(p < next)
- {
- // examine the flags which follow the phoneme string
-
- flag = *p++;
- if(flag >= 100)
- {
- // conditional rule
- if(flag >= 132)
- {
- // fail if this condition is set
- if((tr->dict_condition & (1 << (flag-132))) != 0)
- condition_failed = 1;
- }
- else
- {
- // allow only if this condition is set
- if((tr->dict_condition & (1 << (flag-100))) == 0)
- condition_failed = 1;
- }
- }
- else
- if(flag > 80)
- {
- // flags 81 to 90 match more than one word
- // This comes after the other flags
- n_chars = next - p;
- skipwords = flag - 80;
-
- // don't use the contraction if any of the words are emphasized
- for(ix=0; ix <= skipwords; ix++)
- {
- if(wflags & FLAG_EMPHASIZED2)
- {
- condition_failed = 1;
- }
- }
-
- if(memcmp(word2,p,n_chars) != 0)
- condition_failed = 1;
-
- if(condition_failed)
- {
- p = next;
- break;
- }
-
- dictionary_flags |= FLAG_SKIPWORDS;
- dictionary_skipwords = skipwords;
- p = next;
- word_end = word2 + n_chars;
- }
- else
- if(flag > 64)
- {
- // stressed syllable information, put in bits 0-3
- dictionary_flags = (dictionary_flags & ~0xf) | (flag & 0xf);
- if((flag & 0xc) == 0xc)
- dictionary_flags |= FLAG_STRESS_END;
- }
- else
- if(flag >= 32)
- {
- dictionary_flags2 |= (1L << (flag-32));
- }
- else
- {
- dictionary_flags |= (1L << flag);
- }
- }
-
- if(condition_failed)
- {
- condition_failed=0;
- continue;
- }
-
- if((end_flags & FLAG_SUFX)==0)
- {
- // no suffix has been removed
- if(dictionary_flags & FLAG_STEM)
- continue; // this word must have a suffix
- }
-
- if((end_flags & SUFX_P) && (dictionary_flags & (FLAG_ONLY | FLAG_ONLY_S)))
- continue; // $only or $onlys, don't match if a prefix has been removed
-
- if(end_flags & FLAG_SUFX)
- {
- // a suffix was removed from the word
- if(dictionary_flags & FLAG_ONLY)
- continue; // no match if any suffix
-
- if((dictionary_flags & FLAG_ONLY_S) && ((end_flags & FLAG_SUFX_S)==0))
- {
- // only a 's' suffix allowed, but the suffix wasn't 's'
- continue;
- }
- }
-
- if(dictionary_flags2 & FLAG_HYPHENATED)
- {
- if(!(wflags & FLAG_HYPHEN_AFTER))
- {
- continue;
- }
- }
- if(dictionary_flags2 & FLAG_CAPITAL)
- {
- if(!(wflags & FLAG_FIRST_UPPER))
- {
- continue;
- }
- }
- if(dictionary_flags2 & FLAG_ALLCAPS)
- {
- if(!(wflags & FLAG_ALL_UPPER))
- {
- continue;
- }
- }
-
- if((dictionary_flags & FLAG_ATEND) && (word_end < tr->clause_end))
- {
- // only use this pronunciation if it's the last word of the clause
- continue;
- }
-
- if(dictionary_flags2 & FLAG_VERB)
- {
- // this is a verb-form pronunciation
-
- if(tr->expect_verb || (tr->expect_verb_s && (end_flags & FLAG_SUFX_S)))
- {
- // OK, we are expecting a verb
- }
- else
- {
- /* don't use the 'verb' pronunciation unless we are
- expecting a verb */
- continue;
- }
- }
- if(dictionary_flags2 & FLAG_PAST)
- {
- if(!tr->expect_past)
- {
- /* don't use the 'past' pronunciation unless we are
- expecting past tense */
- continue;
- }
- }
- if(dictionary_flags2 & FLAG_NOUN)
- {
- if(!tr->expect_noun)
- {
- /* don't use the 'noun' pronunciation unless we are
- expecting a noun */
- continue;
- }
- }
-
- if(flags != NULL)
- {
- flags[0] = dictionary_flags | FLAG_FOUND_ATTRIBUTES;
- flags[1] = dictionary_flags2;
- }
-
- if(phoneme_len == 0)
- {
- if(option_phonemes == 2)
- {
- fprintf(f_trans,"Flags: %s %s\n",word1,print_dictionary_flags(flags));
- }
- return(0); // no phoneme translation found here, only flags. So use rules
- }
-
- if(flags != NULL)
- flags[0] |= FLAG_FOUND; // this flag indicates word was found in dictionary
-
- if(option_phonemes == 2)
- {
- unsigned int flags1 = 0;
- char ph_decoded[N_WORD_PHONEMES];
- int textmode;
-
- DecodePhonemes(phonetic,ph_decoded);
- if(flags != NULL)
- flags1 = flags[0];
-
- if((dictionary_flags & FLAG_TEXTMODE) == 0)
- textmode = 0;
- else
- textmode = 1;
-
- if(textmode == translator->langopts.textmode)
- {
- // only show this line if the word translates to phonemes, not replacement text
- fprintf(f_trans,"Found: %s [%s] %s\n",word1,ph_decoded,print_dictionary_flags(flags));
- }
- }
- return(word_end);
-
- }
- return(0);
-} // end of LookupDict2
-
-
-
-int LookupDictList(Translator *tr, char **wordptr, char *ph_out, unsigned int *flags, int end_flags, WORD_TAB *wtab)
-//==================================================================================================================
-/* Lookup a specified word in the word dictionary.
- Returns phonetic data in 'phonetic' and bits in 'flags'
-
- end_flags: indicates if a suffix has been removed
-*/
-{
- int length;
- const char *found;
- const char *word1;
- const char *word2;
- unsigned char c;
- int nbytes;
- int len;
- char word[N_WORD_BYTES];
- static char word_replacement[N_WORD_BYTES];
-
- length = 0;
- word2 = word1 = *wordptr;
-
- while((word2[nbytes = utf8_nbytes(word2)]==' ') && (word2[nbytes+1]=='.'))
- {
- // look for an abbreviation of the form a.b.c
- // try removing the spaces between the dots and looking for a match
- memcpy(&word[length],word2,nbytes);
- length += nbytes;
- word[length++] = '.';
- word2 += nbytes+3;
- }
- if(length > 0)
- {
- // found an abbreviation containing dots
- nbytes = 0;
- while(((c = word2[nbytes]) != 0) && (c != ' '))
- {
- nbytes++;
- }
- memcpy(&word[length],word2,nbytes);
- word[length+nbytes] = 0;
- found = LookupDict2(tr, word, word2, ph_out, flags, end_flags, wtab);
- if(found)
- {
- // set the skip words flag
- flags[0] |= FLAG_SKIPWORDS;
- dictionary_skipwords = length;
- return(1);
- }
- }
-
- for(length=0; length<N_WORD_BYTES; length++)
- {
- if(((c = *word1++)==0) || (c == ' '))
- break;
- word[length] = c;
- }
- word[length] = 0;
-
- found = LookupDict2(tr, word, word1, ph_out, flags, end_flags, wtab);
-
- if(flags[0] & FLAG_MAX3)
- {
- if(strcmp(ph_out, tr->phonemes_repeat) == 0)
- {
- tr->phonemes_repeat_count++;
- if(tr->phonemes_repeat_count > 3)
- {
- ph_out[0] = 0;
- }
- }
- else
- {
- strncpy0(tr->phonemes_repeat, ph_out, sizeof(tr->phonemes_repeat));
- tr->phonemes_repeat_count = 1;
- }
- }
- else
- {
- tr->phonemes_repeat_count = 0;
- }
-
-
- if((found == 0) && (flags[1] & FLAG_ACCENT))
- {
- int letter;
- word2 = word;
- if(*word2 == '_') word2++;
- len = utf8_in(&letter, word2);
- LookupAccentedLetter(tr,letter, ph_out);
- found = word2 + len;
- }
-
- if(found == 0)
- {
- ph_out[0] = 0;
-
- // try modifications to find a recognised word
-
- if((end_flags & FLAG_SUFX_E_ADDED) && (word[length-1] == 'e'))
- {
- // try removing an 'e' which has been added by RemoveEnding
- word[length-1] = 0;
- found = LookupDict2(tr, word, word1, ph_out, flags, end_flags, wtab);
- }
- else
- if((end_flags & SUFX_D) && (word[length-1] == word[length-2]))
- {
- // try removing a double letter
- word[length-1] = 0;
- found = LookupDict2(tr, word, word1, ph_out, flags, end_flags, wtab);
- }
- }
-
- if(found)
- {
- // if textmode is the default, then words which have phonemes are marked.
- if(tr->langopts.textmode)
- *flags ^= FLAG_TEXTMODE;
-
- if(*flags & FLAG_TEXTMODE)
- {
- // the word translates to replacement text, not to phonemes
-
- if(end_flags & FLAG_ALLOW_TEXTMODE)
- {
- // only use replacement text if this is the original word, not if a prefix or suffix has been removed
- word_replacement[0] = 0;
- word_replacement[1] = ' ';
- sprintf(&word_replacement[2],"%s ",ph_out); // replacement word, preceded by zerochar and space
-
- word1 = *wordptr;
- *wordptr = &word_replacement[2];
-
- if(option_phonemes == 2)
- {
- len = found - word1;
- memcpy(word,word1,len); // include multiple matching words
- word[len] = 0;
- fprintf(f_trans,"Replace: %s %s\n",word,*wordptr);
- }
- }
-
- ph_out[0] = 0;
- return(0);
- }
-
- return(1);
- }
-
- ph_out[0] = 0;
- return(0);
-} // end of LookupDictList
-
-
-
-int Lookup(Translator *tr, const char *word, char *ph_out)
-{//===================================================
- unsigned int flags[2]={0,0};
- char* word1 = (char *)word;
- return(LookupDictList(tr, &word1, ph_out, flags, 0, NULL));
-}
-
-
-
-int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy)
-{//========================================================================
-/* Removes a standard suffix from a word, once it has been indicated by the dictionary rules.
- end_type: bits 0-6 number of letters
- bits 8-14 suffix flags
-
- word_copy: make a copy of the original word
- This routine is language specific. In English it deals with reversing y->i and e-dropping
- that were done when the suffix was added to the original word.
-*/
-
- int i;
- char *word_end;
- int len_ending;
- int end_flags;
- const char *p;
- int len;
- static char ending[12];
-
- // these lists are language specific, but are only relevent if the 'e' suffix flag is used
- static const char *add_e_exceptions[] = {
- "ion", NULL };
-
- static const char *add_e_additions[] = {
- "c", "rs", "ir", "ur", "ath", "ns", "lu", NULL };
-
- for(word_end = word; *word_end != ' '; word_end++)
- {
- /* replace discarded 'e's */
- if(*word_end == REPLACED_E)
- *word_end = 'e';
- }
- i = word_end - word;
- memcpy(word_copy,word,i);
- word_copy[i] = 0;
-
- // look for multibyte characters to increase the number of bytes to remove
- for(len_ending = i = (end_type & 0x3f); i>0 ;i--) // num.of characters of the suffix
- {
- word_end--;
- while((*word_end & 0xc0) == 0x80)
- {
- word_end--; // for multibyte characters
- len_ending++;
- }
- }
-
- // remove bytes from the end of the word and replace them by spaces
- for(i=0; i<len_ending; i++)
- {
- ending[i] = word_end[i];
- word_end[i] = ' ';
- }
- ending[i] = 0;
- word_end--; /* now pointing at last character of stem */
-
- end_flags = (end_type & 0xfff0) | FLAG_SUFX;
-
- /* add an 'e' to the stem if appropriate,
- if stem ends in vowel+consonant
- or stem ends in 'c' (add 'e' to soften it) */
-
- if(end_type & SUFX_I)
- {
- if(word_end[0] == 'i')
- word_end[0] = 'y';
- }
-
- if(end_type & SUFX_E)
- {
- // add 'e' to end of stem
- if(IsLetter(tr, word_end[-1],LETTERGP_VOWEL2) && IsLetter(tr, word_end[0],1))
- {
- // vowel(incl.'y') + hard.consonant
-
- for(i=0; (p = add_e_exceptions[i]) != NULL; i++)
- {
- len = strlen(p);
- if(memcmp(p,&word_end[1-len],len)==0)
- {
- break;
- }
- }
- if(p == NULL)
- end_flags |= FLAG_SUFX_E_ADDED; // no exception found
- }
- else
- {
- for(i=0; (p = add_e_additions[i]) != NULL; i++)
- {
- len = strlen(p);
- if(memcmp(p,&word_end[1-len],len)==0)
- {
- end_flags |= FLAG_SUFX_E_ADDED;
- break;
- }
- }
- }
-
- if(end_flags & FLAG_SUFX_E_ADDED)
- {
- word_end[1] = 'e';
-#ifdef LOG_TRANSLATE
-if(option_phonemes == 2)
-{
- fprintf(f_trans,"add e\n");
-}
-#endif
- }
- }
-
- if((end_type & SUFX_V) && (tr->expect_verb==0))
- tr->expect_verb = 1; // this suffix indicates the verb pronunciation
-
-
- if((strcmp(ending,"s")==0) || (strcmp(ending,"es")==0))
- end_flags |= FLAG_SUFX_S;
-
- if(strcmp(ending,"'s")==0)
- end_flags &= ~FLAG_SUFX; // don't consider 's as an added suffix
-
- return(end_flags);
-} /* end of RemoveEnding */
-
-
diff --git a/navit/support/espeak/espeak-data/af_dict b/navit/support/espeak/espeak-data/af_dict
deleted file mode 100644
index 7819c9fe0..000000000
--- a/navit/support/espeak/espeak-data/af_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/ca_dict b/navit/support/espeak/espeak-data/ca_dict
deleted file mode 100644
index b9a4ea43a..000000000
--- a/navit/support/espeak/espeak-data/ca_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/config b/navit/support/espeak/espeak-data/config
deleted file mode 100755
index be1b6246a..000000000
--- a/navit/support/espeak/espeak-data/config
+++ /dev/null
@@ -1,9 +0,0 @@
-//pa_device 7
-
-// play a sound for punctuation, rather than speak its name
-//soundicon _( /usr/share/sounds/sound-icons/left-round-bracket
-//soundicon _) /usr/share/sounds/sound-icons/right-round-bracket
-//soundicon _[ /usr/share/sounds/sound-icons/left-square-bracket
-//soundicon _] /usr/share/sounds/sound-icons/right-square-bracket
-//soundicon _{ /usr/share/sounds/sound-icons/left-brace
-//soundicon _} /usr/share/sounds/sound-icons/right-brace
diff --git a/navit/support/espeak/espeak-data/cs_dict b/navit/support/espeak/espeak-data/cs_dict
deleted file mode 100644
index 3391b98b2..000000000
--- a/navit/support/espeak/espeak-data/cs_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/cy_dict b/navit/support/espeak/espeak-data/cy_dict
deleted file mode 100644
index 13a768030..000000000
--- a/navit/support/espeak/espeak-data/cy_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/da_dict b/navit/support/espeak/espeak-data/da_dict
deleted file mode 100644
index 75ccbd670..000000000
--- a/navit/support/espeak/espeak-data/da_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/de_dict b/navit/support/espeak/espeak-data/de_dict
deleted file mode 100644
index 988f4c31b..000000000
--- a/navit/support/espeak/espeak-data/de_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/el_dict b/navit/support/espeak/espeak-data/el_dict
deleted file mode 100644
index a6ab63dee..000000000
--- a/navit/support/espeak/espeak-data/el_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/en_dict b/navit/support/espeak/espeak-data/en_dict
deleted file mode 100644
index d15b0e9ab..000000000
--- a/navit/support/espeak/espeak-data/en_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/eo_dict b/navit/support/espeak/espeak-data/eo_dict
deleted file mode 100644
index 155523963..000000000
--- a/navit/support/espeak/espeak-data/eo_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/es_dict b/navit/support/espeak/espeak-data/es_dict
deleted file mode 100644
index 203da2639..000000000
--- a/navit/support/espeak/espeak-data/es_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/fi_dict b/navit/support/espeak/espeak-data/fi_dict
deleted file mode 100644
index a08d45a6f..000000000
--- a/navit/support/espeak/espeak-data/fi_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/fr_dict b/navit/support/espeak/espeak-data/fr_dict
deleted file mode 100644
index e66708e04..000000000
--- a/navit/support/espeak/espeak-data/fr_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/grc_dict b/navit/support/espeak/espeak-data/grc_dict
deleted file mode 100644
index 0aeab45e0..000000000
--- a/navit/support/espeak/espeak-data/grc_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/hbs_dict b/navit/support/espeak/espeak-data/hbs_dict
deleted file mode 100644
index 91ee7ba4b..000000000
--- a/navit/support/espeak/espeak-data/hbs_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/hi_dict b/navit/support/espeak/espeak-data/hi_dict
deleted file mode 100644
index 388d3f246..000000000
--- a/navit/support/espeak/espeak-data/hi_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/hu_dict b/navit/support/espeak/espeak-data/hu_dict
deleted file mode 100644
index 5a1f21165..000000000
--- a/navit/support/espeak/espeak-data/hu_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/hy_dict b/navit/support/espeak/espeak-data/hy_dict
deleted file mode 100644
index 18c3e2027..000000000
--- a/navit/support/espeak/espeak-data/hy_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/id_dict b/navit/support/espeak/espeak-data/id_dict
deleted file mode 100644
index 3c9967ce8..000000000
--- a/navit/support/espeak/espeak-data/id_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/is_dict b/navit/support/espeak/espeak-data/is_dict
deleted file mode 100644
index 10cf846f8..000000000
--- a/navit/support/espeak/espeak-data/is_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/it_dict b/navit/support/espeak/espeak-data/it_dict
deleted file mode 100644
index 40cf952a2..000000000
--- a/navit/support/espeak/espeak-data/it_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/jbo_dict b/navit/support/espeak/espeak-data/jbo_dict
deleted file mode 100644
index f7ebcf454..000000000
--- a/navit/support/espeak/espeak-data/jbo_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/ku_dict b/navit/support/espeak/espeak-data/ku_dict
deleted file mode 100644
index 18d285845..000000000
--- a/navit/support/espeak/espeak-data/ku_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/la_dict b/navit/support/espeak/espeak-data/la_dict
deleted file mode 100644
index 3ef82f832..000000000
--- a/navit/support/espeak/espeak-data/la_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/lv_dict b/navit/support/espeak/espeak-data/lv_dict
deleted file mode 100644
index 3ecb61b51..000000000
--- a/navit/support/espeak/espeak-data/lv_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/af1_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/af1_phtrans
deleted file mode 100644
index fc9ad0179..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/af1_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/ca1_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/ca1_phtrans
deleted file mode 100644
index 4fe4188e5..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/ca1_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/cr1_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/cr1_phtrans
deleted file mode 100644
index 15e2c4988..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/cr1_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/cs_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/cs_phtrans
deleted file mode 100644
index 85ebb03e3..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/cs_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/de2_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/de2_phtrans
deleted file mode 100644
index c5af1a7c4..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/de2_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/de4_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/de4_phtrans
deleted file mode 100644
index b10fc8441..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/de4_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/de6_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/de6_phtrans
deleted file mode 100644
index 4cb62d9c2..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/de6_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/en1_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/en1_phtrans
deleted file mode 100644
index c847d1703..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/en1_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/es_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/es_phtrans
deleted file mode 100644
index b959f92c1..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/es_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/fr1_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/fr1_phtrans
deleted file mode 100644
index 1a242b36f..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/fr1_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/gr2_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/gr2_phtrans
deleted file mode 100644
index b3775abbd..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/gr2_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/grc-de6_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/grc-de6_phtrans
deleted file mode 100644
index e41d3105c..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/grc-de6_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/hu1_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/hu1_phtrans
deleted file mode 100644
index 26dad49a0..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/hu1_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/id1_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/id1_phtrans
deleted file mode 100644
index 452de8c8a..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/id1_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/in1_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/in1_phtrans
deleted file mode 100644
index 7f4631899..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/in1_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/it3_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/it3_phtrans
deleted file mode 100644
index 6d826477b..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/it3_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/la1_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/la1_phtrans
deleted file mode 100644
index 1f2eb9290..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/la1_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/nl_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/nl_phtrans
deleted file mode 100644
index d982c1845..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/nl_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/pl1_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/pl1_phtrans
deleted file mode 100644
index 9d4e50fd7..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/pl1_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/pt1_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/pt1_phtrans
deleted file mode 100644
index c5172f7b3..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/pt1_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/pt_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/pt_phtrans
deleted file mode 100644
index 9de1630d9..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/pt_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/ptbr4_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/ptbr4_phtrans
deleted file mode 100644
index 0b94de719..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/ptbr4_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/ptbr_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/ptbr_phtrans
deleted file mode 100644
index a1dbba000..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/ptbr_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/ro1_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/ro1_phtrans
deleted file mode 100644
index 4aeaf54ec..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/ro1_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/sv2_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/sv2_phtrans
deleted file mode 100644
index ae119d86e..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/sv2_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/sv_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/sv_phtrans
deleted file mode 100644
index bb556eb28..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/sv_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/us3_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/us3_phtrans
deleted file mode 100644
index 449b419ac..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/us3_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mbrola_ph/us_phtrans b/navit/support/espeak/espeak-data/mbrola_ph/us_phtrans
deleted file mode 100644
index bdeef5d1a..000000000
--- a/navit/support/espeak/espeak-data/mbrola_ph/us_phtrans
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/mk_dict b/navit/support/espeak/espeak-data/mk_dict
deleted file mode 100644
index a6cf3dc53..000000000
--- a/navit/support/espeak/espeak-data/mk_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/nl_dict b/navit/support/espeak/espeak-data/nl_dict
deleted file mode 100644
index f286bee90..000000000
--- a/navit/support/espeak/espeak-data/nl_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/no_dict b/navit/support/espeak/espeak-data/no_dict
deleted file mode 100644
index 4f8f84f0d..000000000
--- a/navit/support/espeak/espeak-data/no_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/pap_dict b/navit/support/espeak/espeak-data/pap_dict
deleted file mode 100644
index 11eb4b515..000000000
--- a/navit/support/espeak/espeak-data/pap_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/phondata b/navit/support/espeak/espeak-data/phondata
deleted file mode 100644
index d46417ed0..000000000
--- a/navit/support/espeak/espeak-data/phondata
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/phondata-manifest b/navit/support/espeak/espeak-data/phondata-manifest
deleted file mode 100644
index 4197d142d..000000000
--- a/navit/support/espeak/espeak-data/phondata-manifest
+++ /dev/null
@@ -1,729 +0,0 @@
-# This file lists the type of data that has been compiled into the
-# phondata file
-#
-# The first character of a line indicates the type of data:
-# S - A SPECT_SEQ structure
-# W - A wavefile segment
-# E - An envelope
-#
-# Address is the displacement within phondata of this item
-#
-# Address Data file
-# ------- ---------
-W 0x00004 ustop/null
-S 0x00154 vowel/@
-S 0x00218 vowel/@-
-W 0x002dc ustop/percus10
-S 0x004e8 j/j@
-S 0x005ec j2/j2@
-S 0x006b0 w/w@
-S 0x00774 l/l@
-S 0x00838 l^/j2@
-S 0x008fc r/r@
-S 0x009c0 r2/r2@
-S 0x00a84 m/m@
-S 0x00b88 n/n@
-S 0x00c8c nn/nn@
-S 0x00d50 n^/n^@
-S 0x00ed4 l/L1_@L
-S 0x00fd8 l/L2_@L
-S 0x010dc l/l_@
-S 0x011a0 l/xl
-S 0x01224 w/xw
-S 0x012a8 j/xj
-S 0x0132c r/xr
-S 0x013b0 r3/r_@
-S 0x01474 j/ja
-S 0x01578 j2/j2a
-S 0x0163c w/wa
-S 0x01700 l/la
-S 0x01784 l^/j2a
-S 0x01848 r/ra
-S 0x0190c r2/r2a
-S 0x019d0 m/ma
-S 0x01ad4 n/na
-S 0x01bd8 nn/nna
-S 0x01c9c n^/n^a
-S 0x01de0 l/L1_aL
-S 0x01ee4 l/L2_aL
-S 0x01fe8 l/l_a
-S 0x020ac r3/r_a
-S 0x02170 j/je
-S 0x02274 j2/j2e
-S 0x02338 w/we
-S 0x023fc l/le
-S 0x02480 l^/j2e
-S 0x02544 r/re
-S 0x02608 r2/r2e
-S 0x0270c m/me
-S 0x02810 n/ne
-S 0x02914 nn/nne
-S 0x029d8 n^/n^e
-S 0x02b5c l/L1_eL
-S 0x02c20 l/L2_eL
-S 0x02ce4 l/l_e
-S 0x02d68 r3/r_e
-S 0x02e2c j/ji
-S 0x02ef0 j2/j2i
-S 0x02fb4 w/wi
-S 0x03078 l/li
-S 0x0313c l^/j2i
-S 0x03200 r/ri
-S 0x032c4 r2/r2i
-S 0x03388 m/mi
-S 0x034cc n/ni
-S 0x035d0 nn/nni
-S 0x03694 n^/n^i
-S 0x03818 l/L1_iL
-S 0x0391c l/L2_iL
-S 0x03a20 l/l_i
-S 0x03ae4 nn/inn
-S 0x03ba8 j2/xj2
-S 0x03c2c r3/r_i
-S 0x03cf0 j/jo
-S 0x03e34 j2/j2o
-S 0x03f38 w/wo
-S 0x03ffc l/lo
-S 0x04100 l^/j2o
-S 0x04204 r/ro
-S 0x042c8 r2/r2o
-S 0x0438c m/mo
-S 0x04490 n/no
-S 0x04594 nn/nno
-S 0x04658 n^/n^o
-S 0x0481c l/L1_oL
-S 0x04960 l/L2_oL
-S 0x04aa4 l/l_o
-S 0x04ba8 r3/r_o
-S 0x04c6c j/ju
-S 0x04d30 j2/j2u
-S 0x04df4 w/wu
-S 0x04eb8 l/lu
-S 0x04f7c l^/j2u
-S 0x05080 r/ru
-S 0x05144 r2/r2u
-S 0x05208 m/mu
-S 0x0530c n/nu
-S 0x05410 nn/nnu
-S 0x054d4 n^/n^u
-S 0x05658 l/L1_uL
-S 0x0575c l/L2_uL
-S 0x05860 l/l_u
-S 0x05924 r3/r_u
-S 0x059e8 r/r
-S 0x05aac r/_r
-S 0x05b70 r/tr
-S 0x05bf4 r/r_
-S 0x05d38 r3/r_
-W 0x05dbc r3/rx
-S 0x07114 r3/r_n
-S 0x07198 r/rr
-S 0x0725c r/trr
-S 0x07320 r2/_r2
-S 0x073e4 r3/r_trill2
-W 0x074a8 r3/r_trill2.wav
-S 0x07bb4 r3/r_trill
-W 0x07cb8 r3/r_trill.wav
-W 0x08724 r3/r_trill3.wav
-S 0x08b68 r3/r_uvl
-W 0x08c6c r3/r_uvl.wav
-S 0x09b74 l/l
-S 0x09bf8 l/_l
-S 0x09cbc l/tl
-S 0x09d40 l/l_long
-S 0x09dc4 l/l_
-S 0x09e48 l^/l^
-S 0x09f4c l^/_l^
-S 0x0a050 w/w
-S 0x0a0d4 w/_w
-S 0x0a198 w/w_
-S 0x0a25c w/iw_
-S 0x0a320 j/_j
-S 0x0a3a4 j/j_
-S 0x0a468 j2/_j2
-S 0x0a4ec m/_m
-S 0x0a570 m/m_
-S 0x0a634 m/mj
-S 0x0a6f8 n/_n
-S 0x0a77c n/n_
-S 0x0a840 n/nj
-S 0x0a904 n/_nr
-S 0x0a988 n/nr_
-S 0x0aa4c n^/_n^
-S 0x0aad0 n^/n^_
-S 0x0ac14 nn/_nn
-S 0x0ac98 nn/nn_
-S 0x0ad5c nn/nnj
-S 0x0ade0 r3/@tap
-S 0x0af24 r3/@tap2
-S 0x0b068 r3/@tap_rfx
-S 0x0b1ac b/b
-W 0x0b2b0 x/b
-S 0x0b414 b/b_
-W 0x0b4d8 x/b_
-S 0x0b8f0 b/ba
-S 0x0b9f4 b/b@
-S 0x0baf8 b/be
-S 0x0bbfc b/bi
-S 0x0bd00 b/bo
-S 0x0be04 b/bu
-S 0x0bf08 b/b@2
-S 0x0c00c b/xb
-S 0x0c0d0 d/d
-W 0x0c194 x/d
-S 0x0c3b0 d/d_
-W 0x0c474 x/d_
-S 0x0c89c d/dr
-S 0x0c920 d/xd
-W 0x0c9e4 x/d_dnt
-S 0x0ccc8 d/tap3
-S 0x0cdcc d/tap1
-S 0x0ce90 dzh/dzh
-W 0x0cf54 x/dzh
-S 0x0d360 dzh/dzh_
-W 0x0d424 x/dzh_
-S 0x0de5c dzh/xdzh
-W 0x0df20 x/dz_pzd
-S 0x0e380 dzh/dz_pzd
-S 0x0e444 dzh/dz_pzd_
-S 0x0e508 dzh/xdz_pzd
-S 0x0e5cc g/g
-W 0x0e690 x/g2
-S 0x0e918 g/g_
-W 0x0e9dc x/g_
-S 0x0ed9c g/xg
-S 0x0ee60 g2/g
-W 0x0ef24 x/g2_
-S 0x0f2e4 g2/g_
-S 0x0f3a8 g2/xg
-S 0x0f46c voc/bh
-W 0x0f530 vocw/v
-S 0x0fe30 voc/v_
-S 0x0fef4 voc/v
-S 0x0fff8 voc/vj
-S 0x100fc voc/dh
-W 0x101c0 vocw/dh
-S 0x10ac8 voc/dh_
-S 0x10b8c voc/z
-W 0x10c50 ufric/s_
-S 0x11704 voc/z_
-S 0x117c8 voc/zh
-W 0x1188c vocw/zh
-S 0x121f4 voc/zh_
-W 0x122b8 vocw/zh_rfx
-S 0x12b48 voc/z_pzd
-W 0x12c0c ufric/s_pzd
-S 0x13544 voc/z_pzd_
-W 0x13608 ufric/s_pzd_
-W 0x1410c ufric/sh_pzd
-W 0x14a40 ufric/sh_pzd_
-S 0x15508 voc/j
-W 0x1560c ufric/ch
-S 0x15d24 voc/Q
-W 0x15de8 vocw/Q
-S 0x165f4 voc/Q_
-W 0x166b8 vocw/Q_
-S 0x16ec4 voc/Q_ulv
-W 0x16fc8 ufric/xx
-W 0x17ac4 ustop/p
-W 0x17e34 ustop/p_
-W 0x18644 ustop/pr
-W 0x18a8c ustop/p_unasp
-W 0x18db8 ustop/pl
-W 0x191b0 ustop/t
-W 0x195e4 ustop/t_
-W 0x19aa4 ustop/t_dnt
-W 0x19eb4 ustop/tr
-W 0x1a614 ustop/t_hi
-W 0x1a9b0 ustop/tsh
-W 0x1aff0 ustop/tsh_
-W 0x1b930 ustop/ts_pzd
-W 0x1c034 ustop/c
-W 0x1c2e4 ustop/t_pzd
-W 0x1c730 ustop/k
-W 0x1cc04 ustop/k_
-W 0x1d0c0 ustop/kr
-W 0x1d700 ustop/k_unasp
-W 0x1dbd4 ustop/kl
-W 0x1e204 ustop/ki
-W 0x1e7cc ustop/q
-W 0x1e938 ustop/q_u
-W 0x1ea58 ufric/f
-W 0x1f248 ufric/f_
-W 0x1fd18 ufric/th
-W 0x205b0 ufric/th_
-W 0x20e30 ufric/s
-W 0x215d0 ufric/s!
-W 0x21e80 ufric/sh
-W 0x22830 ufric/sh_
-W 0x232e0 ufric/sh_rfx
-W 0x23c7c ufric/ll
-W 0x246c0 ufric/ch_
-W 0x24fe8 ufric/x_hr
-W 0x258fc ufric/x
-W 0x26260 h/h_
-W 0x2690c h/h@
-W 0x26e60 h/ha
-W 0x274dc h/he
-W 0x27b70 h/hi
-W 0x28108 h/ho
-W 0x287c4 h/hu
-S 0x28ee8 vowel/a_2
-S 0x28fec vowel/a#
-S 0x290f0 vowel/e
-S 0x291f4 vowel/ee_1
-S 0x29338 vowel/i
-S 0x2943c vowel/o
-S 0x29580 vowel/oo_4
-S 0x29684 vowel/u_bck
-S 0x29788 vowel/uu_2
-S 0x2988c vowel/y
-S 0x299d0 vowel/y#
-S 0x29ad4 vdiph/au_4
-S 0x29c58 vdiph/eu
-S 0x29d9c vdiph2/iu
-S 0x29f20 vdiph/ai
-S 0x2a064 vdiph/ei
-S 0x2a1a8 vdiph/eei
-S 0x2a32c vdiph/oi
-S 0x2a4f0 vdiph/ui
-S 0x2a634 w/w2
-W 0x2a6f8 ustop/p_unasp_
-W 0x2a834 ustop/ts
-W 0x2b290 ustop/ts_
-W 0x2bbf0 ustop/t_dnt2
-S 0x2be48 vwl_en/@L
-S 0x2bf0c vowel/a
-S 0x2c010 vowel/a#_3
-S 0x2c0d4 vowel/ee_2
-S 0x2c1d8 vowel/ii_4
-S 0x2c2dc vowel/ii_en
-S 0x2c3a0 vowel/0
-S 0x2c4a4 vowel/V_2
-S 0x2c5a8 vowel/uu
-S 0x2c6ac vowel/aa_2
-S 0x2c830 vowel/3_en
-S 0x2c974 vowel/i_en
-S 0x2cab8 w/wi2
-S 0x2cbbc vowel/oo_en
-S 0x2cd00 vdiph2/uw_2
-S 0x2ce44 vwl_en/u_L
-S 0x2cf88 vdiph/au
-S 0x2d10c vdiph/@u_en
-S 0x2d290 vdiph/ai_2
-S 0x2d454 vdiph/ooi
-S 0x2d618 vdiph2/ii@
-S 0x2d79c vdiph2/uu@
-S 0x2d8e0 vwl_en/aI@
-S 0x2daa4 vwl_en/aU@
-S 0x2dc28 vowelr/V_r
-S 0x2dd6c vowelr/V3_r
-S 0x2deb0 vnasal/aa_n2
-S 0x2dff4 vnasal/ee_n
-S 0x2e138 vnasal/oo_n
-S 0x2e23c vowel/oe
-S 0x2e300 vowel/@_fr
-S 0x2e3c4 vowel/ee
-S 0x2e4c8 vowel/ii
-S 0x2e5cc vowel/e_3
-S 0x2e6d0 vowel/0_2
-S 0x2e7d4 vowel/o-_2
-S 0x2e8d8 vowel/aa_5
-S 0x2ea1c vwl_en_n/aa_5
-S 0x2eb60 vowel/3_2
-S 0x2eca4 vowel/oo_1
-S 0x2ede8 vwl_en_n/O@
-S 0x2eeec vdiph2/uw_4
-S 0x2f030 vdiph/eeu_3
-S 0x2f174 vdiph/ae_2
-S 0x2f2f8 vdiph2/ee@
-S 0x2f43c vdiph2/i@
-S 0x2f600 vwl_en_us/3_us
-S 0x2f704 vowel/@_4
-S 0x2f7c8 vowel/@_low2
-S 0x2f88c vwl_en_us/a
-S 0x2f990 vnasal/ee_n2
-S 0x2fad4 vwl_en_us/ee
-S 0x2fbd8 vowel/ii#_3
-S 0x2fcdc vowel/ii_final
-S 0x2fde0 vowel/aa_8
-S 0x2fee4 vwl_en_us/oor
-S 0x30028 vowel/V_6
-S 0x3012c vowel/8_2
-S 0x30230 vwl_en_us/ar
-S 0x30374 vwl_en_us/3_us2
-S 0x304b8 vowel/0_3
-S 0x305bc vwl_en_us/or
-S 0x30700 vowel/aa#
-S 0x30804 vdiph2/uw
-S 0x30948 vdiph/aoo
-S 0x30a8c vdiph/8u
-S 0x30bd0 vdiph/aae
-S 0x30d54 vdiph2/ei_4
-S 0x30e98 vdiph/ooi_4
-S 0x30fdc vwl_en_us/er
-S 0x31120 vwl_en_us/ir
-S 0x31264 vwl_en_us/ur
-S 0x313a8 vwl_en_us/ai@
-S 0x3152c d/tap2
-S 0x315f0 d/x_tap
-S 0x316b4 vowel/@_3
-S 0x31778 vowel/V
-S 0x3187c vowel/a_3
-S 0x31980 vowel/e_e
-S 0x31a84 vowel/e#
-S 0x31b88 vowel/e_5
-S 0x31c8c vowel/oo_2
-S 0x31d90 vowel/V_4
-S 0x31e94 vowel/u#_4
-S 0x31f98 vowelr/aa_r
-S 0x3215c vdiph2/e@
-S 0x322a0 vowel/i_5
-S 0x323a4 vowel/oo
-S 0x324a8 vowelr/oo_r
-S 0x325ac vowelr/o_r
-S 0x32730 vowel/u#
-S 0x32834 vdiph/au#
-S 0x32978 vowel/o_3
-S 0x32a7c vdiph/ai_7
-S 0x32c00 vwl_en/aI@_2
-S 0x32d84 vwl_en/@L_2
-S 0x32e88 vowel/e_2
-S 0x32f8c vdiph/0i_2
-S 0x33110 vowelr/i_r
-S 0x33254 vdiph2/u#@
-S 0x33398 vowel/@_low
-S 0x3345c vowel/&
-S 0x33560 vowel/e_mid
-S 0x33664 vowel/V_3
-S 0x33728 vowel/o-_3
-S 0x3382c vwl_en_rp/aa
-S 0x33970 vowel/3_3
-S 0x33ab4 vowel/u_fnt
-S 0x33bb8 vdiph/au_3
-S 0x33d3c vdiph/@u_2
-S 0x33e80 vdiph/ai_6
-S 0x34044 vdiph2/ei_2
-S 0x34188 vdiph/ooi_3
-S 0x3430c vdiph2/ee@_2
-S 0x34450 vwl_en_rp/i@
-S 0x345d4 vowel/o_mid
-S 0x346d8 vwl_en_rp/aU@
-S 0x3485c vowel/ii_6
-S 0x34920 vdiph2/ei_3
-S 0x34a64 vdiph/@u
-S 0x34ba8 vdiph/Vu_2
-S 0x34d2c vdiph/@i_3
-S 0x34e70 vdiph2/i@_2
-S 0x34ff4 vwl_en/ooi@
-S 0x351b8 vowel/@_fnt
-S 0x352bc vowel/uu_bck
-S 0x353c0 vowel/i_fnt
-S 0x354c4 vdiph2/o_oo
-S 0x35608 vowel/u
-S 0x3570c vdiph/aau_2
-S 0x35850 vdiph2/ie
-S 0x35994 vwl_af/@
-S 0x35a58 vwl_af/r@
-S 0x35b1c vowel/e_mid2
-S 0x35c20 vwl_af/I
-S 0x35ce4 vowel/oo_3
-S 0x35da8 vowel/uu_3
-S 0x35e6c vowel/ee_3
-S 0x35f30 l/L_eL_af
-S 0x35ff4 vowel/aa_3
-S 0x360f8 vdiph/i@_2
-S 0x3627c vowel/i_3
-S 0x36380 vdiph2/o@
-S 0x36504 vowel/y_3
-S 0x36608 vdiph2/iu_3
-S 0x367cc vdiph/Vu
-S 0x36950 vdiph/ai_4
-S 0x36ad4 vdiph/aai_2
-S 0x36c98 vdiph/@i_2
-S 0x36ddc vdiph/ooi_2
-S 0x36f60 vdiph/oi_2
-S 0x37124 vdiph/ui_2
-S 0x372a8 vdiph/y#y_2
-S 0x3742c vdiph2/y#@
-S 0x37570 vnasal/aa_n3
-S 0x376b4 vnasal/e_n
-S 0x377b8 vnasal/o_n2
-W 0x378fc ufric/x2
-S 0x38254 vowel/ii_3
-S 0x38358 vowel/ii#
-S 0x3845c vowel/i#
-S 0x38560 vowel/o_2
-S 0x386a4 vdiph2/iu_4
-S 0x387e8 vdiph/ui_3
-S 0x3896c vowel/aa_6
-S 0x38ab0 vowel/i_2
-S 0x38bb4 vdiph/ai_5
-S 0x38cf8 vowel/yy_4
-S 0x38dfc l/l_3
-S 0x38e80 j/_j_short
-S 0x38f04 vdiph/eei_2
-S 0x39048 vowelr/r-voc
-S 0x3918c vwl_hi/l-voc
-S 0x39290 vowel/i_4
-S 0x39394 vowel/aa_9
-S 0x39498 vowel/u_2
-S 0x3959c vowel/uu_4
-S 0x396a0 vdiph/aai_3
-S 0x39824 vdiph/&i
-S 0x39968 vdiph/y#i
-S 0x39aac vdiph/ui_4
-S 0x39bf0 vdiph/yi
-S 0x39d34 vdiph/aau
-S 0x39eb8 vdiph/ou
-S 0x39ffc vdiph/eu_2
-S 0x3a140 vdiph2/iu_2
-S 0x3a2c4 vdiph/&y
-S 0x3a408 vdiph/eey
-S 0x3a54c vdiph/y#y
-S 0x3a690 vdiph2/iy
-S 0x3a7d4 vdiph2/uo
-S 0x3a918 vdiph2/y-y#
-S 0x3aa5c r3/r_trill_short
-W 0x3ab60 ufric/s_continue
-W 0x3b310 h/hu_fi
-S 0x3bc00 vwl_fr/tr
-S 0x3bc84 vwl_fr/@R5
-S 0x3bd48 vowel/@_hgh
-S 0x3be0c vwl_fr/r_@
-S 0x3bed0 vowel/a_6
-S 0x3bfd4 vwl_fr/r_a
-S 0x3c058 vowel/e_8
-S 0x3c15c vwl_fr/r_e
-S 0x3c220 vwl_fr/r_i
-S 0x3c2e4 vwl_fr/r_o
-S 0x3c3a8 vowel/u_bck2
-S 0x3c4ac vwl_fr/r_u
-S 0x3c570 vowel/y_2
-S 0x3c6b4 l/l_y
-S 0x3c778 vwl_fr/r_y
-S 0x3c83c vowel/@_5
-S 0x3c900 vwl_fr/r_@2
-S 0x3c984 vwl_fr/w_a
-S 0x3cac8 vdiph/yi_fr
-S 0x3cc4c vnasal/aa_n4
-S 0x3cd90 vwl_fr/r_a~
-S 0x3ce14 vnasal/W_n
-S 0x3cf58 vowel/a_en
-S 0x3d05c vwl_fr/r
-S 0x3d0e0 r3/r_2
-W 0x3d164 ustop/t_short
-S 0x3d3a8 vowel/yy
-S 0x3d4ac vdiph/ae
-S 0x3d5f0 vowel/aa
-S 0x3d6f4 vwl_fr/@R2
-S 0x3d7f8 vowel/@_bck
-S 0x3d8fc vowel/i_6
-S 0x3da00 vdiph/ee-e
-S 0x3db44 vnasal/i_n2
-S 0x3dc48 vnasal/aa_n
-S 0x3dd8c vnasal/V_n
-S 0x3de90 vnasal/oo_n2
-S 0x3dfd4 vnasal/o_n
-S 0x3e118 vnasal/u_n
-S 0x3e21c vdiph/aau_3
-S 0x3e3a0 l^/l_rfx
-S 0x3e464 voc/v#
-S 0x3e568 voc/v#_
-W 0x3e62c ustop/p_asp
-S 0x3eb30 d/xd3
-W 0x3ebf4 ustop/ts_pzd2
-W 0x3ef28 ustop/ts_pzd_
-W 0x3f3ec ustop/k_asp
-S 0x3faf0 vowel/a_5
-S 0x3fbf4 vowel/u#_3
-S 0x3fcf8 vowel/u#_2
-S 0x3fdfc vowel/y#_2
-S 0x3ff00 vowel/8_7
-S 0x40004 vdiph/aai
-S 0x40188 vdiph2/uaa
-S 0x4030c vdiph2/ie_2
-W 0x40450 ustop/ts2
-S 0x40920 vowel/o_5
-S 0x40a24 vowel/o_6
-S 0x40ae8 vowel/aa_7
-S 0x40bec vdiph/y#y_3
-S 0x40cf0 vdiph/Vu_3
-S 0x40e74 vdiph2/yu
-S 0x40ff8 voc/Q_less
-W 0x410bc vocw/Q2
-W 0x41988 ufric/sx_sv
-S 0x421d0 vowel/a#_2
-S 0x422d4 vowel/ee#
-S 0x423d8 vowel/i_7
-S 0x424dc vowel/oo_5
-S 0x425e0 vowel/ii#_2
-S 0x426e4 vnasal/ee_u_n
-S 0x42868 vnasal/oo_n3
-W 0x429ec x/d_pzd
-S 0x42e00 d/xd_pzd
-S 0x42ec4 d/xdz
-S 0x42f88 vowel/ee_6
-S 0x4304c vdiph/ou_2
-S 0x43190 vdiph/eei_3
-W 0x432d4 r3/rz_cs
-S 0x43d80 voc/zh_2
-S 0x43e44 vdiph/oou
-W 0x43f88 ufric/sh3
-W 0x4491c ustop/tsh2
-W 0x45028 ustop/ts_pzd3
-S 0x456a8 dzh/dzh2
-W 0x4576c ustop/t_sr
-S 0x45aa4 d/d_dnt
-W 0x45b68 ufric/x_sr
-W 0x463e8 ufric/ch_sr
-W 0x46fc8 ufric/sh_pzd2
-W 0x47b18 ustop/ts_sr
-W 0x482d4 ustop/tsh_sr
-S 0x48bec vwl_ru/ii-
-S 0x48cb0 vwl_ro/mi
-S 0x48df4 vwl_ru/i
-S 0x48ef8 vwl_ru/ii#
-S 0x48fbc vwl_ru/i#
-S 0x490c0 vwl_ru/ii
-S 0x491c4 vwl_ru/e
-S 0x492c8 vwl_ru/E#
-S 0x493cc vwl_ru/E@
-S 0x494d0 vwl_ru/a
-S 0x495d4 vwl_ru/o
-S 0x496d8 vwl_ru/oo
-S 0x4979c vwl_ru/u
-S 0x498a0 vwl_ru/u#
-S 0x499e4 vwl_ru/u#u
-S 0x49b28 vwl_ru/8
-S 0x49bec vwl_ru/ee
-S 0x49d30 vwl_ru/ju
-S 0x49e34 vwl_ru/ja
-S 0x49fb8 vwl_ru/aa
-S 0x4a0bc r3/r_ru2
-W 0x4a1c0 r3/r_ru
-S 0x4a4c4 vowel/ii_5
-S 0x4a5c8 vdiph/eeu_2
-S 0x4a70c d/tap4
-S 0x4a810 voc/v2
-S 0x4a8d4 vnasal/i_n
-S 0x4a9d8 vnasal/a#_n
-S 0x4aadc vnasal/a#u_n
-S 0x4ac20 vnasal/oi_n
-S 0x4ade4 vdiph/0i
-S 0x4afa8 vdiph/eeu
-S 0x4b0ec vowel/i#_5
-S 0x4b1f0 vowel/u_6
-S 0x4b2f4 vwl_fr/@R
-S 0x4b3f8 vwl_ro/ii-
-S 0x4b4bc vwl_ro/li
-S 0x4b5c0 vwl_ro/ni
-S 0x4b6c4 vowel/o-_4
-S 0x4b7c8 vdiph/@u_3
-S 0x4b94c vdiph/ii
-S 0x4bb10 vdiph/i#i
-S 0x4bc54 vdiph2/uw_3
-S 0x4bd98 vdiph2/ea
-S 0x4bedc vdiph2/eo
-S 0x4c060 vdiph2/e[u
-S 0x4c1a4 vdiph2/oa
-S 0x4c2e8 d/tap
-S 0x4c3ac d/tap_i
-S 0x4c470 vowel/a_4
-S 0x4c574 vowel/ee#_2
-S 0x4c678 vowel/y_5
-S 0x4c7bc vowel/yy_3
-S 0x4c8c0 vowel/oe_4
-S 0x4c984 vowel/aa_4
-S 0x4ca88 vwl_sv/r_sv3
-S 0x4cc8c vowel/y_4
-S 0x4cd90 vowel/oe_2
-S 0x4ce94 vwl_no/y#
-S 0x4cf98 vwl_no/&
-S 0x4d09c vwl_no/u#
-S 0x4d1a0 vwl_no/u#2
-S 0x4d2e4 vdiph/ai_3
-S 0x4d428 vwl_no/y#y
-S 0x4d56c vwl_no/au-
-S 0x4d730 vowel/y##
-S 0x4d834 vowel/y#_3
-S 0x4d938 vdiph/ou_3
-S 0x4da3c vdiph/y#i_2
-S 0x4db80 m/m#_
-S 0x4dc84 n/n#_
-S 0x4dd88 n^/n^#_
-S 0x4de8c nn/nn#_
-W 0x4df90 ufric/tl#
-S 0x4e8f8 r3/r#_
-E 0x4e97c envelope/p_level
-E 0x4e9fc envelope/p_fall
-E 0x4ea7c envelope/p_rise
-E 0x4eafc envelope/p_fallrise
-E 0x4eb7c envelope/p_214
-E 0x4ebfc envelope/vi_5amp
-E 0x4ec7c envelope/p_512
-E 0x4ecfc envelope/vi_6amp
-S 0x4ed7c vowel/u_7
-S 0x4ee80 vowel/u#_5
-S 0x4ef84 vowel/@_2
-S 0x4f088 vdiph/&i_3
-S 0x4f20c vdiph/@i
-S 0x4f350 vdiph/u-i
-S 0x4f494 vdiph/aau_4
-S 0x4f618 vdiph2/ii@_3
-S 0x4f79c l/l_vi
-S 0x4f8a0 vwl_zh/ang
-S 0x4faa4 vwl_zh/aang
-S 0x4fce8 vdiph/au_2
-S 0x4fe6c vwl_zh/eng
-S 0x50070 vwl_zh/ing
-S 0x502b4 vwl_zh/ng
-S 0x503f8 vwl_zh/oeng
-S 0x505bc vwl_zh/ong
-S 0x50740 vwl_zh/ung
-S 0x508c4 vowel/8_3
-E 0x509c8 envelope/i_risefall
-W 0x50a48 ustop/t_unasp2
-S 0x50b54 n/n_long_
-W 0x50c18 ustop/k_unasp_
-W 0x50ed4 ustop/tsh_pzd_unasp
-W 0x51724 ustop/tsh_pzd
-W 0x52264 ustop/ts_unasp
-W 0x52adc ustop/ts_rfx_unasp
-W 0x536c8 ustop/ts_rfx
-S 0x543a8 nn/nn2_
-S 0x5446c vwl_zh/a_n
-S 0x54570 vwl_zh/aau
-S 0x546b4 vowel/ii_2
-S 0x54778 vowel/i#_7
-S 0x5487c vowel/i#_6
-S 0x54980 vwl_zh/iaa
-S 0x54ac4 vwl_zh/iaau
-S 0x54c48 vwl_zh/ie
-S 0x54d8c vdiph2/iioo
-S 0x54ed0 vwl_zh/iou
-S 0x55054 vowel/8
-S 0x55158 vwl_zh/uaa
-S 0x5529c vwl_zh/uai
-S 0x55420 vwl_zh/uei
-S 0x555a4 vwl_zh/uo
-S 0x55728 vwl_zh/y&
-S 0x5586c vwl_zh/yee
-S 0x559b0 vdiph2/y@
-S 0x55af4 vowel/u_5
-S 0x55bf8 vnasal/m-
-S 0x55cfc vnasal/n-
-S 0x55e00 vnasal/nn-
-S 0x55f04 vowel/u#_7
-S 0x56008 vowel/8_5
-S 0x5610c vowel/o_7
-S 0x56210 vowel/uu#
-S 0x56314 vowel/8_6
-S 0x56418 vowel/ee_4
-S 0x5651c vdiph2/ye
-S 0x56660 l/l_front_
-S 0x567a4 l/l_front
-S 0x568a8 l/l_4
-S 0x5696c vwl_fr/@R3
-S 0x56a30 vwl_fr/@R4
-S 0x56af4 r/a_
diff --git a/navit/support/espeak/espeak-data/phonindex b/navit/support/espeak/espeak-data/phonindex
deleted file mode 100644
index 8bed38930..000000000
--- a/navit/support/espeak/espeak-data/phonindex
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/phontab b/navit/support/espeak/espeak-data/phontab
deleted file mode 100644
index c0d3a751d..000000000
--- a/navit/support/espeak/espeak-data/phontab
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/pl_dict b/navit/support/espeak/espeak-data/pl_dict
deleted file mode 100644
index e46b00b04..000000000
--- a/navit/support/espeak/espeak-data/pl_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/pt_dict b/navit/support/espeak/espeak-data/pt_dict
deleted file mode 100644
index 9ba2a7a78..000000000
--- a/navit/support/espeak/espeak-data/pt_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/ro_dict b/navit/support/espeak/espeak-data/ro_dict
deleted file mode 100644
index b0a72f406..000000000
--- a/navit/support/espeak/espeak-data/ro_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/ru_dict b/navit/support/espeak/espeak-data/ru_dict
deleted file mode 100644
index 52d652ccd..000000000
--- a/navit/support/espeak/espeak-data/ru_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/sk_dict b/navit/support/espeak/espeak-data/sk_dict
deleted file mode 100644
index a5d7e7c75..000000000
--- a/navit/support/espeak/espeak-data/sk_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/sq_dict b/navit/support/espeak/espeak-data/sq_dict
deleted file mode 100644
index aea3d0625..000000000
--- a/navit/support/espeak/espeak-data/sq_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/sv_dict b/navit/support/espeak/espeak-data/sv_dict
deleted file mode 100644
index 1327d8d0c..000000000
--- a/navit/support/espeak/espeak-data/sv_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/sw_dict b/navit/support/espeak/espeak-data/sw_dict
deleted file mode 100644
index 77e2fd233..000000000
--- a/navit/support/espeak/espeak-data/sw_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/ta_dict b/navit/support/espeak/espeak-data/ta_dict
deleted file mode 100644
index 214e2f4da..000000000
--- a/navit/support/espeak/espeak-data/ta_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/tr_dict b/navit/support/espeak/espeak-data/tr_dict
deleted file mode 100644
index a3f685047..000000000
--- a/navit/support/espeak/espeak-data/tr_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/vi_dict b/navit/support/espeak/espeak-data/vi_dict
deleted file mode 100644
index 24a645a03..000000000
--- a/navit/support/espeak/espeak-data/vi_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/voices/!v/croak b/navit/support/espeak/espeak-data/voices/!v/croak
deleted file mode 100755
index ae76a4c4d..000000000
--- a/navit/support/espeak/espeak-data/voices/!v/croak
+++ /dev/null
@@ -1,11 +0,0 @@
-language variant
-name croak
-gender male 70
-
-pitch 85 117
-flutter 20
-
-formant 0 100 80 110
-
-
-
diff --git a/navit/support/espeak/espeak-data/voices/!v/f1 b/navit/support/espeak/espeak-data/voices/!v/f1
deleted file mode 100755
index 13664a34f..000000000
--- a/navit/support/espeak/espeak-data/voices/!v/f1
+++ /dev/null
@@ -1,18 +0,0 @@
-language variant
-name female1
-gender female
-
-pitch 145 200
-flutter 7
-roughness 4
-formant 0 115 80 150
-formant 1 120 80 180
-formant 2 100 70 150 150
-formant 3 115 70 150
-formant 4 110 80 150
-formant 5 110 90 150
-formant 6 105 80 150
-formant 7 110 70 150
-formant 8 110 70 150
-
-stressAdd -10 -10 -20 -20 0 0 40 70
diff --git a/navit/support/espeak/espeak-data/voices/!v/f2 b/navit/support/espeak/espeak-data/voices/!v/f2
deleted file mode 100755
index e92946707..000000000
--- a/navit/support/espeak/espeak-data/voices/!v/f2
+++ /dev/null
@@ -1,20 +0,0 @@
-language variant
-name female2
-gender female
-
-pitch 142 220
-roughness 3
-
-formant 0 105 80 150
-formant 1 110 80 160
-formant 2 110 70 150
-formant 3 110 70 150
-formant 4 115 80 150
-formant 5 115 80 150
-formant 6 110 70 150
-formant 7 110 70 150
-formant 8 110 70 150
-
-stressAdd 0 0 -10 -10 0 0 10 40
-breath 0 2 3 3 3 3 3 2
-echo 140 10
diff --git a/navit/support/espeak/espeak-data/voices/!v/f3 b/navit/support/espeak/espeak-data/voices/!v/f3
deleted file mode 100644
index 92a158281..000000000
--- a/navit/support/espeak/espeak-data/voices/!v/f3
+++ /dev/null
@@ -1,22 +0,0 @@
-language variant
-name female3
-gender female
-
-pitch 140 240
-formant 0 105 80 150
-formant 1 120 75 150 -50
-formant 2 135 70 150 -250
-formant 3 125 80 150
-formant 4 125 80 150
-formant 5 125 80 150
-formant 6 120 70 150
-formant 7 110 70 150
-formant 8 110 70 150
-
-stressAmp 18 18 20 20 20 20 20 20
-//breath 0 2 4 4 4 4 4 4
-breath 0 2 3 3 3 3 3 2
-echo 120 10
-roughness 4
-
-
diff --git a/navit/support/espeak/espeak-data/voices/!v/f4 b/navit/support/espeak/espeak-data/voices/!v/f4
deleted file mode 100644
index 52c5ac935..000000000
--- a/navit/support/espeak/espeak-data/voices/!v/f4
+++ /dev/null
@@ -1,18 +0,0 @@
-language variant
-name female4
-gender female
-
-echo 130 15
-pitch 142 200
-formant 0 120 80 150
-formant 1 115 80 160 -20
-formant 2 130 75 150 -200
-formant 3 123 75 150
-formant 4 125 80 150
-formant 5 125 80 150
-formant 6 110 80 150
-formant 7 110 75 150
-formant 8 110 75 150
-
-stressAdd -20 -20 -20 -20 0 0 20 120
-stressAmp 18 16 20 20 20 20 20 20
diff --git a/navit/support/espeak/espeak-data/voices/!v/fast b/navit/support/espeak/espeak-data/voices/!v/fast
deleted file mode 100755
index 30441d7e2..000000000
--- a/navit/support/espeak/espeak-data/voices/!v/fast
+++ /dev/null
@@ -1,11 +0,0 @@
-language variant
-name fast_test
-
-// Try decreasing these values to make eSpeak's fastest speed faster.
-// The 3 parameters affect:
-// pauses,
-// unvoiced consonants,
-// vowels and voiced consonants
-// The default values are: fast 15 72 110
-
-fast_test 15 72 110
diff --git a/navit/support/espeak/espeak-data/voices/!v/m1 b/navit/support/espeak/espeak-data/voices/!v/m1
deleted file mode 100755
index 57603a885..000000000
--- a/navit/support/espeak/espeak-data/voices/!v/m1
+++ /dev/null
@@ -1,19 +0,0 @@
-language variant
-name male1
-gender male 70
-
-pitch 74 109
-flutter 4
-roughness 4
-
-formant 0 98 95 100
-formant 1 97 95 100
-formant 2 97 95 100
-formant 3 97 100 100
-formant 4 97 100 100
-formant 5 105 100 100
-formant 6 95 100 100
-formant 7 100 100 100
-formant 8 100 100 100
-
-stressAdd -10 -10 -20 -20 0 0 40 70
diff --git a/navit/support/espeak/espeak-data/voices/!v/m2 b/navit/support/espeak/espeak-data/voices/!v/m2
deleted file mode 100644
index c234f4687..000000000
--- a/navit/support/espeak/espeak-data/voices/!v/m2
+++ /dev/null
@@ -1,15 +0,0 @@
-language variant
-name male2
-gender male
-
-pitch 88 115
-echo 130 15
-formant 0 100 80 120
-formant 1 90 85 120
-formant 2 110 85 120
-formant 3 105 90 120
-formant 4 100 90 120
-formant 5 100 90 120
-formant 6 100 90 120
-formant 7 100 90 120
-formant 8 100 90 120
diff --git a/navit/support/espeak/espeak-data/voices/!v/m3 b/navit/support/espeak/espeak-data/voices/!v/m3
deleted file mode 100644
index 581cd883f..000000000
--- a/navit/support/espeak/espeak-data/voices/!v/m3
+++ /dev/null
@@ -1,16 +0,0 @@
-language variant
-name male3
-gender male
-
-pitch 80 122
-formant 0 100 100 100
-formant 1 96 97 100
-formant 2 96 97 100
-formant 3 96 103 100
-formant 4 95 103 100
-formant 5 95 103 100
-formant 6 100 100 100
-formant 7 100 100 100
-formant 8 100 100 100
-
-stressAdd 10 10 0 0 0 0 -30 -30
diff --git a/navit/support/espeak/espeak-data/voices/!v/m4 b/navit/support/espeak/espeak-data/voices/!v/m4
deleted file mode 100644
index 7199341c3..000000000
--- a/navit/support/espeak/espeak-data/voices/!v/m4
+++ /dev/null
@@ -1,17 +0,0 @@
-language variant
-name male4
-gender male
-
-pitch 70 110
-
-formant 0 103 100 100
-formant 1 103 100 100
-formant 2 103 100 100
-formant 3 103 100 100
-formant 4 106 100 100
-formant 5 106 100 100
-formant 6 106 100 100
-formant 7 103 100 100
-formant 8 103 100 100
-
-stressAdd -10 -10 -30 -30 0 0 60 90
diff --git a/navit/support/espeak/espeak-data/voices/!v/m5 b/navit/support/espeak/espeak-data/voices/!v/m5
deleted file mode 100755
index d25865608..000000000
--- a/navit/support/espeak/espeak-data/voices/!v/m5
+++ /dev/null
@@ -1,15 +0,0 @@
-language variant
-name male5
-gender male
-
-formant 0 100 85 130
-formant 1 90 85 130 40
-formant 2 80 85 130 310
-formant 3 105 85 130
-formant 4 105 85 130
-formant 5 105 85 130
-formant 6 105 85 150
-formant 7 105 85 150
-formant 8 105 85 150
-
-intonation 2
diff --git a/navit/support/espeak/espeak-data/voices/!v/m6 b/navit/support/espeak/espeak-data/voices/!v/m6
deleted file mode 100755
index bd336a988..000000000
--- a/navit/support/espeak/espeak-data/voices/!v/m6
+++ /dev/null
@@ -1,13 +0,0 @@
-language variant
-name male6
-gender male
-
-pitch 82 117
-
-formant 0 100 90 120
-formant 1 100 90 140
-formant 2 100 70 140
-formant 3 100 75 140
-formant 4 100 80 140
-formant 5 100 80 140
-
diff --git a/navit/support/espeak/espeak-data/voices/!v/m7 b/navit/support/espeak/espeak-data/voices/!v/m7
deleted file mode 100755
index 9a8370622..000000000
--- a/navit/support/espeak/espeak-data/voices/!v/m7
+++ /dev/null
@@ -1,18 +0,0 @@
-language variant
-gender male 35
-name male5
-
-formant 0 120 150 220
-
-formant 1 100 100 100
-formant 2 100 100 100
-formant 3 100 100 100
-
-formant 4 100 80 100
-formant 5 100 100 100
-
-formant 6 80 200 80
-formant 7 80 200 100
-
-pitch 80 118
-tone 600 150 255 50 100 100
diff --git a/navit/support/espeak/espeak-data/voices/!v/whisper b/navit/support/espeak/espeak-data/voices/!v/whisper
deleted file mode 100755
index 4f8f5e88f..000000000
--- a/navit/support/espeak/espeak-data/voices/!v/whisper
+++ /dev/null
@@ -1,13 +0,0 @@
-language variant
-name whisper
-gender male
-
-pitch 82 117
-flutter 20
-
-formant 0 100 0 100
-formant 1 100 80 100
-
-voicing 17
-breath 75 75 50 40 15 10
-breathw 150 150 200 200 400 400
diff --git a/navit/support/espeak/espeak-data/voices/af b/navit/support/espeak/espeak-data/voices/af
deleted file mode 100755
index bcbb2a005..000000000
--- a/navit/support/espeak/espeak-data/voices/af
+++ /dev/null
@@ -1,8 +0,0 @@
-name afrikaans
-language af
-gender male
-roughness 0
-pitch 63 120
-
-
-
diff --git a/navit/support/espeak/espeak-data/voices/bs b/navit/support/espeak/espeak-data/voices/bs
deleted file mode 100755
index eadd70732..000000000
--- a/navit/support/espeak/espeak-data/voices/bs
+++ /dev/null
@@ -1,16 +0,0 @@
-name bosnian
-language bs
-phonemes hr
-dictionary hbs
-gender male
-
-pitch 81 120
-formant 0 100 100 100
-formant 1 97 97 100
-formant 2 97 97 100
-formant 3 97 102 100
-formant 4 97 102 100
-formant 5 97 102 100
-
-stressAdd 10 10 0 0 0 0 -30 -30
-dictrules 3 4
diff --git a/navit/support/espeak/espeak-data/voices/ca b/navit/support/espeak/espeak-data/voices/ca
deleted file mode 100644
index dc51396ce..000000000
--- a/navit/support/espeak/espeak-data/voices/ca
+++ /dev/null
@@ -1,4 +0,0 @@
-name catalan
-language ca
-gender male
-
diff --git a/navit/support/espeak/espeak-data/voices/cs b/navit/support/espeak/espeak-data/voices/cs
deleted file mode 100755
index 1c2992dd5..000000000
--- a/navit/support/espeak/espeak-data/voices/cs
+++ /dev/null
@@ -1,4 +0,0 @@
-name czech
-language cs
-gender male
-
diff --git a/navit/support/espeak/espeak-data/voices/cy b/navit/support/espeak/espeak-data/voices/cy
deleted file mode 100755
index 2991e99d1..000000000
--- a/navit/support/espeak/espeak-data/voices/cy
+++ /dev/null
@@ -1,5 +0,0 @@
-language cy
-name welsh-test
-gender male
-
-intonation 4
diff --git a/navit/support/espeak/espeak-data/voices/da b/navit/support/espeak/espeak-data/voices/da
deleted file mode 100755
index ec9936cc2..000000000
--- a/navit/support/espeak/espeak-data/voices/da
+++ /dev/null
@@ -1,3 +0,0 @@
-name danish-test
-language da
-gender male
diff --git a/navit/support/espeak/espeak-data/voices/de b/navit/support/espeak/espeak-data/voices/de
deleted file mode 100755
index 653c3f5c4..000000000
--- a/navit/support/espeak/espeak-data/voices/de
+++ /dev/null
@@ -1,5 +0,0 @@
-name german
-language de
-gender male
-
-
diff --git a/navit/support/espeak/espeak-data/voices/default b/navit/support/espeak/espeak-data/voices/default
deleted file mode 100755
index b2fd9d084..000000000
--- a/navit/support/espeak/espeak-data/voices/default
+++ /dev/null
@@ -1,4 +0,0 @@
-name default
-language en
-gender male
-
diff --git a/navit/support/espeak/espeak-data/voices/el b/navit/support/espeak/espeak-data/voices/el
deleted file mode 100755
index 1e9a757f8..000000000
--- a/navit/support/espeak/espeak-data/voices/el
+++ /dev/null
@@ -1,5 +0,0 @@
-name greek
-language el
-gender male
-
-
diff --git a/navit/support/espeak/espeak-data/voices/en/en b/navit/support/espeak/espeak-data/voices/en/en
deleted file mode 100755
index 43e2ca1fc..000000000
--- a/navit/support/espeak/espeak-data/voices/en/en
+++ /dev/null
@@ -1,9 +0,0 @@
-name english
-language en-uk 2
-language en 2
-gender male
-
-//pitch 80 117
-
-replace 03 I i
-replace 03 I2 i
diff --git a/navit/support/espeak/espeak-data/voices/en/en-n b/navit/support/espeak/espeak-data/voices/en/en-n
deleted file mode 100755
index 933311dad..000000000
--- a/navit/support/espeak/espeak-data/voices/en/en-n
+++ /dev/null
@@ -1,14 +0,0 @@
-name lancashire
-language en-uk-north
-language en-uk 3
-gender male
-
-phonemes en_n
-
-stressLength 160 150 180 180 220 220 290 290
-
-replace 00 i@3 i@
-replace 03 N n
-//replace 03 I i
-//replace 03 I2 i
-
diff --git a/navit/support/espeak/espeak-data/voices/en/en-rp b/navit/support/espeak/espeak-data/voices/en/en-rp
deleted file mode 100755
index 3489f28ad..000000000
--- a/navit/support/espeak/espeak-data/voices/en/en-rp
+++ /dev/null
@@ -1,12 +0,0 @@
-name english_rp
-language en-uk-rp
-language en-uk 4
-gender male
-
-phonemes en_rp
-replace 00 o@ O@
-replace 00 i@3 i@
-replace 03 I i
-replace 03 I2 i
-replace 03 @ a2
-replace 03 3 a2
diff --git a/navit/support/espeak/espeak-data/voices/en/en-sc b/navit/support/espeak/espeak-data/voices/en/en-sc
deleted file mode 100755
index e16ae25a8..000000000
--- a/navit/support/espeak/espeak-data/voices/en/en-sc
+++ /dev/null
@@ -1,16 +0,0 @@
-name en-scottish
-language en-sc
-language en 4
-gender male
-
-phonemes en_sc
-dictrules 5 6 7
-stressLength 180 130 200 200 0 0 250 270
-
-replace 03 @ V
-replace 03 I i
-replace 03 I2 i
-replace 01 aI aI2
-replace 02 a a/
-replace 02 u: U
-replace 02 3: VR
diff --git a/navit/support/espeak/espeak-data/voices/en/en-us b/navit/support/espeak/espeak-data/voices/en/en-us
deleted file mode 100755
index c2656b28c..000000000
--- a/navit/support/espeak/espeak-data/voices/en/en-us
+++ /dev/null
@@ -1,17 +0,0 @@
-// moving towards US English
-name english-us
-language en-us 2
-language en-r
-language en 3
-gender male
-
-phonemes en_us
-dictrules 3 6
-option 12 1 // reduce [t]
-
-stressLength 145 125 170 170 0 0 265 290
-stressAmp 17 16 20 20 20 22 22 20
-
-replace 03 I i
-replace 03 I2 i
-replace 03 @ @/
diff --git a/navit/support/espeak/espeak-data/voices/en/en-wi b/navit/support/espeak/espeak-data/voices/en/en-wi
deleted file mode 100755
index 28a42a563..000000000
--- a/navit/support/espeak/espeak-data/voices/en/en-wi
+++ /dev/null
@@ -1,19 +0,0 @@
-name en-westindies
-language en-wi
-language en-uk 4
-gender male
-
-phonemes en_wi
-dictrules 8
-stressLength 175 175 175 175 220 220 250 290
-
-replace 00 D d
-replace 00 T t[
-replace 00 U@ o@
-replace 00 i@3 i@
-replace 03 @ a2
-replace 03 3 a2
-replace 03 N n
-
-formant 1 98 100 100
-formant 2 98 100 100
diff --git a/navit/support/espeak/espeak-data/voices/en/en-wm b/navit/support/espeak/espeak-data/voices/en/en-wm
deleted file mode 100755
index aa82f88fb..000000000
--- a/navit/support/espeak/espeak-data/voices/en/en-wm
+++ /dev/null
@@ -1,12 +0,0 @@
-name english_wmids
-language en-uk-wmids
-gender male
-
-phonemes en_wm
-
-replace 00 h NULL
-replace 00 o@ O@
-replace 00 i@3 i@
-dictrules 6
-intonation 4
-stressAdd 0 0 0 0 0 0 0 20
diff --git a/navit/support/espeak/espeak-data/voices/eo b/navit/support/espeak/espeak-data/voices/eo
deleted file mode 100755
index 36a4bff65..000000000
--- a/navit/support/espeak/espeak-data/voices/eo
+++ /dev/null
@@ -1,3 +0,0 @@
-name esperanto
-language eo
-gender male
diff --git a/navit/support/espeak/espeak-data/voices/es b/navit/support/espeak/espeak-data/voices/es
deleted file mode 100755
index 1a9e53b6e..000000000
--- a/navit/support/espeak/espeak-data/voices/es
+++ /dev/null
@@ -1,7 +0,0 @@
-name spanish
-language es
-gender male
-
-dictrules 1
-intonation 3
-
diff --git a/navit/support/espeak/espeak-data/voices/es-la b/navit/support/espeak/espeak-data/voices/es-la
deleted file mode 100755
index c326c46f5..000000000
--- a/navit/support/espeak/espeak-data/voices/es-la
+++ /dev/null
@@ -1,11 +0,0 @@
-name spanish-latin-american
-language es-la
-language es-mx 6
-gender male
-
-phonemes es_la
-dictrules 2
-intonation 2
-stressLength 170 200 180 180 0 0 250 280
-
-replace 00 T s
diff --git a/navit/support/espeak/espeak-data/voices/fi b/navit/support/espeak/espeak-data/voices/fi
deleted file mode 100755
index 6e11c9312..000000000
--- a/navit/support/espeak/espeak-data/voices/fi
+++ /dev/null
@@ -1,4 +0,0 @@
-name finnish
-language fi
-gender male
-
diff --git a/navit/support/espeak/espeak-data/voices/fr b/navit/support/espeak/espeak-data/voices/fr
deleted file mode 100755
index 973073161..000000000
--- a/navit/support/espeak/espeak-data/voices/fr
+++ /dev/null
@@ -1,7 +0,0 @@
-language fr
-name french
-gender male
-
-dictrules 1
-intonation 3
-
diff --git a/navit/support/espeak/espeak-data/voices/fr-be b/navit/support/espeak/espeak-data/voices/fr-be
deleted file mode 100755
index cba9b2757..000000000
--- a/navit/support/espeak/espeak-data/voices/fr-be
+++ /dev/null
@@ -1,7 +0,0 @@
-language fr-be
-name french (Belgium)
-gender male
-
-dictrules 2
-intonation 3
-
diff --git a/navit/support/espeak/espeak-data/voices/hi b/navit/support/espeak/espeak-data/voices/hi
deleted file mode 100755
index de4786c94..000000000
--- a/navit/support/espeak/espeak-data/voices/hi
+++ /dev/null
@@ -1,9 +0,0 @@
-name hindi-test
-language hi
-gender male
-
-translator hi
-phonemes hi
-dictionary hi
-
-dictrules 1
diff --git a/navit/support/espeak/espeak-data/voices/hr b/navit/support/espeak/espeak-data/voices/hr
deleted file mode 100755
index d6811d3ae..000000000
--- a/navit/support/espeak/espeak-data/voices/hr
+++ /dev/null
@@ -1,18 +0,0 @@
-name croatian
-language hr
-language hbs
-gender male
-
-dictionary hbs
-
-// attributes towards !variant3
-pitch 81 120
-formant 0 100 100 100
-formant 1 97 97 100
-formant 2 97 97 100
-formant 3 97 102 100
-formant 4 97 102 100
-formant 5 97 102 100
-
-stressAdd 10 10 0 0 0 0 -30 -30
-dictrules 1
diff --git a/navit/support/espeak/espeak-data/voices/hu b/navit/support/espeak/espeak-data/voices/hu
deleted file mode 100755
index ba2bdde41..000000000
--- a/navit/support/espeak/espeak-data/voices/hu
+++ /dev/null
@@ -1,3 +0,0 @@
-name hungarian
-language hu
-gender male
diff --git a/navit/support/espeak/espeak-data/voices/hy b/navit/support/espeak/espeak-data/voices/hy
deleted file mode 100644
index 6c65e3c68..000000000
--- a/navit/support/espeak/espeak-data/voices/hy
+++ /dev/null
@@ -1,3 +0,0 @@
-name armenian
-language hy
-gender male
diff --git a/navit/support/espeak/espeak-data/voices/hy-west b/navit/support/espeak/espeak-data/voices/hy-west
deleted file mode 100644
index 46317618d..000000000
--- a/navit/support/espeak/espeak-data/voices/hy-west
+++ /dev/null
@@ -1,19 +0,0 @@
-name armenian-west
-language hy
-gender male
-
-// change consonants for West Armenian pronunciation
-replace 00 b p#
-replace 00 d t#
-replace 00 dz ts#
-replace 00 dZ tS
-replace 00 g k#
-
-replace 00 p b
-replace 00 t d
-replace 00 ts dz
-replace 00 c dZ
-replace 00 k g
-
-replace 00 ** R // ??
-replace 00 r R
diff --git a/navit/support/espeak/espeak-data/voices/id b/navit/support/espeak/espeak-data/voices/id
deleted file mode 100755
index ce800f70b..000000000
--- a/navit/support/espeak/espeak-data/voices/id
+++ /dev/null
@@ -1,8 +0,0 @@
-name indonesian-test
-language id
-gender male
-
-stressLength 160 200 180 180 0 0 220 240
-stressAmp 16 18 18 18 0 0 22 21
-
-consonants 80 80
diff --git a/navit/support/espeak/espeak-data/voices/is b/navit/support/espeak/espeak-data/voices/is
deleted file mode 100755
index 9e9c4e747..000000000
--- a/navit/support/espeak/espeak-data/voices/is
+++ /dev/null
@@ -1,4 +0,0 @@
-name icelandic-test
-language is
-gender male
-
diff --git a/navit/support/espeak/espeak-data/voices/it b/navit/support/espeak/espeak-data/voices/it
deleted file mode 100755
index 53c2a7048..000000000
--- a/navit/support/espeak/espeak-data/voices/it
+++ /dev/null
@@ -1,6 +0,0 @@
-name italian
-language it
-gender male
-
-replace 03 i I
-
diff --git a/navit/support/espeak/espeak-data/voices/ku b/navit/support/espeak/espeak-data/voices/ku
deleted file mode 100755
index 536957cb8..000000000
--- a/navit/support/espeak/espeak-data/voices/ku
+++ /dev/null
@@ -1,6 +0,0 @@
-name kurdish
-language ku
-gender male
-
-//words 1 48
-
diff --git a/navit/support/espeak/espeak-data/voices/la b/navit/support/espeak/espeak-data/voices/la
deleted file mode 100644
index f3e97b523..000000000
--- a/navit/support/espeak/espeak-data/voices/la
+++ /dev/null
@@ -1,13 +0,0 @@
-name latin
-language la
-gender male
-stressrule 2 33 0 2
-// rule=penultimate
-// flags=0100001 (no automatic secondary stress + don't stres monosyllables)
-// unstressed_wd1=0
-// unstressed_wd2=2
-
-// short gap between words
-words 2
-
-// Note: The Latin voice needs long vowels to be marked with macrons
diff --git a/navit/support/espeak/espeak-data/voices/lv b/navit/support/espeak/espeak-data/voices/lv
deleted file mode 100755
index 0278ea213..000000000
--- a/navit/support/espeak/espeak-data/voices/lv
+++ /dev/null
@@ -1,6 +0,0 @@
-name latvian
-language lv
-gender male
-
-replace 03 o o:
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-af1 b/navit/support/espeak/espeak-data/voices/mb/mb-af1
deleted file mode 100755
index 03dac4f6b..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-af1
+++ /dev/null
@@ -1,7 +0,0 @@
-name afrikaans-mbrola-1
-language af 7
-gender male
-
-pitch 82 117
-mbrola af1 af1_phtrans
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-af1-en b/navit/support/espeak/espeak-data/voices/mb/mb-af1-en
deleted file mode 100755
index 71ecab719..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-af1-en
+++ /dev/null
@@ -1,7 +0,0 @@
-name en-afrikaans
-language en 11
-gender male
-
-pitch 82 117
-mbrola af1 af1_phtrans
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-br1 b/navit/support/espeak/espeak-data/voices/mb/mb-br1
deleted file mode 100755
index ba7c42cc4..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-br1
+++ /dev/null
@@ -1,9 +0,0 @@
-language pt 7
-name brazil-mbrola-1
-gender male
-pitch 82 117
-
-dictrules 2 3 4
-
-mbrola br1 ptbr_phtrans
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-br3 b/navit/support/espeak/espeak-data/voices/mb/mb-br3
deleted file mode 100644
index 8479e658e..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-br3
+++ /dev/null
@@ -1,9 +0,0 @@
-language pt 7
-name brazil-mbrola-3
-gender male
-pitch 82 117
-
-dictrules 2 3 4
-
-mbrola br3 ptbr_phtrans
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-br4 b/navit/support/espeak/espeak-data/voices/mb/mb-br4
deleted file mode 100644
index d3d772007..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-br4
+++ /dev/null
@@ -1,9 +0,0 @@
-language pt 7
-name brazil-mbrola-4
-gender female
-pitch 140 220
-
-dictrules 2 3 4
-
-mbrola br4 ptbr4_phtrans
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-cr1 b/navit/support/espeak/espeak-data/voices/mb/mb-cr1
deleted file mode 100755
index 9b280bf8b..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-cr1
+++ /dev/null
@@ -1,9 +0,0 @@
-name croatian-mbrola-1
-language hr 7
-gender male
-
-dictionary hbs
-dictrules 1
-
-pitch 82 117
-mbrola cr1 cr1_phtrans
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-cz2 b/navit/support/espeak/espeak-data/voices/mb/mb-cz2
deleted file mode 100755
index dbde21234..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-cz2
+++ /dev/null
@@ -1,6 +0,0 @@
-name czech-mbrola-2
-language cs 7
-gender male
-
-pitch 82 117
-mbrola cz2 cs_phtrans
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-de2 b/navit/support/espeak/espeak-data/voices/mb/mb-de2
deleted file mode 100755
index c0a5475ec..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-de2
+++ /dev/null
@@ -1,6 +0,0 @@
-name german-mbrola-2
-language de 6
-gender male
-
-mbrola de2 de2_phtrans
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-de4 b/navit/support/espeak/espeak-data/voices/mb/mb-de4
deleted file mode 100755
index 31bd479a3..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-de4
+++ /dev/null
@@ -1,6 +0,0 @@
-name german-mbrola-4
-language de 6
-gender male
-
-mbrola de4 de4_phtrans
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-de4-en b/navit/support/espeak/espeak-data/voices/mb/mb-de4-en
deleted file mode 100755
index 8fd4a63a1..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-de4-en
+++ /dev/null
@@ -1,6 +0,0 @@
-name en-german
-language en 9
-gender male
-
-mbrola de4 de4_phtrans
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-de5 b/navit/support/espeak/espeak-data/voices/mb/mb-de5
deleted file mode 100755
index 569f9d054..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-de5
+++ /dev/null
@@ -1,10 +0,0 @@
-name german-mbrola-5
-language de 7
-gender female
-
-pitch 140 220
-mbrola de5 de6_phtrans 22050
-
-// avoid glottal stops. de5 assumes [?] between pause and vowel
-replace 00 _! _
-replace 00 _| _
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-de5-en b/navit/support/espeak/espeak-data/voices/mb/mb-de5-en
deleted file mode 100755
index e416c6dc5..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-de5-en
+++ /dev/null
@@ -1,7 +0,0 @@
-name en-german-5
-language en
-gender female
-
-pitch 140 220
-mbrola de5 de6_phtrans 22050
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-de6 b/navit/support/espeak/espeak-data/voices/mb/mb-de6
deleted file mode 100644
index 35a4a3fc5..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-de6
+++ /dev/null
@@ -1,6 +0,0 @@
-name german-mbrola-6
-language de 6
-gender male
-
-mbrola de6 de6_phtrans 22050
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-de6-grc b/navit/support/espeak/espeak-data/voices/mb/mb-de6-grc
deleted file mode 100644
index a6e0f46bb..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-de6-grc
+++ /dev/null
@@ -1,6 +0,0 @@
-name german-mbrola-6
-language grc 6
-gender male
-
-mbrola de6 grc-de6_phtrans 22050
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-de7 b/navit/support/espeak/espeak-data/voices/mb/mb-de7
deleted file mode 100755
index aa80edaad..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-de7
+++ /dev/null
@@ -1,7 +0,0 @@
-name german-mbrola-7
-language de 7
-gender female
-
-pitch 140 220
-mbrola de7 de6_phtrans 22050
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-en1 b/navit/support/espeak/espeak-data/voices/mb/mb-en1
deleted file mode 100755
index fc60f4167..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-en1
+++ /dev/null
@@ -1,7 +0,0 @@
-name english-mb-en1
-language en-uk 3
-language en 2
-gender male
-
-pitch 82 117
-mbrola en1 en1_phtrans
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-es1 b/navit/support/espeak/espeak-data/voices/mb/mb-es1
deleted file mode 100755
index d59fe7952..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-es1
+++ /dev/null
@@ -1,7 +0,0 @@
-language es 7
-name spanish-mbrola-1
-gender male
-pitch 82 117
-
-mbrola es1 es_phtrans
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-es2 b/navit/support/espeak/espeak-data/voices/mb/mb-es2
deleted file mode 100644
index 42de58882..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-es2
+++ /dev/null
@@ -1,7 +0,0 @@
-language es 7
-name spanish-mbrola-2
-gender male
-pitch 82 117
-
-mbrola es2 es_phtrans
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-fr1 b/navit/support/espeak/espeak-data/voices/mb/mb-fr1
deleted file mode 100755
index 7cbdab338..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-fr1
+++ /dev/null
@@ -1,9 +0,0 @@
-language fr 7
-name french-mbrola-1
-gender male
-
-dictrules 1
-stressLength 180 180 180 180 0 0 220 220
-pitch 82 117
-mbrola fr1 fr1_phtrans
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-fr1-en b/navit/support/espeak/espeak-data/voices/mb/mb-fr1-en
deleted file mode 100755
index 366653147..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-fr1-en
+++ /dev/null
@@ -1,8 +0,0 @@
-name en-french
-language en 10
-gender male
-
-dictrules 1
-pitch 82 117
-mbrola fr1 fr1_phtrans
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-fr4 b/navit/support/espeak/espeak-data/voices/mb/mb-fr4
deleted file mode 100755
index c276bec0d..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-fr4
+++ /dev/null
@@ -1,8 +0,0 @@
-language fr 7
-name french-mbrola-4
-gender female
-
-dictrules 1
-pitch 140 220
-mbrola fr1 fr1_phtrans
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-fr4-en b/navit/support/espeak/espeak-data/voices/mb/mb-fr4-en
deleted file mode 100755
index b8f782946..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-fr4-en
+++ /dev/null
@@ -1,8 +0,0 @@
-language en 10
-name en-french
-gender female
-
-dictrules 1
-pitch 140 220
-mbrola fr1 fr1_phtrans
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-gr2 b/navit/support/espeak/espeak-data/voices/mb/mb-gr2
deleted file mode 100755
index 30dea8920..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-gr2
+++ /dev/null
@@ -1,6 +0,0 @@
-name greek-mbrola-1
-language el 7
-gender male
-
-pitch 82 117
-mbrola gr2 gr2_phtrans
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-gr2-en b/navit/support/espeak/espeak-data/voices/mb/mb-gr2-en
deleted file mode 100755
index b48b1788b..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-gr2-en
+++ /dev/null
@@ -1,6 +0,0 @@
-name en-greek
-language en 7
-gender male
-
-pitch 82 117
-mbrola gr2 gr2_phtrans
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-hu1 b/navit/support/espeak/espeak-data/voices/mb/mb-hu1
deleted file mode 100755
index b8519559d..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-hu1
+++ /dev/null
@@ -1,6 +0,0 @@
-name hungarian-mbrola-1
-language hu 7
-gender female
-
-pitch 140 220
-mbrola hu1 hu1_phtrans
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-hu1-en b/navit/support/espeak/espeak-data/voices/mb/mb-hu1-en
deleted file mode 100755
index 73ac62a4a..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-hu1-en
+++ /dev/null
@@ -1,6 +0,0 @@
-name en-hungarian
-language en 10
-gender female
-
-pitch 140 220
-mbrola hu1 hu1_phtrans
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-id1 b/navit/support/espeak/espeak-data/voices/mb/mb-id1
deleted file mode 100755
index b86f59306..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-id1
+++ /dev/null
@@ -1,7 +0,0 @@
-name indonesian-mbrola-1
-language id 7
-gender male
-
-pitch 82 117
-mbrola id1 id1_phtrans
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-it3 b/navit/support/espeak/espeak-data/voices/mb/mb-it3
deleted file mode 100755
index 00e88867c..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-it3
+++ /dev/null
@@ -1,8 +0,0 @@
-name italian-mbrola-3
-language it 7
-gender male
-
-pitch 82 117
-mbrola it3 it3_phtrans
-
-replace 03 i I // final unstressed "i"
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-it4 b/navit/support/espeak/espeak-data/voices/mb/mb-it4
deleted file mode 100755
index f2130ba4f..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-it4
+++ /dev/null
@@ -1,8 +0,0 @@
-name italian-mbrola-4
-language it 7
-gender female
-
-pitch 140 220
-mbrola it4 it3_phtrans
-
-replace 03 i I // final unstressed "i"
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-la1 b/navit/support/espeak/espeak-data/voices/mb/mb-la1
deleted file mode 100755
index 7ef93a5ed..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-la1
+++ /dev/null
@@ -1,6 +0,0 @@
-name latin-mbrola-1
-language la 7
-gender male
-
-pitch 82 117
-mbrola la1 la1_phtrans
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-nl2 b/navit/support/espeak/espeak-data/voices/mb/mb-nl2
deleted file mode 100755
index fc377156b..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-nl2
+++ /dev/null
@@ -1,7 +0,0 @@
-language nl 7
-name dutch-mbrola-2
-gender male
-
-pitch 82 117
-mbrola nl2 nl_phtrans
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-nl2-en b/navit/support/espeak/espeak-data/voices/mb/mb-nl2-en
deleted file mode 100755
index 0c2d13a65..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-nl2-en
+++ /dev/null
@@ -1,7 +0,0 @@
-language en 10
-name en-dutch
-gender male
-
-pitch 82 117
-mbrola nl2 nl_phtrans
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-pl1 b/navit/support/espeak/espeak-data/voices/mb/mb-pl1
deleted file mode 100755
index 4e2b9d23e..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-pl1
+++ /dev/null
@@ -1,6 +0,0 @@
-name polish-mbrola-1
-language pl 7
-gender female
-
-pitch 140 220
-mbrola pl1 pl1_phtrans
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-pl1-en b/navit/support/espeak/espeak-data/voices/mb/mb-pl1-en
deleted file mode 100755
index 9ba872a49..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-pl1-en
+++ /dev/null
@@ -1,6 +0,0 @@
-name en-polish
-language en 11
-gender female
-
-pitch 140 220
-mbrola pl1 pl1_phtrans
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-pt1 b/navit/support/espeak/espeak-data/voices/mb/mb-pt1
deleted file mode 100644
index ebd92ffb3..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-pt1
+++ /dev/null
@@ -1,9 +0,0 @@
-language pt 7
-name portugal-mbrola-1
-gender female
-pitch 140 220
-
-dictrules 1
-
-mbrola pt1 pt1_phtrans
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-ro1 b/navit/support/espeak/espeak-data/voices/mb/mb-ro1
deleted file mode 100755
index 14417c1fd..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-ro1
+++ /dev/null
@@ -1,7 +0,0 @@
-name romanian-mbrola-1
-language ro 7
-gender male
-
-pitch 82 117
-mbrola ro1 ro1_phtrans
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-ro1-en b/navit/support/espeak/espeak-data/voices/mb/mb-ro1-en
deleted file mode 100755
index f310f868e..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-ro1-en
+++ /dev/null
@@ -1,7 +0,0 @@
-name en-romanian
-language en 9
-gender male
-
-pitch 82 117
-mbrola ro1 ro1_phtrans
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-sw1 b/navit/support/espeak/espeak-data/voices/mb/mb-sw1
deleted file mode 100755
index 4c6239268..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-sw1
+++ /dev/null
@@ -1,7 +0,0 @@
-name swedish-mbrola-1
-language sv 7
-gender male
-
-pitch 82 117
-mbrola sw1 sv_phtrans
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-sw1-en b/navit/support/espeak/espeak-data/voices/mb/mb-sw1-en
deleted file mode 100755
index 52692c385..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-sw1-en
+++ /dev/null
@@ -1,7 +0,0 @@
-name en-swedish
-language en 11
-gender male
-
-pitch 82 117
-mbrola sw1 sv_phtrans
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-sw2 b/navit/support/espeak/espeak-data/voices/mb/mb-sw2
deleted file mode 100755
index c632e263c..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-sw2
+++ /dev/null
@@ -1,7 +0,0 @@
-name swedish-mbrola-2
-language sv 8
-gender female
-
-pitch 140 220
-mbrola sw2 sv2_phtrans
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-sw2-en b/navit/support/espeak/espeak-data/voices/mb/mb-sw2-en
deleted file mode 100755
index f2033dc11..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-sw2-en
+++ /dev/null
@@ -1,7 +0,0 @@
-name en-swedish-f
-language en
-gender female
-
-pitch 140 220
-mbrola sw2 sv2_phtrans
-
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-us1 b/navit/support/espeak/espeak-data/voices/mb/mb-us1
deleted file mode 100755
index c62589be7..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-us1
+++ /dev/null
@@ -1,12 +0,0 @@
-name us-mbrola-1
-language en-us
-language en 8
-gender female
-
-phonemes en_us
-dictrules 3 6
-
-stressLength 170 135 205 205 0 0 245 275
-
-pitch 140 220
-mbrola us1 us_phtrans
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-us2 b/navit/support/espeak/espeak-data/voices/mb/mb-us2
deleted file mode 100755
index d94fce5a4..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-us2
+++ /dev/null
@@ -1,12 +0,0 @@
-name us-mbrola-2
-language en-us
-language en 7
-gender male
-
-phonemes en_us
-dictrules 3 6
-
-stressLength 170 135 205 205 0 0 245 275
-
-pitch 82 117
-mbrola us2 us_phtrans
diff --git a/navit/support/espeak/espeak-data/voices/mb/mb-us3 b/navit/support/espeak/espeak-data/voices/mb/mb-us3
deleted file mode 100755
index 645e1b7d0..000000000
--- a/navit/support/espeak/espeak-data/voices/mb/mb-us3
+++ /dev/null
@@ -1,12 +0,0 @@
-name us-mbrola-3
-language en-us
-language en 8
-gender male
-
-phonemes en_us
-dictrules 3 6
-
-stressLength 170 135 205 205 0 0 245 275
-
-pitch 82 117
-mbrola us3 us3_phtrans
diff --git a/navit/support/espeak/espeak-data/voices/mk b/navit/support/espeak/espeak-data/voices/mk
deleted file mode 100755
index 4607dd079..000000000
--- a/navit/support/espeak/espeak-data/voices/mk
+++ /dev/null
@@ -1,4 +0,0 @@
-name macedonian-test
-language mk
-gender male
-
diff --git a/navit/support/espeak/espeak-data/voices/nl b/navit/support/espeak/espeak-data/voices/nl
deleted file mode 100755
index 6a8d5efd8..000000000
--- a/navit/support/espeak/espeak-data/voices/nl
+++ /dev/null
@@ -1,3 +0,0 @@
-language nl
-name dutch-test
-gender male
diff --git a/navit/support/espeak/espeak-data/voices/no b/navit/support/espeak/espeak-data/voices/no
deleted file mode 100755
index 77b60b963..000000000
--- a/navit/support/espeak/espeak-data/voices/no
+++ /dev/null
@@ -1,6 +0,0 @@
-name norwegian-test
-language no
-language nb
-gender male
-
-intonation 4
diff --git a/navit/support/espeak/espeak-data/voices/pl b/navit/support/espeak/espeak-data/voices/pl
deleted file mode 100755
index 8fc65d4ba..000000000
--- a/navit/support/espeak/espeak-data/voices/pl
+++ /dev/null
@@ -1,5 +0,0 @@
-name polish
-language pl
-gender male
-
-intonation 2
diff --git a/navit/support/espeak/espeak-data/voices/pt b/navit/support/espeak/espeak-data/voices/pt
deleted file mode 100755
index 53cb31446..000000000
--- a/navit/support/espeak/espeak-data/voices/pt
+++ /dev/null
@@ -1,7 +0,0 @@
-name brazil
-language pt
-language pt-br
-gender male
-
-dictrules 2
-
diff --git a/navit/support/espeak/espeak-data/voices/pt-pt b/navit/support/espeak/espeak-data/voices/pt-pt
deleted file mode 100755
index e23915f39..000000000
--- a/navit/support/espeak/espeak-data/voices/pt-pt
+++ /dev/null
@@ -1,7 +0,0 @@
-name portugal
-language pt-pt
-gender male
-phonemes pt_pt
-
-dictrules 1
-intonation 2
diff --git a/navit/support/espeak/espeak-data/voices/ro b/navit/support/espeak/espeak-data/voices/ro
deleted file mode 100755
index d8ecd252c..000000000
--- a/navit/support/espeak/espeak-data/voices/ro
+++ /dev/null
@@ -1,5 +0,0 @@
-name romanian
-language ro
-gender male
-
-
diff --git a/navit/support/espeak/espeak-data/voices/ru b/navit/support/espeak/espeak-data/voices/ru
deleted file mode 100755
index 238c69126..000000000
--- a/navit/support/espeak/espeak-data/voices/ru
+++ /dev/null
@@ -1,6 +0,0 @@
-name russian_test
-language ru
-gender male
-
-replace 03 a a#
-
diff --git a/navit/support/espeak/espeak-data/voices/sk b/navit/support/espeak/espeak-data/voices/sk
deleted file mode 100755
index 026363f6a..000000000
--- a/navit/support/espeak/espeak-data/voices/sk
+++ /dev/null
@@ -1,4 +0,0 @@
-name slovak
-language sk
-gender male
-
diff --git a/navit/support/espeak/espeak-data/voices/sq b/navit/support/espeak/espeak-data/voices/sq
deleted file mode 100644
index d0b729579..000000000
--- a/navit/support/espeak/espeak-data/voices/sq
+++ /dev/null
@@ -1,6 +0,0 @@
-name albanian
-language sq
-gender male
-
-// add this line to remove 'ë' at the end of words
-// replace 00 @/ NULL
diff --git a/navit/support/espeak/espeak-data/voices/sr b/navit/support/espeak/espeak-data/voices/sr
deleted file mode 100644
index a7a8223db..000000000
--- a/navit/support/espeak/espeak-data/voices/sr
+++ /dev/null
@@ -1,15 +0,0 @@
-name serbian
-language sr
-gender male
-dictionary hbs
-
-// attributes towards !variant3 pitch 80 120
-formant 0 100 100 100
-formant 1 97 97 100
-formant 2 97 97 100
-formant 3 97 102 100
-formant 4 97 102 100
-formant 5 97 102 100
-
-stressAdd 10 10 0 0 0 0 -30 -30
-dictrules 2 4
diff --git a/navit/support/espeak/espeak-data/voices/sv b/navit/support/espeak/espeak-data/voices/sv
deleted file mode 100755
index df70f4387..000000000
--- a/navit/support/espeak/espeak-data/voices/sv
+++ /dev/null
@@ -1,4 +0,0 @@
-name swedish
-language sv
-gender male
-
diff --git a/navit/support/espeak/espeak-data/voices/sw b/navit/support/espeak/espeak-data/voices/sw
deleted file mode 100755
index cf584b7dd..000000000
--- a/navit/support/espeak/espeak-data/voices/sw
+++ /dev/null
@@ -1,4 +0,0 @@
-name swahihi-test
-language sw
-gender male
-
diff --git a/navit/support/espeak/espeak-data/voices/ta b/navit/support/espeak/espeak-data/voices/ta
deleted file mode 100755
index 8848d6820..000000000
--- a/navit/support/espeak/espeak-data/voices/ta
+++ /dev/null
@@ -1,6 +0,0 @@
-name tamil
-language ta
-gender male
-
-intonation 2
-consonants 80
diff --git a/navit/support/espeak/espeak-data/voices/test/grc b/navit/support/espeak/espeak-data/voices/test/grc
deleted file mode 100755
index ffa942063..000000000
--- a/navit/support/espeak/espeak-data/voices/test/grc
+++ /dev/null
@@ -1,8 +0,0 @@
-name greek-ancient
-language grc
-gender male
-
-stressLength 170 170 190 190 0 0 230 240
-dictrules 1
-words 3
-
diff --git a/navit/support/espeak/espeak-data/voices/test/jbo b/navit/support/espeak/espeak-data/voices/test/jbo
deleted file mode 100644
index ebab1a875..000000000
--- a/navit/support/espeak/espeak-data/voices/test/jbo
+++ /dev/null
@@ -1,3 +0,0 @@
-name lojban
-language jbo
-
diff --git a/navit/support/espeak/espeak-data/voices/test/pap b/navit/support/espeak/espeak-data/voices/test/pap
deleted file mode 100644
index 3b105a7fb..000000000
--- a/navit/support/espeak/espeak-data/voices/test/pap
+++ /dev/null
@@ -1,5 +0,0 @@
-name papiamento-test
-language pap
-
-phonemes base2
-
diff --git a/navit/support/espeak/espeak-data/voices/tr b/navit/support/espeak/espeak-data/voices/tr
deleted file mode 100755
index 4f1904e51..000000000
--- a/navit/support/espeak/espeak-data/voices/tr
+++ /dev/null
@@ -1,4 +0,0 @@
-name turkish
-language tr
-gender male
-
diff --git a/navit/support/espeak/espeak-data/voices/vi b/navit/support/espeak/espeak-data/voices/vi
deleted file mode 100755
index 1596e3c77..000000000
--- a/navit/support/espeak/espeak-data/voices/vi
+++ /dev/null
@@ -1,6 +0,0 @@
-name vietnam-test
-language vi
-gender male
-
-words 1
-pitch 80 118
diff --git a/navit/support/espeak/espeak-data/voices/zh b/navit/support/espeak/espeak-data/voices/zh
deleted file mode 100644
index 03edde41d..000000000
--- a/navit/support/espeak/espeak-data/voices/zh
+++ /dev/null
@@ -1,30 +0,0 @@
-name Mandarin
-language zh
-gender male
-words 1
-pitch 80 118
-
-//for some dialects
-
-//[en]: replace ng with n
-//[zh]: �޺�������ng���n
-//replace 0 N n
-
-//[en]: replace rfx consonants
-//[zh]: �޾�������r���l��z��er���e
-//replace 0 ts.h tsh
-//replace 0 ts. ts
-//replace 0 s. s
-//replace 0 i. i[
-//replace 0 z. l
-//replace 0 z. z
-//replace 0 @r @
-
-//[en]: replace beginning n or l
-//[zh]: ����nl��n���l��l���n
-//replace 2 n l
-//replace 2 l n
-
-//[en]: replace beginning w with v
-//[zh]: w���v
-//replace 0 w v \ No newline at end of file
diff --git a/navit/support/espeak/espeak-data/voices/zh-yue b/navit/support/espeak/espeak-data/voices/zh-yue
deleted file mode 100755
index ba8723264..000000000
--- a/navit/support/espeak/espeak-data/voices/zh-yue
+++ /dev/null
@@ -1,14 +0,0 @@
-name cantonese-test
-language zh-yue
-language yue
-language zhy
-
-translator zhy
-phonemes zhy
-dictionary zhy
-gender male
-
-// interpret English letters as 1=English words, 2=jyutping
-dictrules 1
-
-words 1
diff --git a/navit/support/espeak/espeak-data/zh_dict b/navit/support/espeak/espeak-data/zh_dict
deleted file mode 100644
index 0b611f845..000000000
--- a/navit/support/espeak/espeak-data/zh_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak-data/zhy_dict b/navit/support/espeak/espeak-data/zhy_dict
deleted file mode 100644
index 4ad9e7c21..000000000
--- a/navit/support/espeak/espeak-data/zhy_dict
+++ /dev/null
Binary files differ
diff --git a/navit/support/espeak/espeak.c b/navit/support/espeak/espeak.c
deleted file mode 100644
index 7997d0673..000000000
--- a/navit/support/espeak/espeak.c
+++ /dev/null
@@ -1,665 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2006 to 2007 by Jonathan Duddington *
- * email: jonsd@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write see: *
- * <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <getopt.h>
-#include <time.h>
-#include <sys/stat.h>
-
-#include "speak_lib.h"
-
-// This version of the command-line speak program uses the
-// libespeak.so.1 library
-
-
-
-static const char *help_text =
-"\nspeak [options] [\"<words>\"]\n\n"
-"-f <text file> Text file to speak\n"
-"--stdin Read text input from stdin instead of a file\n\n"
-"If neither -f nor --stdin, <words> are spoken, or if none then text is\n"
-"spoken from stdin, each line separately.\n\n"
-"-a <integer>\n"
-"\t Amplitude, 0 to 200, default is 100\n"
-"-g <integer>\n"
-"\t Word gap. Pause between words, units of 10mS at the default speed\n"
-"-l <integer>\n"
-"\t Line length. If not zero (which is the default), consider\n"
-"\t lines less than this length as end-of-clause\n"
-"-p <integer>\n"
-"\t Pitch adjustment, 0 to 99, default is 50\n"
-"-s <integer>\n"
-"\t Speed in words per minute, 80 to 390, default is 170\n"
-"-v <voice name>\n"
-"\t Use voice file of this name from espeak-data/voices\n"
-"-w <wave file name>\n"
-"\t Write output to this WAV file, rather than speaking it directly\n"
-"-b\t Input text encoding, 1=UTF8, 2=8 bit, 4=16 bit \n"
-"-m\t Interpret SSML markup, and ignore other < > tags\n"
-"-q\t Quiet, don't produce any speech (may be useful with -x)\n"
-"-x\t Write phoneme mnemonics to stdout\n"
-"-X\t Write phonemes mnemonics and translation trace to stdout\n"
-"-z\t No final sentence pause at the end of the text\n"
-"--stdout Write speech output to stdout\n"
-"--compile=<voice name>\n"
-"\t Compile the pronunciation rules and dictionary in the current\n"
-"\t directory. =<voice name> is optional and specifies which language\n"
-"--path=\"<path>\"\n"
-"\t Specifies the directory containing the espeak-data directory\n"
-"--phonout=\"<filename>\"\n"
-"\t Write output from -x -X commands and mbrola phoneme data to this file\n"
-"--punct=\"<characters>\"\n"
-"\t Speak the names of punctuation characters during speaking. If\n"
-"\t =<characters> is omitted, all punctuation is spoken.\n"
-"--split=\"<minutes>\"\n"
-"\t Starts a new WAV file every <minutes>. Used with -w\n"
-"--voices=<language>\n"
-"\t List the available voices for the specified language.\n"
-"\t If <language> is omitted, then list all voices.\n"
-"-k <integer>\n"
-"\t Indicate capital letters with: 1=sound, 2=the word \"capitals\",\n"
-"\t higher values = a pitch increase (try -k20).\n";
-
-
-
-
-int samplerate;
-int quiet = 0;
-unsigned int samples_total = 0;
-unsigned int samples_split = 0;
-unsigned int wavefile_count = 0;
-
-FILE *f_wavfile = NULL;
-char filetype[5];
-char wavefile[200];
-
-
-int GetFileLength(const char *filename)
-{//====================================
- struct stat statbuf;
-
- if(stat(filename,&statbuf) != 0)
- return(0);
-
- if((statbuf.st_mode & S_IFMT) == S_IFDIR)
- return(-2); // a directory
-
- return(statbuf.st_size);
-} // end of GetFileLength
-
-
-void strncpy0(char *dest, const char *source, int size)
-{//====================================================
- if(source!=NULL)
- {
- strncpy(dest,source,size);
- dest[size-1] = 0;
- }
-}
-
-
-void DisplayVoices(FILE *f_out, char *language)
-{//============================================
- int ix;
- const char *p;
- int len;
- int count;
- int scores = 0;
- const espeak_VOICE *v;
- const char *lang_name;
- char age_buf[12];
- const espeak_VOICE **voices;
- espeak_VOICE voice_select;
-
- static char genders[4] = {' ','M','F',' '};
-
- if((language != NULL) && (language[0] != 0))
- {
- // display only voices for the specified language, in order of priority
- voice_select.languages = language;
- voice_select.age = 0;
- voice_select.gender = 0;
- voice_select.name = NULL;
- voices = espeak_ListVoices(&voice_select);
- scores = 1;
- }
- else
- {
- voices = espeak_ListVoices(NULL);
- }
-
- fprintf(f_out,"Pty Language Age/Gender VoiceName File Other Langs\n");
-
- for(ix=0; (v = voices[ix]) != NULL; ix++)
- {
- count = 0;
- p = v->languages;
- while(*p != 0)
- {
- len = strlen(p+1);
- lang_name = p+1;
-
- if(v->age == 0)
- strcpy(age_buf," ");
- else
- sprintf(age_buf,"%3d",v->age);
-
- if(count==0)
- {
- fprintf(f_out,"%2d %-12s%s%c %-17s %-11s ",
- p[0],lang_name,age_buf,genders[v->gender],v->name,v->identifier);
- }
- else
- {
- fprintf(f_out,"(%s %d)",lang_name,p[0]);
- }
- count++;
- p += len+2;
- }
-// if(scores)
-// fprintf(f_out,"%3d ",v->score);
- fputc('\n',f_out);
- }
-} // end of DisplayVoices
-
-
-
-
-static void Write4Bytes(FILE *f, int value)
-{//=================================
-// Write 4 bytes to a file, least significant first
- int ix;
-
- for(ix=0; ix<4; ix++)
- {
- fputc(value & 0xff,f);
- value = value >> 8;
- }
-}
-
-
-
-int OpenWavFile(char *path, int rate)
-//===================================
-{
- static unsigned char wave_hdr[44] = {
- 'R','I','F','F',0x24,0xf0,0xff,0x7f,'W','A','V','E','f','m','t',' ',
- 0x10,0,0,0,1,0,1,0, 9,0x3d,0,0,0x12,0x7a,0,0,
- 2,0,0x10,0,'d','a','t','a', 0x00,0xf0,0xff,0x7f};
-
- if(path == NULL)
- return(2);
-
- if(path[0] == 0)
- return(0);
-
- if(strcmp(path,"stdout")==0)
- f_wavfile = stdout;
- else
- f_wavfile = fopen(path,"wb");
-
- if(f_wavfile != NULL)
- {
- fwrite(wave_hdr,1,24,f_wavfile);
- Write4Bytes(f_wavfile,rate);
- Write4Bytes(f_wavfile,rate * 2);
- fwrite(&wave_hdr[32],1,12,f_wavfile);
- return(0);
- }
- return(1);
-} // end of OpenWavFile
-
-
-
-static void CloseWavFile()
-//========================
-{
- unsigned int pos;
-
- if((f_wavfile==NULL) || (f_wavfile == stdout))
- return;
-
- fflush(f_wavfile);
- pos = ftell(f_wavfile);
-
- fseek(f_wavfile,4,SEEK_SET);
- Write4Bytes(f_wavfile,pos - 8);
-
- fseek(f_wavfile,40,SEEK_SET);
- Write4Bytes(f_wavfile,pos - 44);
-
- fclose(f_wavfile);
- f_wavfile = NULL;
-
-} // end of CloseWavFile
-
-
-static int SynthCallback(short *wav, int numsamples, espeak_EVENT *events)
-{//========================================================================
- char fname[210];
-
- if(quiet) return(0); // -q quiet mode
-
- if(wav == NULL)
- {
- CloseWavFile();
- return(0);
- }
-
- if(samples_split > 0)
- {
- // start a new WAV file when this limit is reached, at the next sentence boundary
- while(events->type != 0)
- {
- if((events->type == espeakEVENT_SENTENCE) && (samples_total > samples_split))
- {
- CloseWavFile();
- samples_total = 0;
- }
- events++;
- }
- }
-
- if(f_wavfile == NULL)
- {
- sprintf(fname,"%s_%.2d%s",wavefile,++wavefile_count,filetype);
- if(OpenWavFile(fname, samplerate) != 0)
- return(1);
- }
-
- if(numsamples > 0)
- {
- samples_total += numsamples;
- fwrite(wav,numsamples*2,1,f_wavfile);
- }
- return(0);
-}
-
-
-
-int main (int argc, char **argv)
-//==============================
-{
- static struct option long_options[] =
- {
- /* These options set a flag. */
-// {"verbose", no_argument, &verbose_flag, 1},
-// {"brief", no_argument, &verbose_flag, 0},
-
- /* These options don't set a flag.
- We distinguish them by their indices. */
- {"help", no_argument, 0, 'h'},
- {"stdin", no_argument, 0, 0x100},
- {"compile-debug", optional_argument, 0, 0x101},
- {"compile", optional_argument, 0, 0x102},
- {"punct", optional_argument, 0, 0x103},
- {"voices", optional_argument, 0, 0x104},
- {"stdout", no_argument, 0, 0x105},
- {"split", optional_argument, 0, 0x106},
- {"path", required_argument, 0, 0x107},
- {"phonout", required_argument, 0, 0x108},
- {0, 0, 0, 0}
- };
-
- static const char* err_load = "Failed to read ";
-
-
- FILE *f_text=NULL;
- char *p_text=NULL;
- FILE *f_phonemes_out = stdout;
- char *data_path = NULL; // use default path for espeak-data
-
- int option_index = 0;
- int c;
- int ix;
- int value;
- int flag_stdin = 0;
- int flag_compile = 0;
- int filesize = 0;
- int synth_flags = espeakCHARS_AUTO | espeakPHONEMES | espeakENDPAUSE;
-
- int volume = -1;
- int speed = -1;
- int pitch = -1;
- int wordgap = -1;
- int option_capitals = -1;
- int option_punctuation = -1;
- int option_phonemes = -1;
- int option_linelength = 0;
- int option_waveout = 0;
-
- espeak_VOICE voice_select;
- char filename[200];
- char voicename[40];
- char voice_mbrola[20];
- char dictname[40];
-#define N_PUNCTLIST 100
- wchar_t option_punctlist[N_PUNCTLIST];
-
- voicename[0] = 0;
- voice_mbrola[0] = 0;
- dictname[0] = 0;
- wavefile[0] = 0;
- filename[0] = 0;
- option_punctlist[0] = 0;
-
- while(true)
- {
- c = getopt_long (argc, argv, "a:b:f:g:hk:l:mp:qs:v:w:xXz",
- long_options, &option_index);
-
- /* Detect the end of the options. */
- if (c == -1)
- break;
-
- switch (c)
- {
- case 'b':
- // input character encoding, 8bit, 16bit, UTF8
- if((sscanf(optarg,"%d",&value) == 1) && (value <= 4))
- synth_flags |= value;
- else
- synth_flags |= espeakCHARS_8BIT;
- break;
-
- case 'h':
- printf("\n");
- printf("eSpeak text-to-speech: %s\n%s",espeak_Info(),help_text);
- exit(0);
- break;
-
- case 'k':
- option_capitals = atoi(optarg);
- break;
-
- case 'x':
- option_phonemes = 1;
- break;
-
- case 'X':
- option_phonemes = 2;
- break;
-
- case 'm':
- synth_flags |= espeakSSML;
- break;
-
- case 'p':
- pitch = atoi(optarg);
- break;
-
- case 'q':
- quiet = 1;
- break;
-
- case 'f':
- strncpy0(filename,optarg,sizeof(filename));
- break;
-
- case 'l':
- option_linelength = atoi(optarg);
- break;
-
- case 'a':
- volume = atoi(optarg);
- break;
-
- case 's':
- speed = atoi(optarg);
- break;
-
- case 'g':
- wordgap = atoi(optarg);
- break;
-
- case 'v':
- strncpy0(voicename,optarg,sizeof(voicename));
- break;
-
- case 'w':
- option_waveout = 1;
- strncpy0(wavefile,optarg,sizeof(filename));
- break;
-
- case 'z': // remove pause from the end of a sentence
- synth_flags &= ~espeakENDPAUSE;
- break;
-
- case 0x100: // --stdin
- flag_stdin = 1;
- break;
-
- case 0x105: // --stdout
- option_waveout = 1;
- strcpy(wavefile,"stdout");
- break;
-
- case 0x101: // --compile-debug
- case 0x102: // --compile
- strncpy0(voicename,optarg,sizeof(voicename));
- flag_compile = c;
- quiet = 1;
- break;
-
- case 0x103: // --punct
- option_punctuation = 1;
- if(optarg != NULL)
- {
- ix = 0;
- while((ix < N_PUNCTLIST) && ((option_punctlist[ix] = optarg[ix]) != 0)) ix++;
- option_punctlist[N_PUNCTLIST-1] = 0;
- option_punctuation = 2;
- }
- break;
-
- case 0x104: // --voices
- espeak_Initialize(AUDIO_OUTPUT_SYNCHRONOUS,0,data_path,0);
- DisplayVoices(stdout,optarg);
- exit(0);
-
- case 0x106: // -- split
- if(optarg == NULL)
- samples_split = 30; // default 30 minutes
- else
- samples_split = atoi(optarg);
- break;
-
- case 0x107: // --path
- data_path = optarg;
- break;
-
- case 0x108: // --phonout
- if((f_phonemes_out = fopen(optarg,"w")) == NULL)
- {
- fprintf(stderr,"Can't write to: %s\n",optarg);
- }
- break;
-
- default:
- exit(0);
- }
- }
-
-
- if(option_waveout || quiet)
- {
- // writing to a file (or no output), we can use synchronous mode
- samplerate = espeak_Initialize(AUDIO_OUTPUT_SYNCHRONOUS,0,data_path,0);
- samples_split = (samplerate * samples_split) * 60;
-
- espeak_SetSynthCallback(SynthCallback);
- if(samples_split)
- {
- char *extn;
- extn = strrchr(wavefile,'.');
- if((extn != NULL) && ((wavefile + strlen(wavefile) - extn) <= 4))
- {
- strcpy(filetype,extn);
- *extn = 0;
- }
- }
- else
- if(option_waveout)
- {
- if(OpenWavFile(wavefile,samplerate) != 0)
- exit(4);
- }
- }
- else
- {
- // play the sound output
- samplerate = espeak_Initialize(AUDIO_OUTPUT_PLAYBACK,0,data_path,0);
- }
-
-
- if(voicename[0] == 0)
- strcpy(voicename,"default");
-
- if(espeak_SetVoiceByName(voicename) != EE_OK)
- {
- memset(&voice_select,0,sizeof(voice_select));
- voice_select.languages = voicename;
- if(espeak_SetVoiceByProperties(&voice_select) != EE_OK)
- {
- fprintf(stderr,"%svoice '%s'\n",err_load,voicename);
- exit(2);
- }
- }
-
- if(flag_compile)
- {
- // This must be done after the voice is set
- espeak_CompileDictionary("", stderr, flag_compile & 0x1);
- exit(0);
- }
-
- // set any non-default values of parameters. This must be done after espeak_Initialize()
- if(speed > 0)
- espeak_SetParameter(espeakRATE,speed,0);
- if(volume >= 0)
- espeak_SetParameter(espeakVOLUME,volume,0);
- if(pitch >= 0)
- espeak_SetParameter(espeakPITCH,pitch,0);
- if(option_capitals >= 0)
- espeak_SetParameter(espeakCAPITALS,option_capitals,0);
- if(option_punctuation >= 0)
- espeak_SetParameter(espeakPUNCTUATION,option_punctuation,0);
- if(wordgap >= 0)
- espeak_SetParameter(espeakWORDGAP,wordgap,0);
- if(option_linelength > 0)
- espeak_SetParameter(espeakLINELENGTH,option_linelength,0);
- if(option_punctuation == 2)
- espeak_SetPunctuationList(option_punctlist);
- espeak_SetPhonemeTrace(option_phonemes,f_phonemes_out);
-
- if(filename[0]==0)
- {
- if((optind < argc) && (flag_stdin == 0))
- {
- // there's a non-option parameter, and no -f or --stdin
- // use it as text
- p_text = argv[optind];
- }
- else
- {
- f_text = stdin;
- if(flag_stdin == 0)
- {
- flag_stdin = 2;
- }
- }
- }
- else
- {
- filesize = GetFileLength(filename);
- f_text = fopen(filename,"r");
- }
-
- if((f_text == NULL) && (p_text == NULL))
- {
- fprintf(stderr,"%sfile '%s'\n",err_load,filename);
- exit(1);
- }
-
-
- if(p_text != NULL)
- {
- int size;
- size = strlen(p_text);
- espeak_Synth(p_text,size+1,0,POS_CHARACTER,0,synth_flags,NULL,NULL);
- }
- else
- if(flag_stdin)
- {
- int max = 1000;
- p_text = (char *)malloc(max);
-
- if(flag_stdin == 2)
- {
- // line by line input on stdin
- while(fgets(p_text,max,stdin) != NULL)
- {
- p_text[max-1] = 0;
- espeak_Synth(p_text,max,0,POS_CHARACTER,0,synth_flags,NULL,NULL);
-
- }
- }
- else
- {
- // bulk input on stdin
- ix = 0;
- while(!feof(stdin))
- {
- p_text[ix++] = fgetc(stdin);
- if(ix >= (max-1))
- {
- max += 1000;
- p_text = (char *)realloc(p_text,max);
- }
- }
- if(ix > 0)
- {
- p_text[ix-1] = 0;
- espeak_Synth(p_text,ix+1,0,POS_CHARACTER,0,synth_flags,NULL,NULL);
- }
- }
- }
- else
- if(f_text != NULL)
- {
- if((p_text = (char *)malloc(filesize+1)) == NULL)
- {
- fprintf(stderr,"Failed to allocate memory %d bytes",filesize);
- exit(3);
- }
-
- fread(p_text,1,filesize,f_text);
- p_text[filesize]=0;
- espeak_Synth(p_text,filesize+1,0,POS_CHARACTER,0,synth_flags,NULL,NULL);
- fclose(f_text);
- }
-
- espeak_Synchronize();
-
- if(f_phonemes_out != stdout)
- fclose(f_phonemes_out); // needed for WinCE
- return(0);
-}
diff --git a/navit/support/espeak/espeak_command.c b/navit/support/espeak/espeak_command.c
deleted file mode 100644
index 1b59333c1..000000000
--- a/navit/support/espeak/espeak_command.c
+++ /dev/null
@@ -1,707 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2007, Gilles Casse <gcasse@oralux.org> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-#include "speech.h"
-
-#ifdef USE_ASYNC
-// This source file is only used for asynchronious modes
-
-#include "espeak_command.h"
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <wchar.h>
-
-#include "debug.h"
-
-
-static unsigned int my_current_text_id=0;
-
-
-//<create_espeak_text
-t_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)
-{
- ENTER("create_espeak_text");
- int a_error=1;
- void* a_text = NULL;
- t_espeak_text* data = NULL;
- t_espeak_command* a_command = (t_espeak_command*)malloc(sizeof(t_espeak_command));
-
- if (!text || !size || !a_command)
- {
- goto text_error;
- }
-
- a_text = malloc( size );
- if (!a_text)
- {
- goto text_error;
- }
- memcpy(a_text, text, size);
-
- a_command->type = ET_TEXT;
- a_command->state = CS_UNDEFINED;
- data = &(a_command->u.my_text);
- data->unique_identifier = ++my_current_text_id;
- data->text = a_text;
- data->size = size;
- data->position = position;
- data->position_type = position_type;
- data->end_position = end_position;
- data->flags = flags;
- data->user_data = user_data;
- a_error=0;
-
- SHOW("ET_TEXT malloc text=%x, command=%x (uid=%d)\n", a_text, a_command, data->unique_identifier);
-
- text_error:
- if (a_error)
- {
- if (a_text)
- {
- free (a_text);
- }
- if (a_command)
- {
- free (a_command);
- }
- a_command = NULL;
- }
-
- SHOW("command=0x%x\n", a_command);
-
- return a_command;
-}
-
-//>
-
-
-t_espeak_command* create_espeak_terminated_msg(unsigned int unique_identifier, void* user_data)
-{
- ENTER("create_espeak_terminated_msg");
- int a_error=1;
- t_espeak_terminated_msg* data = NULL;
- t_espeak_command* a_command = (t_espeak_command*)malloc(sizeof(t_espeak_command));
-
- if (!a_command)
- {
- goto msg_error;
- }
-
- a_command->type = ET_TERMINATED_MSG;
- a_command->state = CS_UNDEFINED;
- data = &(a_command->u.my_terminated_msg);
- data->unique_identifier = unique_identifier;
- data->user_data = user_data;
- a_error=0;
-
- SHOW("ET_TERMINATED_MSG command=%x (uid=%d, user_data=0x%x)\n", a_command, unique_identifier, (int)user_data);
-
- msg_error:
- if (a_error)
- {
- if (a_command)
- {
- free (a_command);
- }
- a_command = NULL;
- }
-
- SHOW("command=0x%x\n", a_command);
-
- return a_command;
-
-}
-
-
-
-
-//<create_espeak_mark
-t_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)
-{
- ENTER("create_espeak_mark");
- int a_error=1;
- void* a_text = NULL;
- char *a_index_mark = NULL;
- t_espeak_mark* data = NULL;
- t_espeak_command* a_command = (t_espeak_command*)malloc(sizeof(t_espeak_command));
-
- if (!text || !size || !index_mark || !a_command)
- {
- goto mark_error;
- }
-
- a_text = malloc( size );
- if (!a_text)
- {
- goto mark_error;
- }
- memcpy(a_text, text, size);
-
- a_index_mark = strdup( index_mark);
-
- a_command->type = ET_MARK;
- a_command->state = CS_UNDEFINED;
- data = &(a_command->u.my_mark);
- data->unique_identifier = ++my_current_text_id;
- data->text = a_text;
- data->size = size;
- data->index_mark = a_index_mark;
- data->end_position = end_position;
- data->flags = flags;
- data->user_data = user_data;
- a_error=0;
-
- mark_error:
- if (a_error)
- {
- if (a_text)
- {
- free (a_text);
- }
- if (a_command)
- {
- free (a_command);
- }
- a_command = NULL;
- if (a_index_mark)
- {
- free (a_index_mark);
- }
- }
-
- SHOW("ET_MARK malloc text=%x, command=%x (uid=%d)\n", a_text, a_command, data->unique_identifier);
-
- return a_command;
-}
-//>
-//< create_espeak_key, create_espeak_char
-
-t_espeak_command* create_espeak_key(const char *key_name, void *user_data)
-{
- ENTER("create_espeak_key");
- int a_error=1;
- t_espeak_command* a_command = (t_espeak_command*)malloc(sizeof(t_espeak_command));
-
- if (!key_name || !a_command)
- {
- goto key_error;
- }
-
- a_command->type = ET_KEY;
- a_command->state = CS_UNDEFINED;
- a_command->u.my_key.user_data = user_data;
- a_command->u.my_key.unique_identifier = ++my_current_text_id;
- a_command->u.my_key.key_name = strdup( key_name);
- a_error=0;
-
- key_error:
- if (a_error)
- {
- if (a_command)
- {
- free (a_command);
- }
- a_command = NULL;
- }
-
- SHOW("command=0x%x\n", a_command);
-
- return a_command;
-}
-
-t_espeak_command* create_espeak_char(wchar_t character, void* user_data)
-{
- ENTER("create_espeak_char");
- int a_error=1;
- t_espeak_command* a_command = (t_espeak_command*)malloc(sizeof(t_espeak_command));
- if (!a_command)
- {
- goto char_error;
- }
-
- a_command->type = ET_CHAR;
- a_command->state = CS_UNDEFINED;
- a_command->u.my_char.user_data = user_data;
- a_command->u.my_char.unique_identifier = ++my_current_text_id;
- a_command->u.my_char.character = character;
- a_error=0;
-
- char_error:
- if (a_error)
- {
- if (a_command)
- {
- free (a_command);
- }
- a_command = NULL;
- }
-
- SHOW("command=0x%x\n", a_command);
-
- return a_command;
-}
-
-//>
-//< create_espeak_parameter
-
-t_espeak_command* create_espeak_parameter(espeak_PARAMETER parameter, int value, int relative)
-{
- ENTER("create_espeak_parameter");
- int a_error=1;
- t_espeak_parameter* data = NULL;
- t_espeak_command* a_command = (t_espeak_command*)malloc(sizeof(t_espeak_command));
- if (!a_command)
- {
- goto param_error;
- }
-
- a_command->type = ET_PARAMETER;
- a_command->state = CS_UNDEFINED;
- data = &(a_command->u.my_param);
- data->parameter = parameter;
- data->value = value;
- data->relative = relative;
- a_error=0;
-
- param_error:
- if (a_error)
- {
- if (a_command)
- {
- free (a_command);
- }
- a_command = NULL;
- }
-
- SHOW("command=0x%x\n", a_command);
-
- return a_command;
-}
-
-//>
-//< create_espeak_punctuation_list
-
-t_espeak_command* create_espeak_punctuation_list(const wchar_t *punctlist)
-{
- ENTER("create_espeak_punctuation_list");
- int a_error=1;
- // wchar_t *a_list = NULL;
- t_espeak_command* a_command = (t_espeak_command*)malloc(sizeof(t_espeak_command));
-
- if (!punctlist || !a_command)
- {
- goto list_error;
- }
-
- a_command->type = ET_PUNCTUATION_LIST;
- a_command->state = CS_UNDEFINED;
-
- {
- size_t len = (wcslen(punctlist) + 1)*sizeof(wchar_t);
- wchar_t* a_list = (wchar_t*)malloc(len);
- memcpy(a_list, punctlist, len);
- a_command->u.my_punctuation_list = a_list;
- }
-
- a_error=0;
-
- list_error:
- if (a_error)
- {
- if (a_command)
- {
- free (a_command);
- }
- a_command = NULL;
- }
-
- SHOW("command=0x%x\n", a_command);
-
- return a_command;
-}
-
-//>
-//< create_espeak_voice_name, create_espeak_voice_spec
-
-t_espeak_command* create_espeak_voice_name(const char *name)
-{
- ENTER("create_espeak_voice_name");
-
- int a_error=1;
- t_espeak_command* a_command = (t_espeak_command*)malloc(sizeof(t_espeak_command));
-
- if (!name || !a_command)
- {
- goto name_error;
- }
-
- a_command->type = ET_VOICE_NAME;
- a_command->state = CS_UNDEFINED;
- a_command->u.my_voice_name = strdup( name);
- a_error=0;
-
- name_error:
- if (a_error)
- {
- if (a_command)
- {
- free (a_command);
- }
- a_command = NULL;
- }
-
- SHOW("command=0x%x\n", a_command);
-
- return a_command;
-}
-
-t_espeak_command* create_espeak_voice_spec(espeak_VOICE *voice)
-{
- ENTER("create_espeak_voice_spec");
- int a_error=1;
- t_espeak_command* a_command = (t_espeak_command*)malloc(sizeof(t_espeak_command));
-
- if (!voice || !a_command)
- {
- goto spec_error;
- }
-
- a_command->type = ET_VOICE_SPEC;
- a_command->state = CS_UNDEFINED;
- {
- espeak_VOICE* data = &(a_command->u.my_voice_spec);
- memcpy(data, voice, sizeof(espeak_VOICE));
-
- if (voice->name)
- {
- data->name = strdup(voice->name);
- }
-
- if (voice->languages)
- {
- data->languages = strdup(voice->languages);
- }
-
- if (voice->identifier)
- {
- data->identifier = strdup(voice->identifier);
- }
-
- a_error=0;
- }
-
- spec_error:
- if (a_error)
- {
- if (a_command)
- {
- free (a_command);
- }
- a_command = NULL;
- }
-
- SHOW("command=0x%x\n", a_command);
-
- return a_command;
-}
-
-//>
-//< delete_espeak_command
-int delete_espeak_command( t_espeak_command* the_command)
-{
- ENTER("delete_espeak_command");
- int a_status = 0;
- if (the_command)
- {
- switch(the_command->type)
- {
- case ET_TEXT:
- if (the_command->u.my_text.text)
- {
- 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);
- free(the_command->u.my_text.text);
- }
- break;
-
- case ET_MARK:
- if (the_command->u.my_mark.text)
- {
- free(the_command->u.my_mark.text);
- }
- if (the_command->u.my_mark.index_mark)
- {
- free((void*)(the_command->u.my_mark.index_mark));
- }
- break;
-
- case ET_TERMINATED_MSG:
- {
- // if the terminated msg is pending,
- // it must be processed here for informing the calling program
- // that its message is finished.
- // This can be important for cleaning the related user data.
- t_espeak_terminated_msg* data = &(the_command->u.my_terminated_msg);
- if (the_command->state == CS_PENDING)
- {
- the_command->state = CS_PROCESSED;
- SHOW("delete_espeak_command > ET_TERMINATED_MSG callback (command=0x%x, uid=%d) \n", the_command, data->unique_identifier);
- sync_espeak_terminated_msg( data->unique_identifier, data->user_data);
- }
- }
- break;
-
- case ET_KEY:
- if (the_command->u.my_key.key_name)
- {
- free((void*)(the_command->u.my_key.key_name));
- }
- break;
-
- case ET_CHAR:
- case ET_PARAMETER:
- // No allocation
- break;
-
- case ET_PUNCTUATION_LIST:
- if (the_command->u.my_punctuation_list)
- {
- free((void*)(the_command->u.my_punctuation_list));
- }
- break;
-
- case ET_VOICE_NAME:
- if (the_command->u.my_voice_name)
- {
- free((void*)(the_command->u.my_voice_name));
- }
- break;
-
- case ET_VOICE_SPEC:
- {
- espeak_VOICE* data = &(the_command->u.my_voice_spec);
-
- if (data->name)
- {
- free((void *)data->name);
- }
-
- if (data->languages)
- {
- free((void *)data->languages);
- }
-
- if (data->identifier)
- {
- free((void *)data->identifier);
- }
- }
- break;
-
- default:
- assert(0);
- }
- SHOW("delete_espeak_command > free command=0x%x\n", the_command);
- free(the_command);
- a_status = 1;
- }
- return a_status;
-}
-//>
-//< process_espeak_command
-void process_espeak_command( t_espeak_command* the_command)
-{
- ENTER("process_espeak_command");
-
- SHOW("command=0x%x\n", the_command);
-
- if (the_command == NULL)
- {
- return;
- }
-
- the_command->state = CS_PROCESSED;
-
- switch(the_command->type)
- {
- case ET_TEXT:
- {
- t_espeak_text* data = &(the_command->u.my_text);
- sync_espeak_Synth( data->unique_identifier, data->text, data->size,
- data->position, data->position_type,
- data->end_position, data->flags, data->user_data);
- }
- break;
-
- case ET_MARK:
- {
- t_espeak_mark* data = &(the_command->u.my_mark);
- sync_espeak_Synth_Mark( data->unique_identifier, data->text, data->size,
- data->index_mark, data->end_position, data->flags,
- data->user_data);
- }
- break;
-
- case ET_TERMINATED_MSG:
- {
- t_espeak_terminated_msg* data = &(the_command->u.my_terminated_msg);
- sync_espeak_terminated_msg( data->unique_identifier, data->user_data);
- }
- break;
-
- case ET_KEY:
- {
- const char* data = the_command->u.my_key.key_name;
- sync_espeak_Key(data);
- }
- break;
-
- case ET_CHAR:
- {
- const wchar_t data = the_command->u.my_char.character;
- sync_espeak_Char( data);
- }
- break;
-
- case ET_PARAMETER:
- {
- t_espeak_parameter* data = &(the_command->u.my_param);
- SetParameter( data->parameter, data->value, data->relative);
- }
- break;
-
- case ET_PUNCTUATION_LIST:
- {
- const wchar_t* data = the_command->u.my_punctuation_list;
- sync_espeak_SetPunctuationList( data);
- }
- break;
-
- case ET_VOICE_NAME:
- {
- const char* data = the_command->u.my_voice_name;
- SetVoiceByName( data);
- }
- break;
-
- case ET_VOICE_SPEC:
- {
- espeak_VOICE* data = &(the_command->u.my_voice_spec);
- SetVoiceByProperties(data);
- }
- break;
-
- default:
- assert(0);
- break;
- }
-}
-
-//>
-
-//< process_espeak_command
-void display_espeak_command( t_espeak_command* the_command)
-{
- ENTER("display_espeak_command");
-#ifdef DEBUG_ENABLED
- if (the_command == NULL)
- {
- SHOW("display_espeak_command > command=%s\n","NULL");
- return;
- }
-
- SHOW("display_espeak_command > state=%d\n",the_command->state);
-
- switch(the_command->type)
- {
- case ET_TEXT:
- {
- t_espeak_text* data = &(the_command->u.my_text);
- 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));
- }
- break;
-
- case ET_MARK:
- {
- t_espeak_mark* data = &(the_command->u.my_mark);
- 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));
- }
- break;
-
- case ET_KEY:
- {
- const char* data = the_command->u.my_key;
- SHOW("display_espeak_command > (0x%x) KEY=%c\n", the_command, data);
- }
- break;
-
- case ET_TERMINATED_MSG:
- {
- t_espeak_terminated_msg* data = &(the_command->u.my_terminated_msg);
-
- SHOW("display_espeak_command > (0x%x) TERMINATED_MSG uid=%d, user_data=0x%x, state=%d\n",
- the_command, data->unique_identifier, data->user_data,
- the_command->state);
- }
- break;
-
- case ET_CHAR:
- {
- const wchar_t data = the_command->u.my_char;
- SHOW("display_espeak_command > (0x%x) CHAR=%c\n", the_command, (char)data);
- }
- break;
-
- case ET_PARAMETER:
- {
- t_espeak_parameter* data = &(the_command->u.my_param);
- SHOW("display_espeak_command > (0x%x) PARAMETER=%d, value=%d, relative=%d\n",
- the_command, data->parameter, data->value, data->relative);
- }
- break;
-
- case ET_PUNCTUATION_LIST:
- {
- const wchar_t* data = the_command->u.my_punctuation_list;
- sync_espeak_SetPunctuationList( data);
- SHOW("display_espeak_command > (0x%x) PUNCTLIST=%s\n", the_command, (char*)data);
- }
- break;
-
- case ET_VOICE_NAME:
- {
- const char* data = the_command->u.my_voice_name;
- SHOW("display_espeak_command > (0x%x) VOICE_NAME=%s\n", the_command, data);
- }
- break;
-
- case ET_VOICE_SPEC:
- {
- SHOW("display_espeak_command > (0x%x) VOICE_SPEC", the_command);
- }
- break;
-
- default:
- assert(0);
- break;
- }
-#endif
-}
-
-#endif
-//>
diff --git a/navit/support/espeak/espeak_command.h b/navit/support/espeak/espeak_command.h
deleted file mode 100644
index b2664be6a..000000000
--- a/navit/support/espeak/espeak_command.h
+++ /dev/null
@@ -1,145 +0,0 @@
-#ifndef ESPEAK_COMMAND_H
-#define ESPEAK_COMMAND_H
-
-#ifndef PLATFORM_WINDOWS
-#include <unistd.h>
-#endif
-#include "speak_lib.h"
-
-enum t_espeak_type
- {
- ET_TEXT,
- ET_MARK,
- ET_KEY,
- ET_CHAR,
- ET_PARAMETER,
- ET_PUNCTUATION_LIST,
- ET_VOICE_NAME,
- ET_VOICE_SPEC,
- ET_TERMINATED_MSG
- };
-
-typedef struct
-{
- unsigned int unique_identifier;
- void* text;
- size_t size;
- unsigned int position;
- espeak_POSITION_TYPE position_type;
- unsigned int end_position;
- unsigned int flags;
- void* user_data;
-} t_espeak_text;
-
-typedef struct
-{
- unsigned int unique_identifier;
- void* text;
- size_t size;
- const char* index_mark;
- unsigned int end_position;
- unsigned int flags;
- void* user_data;
-} t_espeak_mark;
-
-typedef struct
-{
- unsigned int unique_identifier;
- void* user_data;
- wchar_t character;
-} t_espeak_character;
-
-typedef struct
-{
- unsigned int unique_identifier;
- void* user_data;
- const char* key_name;
-} t_espeak_key;
-
-
-typedef struct
-{
- unsigned int unique_identifier;
- void* user_data;
-} t_espeak_terminated_msg;
-
-
-typedef struct
-{
- espeak_PARAMETER parameter;
- int value;
- int relative;
-} t_espeak_parameter;
-
-enum t_command_state
-{
- CS_UNDEFINED, // The command has just been created
- CS_PENDING, // stored in the fifo
- CS_PROCESSED // processed
-};
-
-typedef struct
-{
- enum t_espeak_type type;
- enum t_command_state state;
-
- union command
- {
- t_espeak_text my_text;
- t_espeak_mark my_mark;
- t_espeak_key my_key;
- t_espeak_character my_char;
- t_espeak_parameter my_param;
- const wchar_t* my_punctuation_list;
- const char *my_voice_name;
- espeak_VOICE my_voice_spec;
- t_espeak_terminated_msg my_terminated_msg;
- } u;
-} t_espeak_command;
-
-
-t_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);
-
-t_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);
-
-t_espeak_command* create_espeak_terminated_msg(unsigned int unique_identifier, void* user_data);
-
-t_espeak_command* create_espeak_key(const char *key_name, void *user_data);
-
-t_espeak_command* create_espeak_char(wchar_t character, void *user_data);
-
-t_espeak_command* create_espeak_parameter(espeak_PARAMETER parameter, int value, int relative);
-
-t_espeak_command* create_espeak_punctuation_list(const wchar_t *punctlist);
-
-t_espeak_command* create_espeak_voice_name(const char *name);
-
-t_espeak_command* create_espeak_voice_spec(espeak_VOICE *voice_spec);
-
-void process_espeak_command( t_espeak_command* the_command);
-
-int delete_espeak_command( t_espeak_command* the_command);
-
-void display_espeak_command(t_espeak_command* the_command);
-
-
-espeak_ERROR sync_espeak_Synth(unsigned int unique_identifier, const void *text, size_t size,
- unsigned int position, espeak_POSITION_TYPE position_type,
- unsigned int end_position, unsigned int flags, void* user_data);
-espeak_ERROR sync_espeak_Synth_Mark(unsigned int unique_identifier, const void *text, size_t size,
- const char *index_mark, unsigned int end_position,
- unsigned int flags, void* user_data);
-void sync_espeak_Key(const char *key);
-void sync_espeak_Char(wchar_t character);
-void sync_espeak_SetPunctuationList(const wchar_t *punctlist);
-void sync_espeak_SetParameter(espeak_PARAMETER parameter, int value, int relative);
-int sync_espeak_SetVoiceByName(const char *name);
-int sync_espeak_SetVoiceByProperties(espeak_VOICE *voice_selector);
-espeak_ERROR SetVoiceByName(const char *name);
-espeak_ERROR SetVoiceByProperties(espeak_VOICE *voice_selector);
-void SetParameter(int parameter, int value, int relative);
-
-int sync_espeak_terminated_msg(unsigned int unique_identifier, void* user_data);
-
-//>
-#endif
diff --git a/navit/support/espeak/event.c b/navit/support/espeak/event.c
deleted file mode 100644
index cc696272d..000000000
--- a/navit/support/espeak/event.c
+++ /dev/null
@@ -1,725 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2007, Gilles Casse <gcasse@oralux.org> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-#include "speech.h"
-
-#ifdef USE_ASYNC
-// This source file is only used for asynchronious modes
-
-
-//<includes
-#include <unistd.h>
-#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
-#include <pthread.h>
-#include <semaphore.h>
-#include <sys/time.h>
-#include <errno.h>
-
-#include "speak_lib.h"
-#include "event.h"
-#include "wave.h"
-#include "debug.h"
-//>
-//<decls and function prototypes
-
-
-// my_mutex: protects my_thread_is_talking,
-static pthread_mutex_t my_mutex;
-static sem_t my_sem_start_is_required;
-static sem_t my_sem_stop_is_required;
-static sem_t my_sem_stop_is_acknowledged;
-// my_thread: polls the audio duration and compares it to the duration of the first event.
-static pthread_t my_thread;
-
-static t_espeak_callback* my_callback = NULL;
-static int my_event_is_running=0;
-
-enum {MIN_TIMEOUT_IN_MS=10,
- ACTIVITY_TIMEOUT=50, // in ms, check that the stream is active
- MAX_ACTIVITY_CHECK=6
-};
-
-
-typedef struct t_node
-{
- void* data;
- t_node *next;
-} node;
-
-static node* head=NULL;
-static node* tail=NULL;
-static int node_counter=0;
-static espeak_ERROR push(void* data);
-static void* pop();
-static void init();
-static void* polling_thread(void*);
-
-//>
-//<event_init
-
-void event_set_callback(t_espeak_callback* SynthCallback)
-{
- my_callback = SynthCallback;
-}
-
-void event_init(void)
-{
- ENTER("event_init");
-
- my_event_is_running=0;
-
- // security
- pthread_mutex_init( &my_mutex, (const pthread_mutexattr_t *)NULL);
- init();
-
- assert(-1 != sem_init(&my_sem_start_is_required, 0, 0));
- assert(-1 != sem_init(&my_sem_stop_is_required, 0, 0));
- assert(-1 != sem_init(&my_sem_stop_is_acknowledged, 0, 0));
-
- pthread_attr_t a_attrib;
- if (pthread_attr_init (& a_attrib)
- || pthread_attr_setdetachstate(&a_attrib, PTHREAD_CREATE_JOINABLE)
- || pthread_create( &my_thread,
- & a_attrib,
- polling_thread,
- (void*)NULL))
- {
- assert(0);
- }
-
- pthread_attr_destroy(&a_attrib);
-}
-//>
-//<event_display
-static void event_display(espeak_EVENT* event)
-{
-ENTER("event_display");
-
-#ifdef DEBUG_ENABLED
- if (event==NULL)
- {
- SHOW("event_display > event=%s\n","NULL");
- }
- else
- {
- static const char* label[] = {
- "LIST_TERMINATED",
- "WORD",
- "SENTENCE",
- "MARK",
- "PLAY",
- "END",
- "MSG_TERMINATED"
- };
-
- SHOW("event_display > event=0x%x\n",event);
- SHOW("event_display > type=%s\n",label[event->type]);
- SHOW("event_display > uid=%d\n",event->unique_identifier);
- SHOW("event_display > text_position=%d\n",event->text_position);
- SHOW("event_display > length=%d\n",event->length);
- SHOW("event_display > audio_position=%d\n",event->audio_position);
- SHOW("event_display > sample=%d\n",event->sample);
- SHOW("event_display > user_data=0x%x\n",event->user_data);
- }
-#endif
-}
-//>
-//<event_copy
-
-static espeak_EVENT* event_copy (espeak_EVENT* event)
-{
- ENTER("event_copy");
-
- if (event==NULL)
- {
- return NULL;
- }
-
- espeak_EVENT* a_event=(espeak_EVENT*)malloc(sizeof(espeak_EVENT));
- if (a_event)
- {
- memcpy(a_event, event, sizeof(espeak_EVENT));
-
- switch(event->type)
- {
- case espeakEVENT_MARK:
- case espeakEVENT_PLAY:
- if (event->id.name)
- {
- a_event->id.name = strdup(event->id.name);
- }
- break;
-
- default:
- break;
- }
- }
-
- event_display(a_event);
-
- return a_event;
-}
-
-//>
-//<event_notify
-
-// Call the user supplied callback
-//
-// Note: the current sequence is:
-//
-// * First call with: event->type = espeakEVENT_SENTENCE
-// * 0, 1 or several calls: event->type = espeakEVENT_WORD
-// * Last call: event->type = espeakEVENT_MSG_TERMINATED
-//
-
-static void event_notify(espeak_EVENT* event)
-{
-ENTER("event_notify");
- static unsigned int a_old_uid = 0;
-
- espeak_EVENT events[2];
- memcpy(&events[0],event,sizeof(espeak_EVENT)); // the event parameter in the callback function should be an array of eventd
- memcpy(&events[1],event,sizeof(espeak_EVENT));
- events[1].type = espeakEVENT_LIST_TERMINATED; // ... terminated by an event type=0
-
- if (event && my_callback)
- {
- event_display(event);
-
- switch(event->type)
- {
- case espeakEVENT_SENTENCE:
- my_callback(NULL, 0, events);
- a_old_uid = event->unique_identifier;
- break;
-
- case espeakEVENT_MSG_TERMINATED:
- case espeakEVENT_MARK:
- case espeakEVENT_WORD:
- case espeakEVENT_END:
- case espeakEVENT_PHONEME:
- {
-// jonsd - I'm not sure what this is for. gilles says it's for when Gnome Speech reads a file of blank lines
- if (a_old_uid != event->unique_identifier)
- {
- espeak_EVENT_TYPE a_new_type = events[0].type;
- events[0].type = espeakEVENT_SENTENCE;
- my_callback(NULL, 0, events);
- events[0].type = a_new_type;
- usleep(50000);
- }
- my_callback(NULL, 0, events);
- a_old_uid = event->unique_identifier;
- }
- break;
-
- default:
- case espeakEVENT_LIST_TERMINATED:
- case espeakEVENT_PLAY:
- break;
- }
- }
-}
-//>
-//<event_delete
-
-static int event_delete(espeak_EVENT* event)
-{
-ENTER("event_delete");
-
- event_display(event);
-
- if(event==NULL)
- {
- return 0;
- }
-
- switch(event->type)
- {
- case espeakEVENT_MSG_TERMINATED:
- event_notify(event);
- break;
-
- case espeakEVENT_MARK:
- case espeakEVENT_PLAY:
- if(event->id.name)
- {
- free((void*)(event->id.name));
- }
- break;
-
- default:
- break;
- }
-
- free(event);
- return 1;
-}
-
-//>
-//<event_declare
-
-espeak_ERROR event_declare (espeak_EVENT* event)
-{
-ENTER("event_declare");
-
- event_display(event);
-
- if (!event)
- {
- return EE_INTERNAL_ERROR;
- }
-
- int a_status = pthread_mutex_lock(&my_mutex);
- espeak_ERROR a_error = EE_OK;
-
- if (!a_status)
- {
- SHOW_TIME("event_declare > locked\n");
- espeak_EVENT* a_event = event_copy(event);
- a_error = push(a_event);
- if (a_error != EE_OK)
- {
- event_delete(a_event);
- }
- SHOW_TIME("event_declare > unlocking\n");
- a_status = pthread_mutex_unlock(&my_mutex);
- }
-
- // TBD: remove the comment
- // reminder: code in comment.
- // This wait can lead to an underrun
- //
-// if (!a_status && !my_event_is_running && (a_error == EE_OK))
-// {
-// // quit when command is actually started
-// // (for possible forthcoming 'end of command' checks)
- SHOW_TIME("event_declare > post my_sem_start_is_required\n");
- sem_post(&my_sem_start_is_required);
-// int val=1;
-// while (val)
-// {
-// usleep(50000); // TBD: event?
-// sem_getvalue(&my_sem_start_is_required, &val);
-// }
-// }
-
- if (a_status != 0)
- {
- a_error = EE_INTERNAL_ERROR;
- }
-
- return a_error;
-}
-
-//>
-//<event_clear_all
-
-espeak_ERROR event_clear_all ()
-{
- ENTER("event_clear_all");
-
- int a_status = pthread_mutex_lock(&my_mutex);
- int a_event_is_running = 0;
-
- SHOW_TIME("event_stop > locked\n");
- if (a_status != 0)
- {
- return EE_INTERNAL_ERROR;
- }
-
- if (my_event_is_running)
- {
- SHOW_TIME("event_stop > post my_sem_stop_is_required\n");
- sem_post(&my_sem_stop_is_required);
- a_event_is_running = 1;
- }
- else
- {
- init(); // clear pending events
- }
- SHOW_TIME("event_stop > unlocking\n");
- a_status = pthread_mutex_unlock(&my_mutex);
- if (a_status != 0)
- {
- return EE_INTERNAL_ERROR;
- }
-
- if (a_event_is_running)
- {
- SHOW_TIME("event_stop > wait for my_sem_stop_is_acknowledged\n");
- while ((sem_wait(&my_sem_stop_is_acknowledged) == -1) && errno == EINTR)
- {
- continue; // Restart when interrupted by handler
- }
- SHOW_TIME("event_stop > get my_sem_stop_is_acknowledged\n");
- }
-
- SHOW_TIME("LEAVE event_stop\n");
-
- return EE_OK;
-}
-
-//>
-//<sleep_until_timeout_or_stop_request
-
-static int sleep_until_timeout_or_stop_request(uint32_t time_in_ms)
-{
-ENTER("sleep_until_timeout_or_stop_request");
-
- int a_stop_is_required=0;
- struct timespec ts, to;
- struct timeval tv;
- int err=0;
-
- clock_gettime2( &ts);
- to.tv_sec = ts.tv_sec;
- to.tv_nsec = ts.tv_nsec;
-
- add_time_in_ms( &ts, time_in_ms);
-
- SHOW("polling_thread > sleep_until_timeout_or_stop_request > start sem_timedwait from %d.%09lu to %d.%09lu \n",
- to.tv_sec, to.tv_nsec,
- ts.tv_sec, ts.tv_nsec);
-
- while ((err = sem_timedwait(&my_sem_stop_is_required, &ts)) == -1
- && errno == EINTR)
- {
- continue; // Restart when interrupted by handler
- }
-
- assert (gettimeofday(&tv, NULL) != -1);
- SHOW("polling_thread > sleep_until_timeout_or_stop_request > stop sem_timedwait %d.%09lu \n",
- tv.tv_sec, tv.tv_usec*1000);
-
- if (err == 0)
- {
- SHOW("polling_thread > sleep_until_timeout_or_stop_request > %s\n","stop required!");
- a_stop_is_required=1; // stop required
- }
- return a_stop_is_required;
-}
-
-//>
-//<get_remaining_time
-// Asked for the time interval required for reaching the sample.
-// If the stream is opened but the audio samples are not played,
-// a timeout is started.
-
-static int get_remaining_time(uint32_t sample, uint32_t* time_in_ms, int* stop_is_required)
-{
-ENTER("get_remaining_time");
-
- int err = 0;
- *stop_is_required = 0;
- int i=0;
-
- for (i=0; i < MAX_ACTIVITY_CHECK && (*stop_is_required == 0); i++)
- {
- err = wave_get_remaining_time( sample, time_in_ms);
-
- if (err || wave_is_busy(NULL) || (*time_in_ms == 0))
- { // if err, stream not available: quit
- // if wave is busy, time_in_ms is known: quit
- // if wave is not busy but remaining time == 0, event is reached: quit
- break;
- }
-
- // stream opened but not active
- //
- // Several possible states:
- // * the stream is opened but not yet started:
- //
- // wait for the start of stream
- //
- // * some samples have already been played,
- // ** the end of stream is reached
- // ** or there is an underrun
- //
- // wait for the close of stream
-
- *stop_is_required = sleep_until_timeout_or_stop_request( ACTIVITY_TIMEOUT);
- }
-
- return err;
-}
-
-//>
-//<polling_thread
-
-static void* polling_thread(void*)
-{
-ENTER("polling_thread");
-
- while(1)
- {
- int a_stop_is_required=0;
-
- SHOW_TIME("polling_thread > locking\n");
- int a_status = pthread_mutex_lock(&my_mutex);
- SHOW_TIME("polling_thread > locked (my_event_is_running = 0)\n");
- my_event_is_running = 0;
- pthread_mutex_unlock(&my_mutex);
- SHOW_TIME("polling_thread > unlocked\n");
-
- SHOW_TIME("polling_thread > wait for my_sem_start_is_required\n");
-
- while ((sem_wait(&my_sem_start_is_required) == -1) && errno == EINTR)
- {
- continue; // Restart when interrupted by handler
- }
-
- SHOW_TIME("polling_thread > get my_sem_start_is_required\n");
-
- a_status = pthread_mutex_lock(&my_mutex);
- SHOW_TIME("polling_thread > locked (my_event_is_running = 1)\n");
- my_event_is_running = 1;
- pthread_mutex_unlock(&my_mutex);
- SHOW_TIME("polling_thread > unlocked\n");
-
- a_stop_is_required=0;
- a_status = sem_getvalue(&my_sem_stop_is_required, &a_stop_is_required);
- if ((a_status==0) && a_stop_is_required)
- {
- SHOW("polling_thread > stop required (%d)\n", __LINE__);
- while(0 == sem_trywait(&my_sem_stop_is_required))
- {
- };
- }
- else
- {
- a_stop_is_required=0;
- }
-
- // In this loop, my_event_is_running = 1
- while (head && !a_stop_is_required)
- {
- SHOW_TIME("polling_thread > check head\n");
- while(0 == sem_trywait(&my_sem_start_is_required))
- {
- };
-
- espeak_EVENT* event = (espeak_EVENT*)(head->data);
- assert(event);
-
- uint32_t time_in_ms = 0;
-
- int err = get_remaining_time((uint32_t)event->sample,
- &time_in_ms,
- &a_stop_is_required);
- if (a_stop_is_required)
- {
- break;
- }
- else if (err != 0)
- {
- // No available time: the event is deleted.
- SHOW("polling_thread > %s\n","audio device down");
- a_status = pthread_mutex_lock(&my_mutex);
- SHOW_TIME("polling_thread > locked\n");
- event_delete( (espeak_EVENT*)pop());
- a_status = pthread_mutex_unlock(&my_mutex);
- SHOW_TIME("polling_thread > unlocked\n");
- }
- else if (time_in_ms==0)
- { // the event is already reached.
- if (my_callback)
- {
- event_notify(event);
- // the user_data (and the type) are cleaned to be sure
- // that MSG_TERMINATED is called twice (at delete time too).
- event->type=espeakEVENT_LIST_TERMINATED;
- event->user_data=NULL;
- }
-
- a_status = pthread_mutex_lock(&my_mutex);
- SHOW_TIME("polling_thread > locked\n");
- event_delete( (espeak_EVENT*)pop());
- a_status = pthread_mutex_unlock(&my_mutex);
- SHOW_TIME("polling_thread > unlocked\n");
-
- a_stop_is_required=0;
- a_status = sem_getvalue(&my_sem_stop_is_required, &a_stop_is_required);
-
- if ((a_status==0) && a_stop_is_required)
- {
- SHOW("polling_thread > stop required (%d)\n", __LINE__);
- while(0 == sem_trywait(&my_sem_stop_is_required))
- {
- };
- }
- else
- {
- a_stop_is_required=0;
- }
- }
- else
- { // The event will be notified soon: sleep until timeout or stop request
- a_stop_is_required = sleep_until_timeout_or_stop_request(time_in_ms);
- }
- }
-
- a_status = pthread_mutex_lock(&my_mutex);
- SHOW_TIME("polling_thread > locked\n");
-
- SHOW_TIME("polling_thread > my_event_is_running = 0\n");
- my_event_is_running = 0;
-
- if(!a_stop_is_required)
- {
- a_status = sem_getvalue(&my_sem_stop_is_required, &a_stop_is_required);
- if ((a_status==0) && a_stop_is_required)
- {
- SHOW("polling_thread > stop required (%d)\n", __LINE__);
- while(0 == sem_trywait(&my_sem_stop_is_required))
- {
- };
- }
- else
- {
- a_stop_is_required=0;
- }
- }
-
- a_status = pthread_mutex_unlock(&my_mutex);
- SHOW_TIME("polling_thread > unlocked\n");
-
- if (a_stop_is_required)
- {
- SHOW("polling_thread > %s\n","stop required!");
- // no mutex required since the stop command is synchronous
- // and waiting for my_sem_stop_is_acknowledged
- init();
-
- // acknowledge the stop request
- SHOW_TIME("polling_thread > post my_sem_stop_is_acknowledged\n");
- a_status = sem_post(&my_sem_stop_is_acknowledged);
- }
- }
-
- return NULL;
-}
-
-//>
-//<push, pop, init
-enum {MAX_NODE_COUNTER=1000};
-// return 1 if ok, 0 otherwise
-static espeak_ERROR push(void* the_data)
-{
- ENTER("event > push");
-
- assert((!head && !tail) || (head && tail));
-
- if (the_data == NULL)
- {
- SHOW("event > push > event=0x%x\n", NULL);
- return EE_INTERNAL_ERROR;
- }
-
- if (node_counter >= MAX_NODE_COUNTER)
- {
- SHOW("event > push > %s\n", "EE_BUFFER_FULL");
- return EE_BUFFER_FULL;
- }
-
- node *n = (node *)malloc(sizeof(node));
- if (n == NULL)
- {
- return EE_INTERNAL_ERROR;
- }
-
- if (head == NULL)
- {
- head = n;
- tail = n;
- }
- else
- {
- tail->next = n;
- tail = n;
- }
-
- tail->next = NULL;
- tail->data = the_data;
-
- node_counter++;
- SHOW("event > push > counter=%d (uid=%d)\n",node_counter,((espeak_EVENT*)the_data)->unique_identifier);
-
- return EE_OK;
-}
-
-static void* pop()
-{
- ENTER("event > pop");
- void* the_data = NULL;
-
- assert((!head && !tail) || (head && tail));
-
- if (head != NULL)
- {
- node* n = head;
- the_data = n->data;
- head = n->next;
- free(n);
- node_counter--;
- SHOW("event > pop > event=0x%x (counter=%d, uid=%d)\n",the_data, node_counter,((espeak_EVENT*)the_data)->unique_identifier);
- }
-
- if(head == NULL)
- {
- tail = NULL;
- }
-
- return the_data;
-}
-
-
-static void init()
-{
- ENTER("event > init");
-
- while (event_delete( (espeak_EVENT*)pop() ))
- {}
-
- node_counter = 0;
-}
-
-//>
-//<event_terminate
-void event_terminate()
-{
-ENTER("event_terminate");
-
- if (my_thread)
- {
- pthread_cancel(my_thread);
- pthread_join(my_thread,NULL);
- pthread_mutex_destroy(&my_mutex);
- sem_destroy(&my_sem_start_is_required);
- sem_destroy(&my_sem_stop_is_required);
- sem_destroy(&my_sem_stop_is_acknowledged);
- init(); // purge event
- }
-}
-
-#endif
-//>
-
diff --git a/navit/support/espeak/event.h b/navit/support/espeak/event.h
deleted file mode 100644
index c9ee482b0..000000000
--- a/navit/support/espeak/event.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef EVENT_H
-#define EVENT_H
-
-/*
-Manage events (sentence, word, mark, end,...), is responsible of calling the external
-callback as soon as the relevant audio sample is played.
-
-
-The audio stream is composed of samples from synthetised messages or audio icons.
-Each event is associated to a sample.
-
-Scenario:
-
-- event_declare is called for each expected event.
-
-- A timeout is started for the first pending event.
-
-- When the timeout happens, the synth_callback is called.
-
-Note: the timeout is checked against the real progress of the audio stream, which depends on pauses or underruns. If the real progress is lower than the expected one, a new timeout starts.
-
-*/
-
-#include "speak_lib.h"
-
-// Initialize the event component.
-// First function to be called.
-// the callback will be called when the event actually occurs.
-// The callback is detailled in speak_lib.h .
-void event_init(void);
-void event_set_callback(t_espeak_callback* cb);
-
-// Clear any pending event.
-//
-// Return: EE_OK: operation achieved
-// EE_INTERNAL_ERROR.
-espeak_ERROR event_clear_all ();
-
-// Declare a future event
-//
-// Return: EE_OK: operation achieved
-// EE_BUFFER_FULL: the event can not be buffered;
-// you may try after a while to call the function again.
-// EE_INTERNAL_ERROR.
-espeak_ERROR event_declare (espeak_EVENT* event);
-
-// Terminate the event component.
-// Last function to be called.
-void event_terminate();
-
-#endif
diff --git a/navit/support/espeak/fifo.c b/navit/support/espeak/fifo.c
deleted file mode 100644
index 95d5ab1ed..000000000
--- a/navit/support/espeak/fifo.c
+++ /dev/null
@@ -1,593 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2007, Gilles Casse <gcasse@oralux.org> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-#include "speech.h"
-
-#ifdef USE_ASYNC
-// This source file is only used for asynchronious modes
-
-
-//<includes
-
-#include <unistd.h>
-#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
-#include <pthread.h>
-#include <semaphore.h>
-#include <wchar.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <time.h>
-
-#include "fifo.h"
-#include "wave.h"
-#include "debug.h"
-
-
-//>
-//<decls and function prototypes
-
-// my_mutex: protects my_thread_is_talking,
-// my_stop_is_required, and the command fifo
-static pthread_mutex_t my_mutex;
-static int my_command_is_running = 0;
-static int my_stop_is_required = 0;
-// + fifo
-//
-
-// my_thread: reads commands from the fifo, and runs them.
-static pthread_t my_thread;
-static sem_t my_sem_start_is_required;
-static sem_t my_sem_stop_is_acknowledged;
-
-static void* say_thread(void*);
-
-static espeak_ERROR push(t_espeak_command* the_command);
-static t_espeak_command* pop();
-static void init();
-static int node_counter=0;
-enum {MAX_NODE_COUNTER=400,
- INACTIVITY_TIMEOUT=50, // in ms, check that the stream is inactive
- MAX_INACTIVITY_CHECK=2
-};
-
-//>
-//<fifo_init
-void fifo_init()
-{
- ENTER("fifo_init");
-
- // security
- pthread_mutex_init( &my_mutex, (const pthread_mutexattr_t *)NULL);
- init();
-
- assert(-1 != sem_init(&my_sem_start_is_required, 0, 0));
- assert(-1 != sem_init(&my_sem_stop_is_acknowledged, 0, 0));
-
- pthread_attr_t a_attrib;
- if (pthread_attr_init (& a_attrib)
- || pthread_attr_setdetachstate(&a_attrib, PTHREAD_CREATE_JOINABLE)
- || pthread_create( &my_thread,
- & a_attrib,
- say_thread,
- (void*)NULL))
- {
- assert(0);
- }
-
- pthread_attr_destroy(&a_attrib);
-
- // leave once the thread is actually started
- SHOW_TIME("fifo > wait for my_sem_stop_is_acknowledged\n");
- while ((sem_wait(&my_sem_stop_is_acknowledged) == -1) && errno == EINTR)
- {
- continue; // Restart when interrupted by handler
- }
- SHOW_TIME("fifo > get my_sem_stop_is_acknowledged\n");
-}
-//>
-//<fifo_add_command
-
-espeak_ERROR fifo_add_command (t_espeak_command* the_command)
-{
- ENTER("fifo_add_command");
-
- int a_status = pthread_mutex_lock(&my_mutex);
- espeak_ERROR a_error = EE_OK;
-
- if (!a_status)
- {
- SHOW_TIME("fifo_add_command > locked\n");
- a_error = push(the_command);
- SHOW_TIME("fifo_add_command > unlocking\n");
- a_status = pthread_mutex_unlock(&my_mutex);
- }
-
- if (!a_status && !my_command_is_running && (a_error == EE_OK))
- {
- // quit when command is actually started
- // (for possible forthcoming 'end of command' checks)
- SHOW_TIME("fifo_add_command > post my_sem_start_is_required\n");
- sem_post(&my_sem_start_is_required);
- int val=1;
- while (val)
- {
- usleep(50000); // TBD: event?
- sem_getvalue(&my_sem_start_is_required, &val);
- }
- }
-
- if (a_status != 0)
- {
- a_error = EE_INTERNAL_ERROR;
- }
-
- SHOW_TIME("LEAVE fifo_add_command");
- return a_error;
-}
-
-//>
-//<fifo_add_commands
-
-espeak_ERROR fifo_add_commands (t_espeak_command* command1, t_espeak_command* command2)
-{
- ENTER("fifo_add_command");
-
- int a_status = pthread_mutex_lock(&my_mutex);
- espeak_ERROR a_error = EE_OK;
-
- if (!a_status)
- {
- SHOW_TIME("fifo_add_commands > locked\n");
-
- if (node_counter+1 >= MAX_NODE_COUNTER)
- {
- SHOW("push > %s\n", "EE_BUFFER_FULL");
- a_error = EE_BUFFER_FULL;
- }
- else
- {
- push(command1);
- push(command2);
- }
- SHOW_TIME("fifo_add_command > unlocking\n");
- a_status = pthread_mutex_unlock(&my_mutex);
- }
-
- if (!a_status && !my_command_is_running && (a_error == EE_OK))
- {
- // quit when one command is actually started
- // (for possible forthcoming 'end of command' checks)
- SHOW_TIME("fifo_add_command > post my_sem_start_is_required\n");
- sem_post(&my_sem_start_is_required);
- int val=1;
- while (val)
- {
- usleep(50000); // TBD: event?
- sem_getvalue(&my_sem_start_is_required, &val);
- }
- }
-
- if (a_status != 0)
- {
- a_error = EE_INTERNAL_ERROR;
- }
-
- SHOW_TIME("LEAVE fifo_add_commands");
- return a_error;
-}
-
-//>
-//<fifo_stop
-
-espeak_ERROR fifo_stop ()
-{
- ENTER("fifo_stop");
-
- int a_command_is_running = 0;
- int a_status = pthread_mutex_lock(&my_mutex);
- SHOW_TIME("fifo_stop > locked\n");
- if (a_status != 0)
- {
- return EE_INTERNAL_ERROR;
- }
-
- if (my_command_is_running)
- {
- a_command_is_running = 1;
- my_stop_is_required = 1;
- SHOW_TIME("fifo_stop > my_stop_is_required = 1\n");
- }
- SHOW_TIME("fifo_stop > unlocking\n");
- a_status = pthread_mutex_unlock(&my_mutex);
- if (a_status != 0)
- {
- return EE_INTERNAL_ERROR;
- }
-
- if (a_command_is_running)
- {
- SHOW_TIME("fifo_stop > wait for my_sem_stop_is_acknowledged\n");
- while ((sem_wait(&my_sem_stop_is_acknowledged) == -1) && errno == EINTR)
- {
- continue; // Restart when interrupted by handler
- }
- SHOW_TIME("fifo_stop > get my_sem_stop_is_acknowledged\n");
- }
-
- SHOW_TIME("fifo_stop > my_stop_is_required = 0\n");
- my_stop_is_required = 0;
- SHOW_TIME("LEAVE fifo_stop\n");
-
- return EE_OK;
-}
-
-//>
-
-//<fifo_is_speaking
-int fifo_is_busy ()
-{
- // ENTER("isSpeaking");
- // int aResult = (int) (my_command_is_running || WaveIsPlaying());
- SHOW("fifo_is_busy > aResult = %d\n",my_command_is_running);
- return my_command_is_running;
-}
-
-// int pause ()
-// {
-// ENTER("pause");
-// // TBD
-// // if (espeakPause (espeakHandle, 1))
-// return true;
-// }
-
-// int resume ()
-// {
-// ENTER("resume");
-// // TBD
-// // if (espeakPause (espeakHandle, 0))
-// return true;
-// }
-//>
-
-
-//<sleep_until_start_request_or_inactivity
-
-static int sleep_until_start_request_or_inactivity()
-{
- SHOW_TIME("fifo > sleep_until_start_request_or_inactivity > ENTER");
- int a_start_is_required=0;
-
- // Wait for the start request (my_sem_start_is_required).
- // Besides this, if the audio stream is still busy,
- // check from time to time its end.
- // The end of the stream is confirmed by several checks
- // for filtering underflow.
- //
- int i=0;
- while((i<= MAX_INACTIVITY_CHECK) && !a_start_is_required)
- {
- if (wave_is_busy( NULL) )
- {
- i = 0;
- }
- else
- {
- i++;
- }
-
- int err=0;
- struct timespec ts, to;
- struct timeval tv;
-
- clock_gettime2( &ts);
- to.tv_sec = ts.tv_sec;
- to.tv_nsec = ts.tv_nsec;
-
- add_time_in_ms( &ts, INACTIVITY_TIMEOUT);
-
- SHOW("fifo > sleep_until_start_request_or_inactivity > start sem_timedwait (start_is_required) from %d.%09lu to %d.%09lu \n",
- to.tv_sec, to.tv_nsec,
- ts.tv_sec, ts.tv_nsec);
-
- while ((err = sem_timedwait(&my_sem_start_is_required, &ts)) == -1
- && errno == EINTR)
- {
- continue;
- }
-
- assert (gettimeofday(&tv, NULL) != -1);
- SHOW("fifo > sleep_until_start_request_or_inactivity > stop sem_timedwait (start_is_required, err=%d) %d.%09lu \n", err,
- tv.tv_sec, tv.tv_usec*1000);
-
- if (err==0)
- {
- a_start_is_required = 1;
- }
- }
- SHOW_TIME("fifo > sleep_until_start_request_or_inactivity > LEAVE");
- return a_start_is_required;
-}
-
-//>
-//<close_stream
-
-static void close_stream()
-{
- SHOW_TIME("fifo > close_stream > ENTER\n");
-
- // Warning: a wave_close can be already required by
- // an external command (espeak_Cancel + fifo_stop), if so:
- // my_stop_is_required = 1;
-
- int a_status = pthread_mutex_lock(&my_mutex);
- assert (!a_status);
- int a_stop_is_required = my_stop_is_required;
- if (!a_stop_is_required)
- {
- my_command_is_running = 1;
- }
- a_status = pthread_mutex_unlock(&my_mutex);
-
- if (!a_stop_is_required)
- {
- wave_close(NULL);
-
- int a_status = pthread_mutex_lock(&my_mutex);
- assert (!a_status);
- my_command_is_running = 0;
-
- a_stop_is_required = my_stop_is_required;
- a_status = pthread_mutex_unlock(&my_mutex);
-
- if (a_stop_is_required)
- {
- // acknowledge the stop request
- SHOW_TIME("fifo > close_stream > post my_sem_stop_is_acknowledged\n");
- int a_status = sem_post(&my_sem_stop_is_acknowledged);
- assert( a_status != -1);
- }
- }
-
- SHOW_TIME("fifo > close_stream > LEAVE\n");
-}
-
-//>
-//<say_thread
-
-static void* say_thread(void*)
-{
- ENTER("say_thread");
-
- SHOW_TIME("say_thread > post my_sem_stop_is_acknowledged\n");
-
- // announce that thread is started
- sem_post(&my_sem_stop_is_acknowledged);
-
- int look_for_inactivity=0;
-
- while(1)
- {
- SHOW_TIME("say_thread > wait for my_sem_start_is_required\n");
-
- int a_start_is_required = 0;
- if (look_for_inactivity)
- {
- a_start_is_required = sleep_until_start_request_or_inactivity();
- if (!a_start_is_required)
- {
- close_stream();
- }
- }
- look_for_inactivity = 1;
-
- if (!a_start_is_required)
- {
- while ((sem_wait(&my_sem_start_is_required) == -1) && errno == EINTR)
- {
- continue; // Restart when interrupted by handler
- }
- }
- SHOW_TIME("say_thread > get my_sem_start_is_required\n");
-
- SHOW_TIME("say_thread > my_command_is_running = 1\n");
- my_command_is_running = 1;
-
- while( my_command_is_running)
- {
- SHOW_TIME("say_thread > locking\n");
- int a_status = pthread_mutex_lock(&my_mutex);
- assert (!a_status);
- t_espeak_command* a_command = (t_espeak_command*)pop();
-
- if (a_command == NULL)
- {
- SHOW_TIME("say_thread > text empty (talking=0) \n");
- a_status = pthread_mutex_unlock(&my_mutex);
- SHOW_TIME("say_thread > unlocked\n");
- SHOW_TIME("say_thread > my_command_is_running = 0\n");
- my_command_is_running = 0;
- }
- else
- {
- display_espeak_command(a_command);
- // purge start semaphore
- SHOW_TIME("say_thread > purge my_sem_start_is_required\n");
- while(0 == sem_trywait(&my_sem_start_is_required))
- {
- };
-
- if (my_stop_is_required)
- {
- SHOW_TIME("say_thread > my_command_is_running = 0\n");
- my_command_is_running = 0;
- }
- SHOW_TIME("say_thread > unlocking\n");
- a_status = pthread_mutex_unlock(&my_mutex);
-
- if (my_command_is_running)
- {
- process_espeak_command(a_command);
- }
- delete_espeak_command(a_command);
- }
- }
-
- if (my_stop_is_required)
- {
- // no mutex required since the stop command is synchronous
- // and waiting for my_sem_stop_is_acknowledged
- init();
-
- // purge start semaphore
- SHOW_TIME("say_thread > purge my_sem_start_is_required\n");
- while(0==sem_trywait(&my_sem_start_is_required))
- {
- };
-
- // acknowledge the stop request
- SHOW_TIME("say_thread > post my_sem_stop_is_acknowledged\n");
- int a_status = sem_post(&my_sem_stop_is_acknowledged);
- assert( a_status != -1);
- }
- // and wait for the next start
- SHOW_TIME("say_thread > wait for my_sem_start_is_required\n");
- }
-
- return NULL;
-}
-
-int fifo_is_command_enabled()
-{
- SHOW("ENTER fifo_is_command_enabled=%d\n",(int)(0 == my_stop_is_required));
- return (0 == my_stop_is_required);
-}
-
-//>
-//<fifo
-typedef struct t_node
-{
- t_espeak_command* data;
- t_node *next;
-} node;
-
-static node* head=NULL;
-static node* tail=NULL;
-// return 1 if ok, 0 otherwise
-static espeak_ERROR push(t_espeak_command* the_command)
-{
- ENTER("fifo > push");
-
- assert((!head && !tail) || (head && tail));
-
- if (the_command == NULL)
- {
- SHOW("push > command=0x%x\n", NULL);
- return EE_INTERNAL_ERROR;
- }
-
- if (node_counter >= MAX_NODE_COUNTER)
- {
- SHOW("push > %s\n", "EE_BUFFER_FULL");
- return EE_BUFFER_FULL;
- }
-
- node *n = (node *)malloc(sizeof(node));
- if (n == NULL)
- {
- return EE_INTERNAL_ERROR;
- }
-
- if (head == NULL)
- {
- head = n;
- tail = n;
- }
- else
- {
- tail->next = n;
- tail = n;
- }
-
- tail->next = NULL;
- tail->data = the_command;
-
- node_counter++;
- SHOW("push > counter=%d\n",node_counter);
-
- the_command->state = CS_PENDING;
- display_espeak_command(the_command);
-
- return EE_OK;
-}
-
-static t_espeak_command* pop()
-{
- ENTER("fifo > pop");
- t_espeak_command* the_command = NULL;
-
- assert((!head && !tail) || (head && tail));
-
- if (head != NULL)
- {
- node* n = head;
- the_command = n->data;
- head = n->next;
- free(n);
- node_counter--;
- SHOW("pop > command=0x%x (counter=%d)\n",the_command, node_counter);
- }
-
- if(head == NULL)
- {
- tail = NULL;
- }
-
- display_espeak_command(the_command);
-
- return the_command;
-}
-
-
-static void init()
-{
- ENTER("fifo > init");
- while (delete_espeak_command( pop() ))
- {}
- node_counter = 0;
-}
-
-//>
-//<fifo_init
-void fifo_terminate()
-{
- ENTER("fifo_terminate");
-
- pthread_cancel(my_thread);
- pthread_join(my_thread,NULL);
- pthread_mutex_destroy(&my_mutex);
- sem_destroy(&my_sem_start_is_required);
- sem_destroy(&my_sem_stop_is_acknowledged);
-
- init(); // purge fifo
-}
-
-#endif
-//>
-
diff --git a/navit/support/espeak/fifo.h b/navit/support/espeak/fifo.h
deleted file mode 100644
index b3699ff9b..000000000
--- a/navit/support/espeak/fifo.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#ifndef FIFO_H
-#define FIFO_H
-
-// Helps to add espeak commands in a first-in first-out queue
-// and run them asynchronously.
-
-#include "espeak_command.h"
-#include "speak_lib.h"
-
-// Initialize the fifo component.
-// First function to be called.
-void fifo_init();
-
-// Add an espeak command.
-//
-// Note: this function fails if too many commands are already buffered.
-// In such a case, the calling function could wait and then add again its command.
-//
-// Return: EE_OK: operation achieved
-// EE_BUFFER_FULL: the command can not be buffered;
-// you may try after a while to call the function again.
-// EE_INTERNAL_ERROR.
-espeak_ERROR fifo_add_command (t_espeak_command* c);
-
-// Add two espeak commands in a single transaction.
-//
-// Note: this function fails if too many commands are already buffered.
-// In such a case, the calling function could wait and then add again these commands.
-//
-// Return: EE_OK: operation achieved
-// EE_BUFFER_FULL: at least one command can not be buffered;
-// you may try after a while to call the function again.
-// EE_INTERNAL_ERROR.
-espeak_ERROR fifo_add_commands (t_espeak_command* c1, t_espeak_command* c2);
-
-// The current running command must be stopped and the awaiting commands are cleared.
-// Return: EE_OK: operation achieved
-// EE_INTERNAL_ERROR.
-espeak_ERROR fifo_stop ();
-
-// Is there a running command?
-// Returns 1 if yes; 0 otherwise.
-int fifo_is_busy ();
-
-// Terminate the fifo component.
-// Last function to be called.
-void fifo_terminate();
-
-// Indicates if the running command is still enabled.
-//
-// Note: this function is mainly called by the SynthCallback (speak_lib.cpp)
-// It indicates if the actual wave sample can still be played. It is helpful for
-// stopping speech as soon as a cancel command is applied.
-//
-// Returns 1 if yes, or 0 otherwise.
-int fifo_is_command_enabled();
-
-#endif
diff --git a/navit/support/espeak/intonation.c b/navit/support/espeak/intonation.c
deleted file mode 100755
index 61b2ff282..000000000
--- a/navit/support/espeak/intonation.c
+++ /dev/null
@@ -1,1104 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2005 to 2007 by Jonathan Duddington *
- * email: jonsd@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write see: *
- * <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-#include "StdAfx.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <wctype.h>
-
-#include "speak_lib.h"
-#include "speech.h"
-#include "phoneme.h"
-#include "synthesize.h"
-#include "voice.h"
-#include "translate.h"
-
-
-/* Note this module is mostly old code that needs to be rewritten to
- provide a more flexible intonation system.
-*/
-
-// bits in SYLLABLE.flags
-#define SYL_RISE 1
-#define SYL_EMPHASIS 2
-#define SYL_END_CLAUSE 4
-
-typedef struct {
- char stress;
- char env;
- char flags; //bit 0=pitch rising, bit1=emnphasized, bit2=end of clause
- char nextph_type;
- short pitch1;
- short pitch2;
-} SYLLABLE;
-
-static SYLLABLE *syllable_tab;
-
-
-static int tone_pitch_env; /* used to return pitch envelope */
-
-
-
-/* Pitch data for tone types */
-/*****************************/
-
-
-#define PITCHfall 0
-#define PITCHrise 1
-#define PITCHfrise 2 // and 3 must be for the varient preceded by 'r'
-#define PITCHfrise2 4 // and 5 must be the 'r' variant
-#define PITCHrisefall 6
-
-/* 0 fall */
-unsigned char env_fall[128] = {
- 0xff, 0xfd, 0xfa, 0xf8, 0xf6, 0xf4, 0xf2, 0xf0, 0xee, 0xec, 0xea, 0xe8, 0xe6, 0xe4, 0xe2, 0xe0,
- 0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xd0, 0xce, 0xcc, 0xca, 0xc8, 0xc6, 0xc4, 0xc2, 0xc0,
- 0xbe, 0xbc, 0xba, 0xb8, 0xb6, 0xb4, 0xb2, 0xb0, 0xae, 0xac, 0xaa, 0xa8, 0xa6, 0xa4, 0xa2, 0xa0,
- 0x9e, 0x9c, 0x9a, 0x98, 0x96, 0x94, 0x92, 0x90, 0x8e, 0x8c, 0x8a, 0x88, 0x86, 0x84, 0x82, 0x80,
- 0x7e, 0x7c, 0x7a, 0x78, 0x76, 0x74, 0x72, 0x70, 0x6e, 0x6c, 0x6a, 0x68, 0x66, 0x64, 0x62, 0x60,
- 0x5e, 0x5c, 0x5a, 0x58, 0x56, 0x54, 0x52, 0x50, 0x4e, 0x4c, 0x4a, 0x48, 0x46, 0x44, 0x42, 0x40,
- 0x3e, 0x3c, 0x3a, 0x38, 0x36, 0x34, 0x32, 0x30, 0x2e, 0x2c, 0x2a, 0x28, 0x26, 0x24, 0x22, 0x20,
- 0x1e, 0x1c, 0x1a, 0x18, 0x16, 0x14, 0x12, 0x10, 0x0e, 0x0c, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x00 };
-
-/* 1 rise */
-unsigned char env_rise[128] = {
- 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
- 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
- 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
- 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
- 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
- 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
- 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
- 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfd, 0xff };
-
-unsigned char env_frise[128] = {
- 0xff, 0xf4, 0xea, 0xe0, 0xd6, 0xcc, 0xc3, 0xba, 0xb1, 0xa8, 0x9f, 0x97, 0x8f, 0x87, 0x7f, 0x78,
- 0x71, 0x6a, 0x63, 0x5c, 0x56, 0x50, 0x4a, 0x44, 0x3f, 0x39, 0x34, 0x2f, 0x2b, 0x26, 0x22, 0x1e,
- 0x1a, 0x17, 0x13, 0x10, 0x0d, 0x0b, 0x08, 0x06, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x13, 0x15, 0x17,
- 0x1a, 0x1d, 0x1f, 0x22, 0x25, 0x28, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x39, 0x3b, 0x3d, 0x40,
- 0x42, 0x45, 0x47, 0x4a, 0x4c, 0x4f, 0x51, 0x54, 0x57, 0x5a, 0x5d, 0x5f, 0x62, 0x65, 0x68, 0x6b,
- 0x6e, 0x71, 0x74, 0x78, 0x7b, 0x7e, 0x81, 0x85, 0x88, 0x8b, 0x8f, 0x92, 0x96, 0x99, 0x9d, 0xa0,
- 0xa4, 0xa8, 0xac, 0xaf, 0xb3, 0xb7, 0xbb, 0xbf, 0xc3, 0xc7, 0xcb, 0xcf, 0xd3, 0xd7, 0xdb, 0xe0 };
-
-static unsigned char env_r_frise[128] = {
- 0xcf, 0xcc, 0xc9, 0xc6, 0xc3, 0xc0, 0xbd, 0xb9, 0xb4, 0xb0, 0xab, 0xa7, 0xa2, 0x9c, 0x97, 0x92,
- 0x8c, 0x86, 0x81, 0x7b, 0x75, 0x6f, 0x69, 0x63, 0x5d, 0x57, 0x50, 0x4a, 0x44, 0x3e, 0x38, 0x33,
- 0x2d, 0x27, 0x22, 0x1c, 0x17, 0x12, 0x0d, 0x08, 0x04, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x08, 0x0a, 0x0c, 0x0d, 0x0f, 0x12, 0x14, 0x16,
- 0x19, 0x1b, 0x1e, 0x21, 0x24, 0x27, 0x2a, 0x2d, 0x30, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3f, 0x41,
- 0x43, 0x46, 0x48, 0x4b, 0x4d, 0x50, 0x52, 0x55, 0x58, 0x5a, 0x5d, 0x60, 0x63, 0x66, 0x69, 0x6c,
- 0x6f, 0x72, 0x75, 0x78, 0x7b, 0x7e, 0x81, 0x85, 0x88, 0x8b, 0x8f, 0x92, 0x96, 0x99, 0x9d, 0xa0,
- 0xa4, 0xa8, 0xac, 0xaf, 0xb3, 0xb7, 0xbb, 0xbf, 0xc3, 0xc7, 0xcb, 0xcf, 0xd3, 0xd7, 0xdb, 0xe0 };
-
-static unsigned char env_frise2[128] = {
- 0xff, 0xf9, 0xf4, 0xee, 0xe9, 0xe4, 0xdf, 0xda, 0xd5, 0xd0, 0xcb, 0xc6, 0xc1, 0xbd, 0xb8, 0xb3,
- 0xaf, 0xaa, 0xa6, 0xa1, 0x9d, 0x99, 0x95, 0x90, 0x8c, 0x88, 0x84, 0x80, 0x7d, 0x79, 0x75, 0x71,
- 0x6e, 0x6a, 0x67, 0x63, 0x60, 0x5d, 0x59, 0x56, 0x53, 0x50, 0x4d, 0x4a, 0x47, 0x44, 0x41, 0x3e,
- 0x3c, 0x39, 0x37, 0x34, 0x32, 0x2f, 0x2d, 0x2b, 0x28, 0x26, 0x24, 0x22, 0x20, 0x1e, 0x1c, 0x1a,
- 0x19, 0x17, 0x15, 0x14, 0x12, 0x11, 0x0f, 0x0e, 0x0d, 0x0c, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05,
- 0x05, 0x04, 0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x04, 0x04, 0x05, 0x06, 0x07, 0x08,
- 0x09, 0x0a, 0x0b, 0x0c, 0x0e, 0x0f, 0x10, 0x12, 0x13, 0x15, 0x17, 0x18, 0x1a, 0x1c, 0x1e, 0x20 };
-
-static unsigned char env_r_frise2[128] = {
- 0xd0, 0xce, 0xcd, 0xcc, 0xca, 0xc8, 0xc7, 0xc5, 0xc3, 0xc1, 0xc0, 0xbd, 0xbb, 0xb8, 0xb5, 0xb3,
- 0xb0, 0xad, 0xaa, 0xa7, 0xa3, 0xa0, 0x9d, 0x99, 0x96, 0x92, 0x8f, 0x8b, 0x87, 0x84, 0x80, 0x7c,
- 0x78, 0x74, 0x70, 0x6d, 0x69, 0x65, 0x61, 0x5d, 0x59, 0x55, 0x51, 0x4d, 0x4a, 0x46, 0x42, 0x3e,
- 0x3b, 0x37, 0x34, 0x31, 0x2f, 0x2d, 0x2a, 0x28, 0x26, 0x24, 0x22, 0x20, 0x1e, 0x1c, 0x1a, 0x19,
- 0x17, 0x15, 0x14, 0x12, 0x11, 0x0f, 0x0e, 0x0d, 0x0c, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x05,
- 0x04, 0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x04, 0x04, 0x05, 0x06, 0x07, 0x08,
- 0x09, 0x0a, 0x0b, 0x0c, 0x0e, 0x0f, 0x10, 0x12, 0x13, 0x15, 0x17, 0x18, 0x1a, 0x1c, 0x1e, 0x20 };
-
-static unsigned char env_risefall[128] = {
- 0x98, 0x99, 0x99, 0x9a, 0x9c, 0x9d, 0x9f, 0xa1, 0xa4, 0xa7, 0xa9, 0xac, 0xb0, 0xb3, 0xb6, 0xba,
- 0xbe, 0xc1, 0xc5, 0xc9, 0xcd, 0xd1, 0xd4, 0xd8, 0xdc, 0xdf, 0xe3, 0xe6, 0xea, 0xed, 0xf0, 0xf2,
- 0xf5, 0xf7, 0xf9, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfd,
- 0xfb, 0xfa, 0xf8, 0xf6, 0xf3, 0xf1, 0xee, 0xec, 0xe9, 0xe6, 0xe4, 0xe0, 0xdd, 0xda, 0xd7, 0xd3,
- 0xd0, 0xcc, 0xc8, 0xc4, 0xc0, 0xbc, 0xb8, 0xb4, 0xb0, 0xac, 0xa7, 0xa3, 0x9f, 0x9a, 0x96, 0x91,
- 0x8d, 0x88, 0x84, 0x7f, 0x7b, 0x76, 0x72, 0x6d, 0x69, 0x65, 0x60, 0x5c, 0x58, 0x54, 0x50, 0x4c,
- 0x48, 0x44, 0x40, 0x3c, 0x39, 0x35, 0x32, 0x2f, 0x2b, 0x28, 0x26, 0x23, 0x20, 0x1d, 0x1a, 0x17,
- 0x15, 0x12, 0x0f, 0x0d, 0x0a, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
-static unsigned char env_rise2[128] = {
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x06, 0x06,
- 0x07, 0x08, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
- 0x16, 0x17, 0x18, 0x19, 0x1b, 0x1c, 0x1d, 0x1f, 0x20, 0x22, 0x23, 0x25, 0x26, 0x28, 0x29, 0x2b,
- 0x2d, 0x2f, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x40, 0x42, 0x44, 0x47, 0x49, 0x4b,
- 0x4e, 0x50, 0x52, 0x55, 0x57, 0x5a, 0x5d, 0x5f, 0x62, 0x65, 0x67, 0x6a, 0x6d, 0x70, 0x73, 0x76,
- 0x79, 0x7c, 0x7f, 0x82, 0x86, 0x89, 0x8c, 0x90, 0x93, 0x96, 0x9a, 0x9d, 0xa0, 0xa3, 0xa6, 0xa9,
- 0xac, 0xaf, 0xb2, 0xb5, 0xb8, 0xbb, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd, 0xd0, 0xd3, 0xd6, 0xd9,
- 0xdc, 0xdf, 0xe2, 0xe4, 0xe7, 0xe9, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfb, 0xfd };
-
-static unsigned char env_fall2[128] = {
- 0xfe, 0xfe, 0xfd, 0xfd, 0xfc, 0xfb, 0xfb, 0xfa, 0xfa, 0xf9, 0xf8, 0xf8, 0xf7, 0xf7, 0xf6, 0xf6,
- 0xf5, 0xf4, 0xf4, 0xf3, 0xf3, 0xf2, 0xf2, 0xf1, 0xf0, 0xf0, 0xef, 0xee, 0xee, 0xed, 0xec, 0xeb,
- 0xea, 0xea, 0xe9, 0xe8, 0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0, 0xde, 0xdd, 0xdc, 0xdb,
- 0xd9, 0xd8, 0xd6, 0xd5, 0xd3, 0xd2, 0xd0, 0xce, 0xcc, 0xcb, 0xc9, 0xc7, 0xc5, 0xc3, 0xc0, 0xbe,
- 0xbc, 0xb9, 0xb7, 0xb5, 0xb2, 0xaf, 0xad, 0xaa, 0xa7, 0xa4, 0xa1, 0x9e, 0x9a, 0x97, 0x94, 0x90,
- 0x8d, 0x89, 0x85, 0x81, 0x7d, 0x79, 0x75, 0x71, 0x6d, 0x68, 0x64, 0x61, 0x5e, 0x5b, 0x57, 0x54,
- 0x51, 0x4d, 0x4a, 0x46, 0x43, 0x40, 0x3c, 0x39, 0x35, 0x32, 0x2e, 0x2a, 0x27, 0x23, 0x1f, 0x1c,
- 0x18, 0x14, 0x11, 0x0d, 0x0b, 0x09, 0x07, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00 };
-
-static unsigned char env_fallrise3[128] = {
- 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfd, 0xfc, 0xfa, 0xf8, 0xf6, 0xf4, 0xf1, 0xee, 0xeb,
- 0xe8, 0xe5, 0xe1, 0xde, 0xda, 0xd6, 0xd2, 0xcd, 0xc9, 0xc4, 0xbf, 0xba, 0xb6, 0xb0, 0xab, 0xa6,
- 0xa1, 0x9c, 0x96, 0x91, 0x8b, 0x86, 0x80, 0x7b, 0x75, 0x6f, 0x6a, 0x64, 0x5f, 0x59, 0x54, 0x4f,
- 0x49, 0x44, 0x3f, 0x3a, 0x35, 0x30, 0x2b, 0x26, 0x22, 0x1d, 0x19, 0x15, 0x11, 0x0d, 0x0a, 0x07,
- 0x04, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x04, 0x05,
- 0x07, 0x09, 0x0b, 0x0d, 0x10, 0x12, 0x15, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x29, 0x2d, 0x31, 0x35,
- 0x3a, 0x3e, 0x43, 0x48, 0x4c, 0x51, 0x57, 0x5b, 0x5e, 0x62, 0x65, 0x68, 0x6b, 0x6e, 0x71, 0x74,
- 0x76, 0x78, 0x7b, 0x7c, 0x7e, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x84, 0x83, 0x83, 0x82, 0x81 };
-
-static unsigned char env_fallrise4[128] = {
- 0x72, 0x72, 0x71, 0x71, 0x70, 0x6f, 0x6d, 0x6c, 0x6a, 0x68, 0x66, 0x64, 0x61, 0x5f, 0x5c, 0x5a,
- 0x57, 0x54, 0x51, 0x4e, 0x4b, 0x48, 0x45, 0x42, 0x3f, 0x3b, 0x38, 0x35, 0x32, 0x2f, 0x2c, 0x29,
- 0x26, 0x23, 0x20, 0x1d, 0x1b, 0x18, 0x16, 0x14, 0x12, 0x10, 0x0e, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06,
- 0x07, 0x07, 0x08, 0x09, 0x0a, 0x0c, 0x0d, 0x0f, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1b, 0x1d, 0x20,
- 0x23, 0x26, 0x29, 0x2c, 0x2f, 0x33, 0x37, 0x3b, 0x3f, 0x43, 0x47, 0x4c, 0x51, 0x56, 0x5b, 0x60,
- 0x65, 0x6a, 0x6f, 0x74, 0x79, 0x7f, 0x84, 0x89, 0x8f, 0x95, 0x9b, 0xa1, 0xa7, 0xad, 0xb3, 0xba,
- 0xc0, 0xc7, 0xce, 0xd5, 0xdc, 0xe3, 0xea, 0xf1, 0xf5, 0xf7, 0xfa, 0xfc, 0xfd, 0xfe, 0xff, 0xff };
-
-static unsigned char env_risefallrise[128] = {
- 0x7f, 0x7f, 0x7f, 0x80, 0x81, 0x83, 0x84, 0x87, 0x89, 0x8c, 0x8f, 0x92, 0x96, 0x99, 0x9d, 0xa1,
- 0xa5, 0xaa, 0xae, 0xb2, 0xb7, 0xbb, 0xc0, 0xc5, 0xc9, 0xcd, 0xd2, 0xd6, 0xda, 0xde, 0xe2, 0xe6,
- 0xea, 0xed, 0xf0, 0xf3, 0xf5, 0xf8, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xfd, 0xfc, 0xfb, 0xf9,
- 0xf7, 0xf4, 0xf0, 0xec, 0xe7, 0xe2, 0xdc, 0xd5, 0xce, 0xc6, 0xbd, 0xb4, 0xa9, 0x9e, 0x92, 0x88,
- 0x82, 0x7d, 0x77, 0x72, 0x6c, 0x66, 0x60, 0x5a, 0x54, 0x4e, 0x49, 0x42, 0x3c, 0x37, 0x32, 0x2d,
- 0x28, 0x24, 0x1f, 0x1b, 0x18, 0x14, 0x11, 0x0e, 0x0c, 0x09, 0x07, 0x06, 0x05, 0x04, 0x04, 0x04,
- 0x04, 0x05, 0x06, 0x08, 0x0a, 0x0d, 0x10, 0x14, 0x18, 0x1d, 0x23, 0x29, 0x2f, 0x37, 0x3e, 0x47,
- 0x50, 0x5a, 0x64, 0x70, 0x7c, 0x83, 0x85, 0x88, 0x8a, 0x8c, 0x8e, 0x8f, 0x91, 0x92, 0x93, 0x93 };
-
-
-
-
-unsigned char *envelope_data[18] = {
- env_fall,
- env_rise,
- env_frise, env_r_frise,
- env_frise2, env_r_frise2,
- env_risefall, env_risefall,
-
- env_fallrise3, env_fallrise3,
- env_fallrise4, env_fallrise4,
- env_fall2, env_fall2,
- env_rise2, env_rise2,
- env_risefallrise, env_risefallrise
- };
-
-
-/* all pitches given in Hz above pitch_base */
-
-// pitch change during the main part of the clause
-static int drops_0[8] = {0x400,0x400,0x700,0x700,0x700,0xa00,0x1800,0x0e00};
-//static int drops_1[8] = {0x400,0x400,0x600,0x600,0xc00,0xc00,0x0e00,0x0e00};
-//static int drops_2[8] = {0x400,0x400,0x600,0x600,-0x800,0xc00,0x0e00,0x0e00};
-
-static short oflow[] = {0, 20, 12, 4, 0};
-static short oflow_emf[] = {5, 24, 15, 10, 5};
-static short oflow_less[] = {3, 19, 12, 7, 2};
-// static short oflow_test2[] = {20, 0, 20, 0, 20};
-// static short back_emf[] = {35, 32, 0};
-
-
-#define N_TONE_HEAD_TABLE 13
-#define N_TONE_NUCLEUS_TABLE 13
-
-
-typedef struct {
- unsigned char pre_start;
- unsigned char pre_end;
-
- unsigned char body_start;
- unsigned char body_end;
-
- int *body_drops;
- unsigned char body_max_steps;
- char body_lower_u;
-
- char n_overflow;
- short *overflow;
-} TONE_HEAD;
-
-
-typedef struct {
- unsigned char pitch_env0; /* pitch envelope, tonic syllable at end */
- unsigned char tonic_max0;
- unsigned char tonic_min0;
-
- unsigned char pitch_env1; /* followed by unstressed */
- unsigned char tonic_max1;
- unsigned char tonic_min1;
-
- short *backwards;
-
- unsigned char tail_start;
- unsigned char tail_end;
- unsigned char flags;
-} TONE_NUCLEUS;
-
-#define T_EMPH 1
-
-static TONE_HEAD tone_head_table[N_TONE_HEAD_TABLE] = {
- {20, 25, 34, 22, drops_0, 3, 3, 5, oflow}, // 0 statement
- {20, 25, 34, 20, drops_0, 3, 3, 5, oflow}, // 1 comma
- {20, 25, 34, 20, drops_0, 3, 3, 5, oflow}, // 2 question
- {20, 25, 36, 22, drops_0, 3, 4, 5, oflow_emf}, // 3 exclamation
- {20, 25, 34, 22, drops_0, 3, 3, 5, oflow}, // 4 statement, emphatic
- {20, 25, 32, 24, drops_0, 4, 3, 5, oflow_less}, // 5 statement, less intonation
- {20, 25, 32, 24, drops_0, 4, 3, 5, oflow_less}, // 6 comma, less intonation
- {20, 25, 32, 24, drops_0, 4, 3, 5, oflow_less}, // 7 comma, less intonation, less rise
- {20, 25, 34, 22, drops_0, 3, 3, 5, oflow}, // 8 pitch raises at end of sentence
- {20, 25, 34, 20, drops_0, 3, 3, 5, oflow}, // 9 comma
- {20, 25, 34, 22, drops_0, 3, 3, 5, oflow}, // 10 question
- {15, 18, 18, 14, drops_0, 3, 3, 5, oflow_less}, // 11 test
- {20, 25, 24, 22, drops_0, 3, 3, 5, oflow_less}, // 12 test
-};
-
-static TONE_NUCLEUS tone_nucleus_table[N_TONE_NUCLEUS_TABLE] = {
- {PITCHfall, 30, 5, PITCHfall, 32, 9, NULL, 12, 7, 0}, // 0 statement
- {PITCHfrise, 35, 8, PITCHfrise2, 35,10, NULL, 15, 23, 0}, // 1 comma
- {PITCHfrise, 39,10, PITCHfrise2, 36,10, NULL, 15, 28, 0}, // 2 question
-// {PITCHfall, 41, 4, PITCHfall, 41,27, NULL, 16, 4, T_EMPH}, // 3 exclamation
- {PITCHfall, 41, 4, PITCHfall, 41,35, NULL, 35, 4, T_EMPH}, // 3 exclamation
- {PITCHfall, 38, 2, PITCHfall, 42,30, NULL, 15, 5, 0}, // 4 statement, emphatic
- {PITCHfall, 28, 5, PITCHfall, 28, 9, NULL, 12, 7, 0}, // 5 statement, less intonation
- {PITCHfrise, 30, 8, PITCHfrise2, 30,10, NULL, 13, 20, 0}, // 6 comma, less intonation
- {PITCHfrise2, 28, 7, PITCHfall, 29,14, NULL, 14, 8, 0}, // 7 comma, less intonation, less rise
- {PITCHrise, 30,20, PITCHfall, 19,14, NULL, 20, 26, 0}, // 8 pitch raises at end of sentence
- {PITCHfrise, 35,11, PITCHfrise2, 32,10, NULL, 19, 24, 0}, // 9 comma
- {PITCHfrise, 39,15, PITCHfall, 28,14, NULL, 20, 36, 0}, // 10 question
- {PITCHfall, 28, 6, PITCHfall, 28,10, NULL, 12, 6, 0}, // 11 test
- {PITCHfall, 35, 9, PITCHfall, 35,12, NULL, 16, 10, 0}, // 12 test
-};
-
-
-
-/* index by 0=. 1=, 2=?, 3=! 4=none, 5=emphasized */
-unsigned char punctuation_to_tone[INTONATION_TYPES][PUNCT_INTONATIONS] = {
- {0,1,2,3,0,4},
- {0,1,2,3,0,4},
- {5,6,2,3,0,4},
- {5,7,1,3,0,4},
- {8,9,10,3,0,0},
- {8,8,10,3,0,0},
- {11,11,11,11,0,0}, // 6 test
- {12,12,12,12,0,0}
-};
-
-
-
-/* indexed by stress */
-static int min_drop[] = {0x300,0x300,0x400,0x400,0x900,0x900,0x900,0xb00};
-
-
-
-
-#define SECONDARY 3
-#define PRIMARY 4
-#define PRIMARY_STRESSED 6
-#define PRIMARY_LAST 7
-
-
-static int number_pre;
-static int number_body;
-static int number_tail;
-static int last_primary;
-static int tone_posn;
-static int tone_posn2;
-static int no_tonic;
-
-
-static void count_pitch_vowels(int start, int end, int clause_end)
-/****************************************************************/
-{
- int ix;
- int stress;
- int max_stress = 0;
- int max_stress_posn = 0; // last syllable ot the highest stress
- int max_stress_posn2 = 0; // penuntimate syllable of the highest stress
-
- number_pre = -1; /* number of vowels before 1st primary stress */
- number_body = 0;
- number_tail = 0; /* number between tonic syllable and next primary */
- last_primary = -1;
-
- for(ix=start; ix<end; ix++)
- {
- stress = syllable_tab[ix].stress; /* marked stress level */
-
- if(stress >= max_stress)
- {
- if(stress > max_stress)
- {
- max_stress_posn2 = ix;
- }
- else
- {
- max_stress_posn2 = max_stress_posn;
- }
- max_stress_posn = ix;
- max_stress = stress;
- }
- if(stress >= PRIMARY)
- {
- if(number_pre < 0)
- number_pre = ix - start;
-
- last_primary = ix;
- }
-
- }
-
- if(number_pre < 0)
- number_pre = end;
-
- number_tail = end - max_stress_posn - 1;
- tone_posn = max_stress_posn;
- tone_posn2 = max_stress_posn2;
-
- if(no_tonic)
- {
- tone_posn = tone_posn2 = end; // next position after the end of the truncated clause
- }
- else
- if(last_primary >= 0)
- {
- if(end == clause_end)
- {
- syllable_tab[last_primary].stress = PRIMARY_LAST;
- }
- }
- else
- {
- // no primary stress. Use the highest stress
- syllable_tab[tone_posn].stress = PRIMARY_LAST;
- }
-} /* end of count_pitch_vowels */
-
-
-
-
-static int count_increments(int ix, int end_ix, int min_stress)
-/*************************************************************/
-/* Count number of primary stresses up to tonic syllable or body_reset */
-{
- int count = 0;
- int stress;
-
- while(ix < end_ix)
- {
- stress = syllable_tab[ix++].stress;
- if(stress >= PRIMARY_LAST)
- break;
-
- if(stress >= min_stress)
- count++;
- }
- return(count);
-} /* end of count_increments */
-
-
-
-static void set_pitch(SYLLABLE *syl, int base, int drop)
-/******************************************************/
-// Set the pitch of a vowel in syllable_tab. Base & drop are Hz * 256
-{
- int pitch1, pitch2;
- int flags = 0;
-
- /* adjust experimentally */
- int pitch_range2 = 148;
- int pitch_base2 = 72;
-
- if(base < 0) base = 0;
-
- pitch2 = ((base * pitch_range2 ) >> 15) + pitch_base2;
-
- if(drop < 0)
- {
- flags = SYL_RISE;
- drop = -drop;
- }
-
- pitch1 = pitch2 + ((drop * pitch_range2) >> 15);
-
- if(pitch1 > 511) pitch1 = 511;
- if(pitch2 > 511) pitch2 = 511;
-
- syl->pitch1 = pitch1;
- syl->pitch2 = pitch2;
- syl->flags |= flags;
-} /* end of set_pitch */
-
-
-
-static int calc_pitch_segment(int ix, int end_ix, TONE_HEAD *th, TONE_NUCLEUS *tn, int min_stress, int continuing)
-/**********************************************************************************************/
-/* Calculate pitches until next RESET or tonic syllable, or end.
- Increment pitch if stress is >= min_stress.
- Used for tonic segment */
-{
- int stress;
- int pitch=0;
- int increment=0;
- int n_primary=0;
- int n_steps=0;
- int initial;
- int overflow=0;
- int n_overflow;
- int *drops;
- short *overflow_tab;
- SYLLABLE *syl;
-
- static short continue_tab[5] = {-13, 16, 10, 4, 0};
-
- drops = th->body_drops;
-
- if(continuing)
- {
- initial =0;
- overflow = 0;
- n_overflow = 5;
- overflow_tab = continue_tab;
- increment = (th->body_end - th->body_start) << 8;
- increment = increment / (th->body_max_steps -1);
- }
- else
- {
- n_overflow = th->n_overflow;
- overflow_tab = th->overflow;
- initial = 1;
- }
-
- while(ix < end_ix)
- {
- syl = &syllable_tab[ix];
- stress = syl->stress;
-
-// if(stress == PRIMARY_MARKED)
-// initial = 1; // reset the intonation pattern
-
- if(initial || (stress >= min_stress))
- {
- // a primary stress
-
- if((initial) || (stress == 5))
- {
- initial = 0;
- overflow = 0;
- n_steps = n_primary = count_increments(ix,end_ix,min_stress);
-
- if(n_steps > th->body_max_steps)
- n_steps = th->body_max_steps;
-
- if(n_steps > 1)
- {
- increment = (th->body_end - th->body_start) << 8;
- increment = increment / (n_steps -1);
- }
- else
- increment = 0;
-
- pitch = th->body_start << 8;
- }
- else
- {
- if(n_steps > 0)
- pitch += increment;
- else
- {
- pitch = (th->body_end << 8) - (increment * overflow_tab[overflow++])/16;
- if(overflow >= n_overflow)
- {
- overflow = 0;
- overflow_tab = th->overflow;
- }
- }
- }
-
- n_steps--;
-
- n_primary--;
- if((tn->backwards) && (n_primary < 2))
- {
- pitch = tn->backwards[n_primary] << 8;
- }
- }
-
- if(stress >= PRIMARY)
- {
- syl->stress = PRIMARY_STRESSED;
- set_pitch(syl,pitch,drops[stress]);
- }
- else
- if(stress >= SECONDARY)
- {
- set_pitch(syl,pitch,drops[stress]);
- }
- else
- {
- /* unstressed, drop pitch if preceded by PRIMARY */
- if((syllable_tab[ix-1].stress & 0x3f) >= SECONDARY)
- set_pitch(syl,pitch - (th->body_lower_u << 8), drops[stress]);
- else
- set_pitch(syl,pitch,drops[stress]);
- }
-
- ix++;
- }
- return(ix);
-} /* end of calc_pitch_segment */
-
-
-
-
-
-static int calc_pitch_segment2(int ix, int end_ix, int start_p, int end_p, int min_stress)
-/****************************************************************************************/
-/* Linear pitch rise/fall, change pitch at min_stress or stronger
- Used for pre-head and tail */
-{
- int stress;
- int pitch;
- int increment;
- int n_increments;
- int drop;
- SYLLABLE *syl;
-
- if(ix >= end_ix)
- return(ix);
-
- n_increments = count_increments(ix,end_ix,min_stress);
- increment = (end_p - start_p) << 8;
-
- if(n_increments > 1)
- {
- increment = increment / n_increments;
- }
-
-
- pitch = start_p << 8;
- while(ix < end_ix)
- {
- syl = &syllable_tab[ix];
- stress = syl->stress;
-
- if(increment > 0)
- {
- set_pitch(syl,pitch,-increment);
- pitch += increment;
- }
- else
- {
- drop = -increment;
- if(drop < min_drop[stress])
- drop = min_drop[stress];
-
- pitch += increment;
-
- if(drop > 0x900)
- drop = 0x900;
- set_pitch(syl, pitch, drop);
- }
-
- ix++;
- }
- return(ix);
-} /* end of calc_pitch_segment2 */
-
-
-
-
-
-
-static int calc_pitches(int start, int end, int head_tone, int nucleus_tone)
-//===========================================================================
-// Calculate pitch values for the vowels in this tone group
-{
- int ix;
- TONE_HEAD *th;
- TONE_NUCLEUS *tn;
- int drop;
- int continuing = 0;
-
- if(start > 0)
- continuing = 1;
-
- th = &tone_head_table[head_tone];
- tn = &tone_nucleus_table[nucleus_tone];
- ix = start;
-
- /* vowels before the first primary stress */
- /******************************************/
-
- if(number_pre > 0)
- {
- ix = calc_pitch_segment2(ix, ix+number_pre, th->pre_start, th->pre_end, 0);
- }
-
- /* body of tonic segment */
- /*************************/
-
- if(option_tone_flags & OPTION_EMPHASIZE_PENULTIMATE)
- {
- tone_posn = tone_posn2; // put tone on the penultimate stressed word
- }
- ix = calc_pitch_segment(ix,tone_posn, th, tn, PRIMARY, continuing);
-
- if(no_tonic)
- return(0);
-
- /* tonic syllable */
- /******************/
-
- if(tn->flags & T_EMPH)
- {
- syllable_tab[ix].flags |= SYL_EMPHASIS;
- }
-
- if(number_tail == 0)
- {
- tone_pitch_env = tn->pitch_env0;
- drop = tn->tonic_max0 - tn->tonic_min0;
- set_pitch(&syllable_tab[ix++],tn->tonic_min0 << 8,drop << 8);
- }
- else
- {
- tone_pitch_env = tn->pitch_env1;
- drop = tn->tonic_max1 - tn->tonic_min1;
- set_pitch(&syllable_tab[ix++],tn->tonic_min1 << 8,drop << 8);
- }
-
- syllable_tab[tone_posn].env = tone_pitch_env;
- if(syllable_tab[tone_posn].stress == PRIMARY)
- syllable_tab[tone_posn].stress = PRIMARY_STRESSED;
-
- /* tail, after the tonic syllable */
- /**********************************/
-
- calc_pitch_segment2(ix, end, tn->tail_start, tn->tail_end, 0);
-
- return(tone_pitch_env);
-} /* end of calc_pitches */
-
-
-
-
-
-
-static void CalcPitches_Tone(Translator *tr, int clause_tone)
-{//==========================================================
-// clause_tone: 0=. 1=, 2=?, 3=! 4=none
- PHONEME_LIST *p;
- int ix;
- int count_stressed=0;
- int final_stressed=0;
-
- int tone_ph;
- int pause;
- int tone_promoted;
- PHONEME_TAB *tph;
- PHONEME_TAB *prev_tph; // forget across word boundary
- PHONEME_TAB *prevw_tph; // remember across word boundary
- PHONEME_TAB *prev2_tph; // 2 tones previous
- PHONEME_LIST *prev_p;
-
- int pitch_adjust = 0; // pitch gradient through the clause - inital value
- int pitch_decrement = 0; // decrease by this for each stressed syllable
- int pitch_low = 0; // until it drops to this
- int pitch_high = 0; // then reset to this
-
- p = &phoneme_list[0];
-
- // count number of stressed syllables
- p = &phoneme_list[0];
- for(ix=0; ix<n_phoneme_list; ix++, p++)
- {
- if((p->type == phVOWEL) && (p->stresslevel >= 4))
- {
- if(count_stressed == 0)
- final_stressed = ix;
-
- if(p->stresslevel >= 4)
- {
- final_stressed = ix;
- count_stressed++;
- }
- }
- }
-
- phoneme_list[final_stressed].stresslevel = 7;
-
- // language specific, changes to tones
- if(tr->translator_name == L('v','i'))
- {
- // LANG=vi
- p = &phoneme_list[final_stressed];
- if(p->tone_ph == 0)
- p->tone_ph = PhonemeCode('7'); // change default tone (tone 1) to falling tone at end of clause
- }
-
-
- pause = 1;
- tone_promoted = 0;
-
- prev_p = p = &phoneme_list[0];
- prev_tph = prevw_tph = phoneme_tab[phonPAUSE];
-
- // perform tone sandhi
- for(ix=0; ix<n_phoneme_list; ix++, p++)
- {
- if((p->type == phPAUSE) && (p->ph->std_length > 50))
- {
- pause = 1; // there is a pause since the previous vowel
- prevw_tph = phoneme_tab[phonPAUSE]; // forget previous tone
- }
-
- if(p->newword)
- {
- prev_tph = phoneme_tab[phonPAUSE]; // forget across word boundaries
- }
-
- if(p->synthflags & SFLAG_SYLLABLE)
- {
- tone_ph = p->tone_ph;
- tph = phoneme_tab[tone_ph];
-
- // Mandarin
- if(tr->translator_name == L('z','h'))
- {
- if(tone_ph == 0)
- {
- if(pause || tone_promoted)
- {
- tone_ph = PhonemeCode2('5','5'); // no previous vowel, use tone 1
- tone_promoted = 1;
- }
- else
- {
- tone_ph = PhonemeCode2('1','1'); // default tone 5
- }
-
- p->tone_ph = tone_ph;
- tph = phoneme_tab[tone_ph];
-
- }
- else
- {
- tone_promoted = 0;
- }
-
- if(ix == final_stressed)
- {
- if((tph->mnemonic == 0x3535 ) || (tph->mnemonic == 0x3135))
- {
- // change sentence final tone 1 or 4 to stress 6, not 7
- phoneme_list[final_stressed].stresslevel = 6;
- }
- }
-
- if(prevw_tph->mnemonic == 0x343132) // [214]
- {
- if(tph->mnemonic == 0x343132) // [214]
- prev_p->tone_ph = PhonemeCode2('3','5');
- else
- prev_p->tone_ph = PhonemeCode2('2','1');
- }
- if((prev_tph->mnemonic == 0x3135) && (tph->mnemonic == 0x3135)) // [51] + [51]
- {
- prev_p->tone_ph = PhonemeCode2('5','3');
- }
-
- if(tph->mnemonic == 0x3131) // [11] Tone 5
- {
- // tone 5, change its level depending on the previous tone (across word boundaries)
- if(prevw_tph->mnemonic == 0x3535)
- p->tone_ph = PhonemeCode2('2','2');
- if(prevw_tph->mnemonic == 0x3533)
- p->tone_ph = PhonemeCode2('3','3');
- if(prevw_tph->mnemonic == 0x343132)
- p->tone_ph = PhonemeCode2('4','4');
-
- // tone 5 is unstressed (shorter)
- p->stresslevel = 1; // diminished stress
- }
- }
-
- prev_p = p;
- prev2_tph = prevw_tph;
- prevw_tph = prev_tph = tph;
- pause = 0;
- }
- }
-
- // convert tone numbers to pitch
- p = &phoneme_list[0];
- for(ix=0; ix<n_phoneme_list; ix++, p++)
- {
- if(p->synthflags & SFLAG_SYLLABLE)
- {
- tone_ph = p->tone_ph;
-
- if(p->stresslevel != 1) // TEST, consider all syllables as stressed
- {
- if(ix == final_stressed)
- {
- // the last stressed syllable
- pitch_adjust = pitch_low;
- }
- else
- {
- pitch_adjust -= pitch_decrement;
- if(pitch_adjust <= pitch_low)
- pitch_adjust = pitch_high;
- }
- }
-
- if(tone_ph ==0)
- {
- tone_ph = phonDEFAULTTONE; // no tone specified, use default tone 1
- p->tone_ph = tone_ph;
- }
- p->pitch1 = pitch_adjust + phoneme_tab[tone_ph]->start_type;
- p->pitch2 = pitch_adjust + phoneme_tab[tone_ph]->end_type;
- }
- }
-
-
-} // end of Translator::CalcPitches_Tone
-
-
-
-void CalcPitches(Translator *tr, int clause_type)
-{//==============================================
-// clause_type: 0=. 1=, 2=?, 3=! 4=none
- PHONEME_LIST *p;
- SYLLABLE *syl;
- int ix;
- int x;
- int st_ix;
- int n_st;
- int option;
- int group_tone;
- int group_tone_emph;
- int group_tone_comma;
- int ph_start=0;
- int st_start;
- int st_clause_end;
- int count;
- int n_primary;
- int count_primary;
- PHONEME_TAB *ph;
- int ph_end=n_phoneme_list;
-
- SYLLABLE syllable_tab2[N_PHONEME_LIST];
-
- syllable_tab = syllable_tab2; // don't use permanent storage. it's only needed during the call of CalcPitches()
- n_st = 0;
- n_primary = 0;
- for(ix=0; ix<(n_phoneme_list-1); ix++)
- {
- p = &phoneme_list[ix];
- if(p->synthflags & SFLAG_SYLLABLE)
- {
- syllable_tab[n_st].flags = 0;
- syllable_tab[n_st].env = PITCHfall;
- syllable_tab[n_st].nextph_type = phoneme_list[ix+1].type;
- syllable_tab[n_st++].stress = p->stresslevel;
-
- if(p->stresslevel >= 4)
- n_primary++;
- }
- else
- if((p->ph->code == phonPAUSE_CLAUSE) && (n_st > 0))
- {
- syllable_tab[n_st-1].flags |= SYL_END_CLAUSE;
- }
- }
- syllable_tab[n_st].stress = 0; // extra 0 entry at the end
-
- if(n_st == 0)
- return; // nothing to do
-
-
-
- if(tr->langopts.tone_language == 1)
- {
- CalcPitches_Tone(tr,clause_type);
- return;
- }
-
-
- option = tr->langopts.intonation_group;
- if(option >= INTONATION_TYPES)
- option = 0;
-
- group_tone = tr->punct_to_tone[option][clause_type];
- group_tone_emph = tr->punct_to_tone[option][5]; // emphatic form of statement
- group_tone_comma = tr->punct_to_tone[option][1]; // emphatic form of statement
-
- if(clause_type == 4)
- no_tonic = 1; /* incomplete clause, used for abbreviations such as Mr. Dr. Mrs. */
- else
- no_tonic = 0;
-
- st_start = 0;
- count_primary=0;
- for(st_ix=0; st_ix<n_st; st_ix++)
- {
- syl = &syllable_tab[st_ix];
-
- if(syl->stress >= 4)
- count_primary++;
-
- if(syl->stress == 6)
- {
- // reduce the stress of the previous stressed syllable (review only the previous few syllables)
- for(ix=st_ix-1; ix>=st_start && ix>=(st_ix-3); ix--)
- {
- if(syllable_tab[ix].stress == 6)
- break;
- if(syllable_tab[ix].stress == 4)
- {
- syllable_tab[ix].stress = 3;
- break;
- }
- }
-
- // are the next primary syllables also emphasized ?
- for(ix=st_ix+1; ix<n_st; ix++)
- {
- if(syllable_tab[ix].stress == 4)
- break;
- if(syllable_tab[ix].stress == 6)
- {
- // emphasize this syllable, but don't end the current tone group
- syllable_tab[st_ix].flags = SYL_EMPHASIS;
- syl->stress = 5;
- break;
- }
- }
- }
-
- if(syl->stress == 6)
- {
- // an emphasized syllable, end the tone group after the next primary stress
- syllable_tab[st_ix].flags = SYL_EMPHASIS;
-
- count = 0;
- if((n_primary - count_primary) > 1)
- count =1;
-
- for(ix=st_ix+1; ix<n_st; ix++)
- {
- if(syllable_tab[ix].stress > 4)
- break;
- if(syllable_tab[ix].stress == 4)
- {
- count++;
- if(count > 1)
- break;
- }
- }
-
- count_pitch_vowels(st_start, ix, n_st);
- if((ix < n_st) || (clause_type == 0))
- calc_pitches(st_start, ix, group_tone_emph, group_tone_emph); // split into > 1 tone groups, use emphatic tone
- else
- calc_pitches(st_start, ix, group_tone, group_tone);
-
- st_start = ix;
- }
- if((st_start < st_ix) && (syl->flags & SYL_END_CLAUSE))
- {
- // end of clause after this syllable, indicated by a phonPAUSE_CLAUSE phoneme
- st_clause_end = st_ix+1;
- count_pitch_vowels(st_start, st_clause_end, st_clause_end);
- calc_pitches(st_start, st_clause_end, group_tone_comma, group_tone_comma);
- st_start = st_clause_end;
- }
- }
-
- if(st_start < st_ix)
- {
- count_pitch_vowels(st_start, st_ix, n_st);
- calc_pitches(st_start, st_ix, group_tone, group_tone);
- }
-
-
- // unpack pitch data
- st_ix=0;
- for(ix=ph_start; ix < ph_end; ix++)
- {
- p = &phoneme_list[ix];
- p->stresslevel = syllable_tab[st_ix].stress;
-
- if(p->synthflags & SFLAG_SYLLABLE)
- {
- syl = &syllable_tab[st_ix];
-
- x = syl->pitch1 - 72;
- if(x < 0) x = 0;
- p->pitch1 = x;
-
- x = syl->pitch2 - 72;
- if(x < 0) x = 0;
- p->pitch2 = x;
-
- p->env = PITCHfall;
- if(syl->flags & SYL_RISE)
- {
- p->env = PITCHrise;
- }
- else
- if(p->stresslevel > 5)
- p->env = syl->env;
-
- if(p->pitch1 > p->pitch2)
- {
- // swap so that pitch2 is the higher
- x = p->pitch1;
- p->pitch1 = p->pitch2;
- p->pitch2 = x;
- }
-
-if(p->tone_ph)
-{
- ph = phoneme_tab[p->tone_ph];
- x = (p->pitch1 + p->pitch2)/2;
- p->pitch2 = x + ph->end_type;
- p->pitch1 = x + ph->start_type;
-}
-
- if(syl->flags & SYL_EMPHASIS)
- {
- p->stresslevel |= 8; // emphasized
- }
-
- st_ix++;
- }
- }
-
-} // end of Translator::CalcPitches
-
-
diff --git a/navit/support/espeak/klatt.c b/navit/support/espeak/klatt.c
deleted file mode 100644
index 8cdbf782b..000000000
--- a/navit/support/espeak/klatt.c
+++ /dev/null
@@ -1,1303 +0,0 @@
-
-/***************************************************************************
- * Copyright (C) 2008 by Jonathan Duddington *
- * email: jonsd@users.sourceforge.net *
- * *
- * Based on a re-implementation by: *
- * (c) 1993,94 Jon Iles and Nick Ing-Simmons *
- * of the Klatt cascade-parallel formant synthesizer *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, see: *
- * <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-// See URL: ftp://svr-ftp.eng.cam.ac.uk/pub/comp.speech/synthesis/klatt.3.04.tar.gz
-
-#include "StdAfx.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-
-#include "speak_lib.h"
-#include "speech.h"
-#include "klatt.h"
-#include "phoneme.h"
-#include "synthesize.h"
-#include "voice.h"
-
-#ifdef INCLUDE_KLATT // conditional compilation for the whole file
-
-extern unsigned char *out_ptr; // **JSD
-extern unsigned char *out_start;
-extern unsigned char *out_end;
-extern WGEN_DATA wdata;
-static int nsamples;
-static int sample_count;
-
-
-#ifdef _MSC_VER
-#define getrandom(min,max) ((rand()%(int)(((max)+1)-(min)))+(min))
-#else
-#define getrandom(min,max) ((rand()%(long)(((max)+1)-(min)))+(min))
-#endif
-
-
-/* function prototypes for functions private to this file */
-
-static void flutter(klatt_frame_ptr);
-static double sampled_source (void);
-static double impulsive_source (void);
-static double natural_source (void);
-static void pitch_synch_par_reset (klatt_frame_ptr);
-static double gen_noise (double);
-static double DBtoLIN (long);
-static void frame_init (klatt_frame_ptr);
-static void setabc (long,long,resonator_ptr);
-static void setzeroabc (long,long,resonator_ptr);
-
-static klatt_frame_t kt_frame;
-static klatt_global_t kt_globals;
-
-/*
-function RESONATOR
-
-This is a generic resonator function. Internal memory for the resonator
-is stored in the globals structure.
-*/
-
-static double resonator(resonator_ptr r, double input)
-{
- double x;
-
- x = (double) ((double)r->a * (double)input + (double)r->b * (double)r->p1 + (double)r->c * (double)r->p2);
- r->p2 = (double)r->p1;
- r->p1 = (double)x;
-
- return (double)x;
-}
-
-static double resonator2(resonator_ptr r, double input)
-{
- double x;
-
- x = (double) ((double)r->a * (double)input + (double)r->b * (double)r->p1 + (double)r->c * (double)r->p2);
- r->p2 = (double)r->p1;
- r->p1 = (double)x;
-
- r->a += r->a_inc;
- r->b += r->b_inc;
- r->c += r->c_inc;
- return (double)x;
-}
-
-
-
-/*
-function ANTIRESONATOR
-
-This is a generic anti-resonator function. The code is the same as resonator
-except that a,b,c need to be set with setzeroabc() and we save inputs in
-p1/p2 rather than outputs. There is currently only one of these - "rnz"
-Output = (rnz.a * input) + (rnz.b * oldin1) + (rnz.c * oldin2)
-*/
-
-#ifdef deleted
-static double antiresonator(resonator_ptr r, double input)
-{
- register double x = (double)r->a * (double)input + (double)r->b * (double)r->p1 + (double)r->c * (double)r->p2;
- r->p2 = (double)r->p1;
- r->p1 = (double)input;
- return (double)x;
-}
-#endif
-
-static double antiresonator2(resonator_ptr r, double input)
-{
- register double x = (double)r->a * (double)input + (double)r->b * (double)r->p1 + (double)r->c * (double)r->p2;
- r->p2 = (double)r->p1;
- r->p1 = (double)input;
-
- r->a += r->a_inc;
- r->b += r->b_inc;
- r->c += r->c_inc;
- return (double)x;
-}
-
-
-
-/*
-function FLUTTER
-
-This function adds F0 flutter, as specified in:
-
-"Analysis, synthesis and perception of voice quality variations among
-female and male talkers" D.H. Klatt and L.C. Klatt JASA 87(2) February 1990.
-
-Flutter is added by applying a quasi-random element constructed from three
-slowly varying sine waves.
-*/
-
-static void flutter(klatt_frame_ptr frame)
-{
- static int time_count;
- double delta_f0;
- double fla,flb,flc,fld,fle;
-
- fla = (double) kt_globals.f0_flutter / 50;
- flb = (double) kt_globals.original_f0 / 100;
-// flc = sin(2*PI*12.7*time_count);
-// fld = sin(2*PI*7.1*time_count);
-// fle = sin(2*PI*4.7*time_count);
- flc = sin(PI*12.7*time_count); // because we are calling flutter() more frequently, every 2.9mS
- fld = sin(PI*7.1*time_count);
- fle = sin(PI*4.7*time_count);
- delta_f0 = fla * flb * (flc + fld + fle) * 10;
- frame->F0hz10 = frame->F0hz10 + (long) delta_f0;
- time_count++;
-}
-
-
-
-/*
-function SAMPLED_SOURCE
-
-Allows the use of a glottal excitation waveform sampled from a real
-voice.
-*/
-
-static double sampled_source()
-{
- int itemp;
- double ftemp;
- double result;
- double diff_value;
- int current_value;
- int next_value;
- double temp_diff;
-
- if(kt_globals.T0!=0)
- {
- ftemp = (double) kt_globals.nper;
- ftemp = ftemp / kt_globals.T0;
- ftemp = ftemp * kt_globals.num_samples;
- itemp = (int) ftemp;
-
- temp_diff = ftemp - (double) itemp;
-
- current_value = kt_globals.natural_samples[itemp];
- next_value = kt_globals.natural_samples[itemp+1];
-
- diff_value = (double) next_value - (double) current_value;
- diff_value = diff_value * temp_diff;
-
- result = kt_globals.natural_samples[itemp] + diff_value;
- result = result * kt_globals.sample_factor;
- }
- else
- {
- result = 0;
- }
- return(result);
-}
-
-
-
-
-/*
-function PARWAVE
-
-Converts synthesis parameters to a waveform.
-*/
-
-
-static int parwave(klatt_frame_ptr frame)
-{
- double temp;
- double outbypas;
- double out;
- long n4;
- double frics;
- double glotout;
- double aspiration;
- double casc_next_in;
- double par_glotout;
- static double noise;
- static double voice;
- static double vlast;
- static double glotlast;
- static double sourc;
- int ix;
-
- frame_init(frame); /* get parameters for next frame of speech */
-
- flutter(frame); /* add f0 flutter */
-
-#ifdef deleted
-{
- FILE *f;
- f=fopen("klatt_log","a");
- fprintf(f,"%4dhz %2dAV %4d %3d, %4d %3d, %4d %3d, %4d %3d, %4d, %3d, %4d %3d TLT=%2d\n",frame->F0hz10,frame->AVdb,
- frame->F1hz,frame->B1hz,frame->F2hz,frame->B2hz,frame->F3hz,frame->B3hz,frame->F4hz,frame->B4hz,frame->F5hz,frame->B5hz,frame->F6hz,frame->B6hz,frame->TLTdb);
- fclose(f);
-}
-#endif
-
- /* MAIN LOOP, for each output sample of current frame: */
-
- for (kt_globals.ns=0; kt_globals.ns<kt_globals.nspfr; kt_globals.ns++)
- {
- /* Get low-passed random number for aspiration and frication noise */
- noise = gen_noise(noise);
-
- /*
- Amplitude modulate noise (reduce noise amplitude during
- second half of glottal period) if voicing simultaneously present.
- */
-
- if (kt_globals.nper > kt_globals.nmod)
- {
- noise *= (double) 0.5;
- }
-
- /* Compute frication noise */
- frics = kt_globals.amp_frica * noise;
-
- /*
- Compute voicing waveform. Run glottal source simulation at 4
- times normal sample rate to minimize quantization noise in
- period of female voice.
- */
-
- for (n4=0; n4<4; n4++)
- {
- switch(kt_globals.glsource)
- {
- case IMPULSIVE:
- voice = impulsive_source();
- break;
- case NATURAL:
- voice = natural_source();
- break;
- case SAMPLED:
- voice = sampled_source();
- break;
- }
-
- /* Reset period when counter 'nper' reaches T0 */
- if (kt_globals.nper >= kt_globals.T0)
- {
- kt_globals.nper = 0;
- pitch_synch_par_reset(frame);
- }
-
- /*
- Low-pass filter voicing waveform before downsampling from 4*samrate
- to samrate samples/sec. Resonator f=.09*samrate, bw=.06*samrate
- */
-
- voice = resonator(&(kt_globals.rsn[RLP]),voice);
-
- /* Increment counter that keeps track of 4*samrate samples per sec */
- kt_globals.nper++;
- }
-
- /*
- Tilt spectrum of voicing source down by soft low-pass filtering, amount
- of tilt determined by TLTdb
- */
-
- voice = (voice * kt_globals.onemd) + (vlast * kt_globals.decay);
- vlast = voice;
-
- /*
- Add breathiness during glottal open phase. Amount of breathiness
- determined by parameter Aturb Use nrand rather than noise because
- noise is low-passed.
- */
-
-
- if (kt_globals.nper < kt_globals.nopen)
- {
- voice += kt_globals.amp_breth * kt_globals.nrand;
- }
-
- /* Set amplitude of voicing */
- glotout = kt_globals.amp_voice * voice;
- par_glotout = kt_globals.par_amp_voice * voice;
-
- /* Compute aspiration amplitude and add to voicing source */
- aspiration = kt_globals.amp_aspir * noise;
- glotout += aspiration;
-
- par_glotout += aspiration;
-
- /*
- Cascade vocal tract, excited by laryngeal sources.
- Nasal antiresonator, then formants FNP, F5, F4, F3, F2, F1
- */
-
- out=0;
- if(kt_globals.synthesis_model != ALL_PARALLEL)
- {
- casc_next_in = antiresonator2(&(kt_globals.rsn[Rnz]),glotout);
- casc_next_in = resonator(&(kt_globals.rsn[Rnpc]),casc_next_in);
- casc_next_in = resonator(&(kt_globals.rsn[R8c]),casc_next_in);
- casc_next_in = resonator(&(kt_globals.rsn[R7c]),casc_next_in);
- casc_next_in = resonator(&(kt_globals.rsn[R6c]),casc_next_in);
- casc_next_in = resonator2(&(kt_globals.rsn[R5c]),casc_next_in);
- casc_next_in = resonator2(&(kt_globals.rsn[R4c]),casc_next_in);
- casc_next_in = resonator2(&(kt_globals.rsn[R3c]),casc_next_in);
- casc_next_in = resonator2(&(kt_globals.rsn[R2c]),casc_next_in);
- out = resonator2(&(kt_globals.rsn[R1c]),casc_next_in);
- }
-
- /* Excite parallel F1 and FNP by voicing waveform */
- sourc = par_glotout; /* Source is voicing plus aspiration */
-
- /*
- Standard parallel vocal tract Formants F6,F5,F4,F3,F2,
- outputs added with alternating sign. Sound source for other
- parallel resonators is frication plus first difference of
- voicing waveform.
- */
-
- out += resonator(&(kt_globals.rsn[R1p]),sourc);
- out += resonator(&(kt_globals.rsn[Rnpp]),sourc);
-
- sourc = frics + par_glotout - glotlast;
- glotlast = par_glotout;
-
- for(ix=R2p; ix<=R6p; ix++)
- {
- out = resonator(&(kt_globals.rsn[ix]),sourc) - out;
- }
-
- outbypas = kt_globals.amp_bypas * sourc;
-
- out = outbypas - out;
-
-#ifdef deleted
-// for testing
- if (kt_globals.outsl != 0)
- {
- switch(kt_globals.outsl)
- {
- case 1:
- out = voice;
- break;
- case 2:
- out = aspiration;
- break;
- case 3:
- out = frics;
- break;
- case 4:
- out = glotout;
- break;
- case 5:
- out = par_glotout;
- break;
- case 6:
- out = outbypas;
- break;
- case 7:
- out = sourc;
- break;
- }
- }
-#endif
-
- out = resonator(&(kt_globals.rsn[Rout]),out);
- temp = (out * wdata.amplitude * kt_globals.amp_gain0) ; /* Convert back to integer */
-
-
- // mix with a recorded WAV if required for this phoneme
- {
- int z2;
- signed char c;
- int sample;
-
- z2 = 0;
- if(wdata.mix_wavefile_ix < wdata.n_mix_wavefile)
- {
- if(wdata.mix_wave_scale == 0)
- {
- // a 16 bit sample
- c = wdata.mix_wavefile[wdata.mix_wavefile_ix+1];
- sample = wdata.mix_wavefile[wdata.mix_wavefile_ix] + (c * 256);
- wdata.mix_wavefile_ix += 2;
- }
- else
- {
- // a 8 bit sample, scaled
- sample = (signed char)wdata.mix_wavefile[wdata.mix_wavefile_ix++] * wdata.mix_wave_scale;
- }
- z2 = sample * wdata.amplitude_v / 1024;
- z2 = (z2 * wdata.mix_wave_amp)/40;
- temp += z2;
- }
- }
-
- // if fadeout is set, fade to zero over 64 samples, to avoid clicks at end of synthesis
- if(kt_globals.fadeout > 0)
- {
- kt_globals.fadeout--;
- temp = (temp * kt_globals.fadeout) / 64;
- }
-
- if (temp < -32768.0)
- {
- temp = -32768.0;
- }
-
- if (temp > 32767.0)
- {
- temp = 32767.0;
- }
-
- *out_ptr++ = (int)(temp); // **JSD
- *out_ptr++ = (int)(temp) >> 8;
- sample_count++;
- if(out_ptr >= out_end)
- {
- return(1);
- }
- }
- return(0);
-} // end of parwave
-
-
-
-
-/*
-function PARWAVE_INIT
-
-Initialises all parameters used in parwave, sets resonator internal memory
-to zero.
-*/
-
-static void reset_resonators()
-{
- int r_ix;
-
- for(r_ix=0; r_ix < N_RSN; r_ix++)
- {
- kt_globals.rsn[r_ix].p1 = 0;
- kt_globals.rsn[r_ix].p2 = 0;
- }
-}
-
-static void parwave_init()
-{
- kt_globals.FLPhz = (950 * kt_globals.samrate) / 10000;
- kt_globals.BLPhz = (630 * kt_globals.samrate) / 10000;
- kt_globals.minus_pi_t = -PI / kt_globals.samrate;
- kt_globals.two_pi_t = -2.0 * kt_globals.minus_pi_t;
- setabc(kt_globals.FLPhz,kt_globals.BLPhz,&(kt_globals.rsn[RLP]));
- kt_globals.nper = 0;
- kt_globals.T0 = 0;
- kt_globals.nopen = 0;
- kt_globals.nmod = 0;
-
- reset_resonators();
-}
-
-
-/*
-function FRAME_INIT
-
-Use parameters from the input frame to set up resonator coefficients.
-*/
-
-static void frame_init(klatt_frame_ptr frame)
-{
- double amp_par[7];
- static double amp_par_factor[7] = {0.6, 0.4, 0.15, 0.06, 0.04, 0.022, 0.03};
- long Gain0_tmp;
- int ix;
-
- kt_globals.original_f0 = frame->F0hz10 / 10;
-
- frame->AVdb_tmp = frame->AVdb - 7;
- if (frame->AVdb_tmp < 0)
- {
- frame->AVdb_tmp = 0;
- }
-
- kt_globals.amp_aspir = DBtoLIN(frame->ASP) * 0.05;
- kt_globals.amp_frica = DBtoLIN(frame->AF) * 0.25;
- kt_globals.par_amp_voice = DBtoLIN(frame->AVpdb);
- kt_globals.amp_bypas = DBtoLIN(frame->AB) * 0.05;
-
- for(ix=0; ix <= 6; ix++)
- {
- // parallel amplitudes F1 to F6, and parallel nasal pole
- amp_par[ix] = DBtoLIN(frame->Ap[ix]) * amp_par_factor[ix];
- }
-
- Gain0_tmp = frame->Gain0 - 3;
- if (Gain0_tmp <= 0)
- {
- Gain0_tmp = 57;
- }
- kt_globals.amp_gain0 = DBtoLIN(Gain0_tmp) / kt_globals.scale_wav;
-
- /* Set coefficients of variable cascade resonators */
- for(ix=0; ix<=8; ix++)
- {
- // formants 1 to 8, plus nasal pole
- setabc(frame->Fhz[ix],frame->Bhz[ix],&(kt_globals.rsn[ix]));
-
- if(ix <= 5)
- {
- setabc(frame->Fhz_next[ix],frame->Bhz_next[ix],&(kt_globals.rsn_next[ix]));
-
- kt_globals.rsn[ix].a_inc = (kt_globals.rsn_next[ix].a - kt_globals.rsn[ix].a) / 64.0;
- kt_globals.rsn[ix].b_inc = (kt_globals.rsn_next[ix].b - kt_globals.rsn[ix].b) / 64.0;
- kt_globals.rsn[ix].c_inc = (kt_globals.rsn_next[ix].c - kt_globals.rsn[ix].c) / 64.0;
- }
- }
-
- // nasal zero anti-resonator
- setzeroabc(frame->Fhz[F_NZ],frame->Bhz[F_NZ],&(kt_globals.rsn[Rnz]));
- setzeroabc(frame->Fhz_next[F_NZ],frame->Bhz_next[F_NZ],&(kt_globals.rsn_next[Rnz]));
- kt_globals.rsn[F_NZ].a_inc = (kt_globals.rsn_next[F_NZ].a - kt_globals.rsn[F_NZ].a) / 64.0;
- kt_globals.rsn[F_NZ].b_inc = (kt_globals.rsn_next[F_NZ].b - kt_globals.rsn[F_NZ].b) / 64.0;
- kt_globals.rsn[F_NZ].c_inc = (kt_globals.rsn_next[F_NZ].c - kt_globals.rsn[F_NZ].c) / 64.0;
-
-
- /* Set coefficients of parallel resonators, and amplitude of outputs */
-
- for(ix=0; ix<=6; ix++)
- {
- setabc(frame->Fhz[ix],frame->Bphz[ix],&(kt_globals.rsn[Rparallel+ix]));
- kt_globals.rsn[Rparallel+ix].a *= amp_par[ix];
- }
-
- /* output low-pass filter */
-
- setabc((long)0.0,(long)(kt_globals.samrate/2),&(kt_globals.rsn[Rout]));
-
-}
-
-
-
-/*
-function IMPULSIVE_SOURCE
-
-Generate a low pass filtered train of impulses as an approximation of
-a natural excitation waveform. Low-pass filter the differentiated impulse
-with a critically-damped second-order filter, time constant proportional
-to Kopen.
-*/
-
-
-static double impulsive_source()
-{
- static double doublet[] = {0.0,13000000.0,-13000000.0};
- static double vwave;
-
- if (kt_globals.nper < 3)
- {
- vwave = doublet[kt_globals.nper];
- }
- else
- {
- vwave = 0.0;
- }
-
- return(resonator(&(kt_globals.rsn[RGL]),vwave));
-}
-
-
-
-/*
-function NATURAL_SOURCE
-
-Vwave is the differentiated glottal flow waveform, there is a weak
-spectral zero around 800 Hz, magic constants a,b reset pitch synchronously.
-*/
-
-static double natural_source()
-{
- double lgtemp;
- static double vwave;
-
- if (kt_globals.nper < kt_globals.nopen)
- {
- kt_globals.pulse_shape_a -= kt_globals.pulse_shape_b;
- vwave += kt_globals.pulse_shape_a;
- lgtemp=vwave * 0.028;
-
- return(lgtemp);
- }
- else
- {
- vwave = 0.0;
- return(0.0);
- }
-}
-
-
-
-
-
-/*
-function PITCH_SYNC_PAR_RESET
-
-Reset selected parameters pitch-synchronously.
-
-
-Constant B0 controls shape of glottal pulse as a function
-of desired duration of open phase N0
-(Note that N0 is specified in terms of 40,000 samples/sec of speech)
-
-Assume voicing waveform V(t) has form: k1 t**2 - k2 t**3
-
- If the radiation characterivative, a temporal derivative
- is folded in, and we go from continuous time to discrete
- integers n: dV/dt = vwave[n]
- = sum over i=1,2,...,n of { a - (i * b) }
- = a n - b/2 n**2
-
- where the constants a and b control the detailed shape
- and amplitude of the voicing waveform over the open
- potion of the voicing cycle "nopen".
-
- Let integral of dV/dt have no net dc flow --> a = (b * nopen) / 3
-
- Let maximum of dUg(n)/dn be constant --> b = gain / (nopen * nopen)
- meaning as nopen gets bigger, V has bigger peak proportional to n
-
- Thus, to generate the table below for 40 <= nopen <= 263:
-
- B0[nopen - 40] = 1920000 / (nopen * nopen)
-*/
-
-static void pitch_synch_par_reset(klatt_frame_ptr frame)
-{
- long temp;
- double temp1;
- static long skew;
- static short B0[224] =
- {
- 1200,1142,1088,1038, 991, 948, 907, 869, 833, 799, 768, 738, 710, 683, 658,
- 634, 612, 590, 570, 551, 533, 515, 499, 483, 468, 454, 440, 427, 415, 403,
- 391, 380, 370, 360, 350, 341, 332, 323, 315, 307, 300, 292, 285, 278, 272,
- 265, 259, 253, 247, 242, 237, 231, 226, 221, 217, 212, 208, 204, 199, 195,
- 192, 188, 184, 180, 177, 174, 170, 167, 164, 161, 158, 155, 153, 150, 147,
- 145, 142, 140, 137, 135, 133, 131, 128, 126, 124, 122, 120, 119, 117, 115,
- 113,111, 110, 108, 106, 105, 103, 102, 100, 99, 97, 96, 95, 93, 92, 91, 90,
- 88, 87, 86, 85, 84, 83, 82, 80, 79, 78, 77, 76, 75, 75, 74, 73, 72, 71,
- 70, 69, 68, 68, 67, 66, 65, 64, 64, 63, 62, 61, 61, 60, 59, 59, 58, 57,
- 57, 56, 56, 55, 55, 54, 54, 53, 53, 52, 52, 51, 51, 50, 50, 49, 49, 48, 48,
- 47, 47, 46, 46, 45, 45, 44, 44, 43, 43, 42, 42, 41, 41, 41, 41, 40, 40,
- 39, 39, 38, 38, 38, 38, 37, 37, 36, 36, 36, 36, 35, 35, 35, 35, 34, 34,33,
- 33, 33, 33, 32, 32, 32, 32, 31, 31, 31, 31, 30, 30, 30, 30, 29, 29, 29, 29,
- 28, 28, 28, 28, 27, 27
- };
-
- if (frame->F0hz10 > 0)
- {
- /* T0 is 4* the number of samples in one pitch period */
-
- kt_globals.T0 = (40 * kt_globals.samrate) / frame->F0hz10;
-
-
- kt_globals.amp_voice = DBtoLIN(frame->AVdb_tmp);
-
- /* Duration of period before amplitude modulation */
-
- kt_globals.nmod = kt_globals.T0;
- if (frame->AVdb_tmp > 0)
- {
- kt_globals.nmod >>= 1;
- }
-
- /* Breathiness of voicing waveform */
-
- kt_globals.amp_breth = DBtoLIN(frame->Aturb) * 0.1;
-
- /* Set open phase of glottal period where 40 <= open phase <= 263 */
-
- kt_globals.nopen = 4 * frame->Kopen;
-
- if ((kt_globals.glsource == IMPULSIVE) && (kt_globals.nopen > 263))
- {
- kt_globals.nopen = 263;
- }
-
- if (kt_globals.nopen >= (kt_globals.T0-1))
- {
-// printf("Warning: glottal open period cannot exceed T0, truncated\n");
- kt_globals.nopen = kt_globals.T0 - 2;
- }
-
- if (kt_globals.nopen < 40)
- {
- /* F0 max = 1000 Hz */
-// printf("Warning: minimum glottal open period is 10 samples.\n");
-// printf("truncated, nopen = %d\n",kt_globals.nopen);
- kt_globals.nopen = 40;
- }
-
-
- /* Reset a & b, which determine shape of "natural" glottal waveform */
-
- kt_globals.pulse_shape_b = B0[kt_globals.nopen-40];
- kt_globals.pulse_shape_a = (kt_globals.pulse_shape_b * kt_globals.nopen) * 0.333;
-
- /* Reset width of "impulsive" glottal pulse */
-
- temp = kt_globals.samrate / kt_globals.nopen;
-
- setabc((long)0,temp,&(kt_globals.rsn[RGL]));
-
- /* Make gain at F1 about constant */
-
- temp1 = kt_globals.nopen *.00833;
- kt_globals.rsn[RGL].a *= temp1 * temp1;
-
- /*
- Truncate skewness so as not to exceed duration of closed phase
- of glottal period.
- */
-
-
- temp = kt_globals.T0 - kt_globals.nopen;
- if (frame->Kskew > temp)
- {
-// printf("Kskew duration=%d > glottal closed period=%d, truncate\n", frame->Kskew, kt_globals.T0 - kt_globals.nopen);
- frame->Kskew = temp;
- }
- if (skew >= 0)
- {
- skew = frame->Kskew;
- }
- else
- {
- skew = - frame->Kskew;
- }
-
- /* Add skewness to closed portion of voicing period */
- kt_globals.T0 = kt_globals.T0 + skew;
- skew = - skew;
- }
- else
- {
- kt_globals.T0 = 4; /* Default for f0 undefined */
- kt_globals.amp_voice = 0.0;
- kt_globals.nmod = kt_globals.T0;
- kt_globals.amp_breth = 0.0;
- kt_globals.pulse_shape_a = 0.0;
- kt_globals.pulse_shape_b = 0.0;
- }
-
- /* Reset these pars pitch synchronously or at update rate if f0=0 */
-
- if ((kt_globals.T0 != 4) || (kt_globals.ns == 0))
- {
- /* Set one-pole low-pass filter that tilts glottal source */
-
- kt_globals.decay = (0.033 * frame->TLTdb);
-
- if (kt_globals.decay > 0.0)
- {
- kt_globals.onemd = 1.0 - kt_globals.decay;
- }
- else
- {
- kt_globals.onemd = 1.0;
- }
- }
-}
-
-
-
-/*
-function SETABC
-
-Convert formant freqencies and bandwidth into resonator difference
-equation constants.
-*/
-
-
-static void setabc(long int f, long int bw, resonator_ptr rp)
-{
- double r;
- double arg;
-
- /* Let r = exp(-pi bw t) */
- arg = kt_globals.minus_pi_t * bw;
- r = exp(arg);
-
- /* Let c = -r**2 */
- rp->c = -(r * r);
-
- /* Let b = r * 2*cos(2 pi f t) */
- arg = kt_globals.two_pi_t * f;
- rp->b = r * cos(arg) * 2.0;
-
- /* Let a = 1.0 - b - c */
- rp->a = 1.0 - rp->b - rp->c;
-}
-
-
-/*
-function SETZEROABC
-
-Convert formant freqencies and bandwidth into anti-resonator difference
-equation constants.
-*/
-
-static void setzeroabc(long int f, long int bw, resonator_ptr rp)
-{
- double r;
- double arg;
-
- f = -f;
-
- if(f>=0)
- {
- f = -1;
- }
-
- /* First compute ordinary resonator coefficients */
- /* Let r = exp(-pi bw t) */
- arg = kt_globals.minus_pi_t * bw;
- r = exp(arg);
-
- /* Let c = -r**2 */
- rp->c = -(r * r);
-
- /* Let b = r * 2*cos(2 pi f t) */
- arg = kt_globals.two_pi_t * f;
- rp->b = r * cos(arg) * 2.;
-
- /* Let a = 1.0 - b - c */
- rp->a = 1.0 - rp->b - rp->c;
-
- /* Now convert to antiresonator coefficients (a'=1/a, b'=b/a, c'=c/a) */
- rp->a = 1.0 / rp->a;
- rp->c *= -rp->a;
- rp->b *= -rp->a;
-}
-
-
-/*
-function GEN_NOISE
-
-Random number generator (return a number between -8191 and +8191)
-Noise spectrum is tilted down by soft low-pass filter having a pole near
-the origin in the z-plane, i.e. output = input + (0.75 * lastoutput)
-*/
-
-
-static double gen_noise(double noise)
-{
- long temp;
- static double nlast;
-
- temp = (long) getrandom(-8191,8191);
- kt_globals.nrand = (long) temp;
-
- noise = kt_globals.nrand + (0.75 * nlast);
- nlast = noise;
-
- return(noise);
-}
-
-
-/*
-function DBTOLIN
-
-Convert from decibels to a linear scale factor
-
-
-Conversion table, db to linear, 87 dB --> 32767
- 86 dB --> 29491 (1 dB down = 0.5**1/6)
- ...
- 81 dB --> 16384 (6 dB down = 0.5)
- ...
- 0 dB --> 0
-
-The just noticeable difference for a change in intensity of a vowel
-is approximately 1 dB. Thus all amplitudes are quantized to 1 dB
-steps.
-*/
-
-
-static double DBtoLIN(long dB)
-{
- static short amptable[88] =
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7,
- 8, 9, 10, 11, 13, 14, 16, 18, 20, 22, 25, 28, 32,
- 35, 40, 45, 51, 57, 64, 71, 80, 90, 101, 114, 128,
- 142, 159, 179, 202, 227, 256, 284, 318, 359, 405,
- 455, 512, 568, 638, 719, 881, 911, 1024, 1137, 1276,
- 1438, 1622, 1823, 2048, 2273, 2552, 2875, 3244, 3645,
- 4096, 4547, 5104, 5751, 6488, 7291, 8192, 9093, 10207,
- 11502, 12976, 14582, 16384, 18350, 20644, 23429,
- 26214, 29491, 32767 };
-
- if ((dB < 0) || (dB > 87))
- {
- return(0);
- }
-
- return((double)(amptable[dB]) * 0.001);
-}
-
-
-
-
-
-extern voice_t *wvoice;
-static klatt_peaks_t peaks[N_PEAKS];
-static int end_wave;
-static int klattp[N_KLATTP];
-static double klattp1[N_KLATTP];
-static double klattp_inc[N_KLATTP];
-
-static int scale_wav_tab[] = {45,38,45,45}; // scale output from different voicing sources
-
-
-
-int Wavegen_Klatt(int resume)
-{//==========================
- int pk;
- int x;
- int ix;
-
- if(resume==0)
- {
- sample_count = 0;
- }
-
- while(sample_count < nsamples)
- {
- kt_frame.F0hz10 = (wdata.pitch * 10) / 4096;
-
- // formants F6,F7,F8 are fixed values for cascade resonators, set in KlattInit()
- // but F6 is used for parallel resonator
- // F0 is used for the nasal zero
- for(ix=0; ix < 6; ix++)
- {
- kt_frame.Fhz[ix] = peaks[ix].freq;
- if(ix < 4)
- {
- kt_frame.Bhz[ix] = peaks[ix].bw;
- }
- }
- for(ix=1; ix < 7; ix++)
- {
- kt_frame.Ap[ix] = 0;
- }
-
- kt_frame.AVdb = klattp[KLATT_AV];
- kt_frame.AVpdb = klattp[KLATT_AVp];
- kt_frame.AF = klattp[KLATT_Fric];
- kt_frame.AB = klattp[KLATT_FricBP];
- kt_frame.ASP = klattp[KLATT_Aspr];
- kt_frame.Aturb = klattp[KLATT_Turb];
- kt_frame.Kskew = klattp[KLATT_Skew];
- kt_frame.TLTdb = klattp[KLATT_Tilt];
- kt_frame.Kopen = klattp[KLATT_Kopen];
-
- // advance formants
- for(pk=0; pk<N_PEAKS; pk++)
- {
- peaks[pk].freq1 += peaks[pk].freq_inc;
- peaks[pk].freq = (int)peaks[pk].freq1;
- peaks[pk].bw1 += peaks[pk].bw_inc;
- peaks[pk].bw = (int)peaks[pk].bw1;
- peaks[pk].bp1 += peaks[pk].bp_inc;
- peaks[pk].bp = (int)peaks[pk].bp1;
- peaks[pk].ap1 += peaks[pk].ap_inc;
- peaks[pk].ap = (int)peaks[pk].ap1;
- }
-
- // advance other parameters
- for(ix=0; ix < N_KLATTP; ix++)
- {
- klattp1[ix] += klattp_inc[ix];
- klattp[ix] = (int)(klattp1[ix]);
- }
-
- for(ix=0; ix<=6; ix++)
- {
- kt_frame.Fhz_next[ix] = peaks[ix].freq;
- if(ix < 4)
- {
- kt_frame.Bhz_next[ix] = peaks[ix].bw;
- }
- }
-
- // advance the pitch
- wdata.pitch_ix += wdata.pitch_inc;
- if((ix = wdata.pitch_ix>>8) > 127) ix = 127;
- x = wdata.pitch_env[ix] * wdata.pitch_range;
- wdata.pitch = (x>>8) + wdata.pitch_base;
-
- kt_globals.nspfr = (nsamples - sample_count);
- if(kt_globals.nspfr > STEPSIZE)
- kt_globals.nspfr = STEPSIZE;
-
- if(parwave(&kt_frame) == 1)
- {
- return(1);
- }
- }
-
- if(end_wave == 1)
- {
- // fade out to avoid a click
- kt_globals.fadeout = 64;
- end_wave = 0;
- sample_count -= 64;
- kt_globals.nspfr = 64;
- if(parwave(&kt_frame) == 1)
- {
- return(1);
- }
- }
-
- return(0);
-}
-
-
-void SetSynth_Klatt(int length, int modn, frame_t *fr1, frame_t *fr2, voice_t *v, int control)
-{//===========================================================================================
- int ix;
- DOUBLEX next;
- int qix;
- int cmd;
- static frame_t prev_fr;
-
- if(wvoice != NULL)
- {
- if((wvoice->klattv[0] > 0) && (wvoice->klattv[0] <=3 ))
- {
- kt_globals.glsource = wvoice->klattv[0];
- kt_globals.scale_wav = scale_wav_tab[kt_globals.glsource];
- }
- kt_globals.f0_flutter = wvoice->flutter/32;
- }
-
- end_wave = 0;
- if(control & 2)
- {
- end_wave = 1; // fadeout at the end
- }
- if(control & 1)
- {
- end_wave = 1;
- for(qix=wcmdq_head+1;;qix++)
- {
- if(qix >= N_WCMDQ) qix = 0;
- if(qix == wcmdq_tail) break;
-
- cmd = wcmdq[qix][0];
- if(cmd==WCMD_KLATT)
- {
- end_wave = 0; // next wave generation is from another spectrum
- break;
- }
- if((cmd==WCMD_WAVE) || (cmd==WCMD_PAUSE))
- break; // next is not from spectrum, so continue until end of wave cycle
- }
- }
-
-{
-//FILE *f;
-//f=fopen("klatt_log","a");
-//fprintf(f,"len %4d (%3d %4d %4d) (%3d %4d %4d)\n",length,fr1->ffreq[1],fr1->ffreq[2],fr1->ffreq[3],fr2->ffreq[1],fr2->ffreq[2],fr2->ffreq[3]);
-//fclose(f);
-}
-
- if(control & 1)
- {
- if(wdata.prev_was_synth == 0)
- {
- // A break, not following on from another synthesized sound.
- // Reset the synthesizer
- //reset_resonators(&kt_globals);
- parwave_init();
- }
- else
- {
- if((prev_fr.ffreq[1] != fr1->ffreq[1]) || (prev_fr.ffreq[2] != fr1->ffreq[2]))
- {
-
- // fade out to avoid a click, but only up to the end of output buffer
- ix = (out_end - out_ptr)/2;
- if(ix > 64)
- ix = 64;
- kt_globals.fadeout = ix;
- kt_globals.nspfr = ix;
- parwave(&kt_frame);
-
- //reset_resonators(&kt_globals);
- parwave_init();
- }
- }
- wdata.prev_was_synth = 1;
- memcpy(&prev_fr,fr2,sizeof(prev_fr));
- }
- if(fr2->frflags & FRFLAG_BREAK)
- {
-// fr2 = fr1;
-// reset_resonators(&kt_globals);
- }
-
- for(ix=0; ix<N_KLATTP; ix++)
- {
- if((ix >= 5) && ((fr1->frflags & FRFLAG_KLATT) == 0))
- {
- klattp1[ix] = klattp[ix] = 0;
- klattp_inc[ix] = 0;
- }
- else
- {
- klattp1[ix] = klattp[ix] = fr1->klattp[ix];
- klattp_inc[ix] = (double)((fr2->klattp[ix] - klattp[ix]) * STEPSIZE)/length;
- }
-
- // get klatt parameter adjustments for the voice
-// if((ix>0) && (ix < KLATT_AVp))
-// klattp1[ix] = klattp[ix] = (klattp[ix] + wvoice->klattv[ix]);
- }
-
- nsamples = length;
-
- for(ix=1; ix < 6; ix++)
- {
- peaks[ix].freq1 = (fr1->ffreq[ix] * v->freq[ix] / 256.0) + v->freqadd[ix];
- peaks[ix].freq = (int)(peaks[ix].freq1);
- next = (fr2->ffreq[ix] * v->freq[ix] / 256.0) + v->freqadd[ix];
- peaks[ix].freq_inc = ((next - peaks[ix].freq1) * STEPSIZE) / length;
-
- if(ix < 4)
- {
- // klatt bandwidth for f1, f2, f3 (others are fixed)
- peaks[ix].bw1 = fr1->bw[ix] * 2;
- peaks[ix].bw = (int)(peaks[ix].bw1);
- next = fr2->bw[ix] * 2;
- peaks[ix].bw_inc = ((next - peaks[ix].bw1) * STEPSIZE) / length;
- }
- }
-
- // nasal zero frequency
- peaks[0].freq1 = fr1->klattp[KLATT_FNZ] * 2;
- peaks[0].freq = (int)(peaks[0].freq1);
- next = fr2->klattp[KLATT_FNZ] * 2;
- peaks[0].freq_inc = ((next - peaks[0].freq1) * STEPSIZE) / length;
-
- peaks[0].bw1 = 89;
- peaks[0].bw = 89;
- peaks[0].bw_inc = 0;
-
- if(fr1->frflags & FRFLAG_KLATT)
- {
- // the frame contains additional parameters for parallel resonators
- for(ix=1; ix < 7; ix++)
- {
- peaks[ix].bp1 = fr1->klatt_bp[ix] * 4; // parallel bandwidth
- peaks[ix].bp = (int)(peaks[ix].bp1);
- next = fr2->klatt_bp[ix] * 2;
- peaks[ix].bp_inc = ((next - peaks[ix].bp1) * STEPSIZE) / length;
-
- peaks[ix].ap1 = fr1->klatt_ap[ix]; // parallal amplitude
- peaks[ix].ap = (int)(peaks[ix].ap1);
- next = fr2->klatt_ap[ix] * 2;
- peaks[ix].ap_inc = ((next - peaks[ix].ap1) * STEPSIZE) / length;
- }
- }
-} // end of SetSynth_Klatt
-
-
-int Wavegen_Klatt2(int length, int modulation, int resume, frame_t *fr1, frame_t *fr2)
-{//===================================================================================
- if(resume==0)
- SetSynth_Klatt(length, modulation, fr1, fr2, wvoice, 1);
-
- return(Wavegen_Klatt(resume));
-}
-
-
-
-void KlattInit()
-{
-#define NUMBER_OF_SAMPLES 100
-
- static short natural_samples[NUMBER_OF_SAMPLES]=
- {
- -310,-400,530,356,224,89,23,-10,-58,-16,461,599,536,701,770,
- 605,497,461,560,404,110,224,131,104,-97,155,278,-154,-1165,
- -598,737,125,-592,41,11,-247,-10,65,92,80,-304,71,167,-1,122,
- 233,161,-43,278,479,485,407,266,650,134,80,236,68,260,269,179,
- 53,140,275,293,296,104,257,152,311,182,263,245,125,314,140,44,
- 203,230,-235,-286,23,107,92,-91,38,464,443,176,98,-784,-2449,
- -1891,-1045,-1600,-1462,-1384,-1261,-949,-730
- };
- static short formant_hz[10] = {280,688,1064,2806,3260,3700,6500,7000,8000,280};
- static short bandwidth[10] = {89,160,70,160,200,200,500,500,500,89};
- static short parallel_amp[10] = { 0,59,59,59,59,59,59,0,0,0};
- static short parallel_bw[10] = {59,59,89,149,200,200,500,0,0,0};
-
- int ix;
-
- sample_count=0;
-
- kt_globals.synthesis_model = CASCADE_PARALLEL;
- kt_globals.samrate = 22050;
-
- kt_globals.glsource = IMPULSIVE; // IMPULSIVE, NATURAL, SAMPLED
- kt_globals.scale_wav = scale_wav_tab[kt_globals.glsource];
- kt_globals.natural_samples = natural_samples;
- kt_globals.num_samples = NUMBER_OF_SAMPLES;
- kt_globals.sample_factor = 3.0;
- kt_globals.nspfr = (kt_globals.samrate * 10) / 1000;
- kt_globals.outsl = 0;
- kt_globals.f0_flutter = 20;
-
- parwave_init();
-
- // set default values for frame parameters
- for(ix=0; ix<=9; ix++)
- {
- kt_frame.Fhz[ix] = formant_hz[ix];
- kt_frame.Bhz[ix] = bandwidth[ix];
- kt_frame.Ap[ix] = parallel_amp[ix];
- kt_frame.Bphz[ix] = parallel_bw[ix];
- }
- kt_frame.Bhz_next[F_NZ] = bandwidth[F_NZ];
-
- kt_frame.F0hz10 = 1000;
- kt_frame.AVdb = 59; // 59
- kt_frame.ASP = 0;
- kt_frame.Kopen = 40; // 40
- kt_frame.Aturb = 0;
- kt_frame.TLTdb = 0;
- kt_frame.AF =50;
- kt_frame.Kskew = 0;
- kt_frame.AB = 0;
- kt_frame.AVpdb = 0;
- kt_frame.Gain0 = 60; // 62
-} // end of KlattInit
-
-#endif // INCLUDE_KLATT
diff --git a/navit/support/espeak/klatt.h b/navit/support/espeak/klatt.h
deleted file mode 100644
index 5583b178a..000000000
--- a/navit/support/espeak/klatt.h
+++ /dev/null
@@ -1,153 +0,0 @@
-
-
-#define CASCADE_PARALLEL 1 /* Type of synthesis model */
-#define ALL_PARALLEL 2
-
-#define IMPULSIVE 1 /* Type of voicing source */
-#define NATURAL 2
-#define SAMPLED 3
-
-#define PI 3.1415927
-
-
-/* typedef's that need to be exported */
-
-typedef long flag;
-
-/* Resonator Structure */
-
-typedef struct
-{
- double a;
- double b;
- double c;
- double p1;
- double p2;
- double a_inc;
- double b_inc;
- double c_inc;
-} resonator_t, *resonator_ptr;
-
-/* Structure for Klatt Globals */
-
-typedef struct
-{
- flag synthesis_model; /* cascade-parallel or all-parallel */
- flag outsl; /* Output waveform selector */
- long samrate; /* Number of output samples per second */
- long FLPhz ; /* Frequeny of glottal downsample low-pass filter */
- long BLPhz ; /* Bandwidth of glottal downsample low-pass filter */
- flag glsource; /* Type of glottal source */
- int f0_flutter; /* Percentage of f0 flutter 0-100 */
- long nspfr; /* number of samples per frame */
- long nper; /* Counter for number of samples in a pitch period */
- long ns;
- long T0; /* Fundamental period in output samples times 4 */
- long nopen; /* Number of samples in open phase of period */
- long nmod; /* Position in period to begin noise amp. modul */
- long nrand; /* Varible used by random number generator */
- double pulse_shape_a; /* Makes waveshape of glottal pulse when open */
- double pulse_shape_b; /* Makes waveshape of glottal pulse when open */
- double minus_pi_t;
- double two_pi_t;
- double onemd;
- double decay;
- double amp_bypas; /* AB converted to linear gain */
- double amp_voice; /* AVdb converted to linear gain */
- double par_amp_voice; /* AVpdb converted to linear gain */
- double amp_aspir; /* AP converted to linear gain */
- double amp_frica; /* AF converted to linear gain */
- double amp_breth; /* ATURB converted to linear gain */
- double amp_gain0; /* G0 converted to linear gain */
- int num_samples; /* number of glottal samples */
- double sample_factor; /* multiplication factor for glottal samples */
- short *natural_samples; /* pointer to an array of glottal samples */
- long original_f0; /* original value of f0 not modified by flutter */
-
- int fadeout; // set to 64 to cause fadeout over 64 samples
- int scale_wav; // depends on the voicing source
-
-#define N_RSN 20
-#define Rnpc 0
-#define R1c 1
-#define R2c 2
-#define R3c 3
-#define R4c 4
-#define R5c 5
-#define R6c 6
-#define R7c 7
-#define R8c 8
-#define Rnz 9
-
-#define Rparallel 10
-#define Rnpp 10
-#define R1p 11
-#define R2p 12
-#define R3p 13
-#define R4p 14
-#define R5p 15
-#define R6p 16
-
-#define RGL 17
-#define RLP 18
-#define Rout 19
-
- resonator_t rsn[N_RSN]; // internal storage for resonators
- resonator_t rsn_next[N_RSN];
-
-} klatt_global_t, *klatt_global_ptr;
-
-/* Structure for Klatt Parameters */
-
-#define F_NZ 0 // nasal zero formant
-#define F1 1
-#define F2 2
-#define F3 3
-#define F4 4
-#define F5 5
-#define F6 6
-#define F_NP 9 // nasal pole formant
-
-
-typedef struct
-{
- long F0hz10; /* Voicing fund freq in Hz */
- long AVdb; /* Amp of voicing in dB, 0 to 70 */
- int Fhz[10]; // formant Hz, F_NZ to F6 to F_NP
- int Bhz[10];
- int Ap[10]; /* Amp of parallel formants in dB, 0 to 80 */
- int Bphz[10]; /* Parallel formants bw in Hz, 40 to 1000 */
-
- long ASP; /* Amp of aspiration in dB, 0 to 70 */
- long Kopen; /* # of samples in open period, 10 to 65 */
- long Aturb; /* Breathiness in voicing, 0 to 80 */
- long TLTdb; /* Voicing spectral tilt in dB, 0 to 24 */
- long AF; /* Amp of frication in dB, 0 to 80 */
- long Kskew; /* Skewness of alternate periods, 0 to 40 in sample#/2 */
-
- long AB; /* Amp of bypass fric. in dB, 0 to 80 */
- long AVpdb; /* Amp of voicing, par in dB, 0 to 70 */
- long Gain0; /* Overall gain, 60 dB is unity, 0 to 60 */
-
- long AVdb_tmp; //copy of AVdb, which is changed within parwave()
- int Fhz_next[10]; // Fhz for the next chunk, so we can do interpolation of resonator (a,b,c) parameters
- int Bhz_next[10];
- } klatt_frame_t, *klatt_frame_ptr;
-
-
-typedef struct {
- int freq; // Hz
- int bw; // klatt bandwidth
- int ap; // parallel amplitude
- int bp; // parallel bandwidth
- DOUBLEX freq1; // floating point versions of the above
- DOUBLEX bw1;
- DOUBLEX ap1;
- DOUBLEX bp1;
- DOUBLEX freq_inc; // increment by this every 64 samples
- DOUBLEX bw_inc;
- DOUBLEX ap_inc;
- DOUBLEX bp_inc;
-} klatt_peaks_t;
-
-
diff --git a/navit/support/espeak/mbrolib.h b/navit/support/espeak/mbrolib.h
deleted file mode 100644
index 0616b464b..000000000
--- a/navit/support/espeak/mbrolib.h
+++ /dev/null
@@ -1,205 +0,0 @@
-#ifndef MBROLIB_H
-#define MBROLIB_H
-
-/*
- * mbrolib: mbrola wrapper.
- *
- * Copyright (C) 2007 Gilles Casse <gcasse@oralux.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
-*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* < types */
-
-/** Parameters */
-
-typedef struct {
- int ignore_error; /* 1=Ignore any fatal error or unknown diphone */
- char comment_char; /* Comment character */
- float volume_ratio; /* Volume ratio */
- float frequency_ratio; /* Applied to pitch points */
- float time_ratio; /* Applied to phone durations */
-} mbrolib_parameter;
-
-
-/** Returned errors */
-
-typedef enum {
- MBROLIB_OK=0,
- MBROLIB_DATABASE_NOT_INSTALLED,
- MBROLIB_INVAL,
- MBROLIB_OUT_OF_MEMORY,
- MBROLIB_OUT_OF_RANGE,
- MBROLIB_READ_ERROR,
- MBROLIB_WRITE_ERROR
-} MBROLIB_ERROR;
-
-
-
-/** Gender */
-
-typedef enum {
- MBROLIB_FEMALE,
- MBROLIB_MALE
-} MBROLIB_GENDER;
-
-
-
-/** Voice descriptor */
-
-typedef struct {
- char *name; /* name (for example: "en1") */
- char *filename; /* database pathname (for example: "/usr/share/mbrola/voices/en1) */
- int rate; /* database sample rate */
- MBROLIB_GENDER gender;
- const char *language; /* Language and optional dialect qualifier in ascii (e.g. en, fr_ca). */
-} mbrolib_voice;
-
-/* > */
-
-
-/** Initialization, returns a new handle.
- First function.
-
- @param the_sample_rate: output rate in Hz (for example 22050). If 0, keep the original database rate.
-
- @return handle (or NULL if error).
-*/
-void* mbrolib_init( int sample_rate);
-typedef void* (t_mbrolib_init)(int);
-
-
-/** Returns the list of the installed mbrola databases.
- The databases are searched according to the MBROLA_PATH environment variable if set,
- or under a default path otherwise (see MBROLA_PATH in mbrolib.c).
-
- An array of voices is returned. The last item is set to NULL.
- The caller must not free the returned items or the array.
-
- @param the_handle previously given by mbrolib_init.
-
- @return An array of voices.
-*/
-const mbrolib_voice ** mbrolib_list_voices( void* the_handle);
-typedef const mbrolib_voice ** (t_mbrolib_list_voices)(void*);
-
-
-
-/** Set voice
-
- @param the_handle.
-
- @param the_database (for example, "en1").
-
- @return error code (MBROLIB_OK, MBROLIB_DATABASE_NOT_INSTALLED, MBROLIB_INVAL).
-
-*/
-MBROLIB_ERROR mbrolib_set_voice( void* the_handle, const char* the_name);
-typedef MBROLIB_ERROR (t_mbrolib_set_voice)( void*, const char*);
-
-
-
-/** Get the current database parameters.
- The caller supplies a pointer to an already allocated structure.
-
- @param the_handle previously given by mbrolib_init.
-
- @param the_parameters: pointer to the structure.
-
- @return error code (MBROLIB_OK, MBROLIB_INVAL).
-*/
-MBROLIB_ERROR mbrolib_get_parameter(void* the_handle, mbrolib_parameter* the_parameter);
-typedef MBROLIB_ERROR (t_mbrolib_get_parameter)(void*, mbrolib_parameter*);
-
-
-
-/** Set the database parameters using the supplied data.
-
- @param the_handle previously given by mbrolib_init.
-
- @param the_parameters: pointer to the wished parameters.
-
- @return error code (MBROLIB_OK, MBROLIB_INVAL).
-*/
-MBROLIB_ERROR mbrolib_set_parameter(void* the_handle, const mbrolib_parameter* the_parameter);
-typedef MBROLIB_ERROR (t_mbrolib_set_parameter)(void*, const mbrolib_parameter*);
-
-
-
-/** Write the mbrola phonemes in the internal buffer.
-
- @param the_handle.
-
- @param the_mbrola_phonemes.
-
- @param the_size in bytes.
-
- @return error code (MBROLIB_OK, MBROLIB_INVAL, MBROLIB_WRITE_ERROR, MBROLIB_READ_ERROR).
-*/
-MBROLIB_ERROR mbrolib_write(void* the_handle, const char* the_mbrola_phonemes, size_t the_size);
-typedef MBROLIB_ERROR (t_mbrolib_write)(void*, const char*, size_t);
-
-
-
-/** Read n bytes of the output samples.
-
- @param the_handle.
-
- @param the_samples (raw audio data, 16bits, mono).
-
- @param the_size max number of int16 to read.
-
- @param the_size number of int16 read.
-
- @return error code (MBROLIB_OK, MBROLIB_INVAL, MBROLIB_READ_ERROR).
-
-*/
-MBROLIB_ERROR mbrolib_read(void* the_handle, short* the_samples, int the_max_size, int* the_read_size);
-typedef MBROLIB_ERROR (t_mbrolib_read)(void*, short*, int, int*);
-
-
-
-/** Flush
-
- @param the_handle.
-
-*/
-void mbrolib_flush(void* the_handle);
-typedef void (t_mbrolib_flush)(void*);
-
-
-
-/** Release the handle
-
- @param the_handle.
-
- @return error code (MBROLIB_OK, MBROLIB_INVAL).
-
-*/
-MBROLIB_ERROR mbrolib_terminate(void* the_handle);
-typedef MBROLIB_ERROR (t_mbrolib_terminate)(void*);
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/navit/support/espeak/numbers.c b/navit/support/espeak/numbers.c
deleted file mode 100644
index 9c74eaca3..000000000
--- a/navit/support/espeak/numbers.c
+++ /dev/null
@@ -1,1507 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2005 to 2007 by Jonathan Duddington *
- * email: jonsd@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, see: *
- * <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-#include "StdAfx.h"
-
-#include <stdio.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <wctype.h>
-#include <wchar.h>
-
-#include "speak_lib.h"
-#include "speech.h"
-#include "phoneme.h"
-#include "synthesize.h"
-#include "voice.h"
-#include "translate.h"
-
-
-
-#define M_NAME 0
-#define M_SMALLCAP 1
-#define M_TURNED 2
-#define M_REVERSED 3
-#define M_CURL 4
-
-#define M_ACUTE 5
-#define M_BREVE 6
-#define M_CARON 7
-#define M_CEDILLA 8
-#define M_CIRCUMFLEX 9
-#define M_DIAERESIS 10
-#define M_DOUBLE_ACUTE 11
-#define M_DOT_ABOVE 12
-#define M_GRAVE 13
-#define M_MACRON 14
-#define M_OGONEK 15
-#define M_RING 16
-#define M_STROKE 17
-#define M_TILDE 18
-
-#define M_BAR 19
-#define M_RETROFLEX 20
-#define M_HOOK 21
-
-
-#define M_MIDDLE_DOT M_DOT_ABOVE // duplicate of M_DOT_ABOVE
-#define M_IMPLOSIVE M_HOOK
-
-typedef struct {
-const char *name;
-int flags;
-} ACCENTS;
-
-// these are tokens to look up in the *_list file.
-static ACCENTS accents_tab[] = {
-{"_lig", 1},
-{"_smc", 1}, // smallcap
-{"_tur", 1}, // turned
-{"_rev", 1}, // reversed
-{"_crl", 0}, // curl
-
-{"_acu", 0}, // acute
-{"_brv", 0}, // breve
-{"_hac", 0}, // caron/hacek
-{"_ced", 0}, // cedilla
-{"_cir", 0}, // circumflex
-{"_dia", 0}, // diaeresis
-{"_ac2", 0}, // double acute
-{"_dot", 0}, // dot
-{"_grv", 0}, // grave
-{"_mcn", 0}, // macron
-{"_ogo", 0}, // ogonek
-{"_rng", 0}, // ring
-{"_stk", 0}, // stroke
-{"_tld", 0}, // tilde
-
-{"_bar", 0}, // bar
-{"_rfx", 0}, // retroflex
-{"_hok", 0}, // hook
-};
-
-
-#define CAPITAL 0
-#define LETTER(ch,mod1,mod2) (ch-59)+(mod1 << 6)+(mod2 << 11)
-#define LIGATURE(ch1,ch2,mod1) (ch1-59)+((ch2-59) << 6)+(mod1 << 12)+0x8000
-
-
-#define L_ALPHA 60 // U+3B1
-#define L_SCHWA 61 // U+259
-#define L_OPEN_E 62 // U+25B
-#define L_GAMMA 63 // U+3B3
-#define L_IOTA 64 // U+3B9
-#define L_OE 65 // U+153
-#define L_OMEGA 66 // U+3C9
-
-#define L_PHI 67 // U+3C6
-#define L_ESH 68 // U+283
-#define L_UPSILON 69 // U+3C5
-#define L_EZH 70 // U+292
-#define L_GLOTTAL 71 // U+294
-#define L_RTAP 72 // U+27E
-
-
-static const short non_ascii_tab[] = {
- 0, 0x3b1, 0x259, 0x25b, 0x3b3, 0x3b9, 0x153, 0x3c9,
-0x3c6, 0x283, 0x3c5, 0x292, 0x294, 0x27e };
-
-
-// characters U+00e0 to U+017f
-static const unsigned short letter_accents_0e0[] = {
-LETTER('a',M_GRAVE,0), // U+00e0
-LETTER('a',M_ACUTE,0),
-LETTER('a',M_CIRCUMFLEX,0),
-LETTER('a',M_TILDE,0),
-LETTER('a',M_DIAERESIS,0),
-LETTER('a',M_RING,0),
-LIGATURE('a','e',0),
-LETTER('c',M_CEDILLA,0),
-LETTER('e',M_GRAVE,0),
-LETTER('e',M_ACUTE,0),
-LETTER('e',M_CIRCUMFLEX,0),
-LETTER('e',M_DIAERESIS,0),
-LETTER('i',M_GRAVE,0),
-LETTER('i',M_ACUTE,0),
-LETTER('i',M_CIRCUMFLEX,0),
-LETTER('i',M_DIAERESIS,0),
-LETTER('d',M_NAME,0), // eth // U+00f0
-LETTER('n',M_TILDE,0),
-LETTER('o',M_GRAVE,0),
-LETTER('o',M_ACUTE,0),
-LETTER('o',M_CIRCUMFLEX,0),
-LETTER('o',M_TILDE,0),
-LETTER('o',M_DIAERESIS,0),
-0, // division sign
-LETTER('o',M_STROKE,0),
-LETTER('u',M_GRAVE,0),
-LETTER('u',M_ACUTE,0),
-LETTER('u',M_CIRCUMFLEX,0),
-LETTER('u',M_DIAERESIS,0),
-LETTER('y',M_ACUTE,0),
-LETTER('t',M_NAME,0), // thorn
-LETTER('y',M_DIAERESIS,0),
-CAPITAL, // U+0100
-LETTER('a',M_MACRON,0),
-CAPITAL,
-LETTER('a',M_BREVE,0),
-CAPITAL,
-LETTER('a',M_OGONEK,0),
-CAPITAL,
-LETTER('c',M_ACUTE,0),
-CAPITAL,
-LETTER('c',M_CIRCUMFLEX,0),
-CAPITAL,
-LETTER('c',M_DOT_ABOVE,0),
-CAPITAL,
-LETTER('c',M_CARON,0),
-CAPITAL,
-LETTER('d',M_CARON,0),
-CAPITAL, // U+0110
-LETTER('d',M_STROKE,0),
-CAPITAL,
-LETTER('e',M_MACRON,0),
-CAPITAL,
-LETTER('e',M_BREVE,0),
-CAPITAL,
-LETTER('e',M_DOT_ABOVE,0),
-CAPITAL,
-LETTER('e',M_OGONEK,0),
-CAPITAL,
-LETTER('e',M_CARON,0),
-CAPITAL,
-LETTER('g',M_CIRCUMFLEX,0),
-CAPITAL,
-LETTER('g',M_BREVE,0),
-CAPITAL, // U+0120
-LETTER('g',M_DOT_ABOVE,0),
-CAPITAL,
-LETTER('g',M_CEDILLA,0),
-CAPITAL,
-LETTER('h',M_CIRCUMFLEX,0),
-CAPITAL,
-LETTER('h',M_STROKE,0),
-CAPITAL,
-LETTER('i',M_TILDE,0),
-CAPITAL,
-LETTER('i',M_MACRON,0),
-CAPITAL,
-LETTER('i',M_BREVE,0),
-CAPITAL,
-LETTER('i',M_OGONEK,0),
-CAPITAL, // U+0130
-LETTER('i',M_NAME,0), // dotless i
-CAPITAL,
-LIGATURE('i','j',0),
-CAPITAL,
-LETTER('j',M_CIRCUMFLEX,0),
-CAPITAL,
-LETTER('k',M_CEDILLA,0),
-LETTER('k',M_NAME,0), // kra
-CAPITAL,
-LETTER('l',M_ACUTE,0),
-CAPITAL,
-LETTER('l',M_CEDILLA,0),
-CAPITAL,
-LETTER('l',M_CARON,0),
-CAPITAL,
-LETTER('l',M_MIDDLE_DOT,0), // U+0140
-CAPITAL,
-LETTER('l',M_STROKE,0),
-CAPITAL,
-LETTER('n',M_ACUTE,0),
-CAPITAL,
-LETTER('n',M_CEDILLA,0),
-CAPITAL,
-LETTER('n',M_CARON,0),
-LETTER('n',M_NAME,0), // apostrophe n
-CAPITAL,
-LETTER('n',M_NAME,0), // eng
-CAPITAL,
-LETTER('o',M_MACRON,0),
-CAPITAL,
-LETTER('o',M_BREVE,0),
-CAPITAL, // U+0150
-LETTER('o',M_DOUBLE_ACUTE,0),
-CAPITAL,
-LIGATURE('o','e',0),
-CAPITAL,
-LETTER('r',M_ACUTE,0),
-CAPITAL,
-LETTER('r',M_CEDILLA,0),
-CAPITAL,
-LETTER('r',M_CARON,0),
-CAPITAL,
-LETTER('s',M_ACUTE,0),
-CAPITAL,
-LETTER('s',M_CIRCUMFLEX,0),
-CAPITAL,
-LETTER('s',M_CEDILLA,0),
-CAPITAL, // U+0160
-LETTER('s',M_CARON,0),
-CAPITAL,
-LETTER('t',M_CEDILLA,0),
-CAPITAL,
-LETTER('t',M_CARON,0),
-CAPITAL,
-LETTER('t',M_STROKE,0),
-CAPITAL,
-LETTER('u',M_TILDE,0),
-CAPITAL,
-LETTER('u',M_MACRON,0),
-CAPITAL,
-LETTER('u',M_BREVE,0),
-CAPITAL,
-LETTER('u',M_RING,0),
-CAPITAL, // U+0170
-LETTER('u',M_DOUBLE_ACUTE,0),
-CAPITAL,
-LETTER('u',M_OGONEK,0),
-CAPITAL,
-LETTER('w',M_CIRCUMFLEX,0),
-CAPITAL,
-LETTER('y',M_CIRCUMFLEX,0),
-CAPITAL, // Y-DIAERESIS
-CAPITAL,
-LETTER('z',M_ACUTE,0),
-CAPITAL,
-LETTER('z',M_DOT_ABOVE,0),
-CAPITAL,
-LETTER('z',M_CARON,0),
-LETTER('s',M_NAME,0), // long-s // U+17f
-};
-
-
-// characters U+0250 to U+029F
-static const unsigned short letter_accents_250[] = {
-LETTER('a',M_TURNED,0), // U+250
-LETTER(L_ALPHA,0,0),
-LETTER(L_ALPHA,M_TURNED,0),
-LETTER('b',M_IMPLOSIVE,0),
-0, // open-o
-LETTER('c',M_CURL,0),
-LETTER('d',M_RETROFLEX,0),
-LETTER('d',M_IMPLOSIVE,0),
-LETTER('e',M_REVERSED,0), // U+258
-0, // schwa
-LETTER(L_SCHWA,M_HOOK,0),
-0, // open-e
-LETTER(L_OPEN_E,M_REVERSED,0),
-LETTER(L_OPEN_E,M_HOOK,M_REVERSED),
-0,//LETTER(L_OPEN_E,M_CLOSED,M_REVERSED),
-LETTER('j',M_BAR,0),
-LETTER('g',M_IMPLOSIVE,0), // U+260
-LETTER('g',0,0),
-LETTER('g',M_SMALLCAP,0),
-LETTER(L_GAMMA,0,0),
-0, // ramshorn
-LETTER('h',M_TURNED,0),
-LETTER('h',M_HOOK,0),
-0,//LETTER(L_HENG,M_HOOK,0),
-LETTER('i',M_BAR,0), // U+268
-LETTER(L_IOTA,0,0),
-LETTER('i',M_SMALLCAP,0),
-LETTER('l',M_TILDE,0),
-LETTER('l',M_BAR,0),
-LETTER('l',M_RETROFLEX,0),
-LIGATURE('l','z',0),
-LETTER('m',M_TURNED,0),
-0,//LETTER('m',M_TURNED,M_LEG), // U+270
-LETTER('m',M_HOOK,0),
-0,//LETTER('n',M_LEFTHOOK,0),
-LETTER('n',M_RETROFLEX,0),
-LETTER('n',M_SMALLCAP,0),
-LETTER('o',M_BAR,0),
-LIGATURE('o','e',M_SMALLCAP),
-0,//LETTER(L_OMEGA,M_CLOSED,0),
-LETTER(L_PHI,0,0), // U+278
-LETTER('r',M_TURNED,0),
-0,//LETTER('r',M_TURNED,M_LEG),
-LETTER('r',M_RETROFLEX,M_TURNED),
-0,//LETTER('r',M_LEG,0),
-LETTER('r',M_RETROFLEX,0),
-0, // r-tap
-LETTER(L_RTAP,M_REVERSED,0),
-LETTER('r',M_SMALLCAP,0), // U+280
-LETTER('r',M_TURNED,M_SMALLCAP),
-LETTER('s',M_RETROFLEX,0),
-0, // esh
-0,//LETTER('j',M_BAR,L_IMPLOSIVE),
-LETTER(L_ESH,M_REVERSED,0),
-LETTER(L_ESH,M_CURL,0),
-LETTER('t',M_TURNED,0),
-LETTER('t',M_RETROFLEX,0), // U+288
-LETTER('u',M_BAR,0),
-LETTER(L_UPSILON,0,0),
-LETTER('v',M_HOOK,0),
-LETTER('v',M_TURNED,0),
-LETTER('w',M_TURNED,0),
-LETTER('y',M_TURNED,0),
-LETTER('y',M_SMALLCAP,0),
-LETTER('z',M_RETROFLEX,0), // U+290
-LETTER('z',M_CURL,0),
-0, // ezh
-LETTER(L_EZH,M_CURL,0),
-0, // glottal stop
-LETTER(L_GLOTTAL,M_REVERSED,0),
-LETTER(L_GLOTTAL,M_TURNED,0),
-0,//LETTER('c',M_LONG,0),
-0, // bilabial click // U+298
-LETTER('b',M_SMALLCAP,0),
-0,//LETTER(L_OPEN_E,M_CLOSED,0),
-LETTER('g',M_IMPLOSIVE,M_SMALLCAP),
-LETTER('h',M_SMALLCAP,0),
-LETTER('j',M_CURL,0),
-LETTER('k',M_TURNED,0),
-LETTER('l',M_SMALLCAP,0),
-LETTER('q',M_HOOK,0), // U+2a0
-LETTER(L_GLOTTAL,M_STROKE,0),
-LETTER(L_GLOTTAL,M_STROKE,M_REVERSED),
-LIGATURE('d','z',0),
-0, // dezh
-LIGATURE('d','z',M_CURL),
-LIGATURE('t','s',0),
-0, // tesh
-LIGATURE('t','s',M_CURL),
-};
-
-static int LookupLetter2(Translator *tr, unsigned int letter, char *ph_buf)
-{//========================================================================
- int len;
- char single_letter[10];
-
- single_letter[0] = 0;
- single_letter[1] = '_';
- len = utf8_out(letter, &single_letter[2]);
- single_letter[len+2] = ' ';
- single_letter[len+3] = 0;
-
- if(Lookup(tr, &single_letter[1], ph_buf) == 0)
- {
- single_letter[1] = ' ';
- if(Lookup(tr, &single_letter[2], ph_buf) == 0)
- {
- TranslateRules(tr, &single_letter[2], ph_buf, 20, NULL,0,NULL);
- }
- }
- return(ph_buf[0]);
-}
-
-
-void LookupAccentedLetter(Translator *tr, unsigned int letter, char *ph_buf)
-{//=========================================================================
- // lookup the character in the accents table
- int accent_data = 0;
- int accent1 = 0;
- int accent2 = 0;
- int basic_letter;
- int letter2=0;
- char ph_letter1[30];
- char ph_letter2[30];
- char ph_accent1[30];
- char ph_accent2[30];
-
- ph_accent2[0] = 0;
-
- if((letter >= 0xe0) && (letter < 0x17f))
- {
- accent_data = letter_accents_0e0[letter - 0xe0];
- }
- else
- if((letter >= 0x250) && (letter <= 0x2a8))
- {
- accent_data = letter_accents_250[letter - 0x250];
- }
-
- if(accent_data != 0)
- {
- basic_letter = (accent_data & 0x3f) + 59;
- if(basic_letter < 'a')
- basic_letter = non_ascii_tab[basic_letter-59];
-
- if(accent_data & 0x8000)
- {
- letter2 = (accent_data >> 6) & 0x3f;
- letter2 += 59;
- accent2 = (accent_data >> 12) & 0x7;
- }
- else
- {
- accent1 = (accent_data >> 6) & 0x1f;
- accent2 = (accent_data >> 11) & 0xf;
- }
-
-
- if(Lookup(tr, accents_tab[accent1].name, ph_accent1) != 0)
- {
-
- if(LookupLetter2(tr, basic_letter, ph_letter1) != 0)
- {
- if(accent2 != 0)
- {
- if(Lookup(tr, accents_tab[accent2].name, ph_accent2) == 0)
- {
-// break;
- }
-
- if(accents_tab[accent2].flags & 1)
- {
- strcpy(ph_buf,ph_accent2);
- ph_buf += strlen(ph_buf);
- ph_accent2[0] = 0;
- }
- }
- if(letter2 != 0)
- {
- //ligature
- LookupLetter2(tr, letter2, ph_letter2);
- sprintf(ph_buf,"%s%c%s%c%s%s",ph_accent1, phonPAUSE_VSHORT, ph_letter1, phonSTRESS_P, ph_letter2, ph_accent2);
- }
- else
- {
- if(accent1 == 0)
- strcpy(ph_buf, ph_letter1);
- else
- if((tr->langopts.accents & 1) || (accents_tab[accent1].flags & 1))
- sprintf(ph_buf,"%s%c%c%s", ph_accent1, phonPAUSE_VSHORT, phonSTRESS_P, ph_letter1);
- else
- sprintf(ph_buf,"%c%s%c%s%c", phonSTRESS_2, ph_letter1, phonPAUSE_VSHORT, ph_accent1, phonPAUSE_VSHORT);
- }
- }
- }
- }
-} // end of LookupAccentedLetter
-
-
-
-void LookupLetter(Translator *tr, unsigned int letter, int next_byte, char *ph_buf1)
-{//=================================================================================
- int len;
- unsigned char *p;
- static char single_letter[10] = {0,0};
- char ph_stress[2];
- unsigned int dict_flags[2];
- char ph_buf3[40];
- char *ptr;
-
- ph_buf1[0] = 0;
- len = utf8_out(letter,&single_letter[2]);
- single_letter[len+2] = ' ';
-
- if(next_byte == -1)
- {
- // speaking normal text, not individual characters
- if(Lookup(tr, &single_letter[2], ph_buf1) != 0)
- return;
-
- single_letter[1] = '_';
- if(Lookup(tr, &single_letter[1], ph_buf3) != 0)
- return; // the character is specified as _* so ignore it when speaking normal text
-
- // check whether this character is specified for English
- if(tr->translator_name == L('e','n'))
- return; // we are already using English
-
- SetTranslator2("en");
- if(Lookup(translator2, &single_letter[2], ph_buf3) != 0)
- {
- // yes, switch to English and re-translate the word
- sprintf(ph_buf1,"%c",phonSWITCH);
- }
- SelectPhonemeTable(voice->phoneme_tab_ix); // revert to original phoneme table
- return;
- }
-
- if((letter <= 32) || iswspace(letter))
- {
- // lookup space as _&32 etc.
- sprintf(&single_letter[1],"_#%d ",letter);
- Lookup(tr, &single_letter[1], ph_buf1);
- return;
- }
-
- if(next_byte != ' ')
- next_byte = RULE_SPELLING;
- single_letter[3+len] = next_byte; // follow by space-space if the end of the word, or space-0x31
-
- single_letter[1] = '_';
-
- // if the $accent flag is set for this letter, use the accents table (below)
- dict_flags[1] = 0;
- ptr = &single_letter[1];
-
- if(Lookup(tr, &single_letter[1], ph_buf3) == 0)
- {
- single_letter[1] = ' ';
- if(Lookup(tr, &single_letter[2], ph_buf3) == 0)
- {
- TranslateRules(tr, &single_letter[2], ph_buf3, sizeof(ph_buf3), NULL,FLAG_NO_TRACE,NULL);
- }
- }
-
- if(ph_buf3[0] == 0)
- {
- LookupAccentedLetter(tr, letter, ph_buf3);
- }
-
- if(ph_buf3[0] == 0)
- {
- ph_buf1[0] = 0;
- return;
- }
- if(ph_buf3[0] == phonSWITCH)
- {
- strcpy(ph_buf1,ph_buf3);
- return;
- }
- // at a stress marker at the start of the letter name, unless one is already marked
- ph_stress[0] = phonSTRESS_P;
- ph_stress[1] = 0;
-
- for(p=(unsigned char *)ph_buf3; *p != 0; p++)
- {
- if(phoneme_tab[*p]->type == phSTRESS)
- ph_stress[0] = 0; // stress is already marked
- }
- sprintf(ph_buf1,"%s%s",ph_stress,ph_buf3);
-}
-
-
-
-int TranslateLetter(Translator *tr, char *word, char *phonemes, int control, int word_length)
-{//======================================================================================
-// get pronunciation for an isolated letter
-// return number of bytes used by the letter
-// control 2=say-as glyphs, 3-say-as chars
- int n_bytes;
- int letter;
- int len;
- int save_option_phonemes;
- char *p2;
- char *pbuf;
- char capital[20];
- char ph_buf[60];
- char ph_buf2[60];
- char hexbuf[6];
-
- ph_buf[0] = 0;
- capital[0] = 0;
-
- n_bytes = utf8_in(&letter,word);
-
- if((letter & 0xfff00) == 0x0e000)
- {
- letter &= 0xff; // uncode private usage area
- }
-
- if(control > 2)
- {
- // include CAPITAL information
- if(iswupper(letter))
- {
- Lookup(tr, "_cap", capital);
- }
- }
- letter = towlower2(letter);
-
- LookupLetter(tr, letter, word[n_bytes], ph_buf);
-
- if(ph_buf[0] == phonSWITCH)
- {
- strcpy(phonemes,ph_buf);
- return(0);
- }
-
- if((ph_buf[0] == 0) && (tr->translator_name != L('e','n')))
- {
- // speak as English, check whether there is a translation for this character
- SetTranslator2("en");
- save_option_phonemes = option_phonemes;
- option_phonemes = 0;
- LookupLetter(translator2, letter, word[n_bytes], ph_buf);
- SelectPhonemeTable(voice->phoneme_tab_ix); // revert to original phoneme table
- option_phonemes = save_option_phonemes;
-
- if(ph_buf[0] != 0)
- {
- sprintf(phonemes,"%cen",phonSWITCH);
- return(0);
- }
- }
-
- if(ph_buf[0] == 0)
- {
- // character name not found
- if(iswalpha(letter))
- Lookup(tr, "_?A", ph_buf);
-
- if((ph_buf[0]==0) && !iswspace(letter))
- Lookup(tr, "_??", ph_buf);
-
- if(ph_buf[0] != 0)
- {
- // speak the hexadecimal number of the character code
- sprintf(hexbuf,"%x",letter);
- pbuf = ph_buf;
- for(p2 = hexbuf; *p2 != 0; p2++)
- {
- pbuf += strlen(pbuf);
- *pbuf++ = phonPAUSE_VSHORT;
- LookupLetter(tr, *p2, 0, pbuf);
- }
- }
- }
-
- len = strlen(phonemes);
- if(tr->langopts.accents & 2)
- sprintf(ph_buf2,"%c%s%s",0xff,ph_buf,capital);
- else
- sprintf(ph_buf2,"%c%s%s",0xff,capital,ph_buf); // the 0xff marker will be removed or replaced in SetSpellingStress()
- if((len + strlen(ph_buf2)) < N_WORD_PHONEMES)
- {
- strcpy(&phonemes[len],ph_buf2);
- }
- return(n_bytes);
-} // end of TranslateLetter
-
-
-
-void SetSpellingStress(Translator *tr, char *phonemes, int control, int n_chars)
-{//=============================================================================
-// Individual letter names, reduce the stress of some.
- int ix;
- unsigned int c;
- int n_stress=0;
- int count;
- unsigned char buf[N_WORD_PHONEMES];
-
- for(ix=0; (c = phonemes[ix]) != 0; ix++)
- {
- if(c == phonSTRESS_P)
- {
- n_stress++;
- }
- buf[ix] = c;
- }
- buf[ix] = 0;
-
- count = 0;
- for(ix=0; (c = buf[ix]) != 0; ix++)
- {
- if((c == phonSTRESS_P) && (n_chars > 1))
- {
- count++;
-
- if(tr->langopts.spelling_stress == 1)
- {
- // stress on initial letter when spelling
- if(count > 1)
- c = phonSTRESS_3;
- }
- else
- {
- if(count != n_stress)
- {
- if(((count % 3) != 0) || (count == n_stress-1))
- c = phonSTRESS_3; // reduce to secondary stress
- }
- }
- }
- else
- if(c == 0xff)
- {
- if((control < 2) || (ix==0))
- continue; // don't insert pauses
-
- if(control == 4)
- c = phonPAUSE; // pause after each character
- if(((count % 3) == 0) || (control > 2))
- c = phonPAUSE_SHORT; // pause following a primary stress
- else
- continue; // remove marker
- }
- *phonemes++ = c;
- }
- if(control >= 2)
- *phonemes++ = phonPAUSE_NOLINK;
- *phonemes = 0;
-} // end of SetSpellingStress
-
-
-
-// Numbers
-
-static char ph_ordinal2[12];
-
-int TranslateRoman(Translator *tr, char *word, char *ph_out)
-{//=====================================================
- int c;
- char *p;
- const char *p2;
- int acc;
- int prev;
- int value;
- int subtract;
- int repeat = 0;
- unsigned int flags;
- char ph_roman[30];
- char number_chars[N_WORD_BYTES];
-
- static const char *roman_numbers = "ixcmvld";
- static int roman_values[] = {1,10,100,1000,5,50,500};
-
- acc = 0;
- prev = 0;
- subtract = 0x7fff;
-
- while((c = *word++) != ' ')
- {
- if((p2 = strchr(roman_numbers,c)) == NULL)
- return(0);
-
- value = roman_values[p2 - roman_numbers];
- if(value == prev)
- {
- repeat++;
- if(repeat >= 3)
- return(0);
- }
- else
- repeat = 0;
-
- if((prev > 1) && (prev != 10) && (prev != 100))
- {
- if(value >= prev)
- return(0);
- }
- if((prev != 0) && (prev < value))
- {
- if(((acc % 10) != 0) || ((prev*10) < value))
- return(0);
- subtract = prev;
- value -= subtract;
- }
- else
- if(value >= subtract)
- return(0);
- else
- acc += prev;
- prev = value;
- }
- acc += prev;
- if(acc < 2)
- return(0);
-
- if(acc > tr->langopts.max_roman)
- return(0);
-
- Lookup(tr, "_roman",ph_roman); // precede by "roman" if _rom is defined in *_list
- p = &ph_out[0];
-
- if((tr->langopts.numbers & NUM_ROMAN_AFTER) == 0)
- {
- strcpy(ph_out,ph_roman);
- p = &ph_out[strlen(ph_out)];
- }
-
- sprintf(number_chars," %d ",acc);
- TranslateNumber(tr, &number_chars[1], p, &flags, 0);
-
- if(tr->langopts.numbers & NUM_ROMAN_AFTER)
- strcat(ph_out,ph_roman);
- return(1);
-} // end of TranslateRoman
-
-
-static const char *M_Variant(int value)
-{//====================================
- // returns M, or perhaps MA for some cases
-
- if((translator->langopts.numbers2 & 0x100) && (value >= 2) && (value <= 4))
- return("0MA"); // Czech, Slovak
- else
- if(((value % 100) < 10) || ((value % 100) > 20)) // but not teens, 10 to 19
- {
- if ((translator->langopts.numbers2 & 0x40) &&
- ((value % 10)>=2) &&
- ((value % 10)<=4))
- {
- // for Polish language - two forms of plural!
- return("0MA");
- }
-
- if((translator->langopts.numbers2 & 0x80) &&
- ((value % 10)==1))
- {
- return("1MA");
- }
-
- }
- return("0M");
-}
-
-
-static int LookupThousands(Translator *tr, int value, int thousandplex, char *ph_out)
-{//==================================================================================
- int found;
- char string[12];
- char ph_of[12];
- char ph_thousands[40];
-
- ph_of[0] = 0;
-
- // first look fora match with the exact value of thousands
- sprintf(string,"_%dM%d",value,thousandplex);
-
- if((found = Lookup(tr, string, ph_thousands)) == 0)
- {
- if((value % 100) >= 20)
- {
- Lookup(tr, "_0of", ph_of);
- }
-
- sprintf(string,"_%s%d",M_Variant(value),thousandplex);
-
- if(Lookup(tr, string, ph_thousands) == 0)
- {
- // repeat "thousand" if higher order names are not available
- sprintf(string,"_%dM1",value);
- if((found = Lookup(tr, string, ph_thousands)) == 0)
- Lookup(tr, "_0M1", ph_thousands);
- }
- }
- sprintf(ph_out,"%s%s",ph_of,ph_thousands);
- return(found);
-}
-
-
-static int LookupNum2(Translator *tr, int value, int control, char *ph_out)
-{//========================================================================
-// Lookup a 2 digit number
-// control bit 0: tens and units (use special form of '1')
-// control bit 1: ordinal number
-// control bit 2: use feminine form of '2'
-// control bit 3: speak zero tens
-
- int found;
- int ix;
- int units;
- int used_and=0;
- int found_ordinal = 0;
- int next_phtype;
- char string[12]; // for looking up entries in *_list
- char ph_ordinal[20];
- char ph_tens[50];
- char ph_digits[50];
- char ph_and[12];
-
- // is there a special pronunciation for this 2-digit number
- found = 0;
- ph_ordinal[0] = 0;
-
- if(control & 4)
- {
- sprintf(string,"_%df",value);
- found = Lookup(tr, string, ph_digits);
- }
- if(control & 2)
- {
- strcpy(ph_ordinal, ph_ordinal2);
-
- sprintf(string,"_%do",value);
- if((found = Lookup(tr, string, ph_digits)) != 0)
- {
- found_ordinal = 1;
- }
- }
-
- if(found == 0)
- {
- if((value == 1) && (control & 1))
- {
- if(Lookup(tr, "_1a", ph_out) != 0)
- return(0);
- }
- sprintf(string,"_%d",value);
- found = Lookup(tr, string, ph_digits);
- }
-
- // no, speak as tens+units
-
- if((control & 8) && (value < 10))
- {
- // speak leading zero
- Lookup(tr, "_0", ph_tens);
- }
- else
- {
- if(found)
- {
- ph_tens[0] = 0;
- }
- else
- {
- units = (value % 10);
-
- if((control & 2) && ((units == 0) || (tr->langopts.numbers & 0x10)))
- {
- sprintf(string,"_%dXo",value / 10);
- if(Lookup(tr, string, ph_tens) != 0)
- {
- found_ordinal = 1;
- }
- }
- if(found_ordinal == 0)
- {
- sprintf(string,"_%dX",value / 10);
- Lookup(tr, string, ph_tens);
- }
-
- if((ph_tens[0] == 0) && (tr->langopts.numbers & NUM_VIGESIMAL))
- {
- // tens not found, (for example) 73 is 60+13
- units = (value % 20);
- sprintf(string,"_%dX",(value / 10) & 0xfe);
- Lookup(tr, string, ph_tens);
- }
-
- ph_digits[0] = 0;
- if(units > 0)
- {
- found = 0;
- if(control & 4)
- {
- // is there a variant form of this number?
- sprintf(string,"_%df",units);
- found = Lookup(tr, string, ph_digits);
- }
- if((control & 2) && ((tr->langopts.numbers & 0x10) == 0))
- {
- // ordinal
- sprintf(string,"_%do",units);
- if((found = Lookup(tr, string, ph_digits)) != 0)
- {
- found_ordinal = 1;
- }
- }
- if(found == 0)
- {
- sprintf(string,"_%d",units);
- Lookup(tr, string, ph_digits);
- }
- }
- }
- }
-
- if((control & 2) && (found_ordinal == 0) && (ph_ordinal[0] == 0))
- {
- if((value >= 20) && (((value % 10) == 0) || (tr->langopts.numbers & 0x10)))
- Lookup(tr, "_ord20", ph_ordinal);
- if(ph_ordinal[0] == 0)
- Lookup(tr, "_ord", ph_ordinal);
- }
-
- if((tr->langopts.numbers & 0x30) && (ph_tens[0] != 0) && (ph_digits[0] != 0))
- {
- Lookup(tr, "_0and", ph_and);
- if(tr->langopts.numbers & 0x10)
- sprintf(ph_out,"%s%s%s%s",ph_digits, ph_and, ph_tens, ph_ordinal);
- else
- sprintf(ph_out,"%s%s%s%s",ph_tens, ph_and, ph_digits, ph_ordinal);
- used_and = 1;
- }
- else
- {
- if(tr->langopts.numbers & 0x200)
- {
- // remove vowel from the end of tens if units starts with a vowel (LANG=Italian)
- if(((ix = strlen(ph_tens)-1) >= 0) && (ph_digits[0] != 0))
- {
- if((next_phtype = phoneme_tab[(unsigned int)(ph_digits[0])]->type) == phSTRESS)
- next_phtype = phoneme_tab[(unsigned int)(ph_digits[1])]->type;
-
- if((phoneme_tab[(unsigned int)(ph_tens[ix])]->type == phVOWEL) && (next_phtype == phVOWEL))
- ph_tens[ix] = 0;
- }
- }
- sprintf(ph_out,"%s%s%s",ph_tens, ph_digits, ph_ordinal);
- }
-
- if(tr->langopts.numbers & 0x100)
- {
- // only one primary stress
- found = 0;
- for(ix=strlen(ph_out)-1; ix>=0; ix--)
- {
- if(ph_out[ix] == phonSTRESS_P)
- {
- if(found)
- ph_out[ix] = phonSTRESS_3;
- else
- found = 1;
- }
- }
- }
- return(used_and);
-} // end of LookupNum2
-
-
-static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null, int thousandplex, int control)
-{//=============================================================================================================
-// Translate a 3 digit number
-// control bit 0, previous thousands
-// bit 1, ordinal number
- int found;
- int hundreds;
- int x;
- char string[12]; // for looking up entries in **_list
- char buf1[100];
- char buf2[100];
- char ph_100[20];
- char ph_10T[20];
- char ph_digits[50];
- char ph_thousands[50];
- char ph_hundred_and[12];
- char ph_thousand_and[12];
-
- hundreds = value / 100;
- buf1[0] = 0;
-
- if(hundreds > 0)
- {
- ph_thousands[0] = 0;
- ph_thousand_and[0] = 0;
-
- found = 0;
- if((control & 2) && ((value % 100) == 0))
- {
- // ordinal number, with no tens or units
- found = Lookup(tr, "_0Co", ph_100);
- }
- if(found == 0)
- {
- Lookup(tr, "_0C", ph_100);
- }
-
- if(((tr->langopts.numbers & 0x0800) != 0) && (hundreds == 19))
- {
- // speak numbers such as 1984 as years: nineteen-eighty-four
-// ph_100[0] = 0; // don't say "hundred", we also need to surpess "and"
- }
- else
- if(hundreds >= 10)
- {
- ph_digits[0] = 0;
-
- if(LookupThousands(tr, hundreds / 10, thousandplex+1, ph_10T) == 0)
- {
- x = 0;
- if(tr->langopts.numbers2 & (1 << (thousandplex+1)))
- x = 4;
- LookupNum2(tr, hundreds/10, x, ph_digits);
- }
-
- if(tr->langopts.numbers2 & 0x200)
- sprintf(ph_thousands,"%s%s%c",ph_10T,ph_digits,phonPAUSE_NOLINK); // say "thousands" before its number, not after
- else
- sprintf(ph_thousands,"%s%s%c",ph_digits,ph_10T,phonPAUSE_NOLINK);
-
- hundreds %= 10;
- if(hundreds == 0)
- ph_100[0] = 0;
- suppress_null = 1;
- }
-
- ph_digits[0] = 0;
- if(hundreds > 0)
- {
- if((tr->langopts.numbers & 0x100000) && ((control & 1) || (ph_thousands[0] != 0)))
- {
- Lookup(tr, "_0and", ph_thousand_and);
- }
-
- suppress_null = 1;
-
- found = 0;
- if((value % 1000) == 100)
- {
- // is there a special pronunciation for exactly 100 ?
- found = Lookup(tr, "_1C0", ph_digits);
- }
- if(!found)
- {
- sprintf(string,"_%dC",hundreds);
- found = Lookup(tr, string, ph_digits); // is there a specific pronunciation for n-hundred ?
- }
-
- if(found)
- {
- ph_100[0] = 0;
- }
- else
- {
- if((hundreds > 1) || ((tr->langopts.numbers & 0x400) == 0))
- {
- LookupNum2(tr, hundreds, 0, ph_digits);
- }
- }
- }
-
- sprintf(buf1,"%s%s%s%s",ph_thousands,ph_thousand_and,ph_digits,ph_100);
- }
-
- ph_hundred_and[0] = 0;
- if((tr->langopts.numbers & 0x40) && ((value % 100) != 0))
- {
- if((value > 100) || ((control & 1) && (thousandplex==0)))
- {
- Lookup(tr, "_0and", ph_hundred_and);
- }
- }
-
-
- buf2[0] = 0;
- value = value % 100;
-
- if((value != 0) || (suppress_null == 0))
- {
- x = 0;
- if(thousandplex==0)
- {
- x = 1; // allow "eins" for 1 rather than "ein"
- if(control & 2)
- x = 3; // ordinal number
- }
- else
- {
- if(tr->langopts.numbers2 & (1 << thousandplex))
- x = 4; // use variant (feminine) for before thousands and millions
- }
-
- if(LookupNum2(tr, value, x, buf2) != 0)
- {
- if(tr->langopts.numbers & 0x80)
- ph_hundred_and[0] = 0; // don't put 'and' after 'hundred' if there's 'and' between tens and units
- }
- }
-
- sprintf(ph_out,"%s%s%s",buf1,ph_hundred_and,buf2);
-
- return(0);
-} // end of LookupNum3
-
-
-static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned int *flags, int wflags)
-{//====================================================================================================
-// Number translation with various options
-// the "word" may be up to 4 digits
-// "words" of 3 digits may be preceded by another number "word" for thousands or millions
-
- int n_digits;
- int value;
- unsigned int ix;
- unsigned char c;
- int suppress_null = 0;
- int decimal_point = 0;
- int thousandplex = 0;
- int thousands_inc = 0;
- int prev_thousands = 0;
- int ordinal = 0;
- int this_value;
- static int prev_value;
- int decimal_count;
- int max_decimal_count;
- int decimal_mode;
- int hyphen;
- char *p;
- char string[20]; // for looking up entries in **_list
- char buf1[100];
- char ph_append[50];
- char ph_buf[200];
- char ph_buf2[50];
- char suffix[20];
-
- static const char str_pause[2] = {phonPAUSE_NOLINK,0};
-
- *flags = 0;
-
- for(ix=0; isdigit(word[ix]); ix++) ;
- n_digits = ix;
- value = this_value = atoi(word);
-
- ph_ordinal2[0] = 0;
- if((tr->langopts.numbers & 0x10000) && (word[ix] == '.') && !isdigit(word[ix+2]))
- {
- // ordinal number is indicated by dot after the number
- ordinal = 2;
- word[ix] = ' ';
- }
- else
- {
- // look for an ordinal number suffix after the number
- ix++;
- hyphen = 0;
- p = suffix;
- if(word[ix] == '-')
- {
- *p++ = '-';
- hyphen = 1;
- ix += 2;
- }
- while((word[ix] != 0) && (word[ix] != ' ') && (ix < (sizeof(suffix)-1)))
- {
- *p++ = word[ix++];
- }
- *p = 0;
-
- if(suffix[0] != 0)
- {
- sprintf(string,"_0%s",suffix);
- if(Lookup(tr, string, ph_ordinal2))
- {
- // this is an ordinal suffix
- ordinal = 2;
- flags[0] |= FLAG_SKIPWORDS;
- dictionary_skipwords = 1 + hyphen;
- }
- }
- }
-
- ph_append[0] = 0;
- ph_buf2[0] = 0;
-
- // is there a previous thousands part (as a previous "word") ?
- if((n_digits == 3) && (word[-2] == tr->langopts.thousands_sep) && isdigit(word[-3]))
- {
- prev_thousands = 1;
- }
- else
- if((tr->langopts.thousands_sep == ' ') || (tr->langopts.numbers & 0x1000))
- {
- // thousands groups can be separated by spaces
- if((n_digits == 3) && isdigit(word[-2]))
- {
- prev_thousands = 1;
- }
- }
-
- if((word[0] == '0') && (prev_thousands == 0) && (word[1] != ' ') && (word[1] != tr->langopts.decimal_sep))
- {
- if((n_digits == 2) && (word[3] == ':') && isdigit(word[5]) && isspace(word[7]))
- {
- // looks like a time 02:30, omit the leading zero
- }
- else
- {
- return(0); // number string with leading zero, speak as individual digits
- }
- }
-
- if((tr->langopts.numbers & 0x1000) && (word[n_digits] == ' '))
- thousands_inc = 1;
- else
- if(word[n_digits] == tr->langopts.thousands_sep)
- thousands_inc = 2;
-
- if(thousands_inc > 0)
- {
- // if the following "words" are three-digit groups, count them and add
- // a "thousand"/"million" suffix to this one
-
- ix = n_digits + thousands_inc;
- while(isdigit(word[ix]) && isdigit(word[ix+1]) && isdigit(word[ix+2]))
- {
- thousandplex++;
- if(word[ix+3] == tr->langopts.thousands_sep)
- ix += (3 + thousands_inc);
- else
- break;
- }
- }
-
- if((value == 0) && prev_thousands)
- {
- suppress_null = 1;
- }
-
- if((word[n_digits] == tr->langopts.decimal_sep) && isdigit(word[n_digits+1]))
- {
- // this "word" ends with a decimal point
- Lookup(tr, "_dpt", ph_append);
- decimal_point = 1;
- }
- else
- if(suppress_null == 0)
- {
- if(thousands_inc > 0)
- {
- if((thousandplex > 0) && (value < 1000))
- {
- if((suppress_null == 0) && (LookupThousands(tr,value,thousandplex,ph_append)))
- {
- // found an exact match for N thousand
- value = 0;
- suppress_null = 1;
- }
- }
- }
- }
- else
- if((thousandplex > 1) && prev_thousands && (prev_value > 0))
- {
- sprintf(string,"_%s%d",M_Variant(value),thousandplex+1);
- if(Lookup(tr, string, buf1)==0)
- {
- // speak this thousandplex if there was no word for the previous thousandplex
- sprintf(string,"_0M%d",thousandplex);
- Lookup(tr, string, ph_append);
- }
- }
-
- if((ph_append[0] == 0) && (word[n_digits] == '.') && (thousandplex == 0))
- {
- Lookup(tr, "_.", ph_append);
- }
-
- LookupNum3(tr, value, ph_buf, suppress_null, thousandplex, prev_thousands | ordinal);
- if((thousandplex > 0) && (tr->langopts.numbers2 & 0x200))
- sprintf(ph_out,"%s%s%s",ph_append,ph_buf2,ph_buf); // say "thousands" before its number
- else
- sprintf(ph_out,"%s%s%s",ph_buf2,ph_buf,ph_append);
-
-
- while(decimal_point)
- {
- n_digits++;
-
- decimal_count = 0;
- while(isdigit(word[n_digits+decimal_count]))
- decimal_count++;
-
- if(decimal_count > 1)
- {
- max_decimal_count = 2;
- switch(decimal_mode = (tr->langopts.numbers & 0xe000))
- {
- case 0x8000:
- max_decimal_count = 5;
- case 0x4000:
- // French/Polish decimal fraction
- while(word[n_digits] == '0')
- {
- Lookup(tr, "_0", buf1);
- strcat(ph_out,buf1);
- decimal_count--;
- n_digits++;
- }
- if((decimal_count <= max_decimal_count) && isdigit(word[n_digits]))
- {
- LookupNum3(tr, atoi(&word[n_digits]), buf1, 0,0,0);
- strcat(ph_out,buf1);
- n_digits += decimal_count;
- }
- break;
-
- case 0x2000:
- case 0xa000:
- // Italian decimal fractions
- if(decimal_count <= 4)
- {
- LookupNum3(tr, atoi(&word[n_digits]), ph_buf, 0,0,0);
- if((word[n_digits]=='0') || (decimal_mode == 0xa000))
- {
- // decimal part has leading zeros, so add a "hundredths" or "thousandths" suffix
- sprintf(string,"_0Z%d",decimal_count);
- if(Lookup(tr, string, buf1) == 0)
- break; // revert to speaking single digits
-
- strcat(ph_buf,buf1);
- }
- strcat(ph_out,ph_buf);
- n_digits += decimal_count;
- }
- break;
-
- case 0x6000:
- // Romanian decimal fractions
- if((decimal_count <= 4) && (word[n_digits] != '0'))
- {
- LookupNum3(tr, atoi(&word[n_digits]), buf1, 0,0,0);
- strcat(ph_out,buf1);
- n_digits += decimal_count;
- }
- break;
- }
- }
-
- while(isdigit(c = word[n_digits]) && (strlen(ph_out) < (N_WORD_PHONEMES - 10)))
- {
- value = word[n_digits++] - '0';
- LookupNum2(tr, value, 1, buf1);
- strcat(ph_out,buf1);
- }
-
- // something after the decimal part ?
- if(Lookup(tr, "_dpt2", buf1))
- strcat(ph_out,buf1);
-
- if((c == tr->langopts.decimal_sep) && isdigit(word[n_digits+1]))
- {
- Lookup(tr, "_dpt", buf1);
- strcat(ph_out,buf1);
- }
- else
- {
- decimal_point = 0;
- }
- }
- if((ph_out[0] != 0) && (ph_out[0] != phonSWITCH))
- {
- int next_char;
- char *p;
- p = &word[n_digits+1];
-
- p += utf8_in(&next_char,p);
- if((tr->langopts.numbers & NUM_NOPAUSE) && (next_char == ' '))
- utf8_in(&next_char,p);
-
- if(!iswalpha(next_char))
- strcat(ph_out,str_pause); // don't add pause for 100s, 6th, etc.
- }
-
- *flags |= FLAG_FOUND;
- prev_value = this_value;
- return(1);
-} // end of TranslateNumber_1
-
-
-
-int TranslateNumber(Translator *tr, char *word1, char *ph_out, unsigned int *flags, int wflags)
-{//============================================================================================
- if(option_sayas == SAYAS_DIGITS1)
- return(0); // speak digits individually
-
- if((tr->langopts.numbers & 0x3) == 1)
- return(TranslateNumber_1(tr, word1, ph_out, flags, wflags));
-
- return(0);
-} // end of TranslateNumber
-
diff --git a/navit/support/espeak/phoneme.h b/navit/support/espeak/phoneme.h
deleted file mode 100755
index 596f457ef..000000000
--- a/navit/support/espeak/phoneme.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2005 to 2007 by Jonathan Duddington *
- * email: jonsd@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, see: *
- * <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-
-
-// phoneme types
-#define phPAUSE 0
-#define phSTRESS 1
-#define phVOWEL 2
-#define phLIQUID 3
-#define phSTOP 4
-#define phVSTOP 5
-#define phFRICATIVE 6
-#define phVFRICATIVE 7
-#define phNASAL 8
-#define phVIRTUAL 9
-#define phDELETED 14
-#define phINVALID 15
-
-
-// phoneme properties
-// bits 16-19 give place of articulation (not currently used)
-#define phWAVE 0x01
-#define phUNSTRESSED 0x02
-#define phFORTIS 0x08
-#define phVOICED 0x10
-#define phSIBILANT 0x20
-#define phNOLINK 0x40
-#define phTRILL 0x80
-#define phVOWEL2 0x100 // liquid that is considered a vowel
-#define phPALATAL 0x200
-#define phAPPENDPH 0x2000 // always insert another phoneme (link_out) after this one
-#define phBRKAFTER 0x4000 // [*] add a post-pause
-#define phBEFOREPAUSE 0x8000 // replace with the link_out phoneme if the next phoneme is a pause
-
-#define phALTERNATIVE 0x1c00 // bits 10,11,12 specifying use of alternative_ph
-#define phBEFOREVOWEL 0x0000
-#define phBEFOREVOWELPAUSE 0x0400
-#define phBEFORENOTVOWEL 0x0c00
-#define phBEFORENOTVOWEL2 0x1000
-#define phSWITCHVOICING 0x0800
-#define phBEFORE_R 0x1400
-
-#define phNONSYLLABIC 0x100000 // don't count this vowel as a syllable when finding the stress position
-#define phLONG 0x200000
-#define phLENGTHENSTOP 0x400000 // make the pre-pause slightly longer
-#define phRHOTIC 0x800000
-
-// fixed phoneme code numbers, these can be used from the program code
-#define phonCONTROL 1
-#define phonSTRESS_U 2
-#define phonSTRESS_D 3
-#define phonSTRESS_2 4
-#define phonSTRESS_3 5
-#define phonSTRESS_P 6
-#define phonSTRESS_P2 7 // priority stress within a word
-#define phonSTRESS_PREV 8
-#define phonPAUSE 9
-#define phonPAUSE_SHORT 10
-#define phonPAUSE_NOLINK 11
-#define phonLENGTHEN 12
-#define phonSCHWA 13
-#define phonSCHWA_SHORT 14
-#define phonEND_WORD 15
-#define phonSONORANT 16
-#define phonDEFAULTTONE 17
-#define phonCAPITAL 18
-#define phonGLOTTALSTOP 19
-#define phonSYLLABIC 20
-#define phonSWITCH 21
-#define phonX1 22 // a language specific action
-#define phonPAUSE_VSHORT 23
-#define phonPAUSE_LONG 24
-#define phonT_REDUCED 25
-#define phonSTRESS_TONIC 26
-#define phonPAUSE_CLAUSE 27
-
-extern const unsigned char pause_phonemes[8]; // 0, vshort, short, pause, long, glottalstop
-
-// place of articulation
-#define phPLACE 0xf0000
-#define phPLACE_pla 0x60000
-
-#define N_PHONEME_TABS 100 // number of phoneme tables
-#define N_PHONEME_TAB 256 // max phonemes in a phoneme table
-#define N_PHONEME_TAB_NAME 32 // must be multiple of 4
-
-// main table of phonemes, index by phoneme number (1-254)
-typedef struct {
- unsigned int mnemonic; // 1st char is in the l.s.byte
- unsigned int phflags; // bits 28-30 reduce_to level, bits 16-19 place of articulation
- // bits 10-11 alternative ph control
-
- unsigned short std_length; // for vowels, in mS; for phSTRESS, the stress/tone type
- unsigned short spect;
- unsigned short before;
- unsigned short after;
-
- unsigned char code; // the phoneme number
- unsigned char type; // phVOWEL, phPAUSE, phSTOP etc
- unsigned char start_type;
- unsigned char end_type;
-
- unsigned char length_mod; // a length_mod group number, used to access length_mod_tab
- unsigned char reduce_to; // change to this phoneme if unstressed
- unsigned char alternative_ph; // change to this phoneme if a vowel follows/doesn't follow
- unsigned char link_out; // insert linking phoneme if a vowel follows
-
-} PHONEME_TAB;
-
-
-// Several phoneme tables may be loaded into memory. phoneme_tab points to
-// one for the current voice
-extern int n_phoneme_tab;
-extern int current_phoneme_table;
-extern PHONEME_TAB *phoneme_tab[N_PHONEME_TAB];
-extern unsigned char phoneme_tab_flags[N_PHONEME_TAB]; // bit 0: not inherited
-
-typedef struct {
- char name[N_PHONEME_TAB_NAME];
- PHONEME_TAB *phoneme_tab_ptr;
- int n_phonemes;
- int includes; // also include the phonemes from this other phoneme table
-} PHONEME_TAB_LIST;
-
-
-
-// table of phonemes to be replaced with different phonemes, for the current voice
-#define N_REPLACE_PHONEMES 60
-typedef struct {
- unsigned char old_ph;
- unsigned char new_ph;
- char type; // 0=always replace, 1=only at end of word
-} REPLACE_PHONEMES;
-
-extern int n_replace_phonemes;
-extern REPLACE_PHONEMES replace_phonemes[N_REPLACE_PHONEMES];
-
-
-#define PH(c1,c2) (c2<<8)+c1 // combine two characters into an integer for phoneme name
-#define PH3(c1,c2,c3) (c3<<16)+(c2<<8)+c1
-#define PhonemeCode2(c1,c2) PhonemeCode((c2<<8)+c1)
-int LookupPhonemeString(const char *string);
-int PhonemeCode(unsigned int mnem);
-
-char *EncodePhonemes(char *p, char *outptr, unsigned char *bad_phoneme);
-void DecodePhonemes(const char *inptr, char *outptr);
-
-extern const char *WordToString(unsigned int word);
-
-extern PHONEME_TAB_LIST phoneme_tab_list[N_PHONEME_TABS];
-extern int phoneme_tab_number;
diff --git a/navit/support/espeak/phonemelist.c b/navit/support/espeak/phonemelist.c
deleted file mode 100755
index d663e2e94..000000000
--- a/navit/support/espeak/phonemelist.c
+++ /dev/null
@@ -1,686 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2005 to 2007 by Jonathan Duddington *
- * email: jonsd@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, see: *
- * <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-#include "StdAfx.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "speak_lib.h"
-#include "speech.h"
-#include "phoneme.h"
-#include "synthesize.h"
-#include "translate.h"
-
-
-const unsigned char pause_phonemes[8] = {0, phonPAUSE_VSHORT, phonPAUSE_SHORT, phonPAUSE, phonPAUSE_LONG, phonGLOTTALSTOP, phonPAUSE_LONG, phonPAUSE_LONG};
-
-
-extern int n_ph_list2;
-extern PHONEME_LIST2 ph_list2[N_PHONEME_LIST]; // first stage of text->phonemes
-
-
-
-static int ChangePhonemes(Translator *tr, PHONEME_LIST2 *phlist, int n_ph, int index, PHONEME_TAB *ph, CHANGEPH *ch)
-{//=================================================================================================================
-// Called for each phoneme in the phoneme list, to allow a language to make changes
-// ph The current phoneme
-
- if(tr->translator_name == L('r','u'))
- return(ChangePhonemes_ru(tr, phlist, n_ph, index, ph, ch));
-
- return(0);
-}
-
-
-static int SubstitutePhonemes(Translator *tr, PHONEME_LIST2 *plist_out)
-{//====================================================================
-// Copy the phonemes list and perform any substitutions that are required for the
-// current voice
- int ix;
- int k;
- int replace_flags;
- int n_plist_out = 0;
- int word_end;
- int max_stress = -1;
- int switched_language = 0;
- int max_stress_posn=0;
- int n_syllables = 0;
- int syllable = 0;
- int syllable_stressed = 0;
- PHONEME_LIST2 *plist2;
- PHONEME_LIST2 *pl;
- PHONEME_TAB *next=NULL;
-
- for(ix=0; (ix < n_ph_list2) && (n_plist_out < N_PHONEME_LIST); ix++)
- {
- plist2 = &ph_list2[ix];
-
- if(plist2->phcode == phonSWITCH)
- switched_language ^= 1;
-
- // don't do any substitution if the language has been temporarily changed
- if(switched_language == 0)
- {
- if(ix < (n_ph_list2 -1))
- next = phoneme_tab[ph_list2[ix+1].phcode];
-
- word_end = 0;
- if((plist2+1)->sourceix || ((next != 0) && (next->type == phPAUSE)))
- word_end = 1; // this phoneme is the end of a word
-
- if(tr->langopts.phoneme_change != 0)
- {
- // this language does changes to phonemes after translation
- int flags;
- CHANGEPH ch;
- if(plist2->sourceix)
- {
- // start of a word, find the stressed vowel
- syllable = 0;
- syllable_stressed = 0;
- n_syllables = 0;
-
- max_stress = -1;
- max_stress_posn = ix;
- for(k=ix; k < n_ph_list2; k++)
- {
- if(((pl = &ph_list2[k])->sourceix != 0) && (k > ix))
- break;
-
- pl->stress &= 0xf;
-
- if(phoneme_tab[pl->phcode]->type == phVOWEL)
- {
- n_syllables++;
-
- if(pl->stress > max_stress)
- {
- syllable_stressed = n_syllables;
- max_stress = pl->stress;
- max_stress_posn = k;
- }
- }
- }
- }
-
- if(phoneme_tab[plist2->phcode]->type == phVOWEL)
- {
- syllable++;
- }
-
- // make any language specific changes
- flags = 0;
- if(ix == max_stress_posn)
- flags |= 2;
- if(ix > max_stress_posn)
- flags |= 4;
- if(ph_list2[ix].synthflags & SFLAG_DICTIONARY)
- flags |= 8;
- ch.flags = flags | word_end;
-
- ch.stress = plist2->stress;
- ch.stress_highest = max_stress;
- ch.n_vowels = n_syllables;
- ch.vowel_this = syllable;
- ch.vowel_stressed = syllable_stressed;
-
- ChangePhonemes(tr, ph_list2, n_ph_list2, ix, phoneme_tab[ph_list2[ix].phcode], &ch);
- }
-
- // check whether a Voice has specified that we should replace this phoneme
- for(k=0; k<n_replace_phonemes; k++)
- {
- if(plist2->phcode == replace_phonemes[k].old_ph)
- {
- replace_flags = replace_phonemes[k].type;
-
- if((replace_flags & 1) && (word_end == 0))
- continue; // this replacement only occurs at the end of a word
-
- if((replace_flags & 2) && ((plist2->stress & 0x7) > 3))
- continue; // this replacement doesn't occur in stressed syllables
-
- // substitute the replacement phoneme
- plist2->phcode = replace_phonemes[k].new_ph;
- if((plist2->stress > 1) && (phoneme_tab[plist2->phcode]->phflags & phUNSTRESSED))
- plist2->stress = 0; // the replacement must be unstressed
- break;
- }
- }
-
- if(plist2->phcode == 0)
- {
- continue; // phoneme has been replaced by NULL, so don't copy it
- }
- }
-
- // copy phoneme into the output list
- memcpy(&plist_out[n_plist_out++],plist2,sizeof(PHONEME_LIST2));
- }
- return(n_plist_out);
-} // end of SubstitutePhonemes
-
-
-
-void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
-{//=====================================================================
-
- int ix=0;
- int j;
- int insert_ph = 0;
- PHONEME_LIST *phlist;
- PHONEME_TAB *ph;
- PHONEME_TAB *prev, *next, *next2;
- int unstress_count = 0;
- int word_stress = 0;
- int switched_language = 0;
- int max_stress;
- int voicing;
- int regression;
- int end_sourceix;
- int alternative;
- int first_vowel=0; // first vowel in a word
- PHONEME_LIST2 ph_list3[N_PHONEME_LIST];
-
- static PHONEME_LIST2 ph_list2_null = {0,0,0,0,0};
- PHONEME_LIST2 *plist2 = &ph_list2_null;
- PHONEME_LIST2 *plist2_inserted = NULL;
-
- plist2 = ph_list2;
- phlist = phoneme_list;
- end_sourceix = plist2[n_ph_list2-1].sourceix;
-
- // is the last word of the clause unstressed ?
- max_stress = 0;
- for(j = n_ph_list2-3; j>=0; j--)
- {
- // start with the last phoneme (before the terminating pauses) and move forwards
- if((plist2[j].stress & 0x7f) > max_stress)
- max_stress = plist2[j].stress & 0x7f;
- if(plist2[j].sourceix != 0)
- break;
- }
- if(max_stress < 4)
- {
- // the last word is unstressed, look for a previous word that can be stressed
- while(--j >= 0)
- {
- if(plist2[j].synthflags & SFLAG_PROMOTE_STRESS) // dictionary flags indicated that this stress can be promoted
- {
- plist2[j].stress = 4; // promote to stressed
- break;
- }
- if(plist2[j].stress >= 4)
- {
- // found a stressed syllable, so stop looking
- break;
- }
- }
- }
-
- if((regression = tr->langopts.param[LOPT_REGRESSIVE_VOICING]) != 0)
- {
- // set consonant clusters to all voiced or all unvoiced
- // Regressive
- int type;
- voicing = 0;
-
- for(j=n_ph_list2-1; j>=0; j--)
- {
- ph = phoneme_tab[plist2[j].phcode];
- if(ph == NULL)
- continue;
-
- if(ph->code == phonSWITCH)
- switched_language ^= 1;
- if(switched_language)
- continue;
-
- type = ph->type;
-
- if(regression & 0x2)
- {
- // LANG=Russian, [v] amd [v;] don't cause regression, or [R^]
- if((ph->mnemonic == 'v') || (ph->mnemonic == ((';'<<8)+'v')) || ((ph->mnemonic & 0xff)== 'R'))
- type = phLIQUID;
- }
-
- if((type==phSTOP) || type==(phFRICATIVE))
- {
- if(voicing==0)
- {
- voicing = 1;
- }
- else
- if((voicing==2) && ((ph->phflags & phALTERNATIVE)==phSWITCHVOICING))
- {
- plist2[j].phcode = ph->alternative_ph; // change to voiced equivalent
- }
- }
- else
- if((type==phVSTOP) || type==(phVFRICATIVE))
- {
- if(voicing==0)
- {
- voicing = 2;
- }
- else
- if((voicing==1) && ((ph->phflags & phALTERNATIVE)==phSWITCHVOICING))
- {
- plist2[j].phcode = ph->alternative_ph; // change to unvoiced equivalent
- }
- }
- else
- {
- if(regression & 0x8)
- {
- // LANG=Polish, propagate through liquids and nasals
- if((type == phPAUSE) || (type == phVOWEL))
- voicing = 0;
- }
- else
- {
- voicing = 0;
- }
- }
- if((regression & 0x4) && (plist2[j].sourceix))
- {
- // stop propagation at a word boundary
- voicing = 0;
- }
- }
- }
-
- n_ph_list2 = SubstitutePhonemes(tr,ph_list3) - 2;
-
- // transfer all the phonemes of the clause into phoneme_list
- ph = phoneme_tab[phonPAUSE];
- switched_language = 0;
-
- for(j=0; insert_ph || ((j < n_ph_list2) && (ix < N_PHONEME_LIST-3)); j++)
- {
- prev = ph;
-
- plist2 = &ph_list3[j];
-
- if(insert_ph != 0)
- {
- // we have a (linking) phoneme which we need to insert here
- next = phoneme_tab[plist2->phcode]; // this phoneme, i.e. after the insert
-
- // re-use the previous entry for the inserted phoneme.
- // That's OK because we don't look backwards from plist2
- j--;
- plist2 = plist2_inserted = &ph_list3[j];
- memset(plist2, 0, sizeof(*plist2));
- plist2->phcode = insert_ph;
- ph = phoneme_tab[insert_ph];
- insert_ph = 0;
- }
- else
- {
- // otherwise get the next phoneme from the list
- ph = phoneme_tab[plist2->phcode];
-
- if(plist2->phcode == phonSWITCH)
- {
- // change phoneme table
- SelectPhonemeTable(plist2->tone_number);
- switched_language ^= SFLAG_SWITCHED_LANG;
- }
- next = phoneme_tab[(plist2+1)->phcode]; // the phoneme after this one
- }
-
- if(plist2->sourceix)
- {
- // start of a word
- int k;
- word_stress = 0;
- first_vowel = 1;
-
- // find the highest stress level in this word
- for(k=j+1; k < n_ph_list2; k++)
- {
- if(ph_list3[k].sourceix)
- break; // start of the next word
-
- if(ph_list3[k].stress > word_stress)
- word_stress = ph_list3[k].stress;
- }
- }
-
- if(ph == NULL) continue;
-
- if(ph->type == phVOWEL)
- {
- // check for consecutive unstressed syllables
- if(plist2->stress == 0)
- {
- // an unstressed vowel
- unstress_count++;
- if((unstress_count > 1) && ((unstress_count & 1)==0))
- {
- // in a sequence of unstressed syllables, reduce alternate syllables to 'diminished'
- // stress. But not for the last phoneme of a stressed word
- if((tr->langopts.stress_flags & 0x2) || ((word_stress > 3) && ((plist2+1)->sourceix!=0)))
- {
- // An unstressed final vowel of a stressed word
- unstress_count=1; // try again for next syllable
- }
- else
- {
- plist2->stress = 1; // change stress to 'diminished'
- }
- }
- }
- else
- {
- unstress_count = 0;
- }
- }
-
- alternative = 0;
-
- if(ph->alternative_ph > 0)
- {
- switch(ph->phflags & phALTERNATIVE)
- {
- // This phoneme changes if vowel follows, or doesn't follow, depending on its phNOTFOLLOWS flag
- case phBEFORENOTVOWEL:
- if(next->type != phVOWEL)
- alternative = ph->alternative_ph;
- break;
-
- case phBEFORENOTVOWEL2: // LANG=tr
- if(((plist2+1)->sourceix != 0) ||
- ((next->type != phVOWEL) && ((phoneme_tab[(plist2+2)->phcode]->type != phVOWEL) || ((plist2+2)->sourceix != 0))))
- {
- alternative = ph->alternative_ph;
- }
- break;
-
- case phBEFOREVOWELPAUSE:
- if((next->type == phVOWEL) || (next->type == phPAUSE))
- alternative = ph->alternative_ph;
- break;
-
- case phBEFOREVOWEL:
- if(next->type == phVOWEL)
- alternative = ph->alternative_ph;
- break;
-
- case phBEFORE_R:
- if(next->phflags & phRHOTIC)
- {
- alternative = ph->alternative_ph;
- }
- break;
- }
- }
- if(ph->phflags & phBEFOREPAUSE)
- {
- if(next->type == phPAUSE)
- alternative = ph->link_out; // replace with the link_out phoneme
- }
-
- if(alternative == 1)
- continue; // NULL phoneme, discard
-
- if(alternative > 1)
- {
- PHONEME_TAB *ph2;
- ph2 = ph;
- ph = phoneme_tab[alternative];
-
- if(ph->type == phVOWEL)
- {
- plist2->synthflags |= SFLAG_SYLLABLE;
- if(ph2->type != phVOWEL)
- plist2->stress = 0; // change from non-vowel to vowel, make sure it's unstressed
- }
- else
- plist2->synthflags &= ~SFLAG_SYLLABLE;
- }
-
- if(tr->langopts.param[LOPT_REDUCE_T])
- {
- if((ph->mnemonic == 't') && (plist2->sourceix == 0) && ((prev->type == phVOWEL) || (prev->mnemonic == 'n')))
- {
- if(((plist2+1)->sourceix == 0) && ((plist2+1)->stress < 3) && (next->type == phVOWEL))
- {
- ph = phoneme_tab[phonT_REDUCED];
- }
- }
- }
-
-
- while((ph->reduce_to != 0) && (!(plist2->synthflags & SFLAG_DICTIONARY) || (tr->langopts.param[LOPT_REDUCE] & 1)))
- {
- int reduce_level;
- int stress_level;
- int reduce = 0;
-
- reduce_level = (ph->phflags >> 28) & 7;
-
- if(ph->type == phVOWEL)
- {
- stress_level = plist2->stress;
- }
- else
- {
- // consonant, get stress from the following vowel
- if(next->type == phVOWEL)
- stress_level = (plist2+1)->stress;
- else
- break;
- }
-
- if((stress_level == 1) && (first_vowel))
- stress_level = 0; // ignore 'dimished' stress on first syllable
-
- if(stress_level == 1)
- reduce = 1; // stress = 'reduced'
-
- if(stress_level < reduce_level)
- reduce =1;
-
- if((word_stress < 4) && (tr->langopts.param[LOPT_REDUCE] & 0x2) && (stress_level >= word_stress))
- {
- // don't reduce the most stressed syllable in an unstressed word
- reduce = 0;
- }
-
- if(reduce)
- ph = phoneme_tab[ph->reduce_to];
- else
- break;
- }
-
- if(ph->type == phVOWEL)
- first_vowel = 0;
-
- if((plist2+1)->synthflags & SFLAG_LENGTHEN)
- {
- static char types_double[] = {phFRICATIVE,phVFRICATIVE,phNASAL,phLIQUID,0};
- if(strchr(types_double,next->type))
- {
- // lengthen this consonant by doubling it
- insert_ph = next->code;
- (plist2+1)->synthflags ^= SFLAG_LENGTHEN;
- }
- }
-
- if((plist2+1)->sourceix != 0)
- {
- int x;
-
- if(tr->langopts.vowel_pause && (ph->type != phPAUSE))
- {
-
- if((ph->type != phVOWEL) && (tr->langopts.vowel_pause & 0x200))
- {
- // add a pause after a word which ends in a consonant
- insert_ph = phonPAUSE_NOLINK;
- }
-
- if(next->type == phVOWEL)
- {
- if((x = tr->langopts.vowel_pause & 0x0c) != 0)
- {
- // break before a word which starts with a vowel
- if(x == 0xc)
- insert_ph = phonPAUSE_NOLINK;
- else
- insert_ph = phonPAUSE_VSHORT;
- }
-
- if((ph->type == phVOWEL) && ((x = tr->langopts.vowel_pause & 0x03) != 0))
- {
- // adjacent vowels over a word boundary
- if(x == 2)
- insert_ph = phonPAUSE_SHORT;
- else
- insert_ph = phonPAUSE_VSHORT;
- }
-
- if(((plist2+1)->stress >= 4) && (tr->langopts.vowel_pause & 0x100))
- {
- // pause before a words which starts with a stressed vowel
- insert_ph = phonPAUSE_SHORT;
- }
- }
- }
-
- if(plist2 != plist2_inserted)
- {
- if((x = (tr->langopts.word_gap & 0x7)) != 0)
- {
- if((x > 1) || ((insert_ph != phonPAUSE_SHORT) && (insert_ph != phonPAUSE_NOLINK)))
- {
- // don't reduce the pause
- insert_ph = pause_phonemes[x];
- }
- }
- if(option_wordgap > 0)
- {
- insert_ph = phonPAUSE_LONG;
- }
- }
- }
-
- next2 = phoneme_tab[(plist2+2)->phcode];
-
- if((insert_ph == 0) && (ph->link_out != 0) && !(ph->phflags & phBEFOREPAUSE) && (((plist2+1)->synthflags & SFLAG_EMBEDDED)==0))
- {
- if(ph->phflags & phAPPENDPH)
- {
- // always append the specified phoneme, unless it already is the next phoneme
- if((ph->link_out != (plist2+1)->phcode) && (next->type == phVOWEL))
-// if(ph->link_out != (plist2+1)->phcode)
- {
- insert_ph = ph->link_out;
- }
- }
- else
- if(((tr->langopts.word_gap & 8)==0) || ((plist2+1)->sourceix == 0))
- {
- // This phoneme can be linked to a following vowel by inserting a linking phoneme
- if(next->type == phVOWEL)
- insert_ph = ph->link_out;
- else
- if(next->code == phonPAUSE_SHORT)
- {
- // Pause followed by Vowel, replace the Short Pause with the linking phoneme,
- if(next2->type == phVOWEL)
- (plist2+1)->phcode = ph->link_out; // replace pause by linking phoneme
- }
- }
- }
-
- if(ph->phflags & phVOICED)
- {
- // check that a voiced consonant is preceded or followed by a vowel or liquid
- // and if not, add a short schwa
-
- // not yet implemented
- }
-
- phlist[ix].ph = ph;
- phlist[ix].type = ph->type;
- phlist[ix].env = PITCHfall; // default, can be changed in the "intonation" module
- phlist[ix].synthflags = plist2->synthflags | switched_language;
- phlist[ix].stresslevel = plist2->stress & 0xf;
- phlist[ix].tone_ph = plist2->tone_number;
- phlist[ix].sourceix = 0;
-
- if(plist2->sourceix != 0)
- {
- phlist[ix].sourceix = plist2->sourceix;
- phlist[ix].newword = 1; // this phoneme is the start of a word
-
- if(start_sentence)
- {
- phlist[ix].newword = 5; // start of sentence + start of word
- start_sentence = 0;
- }
- }
- else
- {
- phlist[ix].newword = 0;
- }
-
- phlist[ix].length = ph->std_length;
- if((ph->code == phonPAUSE_LONG) && (option_wordgap > 0))
- {
- phlist[ix].ph = phoneme_tab[phonPAUSE_SHORT];
- phlist[ix].length = option_wordgap*14; // 10mS per unit at the default speed
- }
-
- if(ph->type==phVOWEL || ph->type==phLIQUID || ph->type==phNASAL || ph->type==phVSTOP || ph->type==phVFRICATIVE)
- {
- phlist[ix].length = 128; // length_mod
- phlist[ix].env = PITCHfall;
- }
-
- phlist[ix].prepause = 0;
- phlist[ix].amp = 20; // default, will be changed later
- phlist[ix].pitch1 = 0x400;
- phlist[ix].pitch2 = 0x400;
- ix++;
- }
- phlist[ix].newword = 2; // end of clause
-
- phlist[ix].type = phPAUSE; // terminate with 2 Pause phonemes
- phlist[ix].length = post_pause; // length of the pause, depends on the punctuation
- phlist[ix].sourceix = end_sourceix;
- phlist[ix].synthflags = 0;
-
- phlist[ix++].ph = phoneme_tab[phonPAUSE];
- phlist[ix].type = phPAUSE;
- phlist[ix].length = 0;
- phlist[ix].sourceix=0;
- phlist[ix].synthflags = 0;
- phlist[ix++].ph = phoneme_tab[phonPAUSE_SHORT];
-
- n_phoneme_list = ix;
-} // end of MakePhonemeList
-
-
diff --git a/navit/support/espeak/portaudio.h b/navit/support/espeak/portaudio.h
deleted file mode 100755
index 2ab8e02a4..000000000
--- a/navit/support/espeak/portaudio.h
+++ /dev/null
@@ -1,466 +0,0 @@
-// NOTE: Copy this file to portaudio.h in order to compile with V18 portaudio
-
-
-#ifndef PORT_AUDIO_H
-#define PORT_AUDIO_H
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-/*
- * $Id: portaudio.h,v 1.5 2002/03/26 18:04:22 philburk Exp $
- * PortAudio Portable Real-Time Audio Library
- * PortAudio API Header File
- * Latest version available at: http://www.audiomulch.com/portaudio/
- *
- * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-typedef int PaError;
-typedef enum {
- paNoError = 0,
-
- paHostError = -10000,
- paInvalidChannelCount,
- paInvalidSampleRate,
- paInvalidDeviceId,
- paInvalidFlag,
- paSampleFormatNotSupported,
- paBadIODeviceCombination,
- paInsufficientMemory,
- paBufferTooBig,
- paBufferTooSmall,
- paNullCallback,
- paBadStreamPtr,
- paTimedOut,
- paInternalError,
- paDeviceUnavailable
-} PaErrorNum;
-
-/*
- Pa_Initialize() is the library initialisation function - call this before
- using the library.
-
-*/
-
-PaError Pa_Initialize( void );
-
-/*
- Pa_Terminate() is the library termination function - call this after
- using the library.
-
-*/
-
-PaError Pa_Terminate( void );
-
-/*
- Pa_GetHostError() returns a host specific error code.
- This can be called after receiving a PortAudio error code of paHostError.
-
-*/
-
-long Pa_GetHostError( void );
-
-/*
- Pa_GetErrorText() translates the supplied PortAudio error number
- into a human readable message.
-
-*/
-
-const char *Pa_GetErrorText( PaError errnum );
-
-/*
- Sample formats
-
- These are formats used to pass sound data between the callback and the
- stream. Each device has a "native" format which may be used when optimum
- efficiency or control over conversion is required.
-
- Formats marked "always available" are supported (emulated) by all
- PortAudio implementations.
-
- The floating point representation (paFloat32) uses +1.0 and -1.0 as the
- maximum and minimum respectively.
-
- paUInt8 is an unsigned 8 bit format where 128 is considered "ground"
-
-*/
-
-typedef unsigned long PaSampleFormat;
-#define paFloat32 ((PaSampleFormat) (1<<0)) /*always available*/
-#define paInt16 ((PaSampleFormat) (1<<1)) /*always available*/
-#define paInt32 ((PaSampleFormat) (1<<2)) /*always available*/
-#define paInt24 ((PaSampleFormat) (1<<3))
-#define paPackedInt24 ((PaSampleFormat) (1<<4))
-#define paInt8 ((PaSampleFormat) (1<<5))
-#define paUInt8 ((PaSampleFormat) (1<<6))
-#define paCustomFormat ((PaSampleFormat) (1<<16))
-
-/*
- Device enumeration mechanism.
-
- Device ids range from 0 to Pa_CountDevices()-1.
-
- Devices may support input, output or both.
-
-*/
-
-typedef int PaDeviceID;
-#define paNoDevice -1
-
-int Pa_CountDevices( void );
-
-typedef struct
-{
- int structVersion;
- const char *name;
- int maxInputChannels;
- int maxOutputChannels;
- /* Number of discrete rates, or -1 if range supported. */
- int numSampleRates;
- /* Array of supported sample rates, or {min,max} if range supported. */
- const double *sampleRates;
- PaSampleFormat nativeSampleFormats;
-}
-PaDeviceInfo;
-
-/*
- Pa_GetDefaultInputDeviceID(), Pa_GetDefaultOutputDeviceID() return the
- default device ids for input and output respectively, or paNoDevice if
- no device is available.
- The result can be passed to Pa_OpenStream().
-
- On the PC, the user can specify a default device by
- setting an environment variable. For example, to use device #1.
-
- set PA_RECOMMENDED_OUTPUT_DEVICE=1
-
- The user should first determine the available device ids by using
- the supplied application "pa_devs".
-
-*/
-
-PaDeviceID Pa_GetDefaultInputDeviceID( void );
-PaDeviceID Pa_GetDefaultOutputDeviceID( void );
-
-
-
-/*
- Pa_GetDeviceInfo() returns a pointer to an immutable PaDeviceInfo structure
- for the device specified.
- If the device parameter is out of range the function returns NULL.
-
- PortAudio manages the memory referenced by the returned pointer, the client
- must not manipulate or free the memory. The pointer is only guaranteed to be
- valid between calls to Pa_Initialize() and Pa_Terminate().
-
-*/
-
-const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID device );
-
-/*
- PaTimestamp is used to represent a continuous sample clock with arbitrary
- start time that can be used for syncronization. The type is used for the
- outTime argument to the PortAudioCallback and as the result of Pa_StreamTime()
-
-*/
-
-typedef double PaTimestamp;
-
-/*
- PortAudioCallback is implemented by PortAudio clients.
-
- inputBuffer and outputBuffer are arrays of interleaved samples,
- the format, packing and number of channels used by the buffers are
- determined by parameters to Pa_OpenStream() (see below).
-
- framesPerBuffer is the number of sample frames to be processed by the callback.
-
- outTime is the time in samples when the buffer(s) processed by
- this callback will begin being played at the audio output.
- See also Pa_StreamTime()
-
- userData is the value of a user supplied pointer passed to Pa_OpenStream()
- intended for storing synthesis data etc.
-
- return value:
- The callback can return a non-zero value to stop the stream. This may be
- useful in applications such as soundfile players where a specific duration
- of output is required. However, it is not necessary to utilise this mechanism
- as StopStream() will also terminate the stream. A callback returning a
- non-zero value must fill the entire outputBuffer.
-
- NOTE: None of the other stream functions may be called from within the
- callback function except for Pa_GetCPULoad().
-
-*/
-
-typedef int (PortAudioCallback)(
- void *inputBuffer, void *outputBuffer,
- unsigned long framesPerBuffer,
- PaTimestamp outTime, void *userData );
-
-
-/*
- Stream flags
-
- These flags may be supplied (ored together) in the streamFlags argument to
- the Pa_OpenStream() function.
-
-*/
-
-#define paNoFlag (0)
-#define paClipOff (1<<0) /* disable default clipping of out of range samples */
-#define paDitherOff (1<<1) /* disable default dithering */
-#define paPlatformSpecificFlags (0x00010000)
-typedef unsigned long PaStreamFlags;
-
-/*
- A single PortAudioStream provides multiple channels of real-time
- input and output audio streaming to a client application.
- Pointers to PortAudioStream objects are passed between PortAudio functions.
-*/
-
-typedef void PortAudioStream;
-#define PaStream PortAudioStream
-
-/*
- Pa_OpenStream() opens a stream for either input, output or both.
-
- stream is the address of a PortAudioStream pointer which will receive
- a pointer to the newly opened stream.
-
- inputDevice is the id of the device used for input (see PaDeviceID above.)
- inputDevice may be paNoDevice to indicate that an input device is not required.
-
- numInputChannels is the number of channels of sound to be delivered to the
- callback. It can range from 1 to the value of maxInputChannels in the
- PaDeviceInfo record for the device specified by the inputDevice parameter.
- If inputDevice is paNoDevice numInputChannels is ignored.
-
- inputSampleFormat is the sample format of inputBuffer provided to the callback
- function. inputSampleFormat may be any of the formats described by the
- PaSampleFormat enumeration (see above). PortAudio guarantees support for
- the device's native formats (nativeSampleFormats in the device info record)
- and additionally 16 and 32 bit integer and 32 bit floating point formats.
- Support for other formats is implementation defined.
-
- inputDriverInfo is a pointer to an optional driver specific data structure
- containing additional information for device setup or stream processing.
- inputDriverInfo is never required for correct operation. If not used
- inputDriverInfo should be NULL.
-
- outputDevice is the id of the device used for output (see PaDeviceID above.)
- outputDevice may be paNoDevice to indicate that an output device is not required.
-
- numOutputChannels is the number of channels of sound to be supplied by the
- callback. See the definition of numInputChannels above for more details.
-
- outputSampleFormat is the sample format of the outputBuffer filled by the
- callback function. See the definition of inputSampleFormat above for more
- details.
-
- outputDriverInfo is a pointer to an optional driver specific data structure
- containing additional information for device setup or stream processing.
- outputDriverInfo is never required for correct operation. If not used
- outputDriverInfo should be NULL.
-
- sampleRate is the desired sampleRate. For full-duplex streams it is the
- sample rate for both input and output
-
- framesPerBuffer is the length in sample frames of all internal sample buffers
- used for communication with platform specific audio routines. Wherever
- possible this corresponds to the framesPerBuffer parameter passed to the
- callback function.
-
- numberOfBuffers is the number of buffers used for multibuffered communication
- with the platform specific audio routines. If you pass zero, then an optimum
- value will be chosen for you internally. This parameter is provided only
- as a guide - and does not imply that an implementation must use multibuffered
- i/o when reliable double buffering is available (such as SndPlayDoubleBuffer()
- on the Macintosh.)
-
- streamFlags may contain a combination of flags ORed together.
- These flags modify the behaviour of the streaming process. Some flags may only
- be relevant to certain buffer formats.
-
- callback is a pointer to a client supplied function that is responsible
- for processing and filling input and output buffers (see above for details.)
-
- userData is a client supplied pointer which is passed to the callback
- function. It could for example, contain a pointer to instance data necessary
- for processing the audio buffers.
-
- return value:
- Upon success Pa_OpenStream() returns PaNoError and places a pointer to a
- valid PortAudioStream in the stream argument. The stream is inactive (stopped).
- If a call to Pa_OpenStream() fails a non-zero error code is returned (see
- PaError above) and the value of stream is invalid.
-
-*/
-
-PaError Pa_OpenStream( PortAudioStream** stream,
- PaDeviceID inputDevice,
- int numInputChannels,
- PaSampleFormat inputSampleFormat,
- void *inputDriverInfo,
- PaDeviceID outputDevice,
- int numOutputChannels,
- PaSampleFormat outputSampleFormat,
- void *outputDriverInfo,
- double sampleRate,
- unsigned long framesPerBuffer,
- unsigned long numberOfBuffers,
- PaStreamFlags streamFlags,
- PortAudioCallback *callback,
- void *userData );
-
-
-/*
- Pa_OpenDefaultStream() is a simplified version of Pa_OpenStream() that opens
- the default input and/or output devices. Most parameters have identical meaning
- to their Pa_OpenStream() counterparts, with the following exceptions:
-
- If either numInputChannels or numOutputChannels is 0 the respective device
- is not opened. This has the same effect as passing paNoDevice in the device
- arguments to Pa_OpenStream().
-
- sampleFormat applies to both the input and output buffers.
-
-*/
-
-PaError Pa_OpenDefaultStream( PortAudioStream** stream,
- int numInputChannels,
- int numOutputChannels,
- PaSampleFormat sampleFormat,
- double sampleRate,
- unsigned long framesPerBuffer,
- unsigned long numberOfBuffers,
- PortAudioCallback *callback,
- void *userData );
-
-/*
- Pa_CloseStream() closes an audio stream, flushing any pending buffers.
-
-*/
-
-PaError Pa_CloseStream( PortAudioStream* );
-
-/*
- Pa_StartStream() and Pa_StopStream() begin and terminate audio processing.
- Pa_StopStream() waits until all pending audio buffers have been played.
- Pa_AbortStream() stops playing immediately without waiting for pending
- buffers to complete.
-
-*/
-
-PaError Pa_StartStream( PortAudioStream *stream );
-
-PaError Pa_StopStream( PortAudioStream *stream );
-
-PaError Pa_AbortStream( PortAudioStream *stream );
-
-/*
- Pa_StreamActive() returns one (1) when the stream is active (ie playing
- or recording audio), zero (0) when not playing, or a negative error number
- if the stream is invalid.
- The stream is active between calls to Pa_StartStream() and Pa_StopStream(),
- but may also become inactive if the callback returns a non-zero value.
- In the latter case, the stream is considered inactive after the last
- buffer has finished playing.
-
-*/
-
-PaError Pa_StreamActive( PortAudioStream *stream );
-
-/*
- Pa_StreamTime() returns the current output time in samples for the stream.
- This time may be used as a time reference (for example synchronizing audio to
- MIDI).
-
-*/
-
-PaTimestamp Pa_StreamTime( PortAudioStream *stream );
-
-/*
- Pa_GetCPULoad() returns the CPU Load for the stream.
- The "CPU Load" is a fraction of total CPU time consumed by the stream's
- audio processing routines including, but not limited to the client supplied
- callback.
- A value of 0.5 would imply that PortAudio and the sound generating
- callback was consuming roughly 50% of the available CPU time.
- This function may be called from the callback function or the application.
-
-*/
-
-double Pa_GetCPULoad( PortAudioStream* stream );
-
-/*
- Pa_GetMinNumBuffers() returns the minimum number of buffers required by
- the current host based on minimum latency.
- On the PC, for the DirectSound implementation, latency can be optionally set
- by user by setting an environment variable.
- For example, to set latency to 200 msec, put:
-
- set PA_MIN_LATENCY_MSEC=200
-
- in the AUTOEXEC.BAT file and reboot.
- If the environment variable is not set, then the latency will be determined
- based on the OS. Windows NT has higher latency than Win95.
-
-*/
-
-int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate );
-
-/*
- Pa_Sleep() puts the caller to sleep for at least 'msec' milliseconds.
- You may sleep longer than the requested time so don't rely on this for
- accurate musical timing.
-
- Pa_Sleep() is provided as a convenience for authors of portable code (such as
- the tests and examples in the PortAudio distribution.)
-
-*/
-
-void Pa_Sleep( long msec );
-
-/*
- Pa_GetSampleSize() returns the size in bytes of a single sample in the
- supplied PaSampleFormat, or paSampleFormatNotSupported if the format is
- no supported.
-
-*/
-
-PaError Pa_GetSampleSize( PaSampleFormat format );
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* PORT_AUDIO_H */
diff --git a/navit/support/espeak/portaudio18.h b/navit/support/espeak/portaudio18.h
deleted file mode 100755
index 2ab8e02a4..000000000
--- a/navit/support/espeak/portaudio18.h
+++ /dev/null
@@ -1,466 +0,0 @@
-// NOTE: Copy this file to portaudio.h in order to compile with V18 portaudio
-
-
-#ifndef PORT_AUDIO_H
-#define PORT_AUDIO_H
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-/*
- * $Id: portaudio.h,v 1.5 2002/03/26 18:04:22 philburk Exp $
- * PortAudio Portable Real-Time Audio Library
- * PortAudio API Header File
- * Latest version available at: http://www.audiomulch.com/portaudio/
- *
- * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-typedef int PaError;
-typedef enum {
- paNoError = 0,
-
- paHostError = -10000,
- paInvalidChannelCount,
- paInvalidSampleRate,
- paInvalidDeviceId,
- paInvalidFlag,
- paSampleFormatNotSupported,
- paBadIODeviceCombination,
- paInsufficientMemory,
- paBufferTooBig,
- paBufferTooSmall,
- paNullCallback,
- paBadStreamPtr,
- paTimedOut,
- paInternalError,
- paDeviceUnavailable
-} PaErrorNum;
-
-/*
- Pa_Initialize() is the library initialisation function - call this before
- using the library.
-
-*/
-
-PaError Pa_Initialize( void );
-
-/*
- Pa_Terminate() is the library termination function - call this after
- using the library.
-
-*/
-
-PaError Pa_Terminate( void );
-
-/*
- Pa_GetHostError() returns a host specific error code.
- This can be called after receiving a PortAudio error code of paHostError.
-
-*/
-
-long Pa_GetHostError( void );
-
-/*
- Pa_GetErrorText() translates the supplied PortAudio error number
- into a human readable message.
-
-*/
-
-const char *Pa_GetErrorText( PaError errnum );
-
-/*
- Sample formats
-
- These are formats used to pass sound data between the callback and the
- stream. Each device has a "native" format which may be used when optimum
- efficiency or control over conversion is required.
-
- Formats marked "always available" are supported (emulated) by all
- PortAudio implementations.
-
- The floating point representation (paFloat32) uses +1.0 and -1.0 as the
- maximum and minimum respectively.
-
- paUInt8 is an unsigned 8 bit format where 128 is considered "ground"
-
-*/
-
-typedef unsigned long PaSampleFormat;
-#define paFloat32 ((PaSampleFormat) (1<<0)) /*always available*/
-#define paInt16 ((PaSampleFormat) (1<<1)) /*always available*/
-#define paInt32 ((PaSampleFormat) (1<<2)) /*always available*/
-#define paInt24 ((PaSampleFormat) (1<<3))
-#define paPackedInt24 ((PaSampleFormat) (1<<4))
-#define paInt8 ((PaSampleFormat) (1<<5))
-#define paUInt8 ((PaSampleFormat) (1<<6))
-#define paCustomFormat ((PaSampleFormat) (1<<16))
-
-/*
- Device enumeration mechanism.
-
- Device ids range from 0 to Pa_CountDevices()-1.
-
- Devices may support input, output or both.
-
-*/
-
-typedef int PaDeviceID;
-#define paNoDevice -1
-
-int Pa_CountDevices( void );
-
-typedef struct
-{
- int structVersion;
- const char *name;
- int maxInputChannels;
- int maxOutputChannels;
- /* Number of discrete rates, or -1 if range supported. */
- int numSampleRates;
- /* Array of supported sample rates, or {min,max} if range supported. */
- const double *sampleRates;
- PaSampleFormat nativeSampleFormats;
-}
-PaDeviceInfo;
-
-/*
- Pa_GetDefaultInputDeviceID(), Pa_GetDefaultOutputDeviceID() return the
- default device ids for input and output respectively, or paNoDevice if
- no device is available.
- The result can be passed to Pa_OpenStream().
-
- On the PC, the user can specify a default device by
- setting an environment variable. For example, to use device #1.
-
- set PA_RECOMMENDED_OUTPUT_DEVICE=1
-
- The user should first determine the available device ids by using
- the supplied application "pa_devs".
-
-*/
-
-PaDeviceID Pa_GetDefaultInputDeviceID( void );
-PaDeviceID Pa_GetDefaultOutputDeviceID( void );
-
-
-
-/*
- Pa_GetDeviceInfo() returns a pointer to an immutable PaDeviceInfo structure
- for the device specified.
- If the device parameter is out of range the function returns NULL.
-
- PortAudio manages the memory referenced by the returned pointer, the client
- must not manipulate or free the memory. The pointer is only guaranteed to be
- valid between calls to Pa_Initialize() and Pa_Terminate().
-
-*/
-
-const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID device );
-
-/*
- PaTimestamp is used to represent a continuous sample clock with arbitrary
- start time that can be used for syncronization. The type is used for the
- outTime argument to the PortAudioCallback and as the result of Pa_StreamTime()
-
-*/
-
-typedef double PaTimestamp;
-
-/*
- PortAudioCallback is implemented by PortAudio clients.
-
- inputBuffer and outputBuffer are arrays of interleaved samples,
- the format, packing and number of channels used by the buffers are
- determined by parameters to Pa_OpenStream() (see below).
-
- framesPerBuffer is the number of sample frames to be processed by the callback.
-
- outTime is the time in samples when the buffer(s) processed by
- this callback will begin being played at the audio output.
- See also Pa_StreamTime()
-
- userData is the value of a user supplied pointer passed to Pa_OpenStream()
- intended for storing synthesis data etc.
-
- return value:
- The callback can return a non-zero value to stop the stream. This may be
- useful in applications such as soundfile players where a specific duration
- of output is required. However, it is not necessary to utilise this mechanism
- as StopStream() will also terminate the stream. A callback returning a
- non-zero value must fill the entire outputBuffer.
-
- NOTE: None of the other stream functions may be called from within the
- callback function except for Pa_GetCPULoad().
-
-*/
-
-typedef int (PortAudioCallback)(
- void *inputBuffer, void *outputBuffer,
- unsigned long framesPerBuffer,
- PaTimestamp outTime, void *userData );
-
-
-/*
- Stream flags
-
- These flags may be supplied (ored together) in the streamFlags argument to
- the Pa_OpenStream() function.
-
-*/
-
-#define paNoFlag (0)
-#define paClipOff (1<<0) /* disable default clipping of out of range samples */
-#define paDitherOff (1<<1) /* disable default dithering */
-#define paPlatformSpecificFlags (0x00010000)
-typedef unsigned long PaStreamFlags;
-
-/*
- A single PortAudioStream provides multiple channels of real-time
- input and output audio streaming to a client application.
- Pointers to PortAudioStream objects are passed between PortAudio functions.
-*/
-
-typedef void PortAudioStream;
-#define PaStream PortAudioStream
-
-/*
- Pa_OpenStream() opens a stream for either input, output or both.
-
- stream is the address of a PortAudioStream pointer which will receive
- a pointer to the newly opened stream.
-
- inputDevice is the id of the device used for input (see PaDeviceID above.)
- inputDevice may be paNoDevice to indicate that an input device is not required.
-
- numInputChannels is the number of channels of sound to be delivered to the
- callback. It can range from 1 to the value of maxInputChannels in the
- PaDeviceInfo record for the device specified by the inputDevice parameter.
- If inputDevice is paNoDevice numInputChannels is ignored.
-
- inputSampleFormat is the sample format of inputBuffer provided to the callback
- function. inputSampleFormat may be any of the formats described by the
- PaSampleFormat enumeration (see above). PortAudio guarantees support for
- the device's native formats (nativeSampleFormats in the device info record)
- and additionally 16 and 32 bit integer and 32 bit floating point formats.
- Support for other formats is implementation defined.
-
- inputDriverInfo is a pointer to an optional driver specific data structure
- containing additional information for device setup or stream processing.
- inputDriverInfo is never required for correct operation. If not used
- inputDriverInfo should be NULL.
-
- outputDevice is the id of the device used for output (see PaDeviceID above.)
- outputDevice may be paNoDevice to indicate that an output device is not required.
-
- numOutputChannels is the number of channels of sound to be supplied by the
- callback. See the definition of numInputChannels above for more details.
-
- outputSampleFormat is the sample format of the outputBuffer filled by the
- callback function. See the definition of inputSampleFormat above for more
- details.
-
- outputDriverInfo is a pointer to an optional driver specific data structure
- containing additional information for device setup or stream processing.
- outputDriverInfo is never required for correct operation. If not used
- outputDriverInfo should be NULL.
-
- sampleRate is the desired sampleRate. For full-duplex streams it is the
- sample rate for both input and output
-
- framesPerBuffer is the length in sample frames of all internal sample buffers
- used for communication with platform specific audio routines. Wherever
- possible this corresponds to the framesPerBuffer parameter passed to the
- callback function.
-
- numberOfBuffers is the number of buffers used for multibuffered communication
- with the platform specific audio routines. If you pass zero, then an optimum
- value will be chosen for you internally. This parameter is provided only
- as a guide - and does not imply that an implementation must use multibuffered
- i/o when reliable double buffering is available (such as SndPlayDoubleBuffer()
- on the Macintosh.)
-
- streamFlags may contain a combination of flags ORed together.
- These flags modify the behaviour of the streaming process. Some flags may only
- be relevant to certain buffer formats.
-
- callback is a pointer to a client supplied function that is responsible
- for processing and filling input and output buffers (see above for details.)
-
- userData is a client supplied pointer which is passed to the callback
- function. It could for example, contain a pointer to instance data necessary
- for processing the audio buffers.
-
- return value:
- Upon success Pa_OpenStream() returns PaNoError and places a pointer to a
- valid PortAudioStream in the stream argument. The stream is inactive (stopped).
- If a call to Pa_OpenStream() fails a non-zero error code is returned (see
- PaError above) and the value of stream is invalid.
-
-*/
-
-PaError Pa_OpenStream( PortAudioStream** stream,
- PaDeviceID inputDevice,
- int numInputChannels,
- PaSampleFormat inputSampleFormat,
- void *inputDriverInfo,
- PaDeviceID outputDevice,
- int numOutputChannels,
- PaSampleFormat outputSampleFormat,
- void *outputDriverInfo,
- double sampleRate,
- unsigned long framesPerBuffer,
- unsigned long numberOfBuffers,
- PaStreamFlags streamFlags,
- PortAudioCallback *callback,
- void *userData );
-
-
-/*
- Pa_OpenDefaultStream() is a simplified version of Pa_OpenStream() that opens
- the default input and/or output devices. Most parameters have identical meaning
- to their Pa_OpenStream() counterparts, with the following exceptions:
-
- If either numInputChannels or numOutputChannels is 0 the respective device
- is not opened. This has the same effect as passing paNoDevice in the device
- arguments to Pa_OpenStream().
-
- sampleFormat applies to both the input and output buffers.
-
-*/
-
-PaError Pa_OpenDefaultStream( PortAudioStream** stream,
- int numInputChannels,
- int numOutputChannels,
- PaSampleFormat sampleFormat,
- double sampleRate,
- unsigned long framesPerBuffer,
- unsigned long numberOfBuffers,
- PortAudioCallback *callback,
- void *userData );
-
-/*
- Pa_CloseStream() closes an audio stream, flushing any pending buffers.
-
-*/
-
-PaError Pa_CloseStream( PortAudioStream* );
-
-/*
- Pa_StartStream() and Pa_StopStream() begin and terminate audio processing.
- Pa_StopStream() waits until all pending audio buffers have been played.
- Pa_AbortStream() stops playing immediately without waiting for pending
- buffers to complete.
-
-*/
-
-PaError Pa_StartStream( PortAudioStream *stream );
-
-PaError Pa_StopStream( PortAudioStream *stream );
-
-PaError Pa_AbortStream( PortAudioStream *stream );
-
-/*
- Pa_StreamActive() returns one (1) when the stream is active (ie playing
- or recording audio), zero (0) when not playing, or a negative error number
- if the stream is invalid.
- The stream is active between calls to Pa_StartStream() and Pa_StopStream(),
- but may also become inactive if the callback returns a non-zero value.
- In the latter case, the stream is considered inactive after the last
- buffer has finished playing.
-
-*/
-
-PaError Pa_StreamActive( PortAudioStream *stream );
-
-/*
- Pa_StreamTime() returns the current output time in samples for the stream.
- This time may be used as a time reference (for example synchronizing audio to
- MIDI).
-
-*/
-
-PaTimestamp Pa_StreamTime( PortAudioStream *stream );
-
-/*
- Pa_GetCPULoad() returns the CPU Load for the stream.
- The "CPU Load" is a fraction of total CPU time consumed by the stream's
- audio processing routines including, but not limited to the client supplied
- callback.
- A value of 0.5 would imply that PortAudio and the sound generating
- callback was consuming roughly 50% of the available CPU time.
- This function may be called from the callback function or the application.
-
-*/
-
-double Pa_GetCPULoad( PortAudioStream* stream );
-
-/*
- Pa_GetMinNumBuffers() returns the minimum number of buffers required by
- the current host based on minimum latency.
- On the PC, for the DirectSound implementation, latency can be optionally set
- by user by setting an environment variable.
- For example, to set latency to 200 msec, put:
-
- set PA_MIN_LATENCY_MSEC=200
-
- in the AUTOEXEC.BAT file and reboot.
- If the environment variable is not set, then the latency will be determined
- based on the OS. Windows NT has higher latency than Win95.
-
-*/
-
-int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate );
-
-/*
- Pa_Sleep() puts the caller to sleep for at least 'msec' milliseconds.
- You may sleep longer than the requested time so don't rely on this for
- accurate musical timing.
-
- Pa_Sleep() is provided as a convenience for authors of portable code (such as
- the tests and examples in the PortAudio distribution.)
-
-*/
-
-void Pa_Sleep( long msec );
-
-/*
- Pa_GetSampleSize() returns the size in bytes of a single sample in the
- supplied PaSampleFormat, or paSampleFormatNotSupported if the format is
- no supported.
-
-*/
-
-PaError Pa_GetSampleSize( PaSampleFormat format );
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* PORT_AUDIO_H */
diff --git a/navit/support/espeak/portaudio19.h b/navit/support/espeak/portaudio19.h
deleted file mode 100644
index 5c060b711..000000000
--- a/navit/support/espeak/portaudio19.h
+++ /dev/null
@@ -1,1127 +0,0 @@
-// NOTE: Copy this file to portaudio.h in order to compile with V19 portaudio
-
-#ifndef PORTAUDIO_H
-#define PORTAUDIO_H
-/*
- * $Id: portaudio.h 1061 2006-06-19 22:46:41Z lschwardt $
- * PortAudio Portable Real-Time Audio Library
- * PortAudio API Header File
- * Latest version available at: http://www.portaudio.com/
- *
- * Copyright (c) 1999-2002 Ross Bencina and Phil Burk
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * Any person wishing to distribute modifications to the Software is
- * requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/** @file
- @brief The PortAudio API.
-*/
-
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-
-/** Retrieve the release number of the currently running PortAudio build,
- eg 1900.
-*/
-int Pa_GetVersion( void );
-
-
-/** Retrieve a textual description of the current PortAudio build,
- eg "PortAudio V19-devel 13 October 2002".
-*/
-const char* Pa_GetVersionText( void );
-
-
-/** Error codes returned by PortAudio functions.
- Note that with the exception of paNoError, all PaErrorCodes are negative.
-*/
-
-typedef int PaError;
-typedef enum PaErrorCode
-{
- paNoError = 0,
-
- paNotInitialized = -10000,
- paUnanticipatedHostError,
- paInvalidChannelCount,
- paInvalidSampleRate,
- paInvalidDevice,
- paInvalidFlag,
- paSampleFormatNotSupported,
- paBadIODeviceCombination,
- paInsufficientMemory,
- paBufferTooBig,
- paBufferTooSmall,
- paNullCallback,
- paBadStreamPtr,
- paTimedOut,
- paInternalError,
- paDeviceUnavailable,
- paIncompatibleHostApiSpecificStreamInfo,
- paStreamIsStopped,
- paStreamIsNotStopped,
- paInputOverflowed,
- paOutputUnderflowed,
- paHostApiNotFound,
- paInvalidHostApi,
- paCanNotReadFromACallbackStream, /**< @todo review error code name */
- paCanNotWriteToACallbackStream, /**< @todo review error code name */
- paCanNotReadFromAnOutputOnlyStream, /**< @todo review error code name */
- paCanNotWriteToAnInputOnlyStream, /**< @todo review error code name */
- paIncompatibleStreamHostApi,
- paBadBufferPtr
-} PaErrorCode;
-
-
-/** Translate the supplied PortAudio error code into a human readable
- message.
-*/
-const char *Pa_GetErrorText( PaError errorCode );
-
-
-/** Library initialization function - call this before using PortAudio.
- This function initialises internal data structures and prepares underlying
- host APIs for use. This function MUST be called before using any other
- PortAudio API functions.
-
- If Pa_Initialize() is called multiple times, each successful
- call must be matched with a corresponding call to Pa_Terminate().
- Pairs of calls to Pa_Initialize()/Pa_Terminate() may overlap, and are not
- required to be fully nested.
-
- Note that if Pa_Initialize() returns an error code, Pa_Terminate() should
- NOT be called.
-
- @return paNoError if successful, otherwise an error code indicating the cause
- of failure.
-
- @see Pa_Terminate
-*/
-PaError Pa_Initialize( void );
-
-
-/** Library termination function - call this when finished using PortAudio.
- This function deallocates all resources allocated by PortAudio since it was
- initializied by a call to Pa_Initialize(). In cases where Pa_Initialise() has
- been called multiple times, each call must be matched with a corresponding call
- to Pa_Terminate(). The final matching call to Pa_Terminate() will automatically
- close any PortAudio streams that are still open.
-
- Pa_Terminate() MUST be called before exiting a program which uses PortAudio.
- Failure to do so may result in serious resource leaks, such as audio devices
- not being available until the next reboot.
-
- @return paNoError if successful, otherwise an error code indicating the cause
- of failure.
-
- @see Pa_Initialize
-*/
-PaError Pa_Terminate( void );
-
-
-
-/** The type used to refer to audio devices. Values of this type usually
- range from 0 to (Pa_DeviceCount-1), and may also take on the PaNoDevice
- and paUseHostApiSpecificDeviceSpecification values.
-
- @see Pa_DeviceCount, paNoDevice, paUseHostApiSpecificDeviceSpecification
-*/
-typedef int PaDeviceIndex;
-
-
-/** A special PaDeviceIndex value indicating that no device is available,
- or should be used.
-
- @see PaDeviceIndex
-*/
-#define paNoDevice ((PaDeviceIndex)-1)
-
-
-/** A special PaDeviceIndex value indicating that the device(s) to be used
- are specified in the host api specific stream info structure.
-
- @see PaDeviceIndex
-*/
-#define paUseHostApiSpecificDeviceSpecification ((PaDeviceIndex)-2)
-
-
-/* Host API enumeration mechanism */
-
-/** The type used to enumerate to host APIs at runtime. Values of this type
- range from 0 to (Pa_GetHostApiCount()-1).
-
- @see Pa_GetHostApiCount
-*/
-typedef int PaHostApiIndex;
-
-
-/** Retrieve the number of available host APIs. Even if a host API is
- available it may have no devices available.
-
- @return A non-negative value indicating the number of available host APIs
- or, a PaErrorCode (which are always negative) if PortAudio is not initialized
- or an error is encountered.
-
- @see PaHostApiIndex
-*/
-PaHostApiIndex Pa_GetHostApiCount( void );
-
-
-/** Retrieve the index of the default host API. The default host API will be
- the lowest common denominator host API on the current platform and is
- unlikely to provide the best performance.
-
- @return A non-negative value ranging from 0 to (Pa_GetHostApiCount()-1)
- indicating the default host API index or, a PaErrorCode (which are always
- negative) if PortAudio is not initialized or an error is encountered.
-*/
-PaHostApiIndex Pa_GetDefaultHostApi( void );
-
-
-/** Unchanging unique identifiers for each supported host API. This type
- is used in the PaHostApiInfo structure. The values are guaranteed to be
- unique and to never change, thus allowing code to be written that
- conditionally uses host API specific extensions.
-
- New type ids will be allocated when support for a host API reaches
- "public alpha" status, prior to that developers should use the
- paInDevelopment type id.
-
- @see PaHostApiInfo
-*/
-typedef enum PaHostApiTypeId
-{
- paInDevelopment=0, /* use while developing support for a new host API */
- paDirectSound=1,
- paMME=2,
- paASIO=3,
- paSoundManager=4,
- paCoreAudio=5,
- paOSS=7,
- paALSA=8,
- paAL=9,
- paBeOS=10,
- paWDMKS=11,
- paJACK=12,
- paWASAPI=13,
- paAudioScienceHPI=14
-} PaHostApiTypeId;
-
-
-/** A structure containing information about a particular host API. */
-
-typedef struct PaHostApiInfo
-{
- /** this is struct version 1 */
- int structVersion;
- /** The well known unique identifier of this host API @see PaHostApiTypeId */
- PaHostApiTypeId type;
- /** A textual description of the host API for display on user interfaces. */
- const char *name;
-
- /** The number of devices belonging to this host API. This field may be
- used in conjunction with Pa_HostApiDeviceIndexToDeviceIndex() to enumerate
- all devices for this host API.
- @see Pa_HostApiDeviceIndexToDeviceIndex
- */
- int deviceCount;
-
- /** The default input device for this host API. The value will be a
- device index ranging from 0 to (Pa_GetDeviceCount()-1), or paNoDevice
- if no default input device is available.
- */
- PaDeviceIndex defaultInputDevice;
-
- /** The default output device for this host API. The value will be a
- device index ranging from 0 to (Pa_GetDeviceCount()-1), or paNoDevice
- if no default output device is available.
- */
- PaDeviceIndex defaultOutputDevice;
-
-} PaHostApiInfo;
-
-
-/** Retrieve a pointer to a structure containing information about a specific
- host Api.
-
- @param hostApi A valid host API index ranging from 0 to (Pa_GetHostApiCount()-1)
-
- @return A pointer to an immutable PaHostApiInfo structure describing
- a specific host API. If the hostApi parameter is out of range or an error
- is encountered, the function returns NULL.
-
- The returned structure is owned by the PortAudio implementation and must not
- be manipulated or freed. The pointer is only guaranteed to be valid between
- calls to Pa_Initialize() and Pa_Terminate().
-*/
-const PaHostApiInfo * Pa_GetHostApiInfo( PaHostApiIndex hostApi );
-
-
-/** Convert a static host API unique identifier, into a runtime
- host API index.
-
- @param type A unique host API identifier belonging to the PaHostApiTypeId
- enumeration.
-
- @return A valid PaHostApiIndex ranging from 0 to (Pa_GetHostApiCount()-1) or,
- a PaErrorCode (which are always negative) if PortAudio is not initialized
- or an error is encountered.
-
- The paHostApiNotFound error code indicates that the host API specified by the
- type parameter is not available.
-
- @see PaHostApiTypeId
-*/
-PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type );
-
-
-/** Convert a host-API-specific device index to standard PortAudio device index.
- This function may be used in conjunction with the deviceCount field of
- PaHostApiInfo to enumerate all devices for the specified host API.
-
- @param hostApi A valid host API index ranging from 0 to (Pa_GetHostApiCount()-1)
-
- @param hostApiDeviceIndex A valid per-host device index in the range
- 0 to (Pa_GetHostApiInfo(hostApi)->deviceCount-1)
-
- @return A non-negative PaDeviceIndex ranging from 0 to (Pa_GetDeviceCount()-1)
- or, a PaErrorCode (which are always negative) if PortAudio is not initialized
- or an error is encountered.
-
- A paInvalidHostApi error code indicates that the host API index specified by
- the hostApi parameter is out of range.
-
- A paInvalidDevice error code indicates that the hostApiDeviceIndex parameter
- is out of range.
-
- @see PaHostApiInfo
-*/
-PaDeviceIndex Pa_HostApiDeviceIndexToDeviceIndex( PaHostApiIndex hostApi,
- int hostApiDeviceIndex );
-
-
-
-/** Structure used to return information about a host error condition.
-*/
-typedef struct PaHostErrorInfo{
- PaHostApiTypeId hostApiType; /**< the host API which returned the error code */
- long errorCode; /**< the error code returned */
- const char *errorText; /**< a textual description of the error if available, otherwise a zero-length string */
-}PaHostErrorInfo;
-
-
-/** Return information about the last host error encountered. The error
- information returned by Pa_GetLastHostErrorInfo() will never be modified
- asyncronously by errors occurring in other PortAudio owned threads
- (such as the thread that manages the stream callback.)
-
- This function is provided as a last resort, primarily to enhance debugging
- by providing clients with access to all available error information.
-
- @return A pointer to an immutable structure constaining information about
- the host error. The values in this structure will only be valid if a
- PortAudio function has previously returned the paUnanticipatedHostError
- error code.
-*/
-const PaHostErrorInfo* Pa_GetLastHostErrorInfo( void );
-
-
-
-/* Device enumeration and capabilities */
-
-/** Retrieve the number of available devices. The number of available devices
- may be zero.
-
- @return A non-negative value indicating the number of available devices or,
- a PaErrorCode (which are always negative) if PortAudio is not initialized
- or an error is encountered.
-*/
-PaDeviceIndex Pa_GetDeviceCount( void );
-
-
-/** Retrieve the index of the default input device. The result can be
- used in the inputDevice parameter to Pa_OpenStream().
-
- @return The default input device index for the default host API, or paNoDevice
- if no default input device is available or an error was encountered.
-*/
-PaDeviceIndex Pa_GetDefaultInputDevice( void );
-
-
-/** Retrieve the index of the default output device. The result can be
- used in the outputDevice parameter to Pa_OpenStream().
-
- @return The default output device index for the defualt host API, or paNoDevice
- if no default output device is available or an error was encountered.
-
- @note
- On the PC, the user can specify a default device by
- setting an environment variable. For example, to use device #1.
-<pre>
- set PA_RECOMMENDED_OUTPUT_DEVICE=1
-</pre>
- The user should first determine the available device ids by using
- the supplied application "pa_devs".
-*/
-PaDeviceIndex Pa_GetDefaultOutputDevice( void );
-
-
-/** The type used to represent monotonic time in seconds that can be used
- for syncronisation. The type is used for the outTime argument to the
- PaStreamCallback and as the result of Pa_GetStreamTime().
-
- @see PaStreamCallback, Pa_GetStreamTime
-*/
-typedef double PaTime;
-
-
-/** A type used to specify one or more sample formats. Each value indicates
- a possible format for sound data passed to and from the stream callback,
- Pa_ReadStream and Pa_WriteStream.
-
- The standard formats paFloat32, paInt16, paInt32, paInt24, paInt8
- and aUInt8 are usually implemented by all implementations.
-
- The floating point representation (paFloat32) uses +1.0 and -1.0 as the
- maximum and minimum respectively.
-
- paUInt8 is an unsigned 8 bit format where 128 is considered "ground"
-
- The paNonInterleaved flag indicates that a multichannel buffer is passed
- as a set of non-interleaved pointers.
-
- @see Pa_OpenStream, Pa_OpenDefaultStream, PaDeviceInfo
- @see paFloat32, paInt16, paInt32, paInt24, paInt8
- @see paUInt8, paCustomFormat, paNonInterleaved
-*/
-typedef unsigned long PaSampleFormat;
-
-
-#define paFloat32 ((PaSampleFormat) 0x00000001) /**< @see PaSampleFormat */
-#define paInt32 ((PaSampleFormat) 0x00000002) /**< @see PaSampleFormat */
-#define paInt24 ((PaSampleFormat) 0x00000004) /**< Packed 24 bit format. @see PaSampleFormat */
-#define paInt16 ((PaSampleFormat) 0x00000008) /**< @see PaSampleFormat */
-#define paInt8 ((PaSampleFormat) 0x00000010) /**< @see PaSampleFormat */
-#define paUInt8 ((PaSampleFormat) 0x00000020) /**< @see PaSampleFormat */
-#define paCustomFormat ((PaSampleFormat) 0x00010000)/**< @see PaSampleFormat */
-
-#define paNonInterleaved ((PaSampleFormat) 0x80000000)
-
-/** A structure providing information and capabilities of PortAudio devices.
- Devices may support input, output or both input and output.
-*/
-typedef struct PaDeviceInfo
-{
- int structVersion; /* this is struct version 2 */
- const char *name;
- PaHostApiIndex hostApi; /* note this is a host API index, not a type id*/
-
- int maxInputChannels;
- int maxOutputChannels;
-
- /* Default latency values for interactive performance. */
- PaTime defaultLowInputLatency;
- PaTime defaultLowOutputLatency;
- /* Default latency values for robust non-interactive applications (eg. playing sound files). */
- PaTime defaultHighInputLatency;
- PaTime defaultHighOutputLatency;
-
- double defaultSampleRate;
-} PaDeviceInfo;
-
-
-/** Retrieve a pointer to a PaDeviceInfo structure containing information
- about the specified device.
- @return A pointer to an immutable PaDeviceInfo structure. If the device
- parameter is out of range the function returns NULL.
-
- @param device A valid device index in the range 0 to (Pa_GetDeviceCount()-1)
-
- @note PortAudio manages the memory referenced by the returned pointer,
- the client must not manipulate or free the memory. The pointer is only
- guaranteed to be valid between calls to Pa_Initialize() and Pa_Terminate().
-
- @see PaDeviceInfo, PaDeviceIndex
-*/
-const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceIndex device );
-
-
-/** Parameters for one direction (input or output) of a stream.
-*/
-typedef struct PaStreamParameters
-{
- /** A valid device index in the range 0 to (Pa_GetDeviceCount()-1)
- specifying the device to be used or the special constant
- paUseHostApiSpecificDeviceSpecification which indicates that the actual
- device(s) to use are specified in hostApiSpecificStreamInfo.
- This field must not be set to paNoDevice.
- */
- PaDeviceIndex device;
-
- /** The number of channels of sound to be delivered to the
- stream callback or accessed by Pa_ReadStream() or Pa_WriteStream().
- It can range from 1 to the value of maxInputChannels in the
- PaDeviceInfo record for the device specified by the device parameter.
- */
- int channelCount;
-
- /** The sample format of the buffer provided to the stream callback,
- a_ReadStream() or Pa_WriteStream(). It may be any of the formats described
- by the PaSampleFormat enumeration.
- */
- PaSampleFormat sampleFormat;
-
- /** The desired latency in seconds. Where practical, implementations should
- configure their latency based on these parameters, otherwise they may
- choose the closest viable latency instead. Unless the suggested latency
- is greater than the absolute upper limit for the device implementations
- should round the suggestedLatency up to the next practial value - ie to
- provide an equal or higher latency than suggestedLatency wherever possibe.
- Actual latency values for an open stream may be retrieved using the
- inputLatency and outputLatency fields of the PaStreamInfo structure
- returned by Pa_GetStreamInfo().
- @see default*Latency in PaDeviceInfo, *Latency in PaStreamInfo
- */
- PaTime suggestedLatency;
-
- /** An optional pointer to a host api specific data structure
- containing additional information for device setup and/or stream processing.
- hostApiSpecificStreamInfo is never required for correct operation,
- if not used it should be set to NULL.
- */
- void *hostApiSpecificStreamInfo;
-
-} PaStreamParameters;
-
-
-/** Return code for Pa_IsFormatSupported indicating success. */
-#define paFormatIsSupported (0)
-
-/** Determine whether it would be possible to open a stream with the specified
- parameters.
-
- @param inputParameters A structure that describes the input parameters used to
- open a stream. The suggestedLatency field is ignored. See PaStreamParameters
- for a description of these parameters. inputParameters must be NULL for
- output-only streams.
-
- @param outputParameters A structure that describes the output parameters used
- to open a stream. The suggestedLatency field is ignored. See PaStreamParameters
- for a description of these parameters. outputParameters must be NULL for
- input-only streams.
-
- @param sampleRate The required sampleRate. For full-duplex streams it is the
- sample rate for both input and output
-
- @return Returns 0 if the format is supported, and an error code indicating why
- the format is not supported otherwise. The constant paFormatIsSupported is
- provided to compare with the return value for success.
-
- @see paFormatIsSupported, PaStreamParameters
-*/
-PaError Pa_IsFormatSupported( const PaStreamParameters *inputParameters,
- const PaStreamParameters *outputParameters,
- double sampleRate );
-
-
-
-/* Streaming types and functions */
-
-
-/**
- A single PaStream can provide multiple channels of real-time
- streaming audio input and output to a client application. A stream
- provides access to audio hardware represented by one or more
- PaDevices. Depending on the underlying Host API, it may be possible
- to open multiple streams using the same device, however this behavior
- is implementation defined. Portable applications should assume that
- a PaDevice may be simultaneously used by at most one PaStream.
-
- Pointers to PaStream objects are passed between PortAudio functions that
- operate on streams.
-
- @see Pa_OpenStream, Pa_OpenDefaultStream, Pa_OpenDefaultStream, Pa_CloseStream,
- Pa_StartStream, Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive,
- Pa_GetStreamTime, Pa_GetStreamCpuLoad
-
-*/
-typedef void PaStream;
-
-
-/** Can be passed as the framesPerBuffer parameter to Pa_OpenStream()
- or Pa_OpenDefaultStream() to indicate that the stream callback will
- accept buffers of any size.
-*/
-#define paFramesPerBufferUnspecified (0)
-
-
-/** Flags used to control the behavior of a stream. They are passed as
- parameters to Pa_OpenStream or Pa_OpenDefaultStream. Multiple flags may be
- ORed together.
-
- @see Pa_OpenStream, Pa_OpenDefaultStream
- @see paNoFlag, paClipOff, paDitherOff, paNeverDropInput,
- paPrimeOutputBuffersUsingStreamCallback, paPlatformSpecificFlags
-*/
-typedef unsigned long PaStreamFlags;
-
-/** @see PaStreamFlags */
-#define paNoFlag ((PaStreamFlags) 0)
-
-/** Disable default clipping of out of range samples.
- @see PaStreamFlags
-*/
-#define paClipOff ((PaStreamFlags) 0x00000001)
-
-/** Disable default dithering.
- @see PaStreamFlags
-*/
-#define paDitherOff ((PaStreamFlags) 0x00000002)
-
-/** Flag requests that where possible a full duplex stream will not discard
- overflowed input samples without calling the stream callback. This flag is
- only valid for full duplex callback streams and only when used in combination
- with the paFramesPerBufferUnspecified (0) framesPerBuffer parameter. Using
- this flag incorrectly results in a paInvalidFlag error being returned from
- Pa_OpenStream and Pa_OpenDefaultStream.
-
- @see PaStreamFlags, paFramesPerBufferUnspecified
-*/
-#define paNeverDropInput ((PaStreamFlags) 0x00000004)
-
-/** Call the stream callback to fill initial output buffers, rather than the
- default behavior of priming the buffers with zeros (silence). This flag has
- no effect for input-only and blocking read/write streams.
-
- @see PaStreamFlags
-*/
-#define paPrimeOutputBuffersUsingStreamCallback ((PaStreamFlags) 0x00000008)
-
-/** A mask specifying the platform specific bits.
- @see PaStreamFlags
-*/
-#define paPlatformSpecificFlags ((PaStreamFlags)0xFFFF0000)
-
-/**
- Timing information for the buffers passed to the stream callback.
-*/
-typedef struct PaStreamCallbackTimeInfo{
- PaTime inputBufferAdcTime;
- PaTime currentTime;
- PaTime outputBufferDacTime;
-} PaStreamCallbackTimeInfo;
-
-
-/**
- Flag bit constants for the statusFlags to PaStreamCallback.
-
- @see paInputUnderflow, paInputOverflow, paOutputUnderflow, paOutputOverflow,
- paPrimingOutput
-*/
-typedef unsigned long PaStreamCallbackFlags;
-
-/** In a stream opened with paFramesPerBufferUnspecified, indicates that
- input data is all silence (zeros) because no real data is available. In a
- stream opened without paFramesPerBufferUnspecified, it indicates that one or
- more zero samples have been inserted into the input buffer to compensate
- for an input underflow.
- @see PaStreamCallbackFlags
-*/
-#define paInputUnderflow ((PaStreamCallbackFlags) 0x00000001)
-
-/** In a stream opened with paFramesPerBufferUnspecified, indicates that data
- prior to the first sample of the input buffer was discarded due to an
- overflow, possibly because the stream callback is using too much CPU time.
- Otherwise indicates that data prior to one or more samples in the
- input buffer was discarded.
- @see PaStreamCallbackFlags
-*/
-#define paInputOverflow ((PaStreamCallbackFlags) 0x00000002)
-
-/** Indicates that output data (or a gap) was inserted, possibly because the
- stream callback is using too much CPU time.
- @see PaStreamCallbackFlags
-*/
-#define paOutputUnderflow ((PaStreamCallbackFlags) 0x00000004)
-
-/** Indicates that output data will be discarded because no room is available.
- @see PaStreamCallbackFlags
-*/
-#define paOutputOverflow ((PaStreamCallbackFlags) 0x00000008)
-
-/** Some of all of the output data will be used to prime the stream, input
- data may be zero.
- @see PaStreamCallbackFlags
-*/
-#define paPrimingOutput ((PaStreamCallbackFlags) 0x00000010)
-
-/**
- Allowable return values for the PaStreamCallback.
- @see PaStreamCallback
-*/
-typedef enum PaStreamCallbackResult
-{
- paContinue=0,
- paComplete=1,
- paAbort=2
-} PaStreamCallbackResult;
-
-
-/**
- Functions of type PaStreamCallback are implemented by PortAudio clients.
- They consume, process or generate audio in response to requests from an
- active PortAudio stream.
-
- @param input and @param output are arrays of interleaved samples,
- the format, packing and number of channels used by the buffers are
- determined by parameters to Pa_OpenStream().
-
- @param frameCount The number of sample frames to be processed by
- the stream callback.
-
- @param timeInfo The time in seconds when the first sample of the input
- buffer was received at the audio input, the time in seconds when the first
- sample of the output buffer will begin being played at the audio output, and
- the time in seconds when the stream callback was called.
- See also Pa_GetStreamTime()
-
- @param statusFlags Flags indicating whether input and/or output buffers
- have been inserted or will be dropped to overcome underflow or overflow
- conditions.
-
- @param userData The value of a user supplied pointer passed to
- Pa_OpenStream() intended for storing synthesis data etc.
-
- @return
- The stream callback should return one of the values in the
- PaStreamCallbackResult enumeration. To ensure that the callback continues
- to be called, it should return paContinue (0). Either paComplete or paAbort
- can be returned to finish stream processing, after either of these values is
- returned the callback will not be called again. If paAbort is returned the
- stream will finish as soon as possible. If paComplete is returned, the stream
- will continue until all buffers generated by the callback have been played.
- This may be useful in applications such as soundfile players where a specific
- duration of output is required. However, it is not necessary to utilise this
- mechanism as Pa_StopStream(), Pa_AbortStream() or Pa_CloseStream() can also
- be used to stop the stream. The callback must always fill the entire output
- buffer irrespective of its return value.
-
- @see Pa_OpenStream, Pa_OpenDefaultStream
-
- @note With the exception of Pa_GetStreamCpuLoad() it is not permissable to call
- PortAudio API functions from within the stream callback.
-*/
-typedef int PaStreamCallback(
- const void *input, void *output,
- unsigned long frameCount,
- const PaStreamCallbackTimeInfo* timeInfo,
- PaStreamCallbackFlags statusFlags,
- void *userData );
-
-
-/** Opens a stream for either input, output or both.
-
- @param stream The address of a PaStream pointer which will receive
- a pointer to the newly opened stream.
-
- @param inputParameters A structure that describes the input parameters used by
- the opened stream. See PaStreamParameters for a description of these parameters.
- inputParameters must be NULL for output-only streams.
-
- @param outputParameters A structure that describes the output parameters used by
- the opened stream. See PaStreamParameters for a description of these parameters.
- outputParameters must be NULL for input-only streams.
-
- @param sampleRate The desired sampleRate. For full-duplex streams it is the
- sample rate for both input and output
-
- @param framesPerBuffer The number of frames passed to the stream callback
- function, or the preferred block granularity for a blocking read/write stream.
- The special value paFramesPerBufferUnspecified (0) may be used to request that
- the stream callback will recieve an optimal (and possibly varying) number of
- frames based on host requirements and the requested latency settings.
- Note: With some host APIs, the use of non-zero framesPerBuffer for a callback
- stream may introduce an additional layer of buffering which could introduce
- additional latency. PortAudio guarantees that the additional latency
- will be kept to the theoretical minimum however, it is strongly recommended
- that a non-zero framesPerBuffer value only be used when your algorithm
- requires a fixed number of frames per stream callback.
-
- @param streamFlags Flags which modify the behaviour of the streaming process.
- This parameter may contain a combination of flags ORed together. Some flags may
- only be relevant to certain buffer formats.
-
- @param streamCallback A pointer to a client supplied function that is responsible
- for processing and filling input and output buffers. If this parameter is NULL
- the stream will be opened in 'blocking read/write' mode. In blocking mode,
- the client can receive sample data using Pa_ReadStream and write sample data
- using Pa_WriteStream, the number of samples that may be read or written
- without blocking is returned by Pa_GetStreamReadAvailable and
- Pa_GetStreamWriteAvailable respectively.
-
- @param userData A client supplied pointer which is passed to the stream callback
- function. It could for example, contain a pointer to instance data necessary
- for processing the audio buffers. This parameter is ignored if streamCallback
- is NULL.
-
- @return
- Upon success Pa_OpenStream() returns paNoError and places a pointer to a
- valid PaStream in the stream argument. The stream is inactive (stopped).
- If a call to Pa_OpenStream() fails, a non-zero error code is returned (see
- PaError for possible error codes) and the value of stream is invalid.
-
- @see PaStreamParameters, PaStreamCallback, Pa_ReadStream, Pa_WriteStream,
- Pa_GetStreamReadAvailable, Pa_GetStreamWriteAvailable
-*/
-PaError Pa_OpenStream( PaStream** stream,
- const PaStreamParameters *inputParameters,
- const PaStreamParameters *outputParameters,
- double sampleRate,
- unsigned long framesPerBuffer,
- PaStreamFlags streamFlags,
- PaStreamCallback *streamCallback,
- void *userData );
-
-
-/** A simplified version of Pa_OpenStream() that opens the default input
- and/or output devices.
-
- @param stream The address of a PaStream pointer which will receive
- a pointer to the newly opened stream.
-
- @param numInputChannels The number of channels of sound that will be supplied
- to the stream callback or returned by Pa_ReadStream. It can range from 1 to
- the value of maxInputChannels in the PaDeviceInfo record for the default input
- device. If 0 the stream is opened as an output-only stream.
-
- @param numOutputChannels The number of channels of sound to be delivered to the
- stream callback or passed to Pa_WriteStream. It can range from 1 to the value
- of maxOutputChannels in the PaDeviceInfo record for the default output dvice.
- If 0 the stream is opened as an output-only stream.
-
- @param sampleFormat The sample format of both the input and output buffers
- provided to the callback or passed to and from Pa_ReadStream and Pa_WriteStream.
- sampleFormat may be any of the formats described by the PaSampleFormat
- enumeration.
-
- @param sampleRate Same as Pa_OpenStream parameter of the same name.
- @param framesPerBuffer Same as Pa_OpenStream parameter of the same name.
- @param streamCallback Same as Pa_OpenStream parameter of the same name.
- @param userData Same as Pa_OpenStream parameter of the same name.
-
- @return As for Pa_OpenStream
-
- @see Pa_OpenStream, PaStreamCallback
-*/
-PaError Pa_OpenDefaultStream( PaStream** stream,
- int numInputChannels,
- int numOutputChannels,
- PaSampleFormat sampleFormat,
- double sampleRate,
- unsigned long framesPerBuffer,
- PaStreamCallback *streamCallback,
- void *userData );
-
-
-/** Closes an audio stream. If the audio stream is active it
- discards any pending buffers as if Pa_AbortStream() had been called.
-*/
-PaError Pa_CloseStream( PaStream *stream );
-
-
-/** Functions of type PaStreamFinishedCallback are implemented by PortAudio
- clients. They can be registered with a stream using the Pa_SetStreamFinishedCallback
- function. Once registered they are called when the stream becomes inactive
- (ie once a call to Pa_StopStream() will not block).
- A stream will become inactive after the stream callback returns non-zero,
- or when Pa_StopStream or Pa_AbortStream is called. For a stream providing audio
- output, if the stream callback returns paComplete, or Pa_StopStream is called,
- the stream finished callback will not be called until all generated sample data
- has been played.
-
- @param userData The userData parameter supplied to Pa_OpenStream()
-
- @see Pa_SetStreamFinishedCallback
-*/
-typedef void PaStreamFinishedCallback( void *userData );
-
-
-/** Register a stream finished callback function which will be called when the
- stream becomes inactive. See the description of PaStreamFinishedCallback for
- further details about when the callback will be called.
-
- @param stream a pointer to a PaStream that is in the stopped state - if the
- stream is not stopped, the stream's finished callback will remain unchanged
- and an error code will be returned.
-
- @param streamFinishedCallback a pointer to a function with the same signature
- as PaStreamFinishedCallback, that will be called when the stream becomes
- inactive. Passing NULL for this parameter will un-register a previously
- registered stream finished callback function.
-
- @return on success returns paNoError, otherwise an error code indicating the cause
- of the error.
-
- @see PaStreamFinishedCallback
-*/
-PaError Pa_SetStreamFinishedCallback( PaStream *stream, PaStreamFinishedCallback* streamFinishedCallback );
-
-
-/** Commences audio processing.
-*/
-PaError Pa_StartStream( PaStream *stream );
-
-
-/** Terminates audio processing. It waits until all pending
- audio buffers have been played before it returns.
-*/
-PaError Pa_StopStream( PaStream *stream );
-
-
-/** Terminates audio processing immediately without waiting for pending
- buffers to complete.
-*/
-PaError Pa_AbortStream( PaStream *stream );
-
-
-/** Determine whether the stream is stopped.
- A stream is considered to be stopped prior to a successful call to
- Pa_StartStream and after a successful call to Pa_StopStream or Pa_AbortStream.
- If a stream callback returns a value other than paContinue the stream is NOT
- considered to be stopped.
-
- @return Returns one (1) when the stream is stopped, zero (0) when
- the stream is running or, a PaErrorCode (which are always negative) if
- PortAudio is not initialized or an error is encountered.
-
- @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive
-*/
-PaError Pa_IsStreamStopped( PaStream *stream );
-
-
-/** Determine whether the stream is active.
- A stream is active after a successful call to Pa_StartStream(), until it
- becomes inactive either as a result of a call to Pa_StopStream() or
- Pa_AbortStream(), or as a result of a return value other than paContinue from
- the stream callback. In the latter case, the stream is considered inactive
- after the last buffer has finished playing.
-
- @return Returns one (1) when the stream is active (ie playing or recording
- audio), zero (0) when not playing or, a PaErrorCode (which are always negative)
- if PortAudio is not initialized or an error is encountered.
-
- @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamStopped
-*/
-PaError Pa_IsStreamActive( PaStream *stream );
-
-
-
-/** A structure containing unchanging information about an open stream.
- @see Pa_GetStreamInfo
-*/
-
-typedef struct PaStreamInfo
-{
- /** this is struct version 1 */
- int structVersion;
-
- /** The input latency of the stream in seconds. This value provides the most
- accurate estimate of input latency available to the implementation. It may
- differ significantly from the suggestedLatency value passed to Pa_OpenStream().
- The value of this field will be zero (0.) for output-only streams.
- @see PaTime
- */
- PaTime inputLatency;
-
- /** The output latency of the stream in seconds. This value provides the most
- accurate estimate of output latency available to the implementation. It may
- differ significantly from the suggestedLatency value passed to Pa_OpenStream().
- The value of this field will be zero (0.) for input-only streams.
- @see PaTime
- */
- PaTime outputLatency;
-
- /** The sample rate of the stream in Hertz (samples per second). In cases
- where the hardware sample rate is inaccurate and PortAudio is aware of it,
- the value of this field may be different from the sampleRate parameter
- passed to Pa_OpenStream(). If information about the actual hardware sample
- rate is not available, this field will have the same value as the sampleRate
- parameter passed to Pa_OpenStream().
- */
- double sampleRate;
-
-} PaStreamInfo;
-
-
-/** Retrieve a pointer to a PaStreamInfo structure containing information
- about the specified stream.
- @return A pointer to an immutable PaStreamInfo structure. If the stream
- parameter invalid, or an error is encountered, the function returns NULL.
-
- @param stream A pointer to an open stream previously created with Pa_OpenStream.
-
- @note PortAudio manages the memory referenced by the returned pointer,
- the client must not manipulate or free the memory. The pointer is only
- guaranteed to be valid until the specified stream is closed.
-
- @see PaStreamInfo
-*/
-const PaStreamInfo* Pa_GetStreamInfo( PaStream *stream );
-
-
-/** Determine the current time for the stream according to the same clock used
- to generate buffer timestamps. This time may be used for syncronising other
- events to the audio stream, for example synchronizing audio to MIDI.
-
- @return The stream's current time in seconds, or 0 if an error occurred.
-
- @see PaTime, PaStreamCallback
-*/
-PaTime Pa_GetStreamTime( PaStream *stream );
-
-
-/** Retrieve CPU usage information for the specified stream.
- The "CPU Load" is a fraction of total CPU time consumed by a callback stream's
- audio processing routines including, but not limited to the client supplied
- stream callback. This function does not work with blocking read/write streams.
-
- This function may be called from the stream callback function or the
- application.
-
- @return
- A floating point value, typically between 0.0 and 1.0, where 1.0 indicates
- that the stream callback is consuming the maximum number of CPU cycles possible
- to maintain real-time operation. A value of 0.5 would imply that PortAudio and
- the stream callback was consuming roughly 50% of the available CPU time. The
- return value may exceed 1.0. A value of 0.0 will always be returned for a
- blocking read/write stream, or if an error occurrs.
-*/
-double Pa_GetStreamCpuLoad( PaStream* stream );
-
-
-/** Read samples from an input stream. The function doesn't return until
- the entire buffer has been filled - this may involve waiting for the operating
- system to supply the data.
-
- @param stream A pointer to an open stream previously created with Pa_OpenStream.
-
- @param buffer A pointer to a buffer of sample frames. The buffer contains
- samples in the format specified by the inputParameters->sampleFormat field
- used to open the stream, and the number of channels specified by
- inputParameters->numChannels. If non-interleaved samples were requested,
- buffer is a pointer to the first element of an array of non-interleaved
- buffer pointers, one for each channel.
-
- @param frames The number of frames to be read into buffer. This parameter
- is not constrained to a specific range, however high performance applications
- will want to match this parameter to the framesPerBuffer parameter used
- when opening the stream.
-
- @return On success PaNoError will be returned, or PaInputOverflowed if input
- data was discarded by PortAudio after the previous call and before this call.
-*/
-PaError Pa_ReadStream( PaStream* stream,
- void *buffer,
- unsigned long frames );
-
-
-/** Write samples to an output stream. This function doesn't return until the
- entire buffer has been consumed - this may involve waiting for the operating
- system to consume the data.
-
- @param stream A pointer to an open stream previously created with Pa_OpenStream.
-
- @param buffer A pointer to a buffer of sample frames. The buffer contains
- samples in the format specified by the outputParameters->sampleFormat field
- used to open the stream, and the number of channels specified by
- outputParameters->numChannels. If non-interleaved samples were requested,
- buffer is a pointer to the first element of an array of non-interleaved
- buffer pointers, one for each channel.
-
- @param frames The number of frames to be written from buffer. This parameter
- is not constrained to a specific range, however high performance applications
- will want to match this parameter to the framesPerBuffer parameter used
- when opening the stream.
-
- @return On success PaNoError will be returned, or paOutputUnderflowed if
- additional output data was inserted after the previous call and before this
- call.
-*/
-PaError Pa_WriteStream( PaStream* stream,
- const void *buffer,
- unsigned long frames );
-
-
-/** Retrieve the number of frames that can be read from the stream without
- waiting.
-
- @return Returns a non-negative value representing the maximum number of frames
- that can be read from the stream without blocking or busy waiting or, a
- PaErrorCode (which are always negative) if PortAudio is not initialized or an
- error is encountered.
-*/
-signed long Pa_GetStreamReadAvailable( PaStream* stream );
-
-
-/** Retrieve the number of frames that can be written to the stream without
- waiting.
-
- @return Returns a non-negative value representing the maximum number of frames
- that can be written to the stream without blocking or busy waiting or, a
- PaErrorCode (which are always negative) if PortAudio is not initialized or an
- error is encountered.
-*/
-signed long Pa_GetStreamWriteAvailable( PaStream* stream );
-
-
-/* Miscellaneous utilities */
-
-
-/** Retrieve the size of a given sample format in bytes.
-
- @return The size in bytes of a single sample in the specified format,
- or paSampleFormatNotSupported if the format is not supported.
-*/
-PaError Pa_GetSampleSize( PaSampleFormat format );
-
-
-/** Put the caller to sleep for at least 'msec' milliseconds. This function is
- provided only as a convenience for authors of portable code (such as the tests
- and examples in the PortAudio distribution.)
-
- The function may sleep longer than requested so don't rely on this for accurate
- musical timing.
-*/
-void Pa_Sleep( long msec );
-
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* PORTAUDIO_H */
diff --git a/navit/support/espeak/readclause.c b/navit/support/espeak/readclause.c
deleted file mode 100644
index b8d302a27..000000000
--- a/navit/support/espeak/readclause.c
+++ /dev/null
@@ -1,2440 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2005 to 2007 by Jonathan Duddington *
- * email: jonsd@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write see: *
- * <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-#include "StdAfx.h"
-
-#include <stdio.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-#include <wctype.h>
-#include <wchar.h>
-#include <math.h>
-
-#include "speak_lib.h"
-#include "speech.h"
-#include "phoneme.h"
-#include "synthesize.h"
-#include "voice.h"
-#include "translate.h"
-
-#ifdef PLATFORM_POSIX
-#include <unistd.h>
-#endif
-
-#include <locale.h>
-#define N_XML_BUF 256
-
-#define double(x) ((double)(x))
-static const char *xmlbase = ""; // base URL from <speak>
-
-static int namedata_ix=0;
-static int n_namedata = 0;
-char *namedata = NULL;
-
-
-static FILE *f_input = NULL;
-static int ungot_char2 = 0;
-unsigned char *p_textinput;
-wchar_t *p_wchar_input;
-static int ungot_char;
-static const char *ungot_word = NULL;
-static int end_of_input;
-
-static int ignore_text=0; // set during <sub> ... </sub> to ignore text which has been replaced by an alias
-static int clear_skipping_text = 0; // next clause should clear the skipping_text flag
-int count_characters = 0;
-static int sayas_mode;
-static int ssml_ignore_l_angle = 0;
-
-static const char *punct_stop = ".:!?"; // pitch fall if followed by space
-static const char *punct_close = ")]}>;'\""; // always pitch fall unless followed by alnum
-
-// alter tone for announce punctuation or capitals
-static const char *tone_punct_on = "\0016T"; // add reverberation, lower pitch
-static const char *tone_punct_off = "\001T";
-
-// punctuations symbols that can end a clause
-static const unsigned short punct_chars[] = {',','.','?','!',':',';',
- 0x2013, // en-dash
- 0x2014, // em-dash
- 0x2026, // elipsis
-
- 0x037e, // Greek question mark (looks like semicolon)
- 0x0387, // Greek semicolon, ano teleia
- 0x0964, // Devanagari Danda (fullstop)
-
- 0x0589, // Armenian period
- 0x055d, // Armenian comma
- 0x055c, // Armenian exclamation
- 0x055e, // Armenian question
- 0x055b, // Armenian emphasis mark
-
- 0x1362, // Ethiopic period
- 0x1363,
- 0x1364,
- 0x1365,
- 0x1366,
- 0x1367,
- 0x1368,
-
- 0x3001, // ideograph comma
- 0x3002, // ideograph period
-
- 0xff01, // fullwidth exclamation
- 0xff0c, // fullwidth comma
- 0xff0e, // fullwidth period
- 0xff1a, // fullwidth colon
- 0xff1b, // fullwidth semicolon
- 0xff1f, // fullwidth question mark
-
- 0};
-
-
-// indexed by (entry num. in punct_chars) + 1
-// bits 0-7 pause x 10mS, bits 12-14 intonation type, bit 15 don't need following space or bracket
-static const unsigned int punct_attributes [] = { 0,
- CLAUSE_COMMA, CLAUSE_PERIOD, CLAUSE_QUESTION, CLAUSE_EXCLAMATION, CLAUSE_COLON, CLAUSE_SEMICOLON,
- CLAUSE_SEMICOLON, // en-dash
- CLAUSE_SEMICOLON, // em-dash
- CLAUSE_SEMICOLON, // elipsis
-
- CLAUSE_QUESTION, // Greek question mark
- CLAUSE_SEMICOLON, // Greek semicolon
- CLAUSE_PERIOD+0x8000, // Devanagari Danda (fullstop)
-
- CLAUSE_PERIOD+0x8000, // Armenian period
- CLAUSE_COMMA, // Armenian comma
- CLAUSE_EXCLAMATION + PUNCT_IN_WORD, // Armenian exclamation
- CLAUSE_QUESTION + PUNCT_IN_WORD, // Armenian question
- CLAUSE_PERIOD + PUNCT_IN_WORD, // Armenian emphasis mark
-
- CLAUSE_PERIOD, // Ethiopic period
- CLAUSE_COMMA, // Ethiopic comma
- CLAUSE_SEMICOLON, // Ethiopic semicolon
- CLAUSE_COLON, // Ethiopic colon
- CLAUSE_COLON, // Ethiopic preface colon
- CLAUSE_QUESTION, // Ethiopic question mark
- CLAUSE_PERIOD, // Ethiopic paragraph
-
- CLAUSE_COMMA+0x8000, // ideograph comma
- CLAUSE_PERIOD+0x8000, // ideograph period
-
- CLAUSE_EXCLAMATION+0x8000, // fullwidth
- CLAUSE_COMMA+0x8000,
- CLAUSE_PERIOD+0x8000,
- CLAUSE_COLON+0x8000,
- CLAUSE_SEMICOLON+0x8000,
- CLAUSE_QUESTION+0x8000,
-
- CLAUSE_SEMICOLON, // spare
- 0 };
-
-
-// stack for language and voice properties
-// frame 0 is for the defaults, before any ssml tags.
-typedef struct {
- int tag_type;
- int voice_variant;
- int voice_gender;
- int voice_age;
- char voice_name[40];
- char language[20];
-} SSML_STACK;
-
-#define N_SSML_STACK 20
-static int n_ssml_stack;
-static SSML_STACK ssml_stack[N_SSML_STACK];
-
-static char current_voice_id[40] = {0};
-
-
-#define N_PARAM_STACK 20
-static int n_param_stack;
-PARAM_STACK param_stack[N_PARAM_STACK];
-
-static int speech_parameters[N_SPEECH_PARAM]; // current values, from param_stack
-
-const int param_defaults[N_SPEECH_PARAM] = {
- 0, // silence (internal use)
- 170, // rate wpm
- 100, // volume
- 50, // pitch
- 50, // range
- 0, // punctuation
- 0, // capital letters
- 0, // wordgap
- 0, // options
- 0, // intonation
- 0,
- 0,
- 0, // emphasis
- 0, // line length
- 0, // voice type
-};
-
-
-#ifdef NEED_WCHAR_FUNCTIONS
-
-// additional Latin characters beyond the Latin1 character set
-#define MAX_WALPHA 0x233
-// indexed by character - 0x100
-// 0=not alphabetic, 0xff=lower case, other=value to add to upper case to convert to lower case
-static unsigned char walpha_tab[MAX_WALPHA-0xff] = {
- 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 100
- 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 110
- 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 120
- 0xff,0xff, 1,0xff, 1,0xff, 1,0xff,0xff, 1,0xff, 1,0xff, 1,0xff, 1, // 130
- 0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff,0xff, 1,0xff, 1,0xff, 1,0xff, // 140
- 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 150
- 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 160
- 1,0xff, 1,0xff, 1,0xff, 1,0xff,0xff, 1,0xff, 1,0xff, 1,0xff,0xff, // 170
- 0xff, 210, 1,0xff, 1,0xff, 206, 1,0xff, 205, 205, 1,0xff,0xff, 79, 202, // 180
- 203, 1,0xff, 205, 207,0xff, 211, 209, 1,0xff,0xff,0xff, 211, 213,0xff, 214, // 190
- 1,0xff, 1,0xff, 1,0xff, 218, 1,0xff, 218,0xff,0xff, 1,0xff, 218, 1, // 1a0
- 0xff, 217, 217, 1,0xff, 1,0xff, 219, 1,0xff,0xff,0xff, 1,0xff,0xff,0xff, // 1b0
- 0xff,0xff,0xff,0xff, 2, 1,0xff, 2, 1,0xff, 2, 1,0xff, 1,0xff, 1, // 1c0
- 0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff,0xff, 1,0xff, // 1d0
- 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 1e0
- 0xff, 2, 1,0xff, 1,0xff,0xff,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 1f0
- 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 200
- 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 210
- 0xff, 0, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 220
- 1,0xff, 1,0xff }; // 230
-
-// use ctype.h functions for Latin1 (character < 0x100)
-int iswalpha(int c)
-{
- if(c < 0x100)
- return(isalpha(c));
- if((c > 0x3040) && (c <= 0xa700))
- return(1); // japanese, chinese characters
- if(c > MAX_WALPHA)
- return(0);
- return(walpha_tab[c-0x100]);
-}
-
-int iswdigit(int c)
-{
- if(c < 0x100)
- return(isdigit(c));
- return(0);
-}
-
-int iswalnum(int c)
-{
- if(iswdigit(c))
- return(1);
- return(iswalpha(c));
-}
-
-int towlower(int c)
-{
- int x;
- if(c < 0x100)
- return(tolower(c));
- if((c > MAX_WALPHA) || ((x = walpha_tab[c-0x100])==0xff))
- return(c); // already lower case
- return(c + x); // convert to lower case
-}
-
-int towupper(int c)
-{
- // check whether the previous character code is the upper-case equivalent of this character
- if(tolower(c-1) == c)
- return(c-1); // yes, use it
- return(c); // no
-}
-
-int iswupper(int c)
-{
- int x;
- if(c < 0x100)
- return(isupper(c));
- if(((c > MAX_WALPHA) || (x = walpha_tab[c-0x100])==0) || (x == 0xff))
- return(0);
- return(1);
-}
-
-int iswlower(int c)
-{
- if(c < 0x100)
- return(islower(c));
- if((c > MAX_WALPHA) || (walpha_tab[c-0x100] != 0xff))
- return(0);
- return(1);
-}
-
-int iswspace(int c)
-{
- if(c < 0x100)
- return(isspace(c));
- return(0);
-}
-
-int iswpunct(int c)
-{
- if(c < 0x100)
- return(ispunct(c));
- return(0);
-}
-
-const wchar_t *wcschr(const wchar_t *str, int c)
-{
- while(*str != 0)
- {
- if(*str == c)
- return(str);
- str++;
- }
- return(NULL);
-}
-
-#ifndef WINCE
-// wcslen() is provided by WINCE, but not the other wchar functions
-const int wcslen(const wchar_t *str)
-{
- int ix=0;
-
- while(*str != 0)
- {
- ix++;
- }
- return(ix);
-}
-#endif
-
-float wcstod(const wchar_t *str, wchar_t **tailptr)
-{
- int ix;
- char buf[80];
- while(isspace(*str)) str++;
- for(ix=0; ix<80; ix++)
- {
- buf[ix] = str[ix];
- if(isspace(buf[ix]))
- break;
- }
- *tailptr = (wchar_t *)&str[ix];
- return(atof(buf));
-}
-#endif
-
-int towlower2(unsigned int c)
-{
- // check for non-standard upper to lower case conversions
- if(c == 'I')
- {
- if(translator->translator_name == L('t','r'))
- {
- c = 0x131; // I -> ı
- }
- }
- return(towlower(c));
-}
-
-static void GetC_unget(int c)
-{//==========================
-// This is only called with UTF8 input, not wchar input
- if(f_input != NULL)
- ungetc(c,f_input);
- else
- {
- p_textinput--;
- *p_textinput = c;
- end_of_input = 0;
- }
-}
-
-int Eof(void)
-{//==========
- if(ungot_char != 0)
- return(0);
-
- if(f_input != 0)
- return(feof(f_input));
-
- return(end_of_input);
-}
-
-
-static int GetC_get(void)
-{//======================
- unsigned int c;
- unsigned int c2;
-
- if(f_input != NULL)
- {
- c = fgetc(f_input);
- if(feof(f_input)) c = ' ';
-
- if(option_multibyte == espeakCHARS_16BIT)
- {
- c2 = fgetc(f_input);
- if(feof(f_input)) c2 = 0;
- c = c + (c2 << 8);
- }
- return(c);
- }
-
- if(option_multibyte == espeakCHARS_WCHAR)
- {
- if(*p_wchar_input == 0)
- {
- end_of_input = 1;
- return(0);
- }
-
- if(!end_of_input)
- return(*p_wchar_input++);
- }
- else
- {
- if(*p_textinput == 0)
- {
- end_of_input = 1;
- return(0);
- }
-
- if(!end_of_input)
- {
- if(option_multibyte == espeakCHARS_16BIT)
- {
- c = p_textinput[0] + (p_textinput[1] << 8);
- p_textinput += 2;
- return(c);
- }
- return(*p_textinput++ & 0xff);
- }
- }
- return(0);
-}
-
-
-static int GetC(void)
-{//==================
-// Returns a unicode wide character
-// Performs UTF8 checking and conversion
-
- int c;
- int c1;
- int c2;
- int cbuf[4];
- int ix;
- int n_bytes;
- unsigned char m;
- static int ungot2 = 0;
- static const unsigned char mask[4] = {0xff,0x1f,0x0f,0x07};
- static const unsigned char mask2[4] = {0,0x80,0x20,0x30};
-
- if((c1 = ungot_char) != 0)
- {
- ungot_char = 0;
- return(c1);
- }
-
- if(ungot2 != 0)
- {
- c1 = ungot2;
- ungot2 = 0;
- }
- else
- {
- c1 = GetC_get();
- }
-
- if((option_multibyte == espeakCHARS_WCHAR) || (option_multibyte == espeakCHARS_16BIT))
- {
- count_characters++;
- return(c1); // wchar_t text
- }
-
- if((option_multibyte < 2) && (c1 & 0x80))
- {
- // multi-byte utf8 encoding, convert to unicode
- n_bytes = 0;
-
- if(((c1 & 0xe0) == 0xc0) && ((c1 & 0x1e) != 0))
- n_bytes = 1;
- else
- if((c1 & 0xf0) == 0xe0)
- n_bytes = 2;
- else
- if(((c1 & 0xf8) == 0xf0) && ((c1 & 0x0f) <= 4))
- n_bytes = 3;
-
- if((ix = n_bytes) > 0)
- {
- c = c1 & mask[ix];
- m = mask2[ix];
- while(ix > 0)
- {
- if((c2 = cbuf[ix] = GetC_get()) == 0)
- {
- if(option_multibyte==espeakCHARS_AUTO)
- option_multibyte=espeakCHARS_8BIT; // change "auto" option to "no"
- GetC_unget(' ');
- break;
- }
-
- if((c2 & 0xc0) != 0x80)
- {
- // This is not UTF8. Change to 8-bit characterset.
- if((n_bytes == 2) && (ix == 1))
- ungot2 = cbuf[2];
- GetC_unget(c2);
- break;
- }
- m = 0x80;
- c = (c << 6) + (c2 & 0x3f);
- ix--;
- }
- if(ix == 0)
- {
- count_characters++;
- return(c);
- }
- }
- // top-bit-set character is not utf8, drop through to 8bit charset case
- if((option_multibyte==espeakCHARS_AUTO) && !Eof())
- option_multibyte=espeakCHARS_8BIT; // change "auto" option to "no"
- }
-
- // 8 bit character set, convert to unicode if
- count_characters++;
- if(c1 >= 0xa0)
- return(translator->charset_a0[c1-0xa0]);
- return(c1);
-} // end of GetC
-
-
-static void UngetC(int c)
-{//======================
- ungot_char = c;
-}
-
-
-static const char *WordToString2(unsigned int word)
-{//================================================
-// Convert a language mnemonic word into a string
- int ix;
- static char buf[5];
- char *p;
-
- p = buf;
- for(ix=3; ix>=0; ix--)
- {
- if((*p = word >> (ix*8)) != 0)
- p++;
- }
- *p = 0;
- return(buf);
-}
-
-
-static const char *LookupSpecial(Translator *tr, const char *string, char* text_out)
-{//=================================================================================
- unsigned int flags[2];
- char phonemes[55];
- char phonemes2[55];
- char *string1 = (char *)string;
-
- if(LookupDictList(tr,&string1,phonemes,flags,0,NULL))
- {
- SetWordStress(tr, phonemes, &flags[0], -1, 0);
- DecodePhonemes(phonemes,phonemes2);
- sprintf(text_out,"[[%s]]",phonemes2);
- option_phoneme_input |= 2;
- return(text_out);
- }
- return(NULL);
-}
-
-
-static const char *LookupCharName(Translator *tr, int c)
-{//=====================================================
-// Find the phoneme string (in ascii) to speak the name of character c
-// Used for punctuation characters and symbols
-
- int ix;
- unsigned int flags[2];
- char single_letter[24];
- char phonemes[60];
- char phonemes2[60];
- const char *lang_name = NULL;
- char *string;
- static char buf[60];
-
- buf[0] = 0;
- flags[0] = 0;
- flags[1] = 0;
- single_letter[0] = 0;
- single_letter[1] = '_';
- ix = utf8_out(c,&single_letter[2]);
- single_letter[2+ix]=0;
-
- string = &single_letter[1];
- if(LookupDictList(tr, &string, phonemes, flags, 0, NULL) == 0)
- {
- // try _* then *
- string = &single_letter[2];
- if(LookupDictList(tr, &string, phonemes, flags, 0, NULL) == 0)
- {
- // now try the rules
- single_letter[1] = ' ';
- TranslateRules(tr, &single_letter[2], phonemes, sizeof(phonemes), NULL,0,NULL);
- }
- }
-
- if((phonemes[0] == 0) && (tr->translator_name != L('e','n')))
- {
- // not found, try English
- SetTranslator2("en");
- string = &single_letter[1];
- single_letter[1] = '_';
- if(LookupDictList(translator2, &string, phonemes, flags, 0, NULL) == 0)
- {
- string = &single_letter[2];
- LookupDictList(translator2, &string, phonemes, flags, 0, NULL);
- }
- if(phonemes[0])
- {
- lang_name = "en";
- }
- else
- {
- SelectPhonemeTable(voice->phoneme_tab_ix); // revert to original phoneme table
- }
- }
-
- if(phonemes[0])
- {
- if(lang_name)
- {
- SetWordStress(translator2, phonemes, &flags[0], -1, 0);
- DecodePhonemes(phonemes,phonemes2);
- sprintf(buf,"[[_^_%s %s _^_%s]]","en",phonemes2,WordToString2(tr->translator_name));
- SelectPhonemeTable(voice->phoneme_tab_ix); // revert to original phoneme table
- }
- else
- {
- SetWordStress(tr, phonemes, &flags[0], -1, 0);
- DecodePhonemes(phonemes,phonemes2);
- sprintf(buf,"[[%s]] ",phonemes2);
- }
- option_phoneme_input |= 2;
- }
- else
- {
- strcpy(buf,"[[(X1)(X1)(X1)]]");
- option_phoneme_input |= 2;
- }
-
- return(buf);
-}
-
-int Read4Bytes(FILE *f)
-{//====================
-// Read 4 bytes (least significant first) into a word
- int ix;
- unsigned char c;
- int acc=0;
-
- for(ix=0; ix<4; ix++)
- {
- c = fgetc(f) & 0xff;
- acc += (c << (ix*8));
- }
- return(acc);
-}
-
-
-static int LoadSoundFile(const char *fname, int index)
-{//===================================================
- FILE *f;
- char *p;
- int *ip;
- int length;
- char fname_temp[100];
- char fname2[sizeof(path_home)+13+40];
-
- if(fname == NULL)
- {
- // filename is already in the table
- fname = soundicon_tab[index].filename;
- }
-
- if(fname==NULL)
- return(1);
-
- if(fname[0] != '/')
- {
- // a relative path, look in espeak-data/soundicons
- sprintf(fname2,"%s%csoundicons%c%s",path_home,PATHSEP,PATHSEP,fname);
- fname = fname2;
- }
-
- f = NULL;
-#ifdef PLATFORM_POSIX
- if((f = fopen(fname,"rb")) != NULL)
- {
- int ix;
- int fd_temp;
- const char *resample;
- int header[3];
- char command[sizeof(fname2)+sizeof(fname2)+40];
-
- fseek(f,20,SEEK_SET);
- for(ix=0; ix<3; ix++)
- header[ix] = Read4Bytes(f);
-
- // if the sound file is not mono, 16 bit signed, at the correct sample rate, then convert it
- if((header[0] != 0x10001) || (header[1] != samplerate) || (header[2] != samplerate*2))
- {
- fclose(f);
- f = NULL;
-
- if(header[2] == samplerate)
- resample = "";
- else
- resample = "polyphase";
-
- strcpy(fname_temp,"/tmp/espeakXXXXXX");
- if((fd_temp = mkstemp(fname_temp)) >= 0)
- {
- close(fd_temp);
-// sprintf(fname_temp,"%s.wav",tmpnam(NULL));
- sprintf(command,"sox \"%s\" -r %d -w -s -c1 %s %s\n", fname, samplerate, fname_temp, resample);
- if(system(command) == 0)
- {
- fname = fname_temp;
- }
- }
- }
- }
-#endif
-
- if(f == NULL)
- {
- f = fopen(fname,"rb");
- if(f == NULL)
- {
- fprintf(stderr,"Can't read temp file: %s\n",fname);
- return(3);
- }
- }
-
- length = GetFileLength(fname);
- fseek(f,0,SEEK_SET);
- if((p = (char *)realloc(soundicon_tab[index].data, length)) == NULL)
- {
- fclose(f);
- return(4);
- }
- fread(p,length,1,f);
- fclose(f);
-#if 0
- remove(fname_temp);
-#endif
-
- ip = (int *)(&p[40]);
- soundicon_tab[index].length = (*ip) / 2; // length in samples
- soundicon_tab[index].data = p;
- return(0);
-} // end of LoadSoundFile
-
-
-static int LookupSoundicon(int c)
-{//==============================
-// Find the sound icon number for a punctuation chatacter
- int ix;
-
- for(ix=N_SOUNDICON_SLOTS; ix<n_soundicon_tab; ix++)
- {
- if(soundicon_tab[ix].name == c)
- {
- if(soundicon_tab[ix].length == 0)
- {
- if(LoadSoundFile(NULL,ix)!=0)
- return(-1); // sound file is not available
- }
- return(ix);
- }
- }
- return(-1);
-}
-
-
-static int LoadSoundFile2(const char *fname)
-{//=========================================
-// Load a sound file into one of the reserved slots in the sound icon table
-// (if it'snot already loaded)
-
- int ix;
- static int slot = -1;
-
- for(ix=0; ix<n_soundicon_tab; ix++)
- {
- if(((soundicon_tab[ix].filename != NULL) && strcmp(fname, soundicon_tab[ix].filename) == 0))
- return(ix); // already loaded
- }
-
- // load the file into the next slot
- slot++;
- if(slot >= N_SOUNDICON_SLOTS)
- slot = 0;
-
- if(LoadSoundFile(fname, slot) != 0)
- return(-1);
-
- soundicon_tab[slot].filename = (char *)realloc(soundicon_tab[ix].filename, strlen(fname)+1);
- strcpy(soundicon_tab[slot].filename, fname);
- return(slot);
-}
-
-
-
-static int AnnouncePunctuation(Translator *tr, int c1, int c2, char *buf, int bufix)
-{//=================================================================================
- // announce punctuation names
- // c1: the punctuation character
- // c2: the following character
-
- int punct_count;
- const char *punctname;
- int found = 0;
- int soundicon;
- char *p;
-
- if((soundicon = LookupSoundicon(c1)) >= 0)
- {
- // add an embedded command to play the soundicon
- sprintf(&buf[bufix],"\001%dI ",soundicon);
- UngetC(c2);
- found = 1;
- }
- else
- if((punctname = LookupCharName(tr, c1)) != NULL)
- {
- found = 1;
- if(bufix==0)
- {
- punct_count=1;
- while(c2 == c1)
- {
- punct_count++;
- c2 = GetC();
- }
- UngetC(c2);
-
- p = &buf[bufix];
- if(punct_count==1)
- {
- sprintf(p,"%s %s %s",tone_punct_on,punctname,tone_punct_off);
- }
- else
- if(punct_count < 4)
- {
- sprintf(p,"\001+10S%s",tone_punct_on);
- while(punct_count-- > 0)
- sprintf(buf,"%s %s",buf,punctname);
- sprintf(p,"%s %s\001-10S",buf,tone_punct_off);
- }
- else
- {
- sprintf(p,"%s %s %d %s %s",
- tone_punct_on,punctname,punct_count,punctname,tone_punct_off);
- return(CLAUSE_COMMA);
- }
- }
- else
- {
- // end the clause now and pick up the punctuation next time
- UngetC(c2);
- if(option_ssml)
- {
- if((c1 == '<') || (c1 == '&'))
- ssml_ignore_l_angle = c1; // this was &lt; which was converted to <, don't pick it up again as <
- }
- ungot_char2 = c1;
- buf[bufix] = ' ';
- buf[bufix+1] = 0;
- }
- }
-
- if(found == 0)
- return(-1);
-
- if(c1 == '-')
- return(CLAUSE_NONE); // no pause
- if(bufix > 0)
- return(CLAUSE_SHORTCOMMA);
- if((strchr_w(punct_close,c1) != NULL) && !iswalnum(c2))
- return(CLAUSE_SHORTFALL+4);
- if(iswspace(c2) && strchr_w(punct_stop,c1)!=NULL)
- return(punct_attributes[lookupwchar(punct_chars,c1)]);
-
- return(CLAUSE_SHORTCOMMA);
-} // end of AnnouncePunctuation
-
-#define SSML_SPEAK 1
-#define SSML_VOICE 2
-#define SSML_PROSODY 3
-#define SSML_SAYAS 4
-#define SSML_MARK 5
-#define SSML_SENTENCE 6
-#define SSML_PARAGRAPH 7
-#define SSML_PHONEME 8
-#define SSML_SUB 9
-#define SSML_STYLE 10
-#define SSML_AUDIO 11
-#define SSML_EMPHASIS 12
-#define SSML_BREAK 13
-#define SSML_IGNORE_TEXT 14
-#define HTML_BREAK 15
-#define SSML_CLOSE 0x10 // for a closing tag, OR this with the tag type
-
-// these tags have no effect if they are self-closing, eg. <voice />
-static char ignore_if_self_closing[] = {0,1,1,1,1,0,0,0,0,1,1,0,1,0,1,0,0};
-
-
-static MNEM_TAB ssmltags[] = {
- {"speak", SSML_SPEAK},
- {"voice", SSML_VOICE},
- {"prosody", SSML_PROSODY},
- {"say-as", SSML_SAYAS},
- {"mark", SSML_MARK},
- {"s", SSML_SENTENCE},
- {"p", SSML_PARAGRAPH},
- {"phoneme", SSML_PHONEME},
- {"sub", SSML_SUB},
- {"tts:style", SSML_STYLE},
- {"audio", SSML_AUDIO},
- {"emphasis", SSML_EMPHASIS},
- {"break", SSML_BREAK},
- {"metadata", SSML_IGNORE_TEXT},
-
- {"br", HTML_BREAK},
- {"li", HTML_BREAK},
- {"img", HTML_BREAK},
- {"td", HTML_BREAK},
- {"h1", SSML_PARAGRAPH},
- {"h2", SSML_PARAGRAPH},
- {"h3", SSML_PARAGRAPH},
- {"h4", SSML_PARAGRAPH},
- {"hr", SSML_PARAGRAPH},
- {"script", SSML_IGNORE_TEXT},
- {"style", SSML_IGNORE_TEXT},
- {NULL,0}};
-
-
-
-
-static const char *VoiceFromStack()
-{//================================
-// Use the voice properties from the SSML stack to choose a voice, and switch
-// to that voice if it's not the current voice
- int ix;
- SSML_STACK *sp;
- const char *v_id;
- int voice_name_specified;
- int voice_found;
- espeak_VOICE voice_select;
- char voice_name[40];
- char language[40];
-
- strcpy(voice_name,ssml_stack[0].voice_name);
- strcpy(language,ssml_stack[0].language);
- voice_select.age = ssml_stack[0].voice_age;
- voice_select.gender = ssml_stack[0].voice_gender;
- voice_select.variant = ssml_stack[0].voice_variant;
- voice_select.identifier = NULL;
-
- for(ix=0; ix<n_ssml_stack; ix++)
- {
- sp = &ssml_stack[ix];
- voice_name_specified = 0;
-
- if((sp->voice_name[0] != 0) && (SelectVoiceByName(NULL,sp->voice_name) != NULL))
- {
- voice_name_specified = 1;
- strcpy(voice_name, sp->voice_name);
- language[0] = 0;
- voice_select.gender = 0;
- voice_select.age = 0;
- voice_select.variant = 0;
- }
- if(sp->language[0] != 0)
- {
- strcpy(language, sp->language);
- if(voice_name_specified == 0)
- voice_name[0] = 0; // forget a previous voice name if a language is specified
- }
- if(sp->voice_gender != 0)
- voice_select.gender = sp->voice_gender;
- if(sp->voice_age != 0)
- voice_select.age = sp->voice_age;
- if(sp->voice_variant != 0)
- voice_select.variant = sp->voice_variant;
- }
-
- voice_select.name = voice_name;
- voice_select.languages = language;
- v_id = SelectVoice(&voice_select, &voice_found);
- if(v_id == NULL)
- return("default");
- return(v_id);
-} // end of VoiceFromStack
-
-
-
-static void ProcessParamStack(char *outbuf, int *outix)
-{//====================================================
-// Set the speech parameters from the parameter stack
- int param;
- int ix;
- int value;
- char buf[20];
- int new_parameters[N_SPEECH_PARAM];
- static char cmd_letter[N_SPEECH_PARAM] = {0, 'S','A','P','R', 0, 0, 0, 0, 0, 0, 0, 'F'}; // embedded command letters
-
-
- for(param=0; param<N_SPEECH_PARAM; param++)
- new_parameters[param] = -1;
-
- for(ix=0; ix<n_param_stack; ix++)
- {
- for(param=0; param<N_SPEECH_PARAM; param++)
- {
- if(param_stack[ix].parameter[param] >= 0)
- new_parameters[param] = param_stack[ix].parameter[param];
- }
- }
-
- for(param=0; param<N_SPEECH_PARAM; param++)
- {
- if((value = new_parameters[param]) != speech_parameters[param])
- {
- buf[0] = 0;
-
- switch(param)
- {
- case espeakPUNCTUATION:
- option_punctuation = value-1;
- break;
-
- case espeakCAPITALS:
- option_capitals = value;
- break;
-
- case espeakRATE:
- case espeakVOLUME:
- case espeakPITCH:
- case espeakRANGE:
- case espeakEMPHASIS:
- sprintf(buf,"%c%d%c",CTRL_EMBEDDED,value,cmd_letter[param]);
- break;
- }
-
- speech_parameters[param] = new_parameters[param];
- strcpy(&outbuf[*outix],buf);
- (*outix) += strlen(buf);
- }
- }
-} // end of ProcessParamStack
-
-
-static PARAM_STACK *PushParamStack(int tag_type)
-{//=============================================
- int ix;
- PARAM_STACK *sp;
-
- sp = &param_stack[n_param_stack];
- if(n_param_stack < (N_PARAM_STACK-1))
- n_param_stack++;
-
- sp->type = tag_type;
- for(ix=0; ix<N_SPEECH_PARAM; ix++)
- {
- sp->parameter[ix] = -1;
- }
- return(sp);
-} // end of PushParamStack
-
-
-static void PopParamStack(int tag_type, char *outbuf, int *outix)
-{//==============================================================
- // unwind the stack up to and including the previous tag of this type
- int ix;
- int top = 0;
-
- if(tag_type >= SSML_CLOSE)
- tag_type -= SSML_CLOSE;
-
- for(ix=0; ix<n_param_stack; ix++)
- {
- if(param_stack[ix].type == tag_type)
- {
- top = ix;
- }
- }
- if(top > 0)
- {
- n_param_stack = top;
- }
- ProcessParamStack(outbuf, outix);
-} // end of PopParamStack
-
-
-
-static wchar_t *GetSsmlAttribute(wchar_t *pw, const char *name)
-{//============================================================
-// Gets the value string for an attribute.
-// Returns NULL if the attribute is not present
- int ix;
- static wchar_t empty[1] = {0};
-
- while(*pw != 0)
- {
- if(iswspace(pw[-1]))
- {
- ix = 0;
- while(*pw == name[ix])
- {
- pw++;
- ix++;
- }
- if(name[ix]==0)
- {
- // found the attribute, now get the value
- while(iswspace(*pw)) pw++;
- if(*pw == '=') pw++;
- while(iswspace(*pw)) pw++;
- if(*pw == '"')
- return(pw+1);
- else
- return(empty);
- }
- }
- pw++;
- }
- return(NULL);
-} // end of GetSsmlAttribute
-
-
-static int attrcmp(const wchar_t *string1, const char *string2)
-{//============================================================
- int ix;
-
- if(string1 == NULL)
- return(1);
-
- for(ix=0; (string1[ix] == string2[ix]) && (string1[ix] != 0); ix++)
- {
- }
- if((string1[ix]=='"') && (string2[ix]==0))
- return(0);
- return(1);
-}
-
-
-static int attrlookup(const wchar_t *string1, const MNEM_TAB *mtab)
-{//================================================================
- int ix;
-
- for(ix=0; mtab[ix].mnem != NULL; ix++)
- {
- if(attrcmp(string1,mtab[ix].mnem) == 0)
- return(mtab[ix].value);
- }
- return(mtab[ix].value);
-}
-
-
-static int attrnumber(const wchar_t *pw, int default_value, int type)
-{//==================================================================
- int value = 0;
-
- if((pw == NULL) || !isdigit(*pw))
- return(default_value);
-
- while(isdigit(*pw))
- {
- value = value*10 + *pw++ - '0';
- }
- if((type==1) && (towlower(*pw)=='s'))
- {
- // time: seconds rather than ms
- value *= 1000;
- }
- return(value);
-} // end of attrnumber
-
-
-
-static int attrcopy_utf8(char *buf, const wchar_t *pw, int len)
-{//============================================================
-// Convert attribute string into utf8, write to buf, and return its utf8 length
- unsigned int c;
- int ix = 0;
- int n;
- int prev_c = 0;
-
- if(pw != NULL)
- {
- while((ix < (len-4)) && ((c = *pw++) != 0))
- {
- if((c=='"') && (prev_c != '\\'))
- break; // " indicates end of attribute, unless preceded by backstroke
- n = utf8_out(c,&buf[ix]);
- ix += n;
- prev_c = c;
- }
- }
- buf[ix] = 0;
- return(ix);
-} // end of attrcopy_utf8
-
-
-
-static int attr_prosody_value(int param_type, const wchar_t *pw, int *value_out)
-{//=============================================================================
- int sign = 0;
- wchar_t *tail;
- float value;
-
- while(iswspace(*pw)) pw++;
- if(*pw == '+')
- {
- pw++;
- sign = 1;
- }
- if(*pw == '-')
- {
- pw++;
- sign = -1;
- }
- value = (float)wcstod(pw,&tail);
- if(tail == pw)
- {
- // failed to find a number, return 100%
- *value_out = 100;
- return(2);
- }
-
- if(*tail == '%')
- {
- if(sign != 0)
- value = 100 + (sign * value);
- *value_out = (int)value;
- return(2); // percentage
- }
-
- if((tail[0]=='s') && (tail[1]=='t'))
- {
- double x;
- // convert from semitones to a frequency percentage
- x = pow(double(2.0),double((value*sign)/12)) * 100;
- *value_out = (int)x;
- return(2); // percentage
- }
-
- if(param_type == espeakRATE)
- {
- *value_out = (int)(value * 100);
- return(2); // percentage
- }
-
- *value_out = (int)value;
- return(sign); // -1, 0, or 1
-} // end of attr_prosody_value
-
-
-int AddNameData(const char *name, int wide)
-{//========================================
-// Add the name to the namedata and return its position
-// (Used by the Windows SAPI wrapper)
- int ix;
- int len;
- void *vp;
-
- if(wide)
- {
- len = (wcslen((const wchar_t *)name)+1)*sizeof(wchar_t);
- n_namedata = (n_namedata + sizeof(wchar_t) - 1) % sizeof(wchar_t); // round to wchar_t boundary
- }
- else
- {
- len = strlen(name)+1;
- }
-
- if(namedata_ix+len >= n_namedata)
- {
- // allocate more space for marker names
- if((vp = realloc(namedata, namedata_ix+len + 300)) == NULL)
- return(-1); // failed to allocate, original data is unchanged but ignore this new name
-
- namedata = (char *)vp;
- n_namedata = namedata_ix+len + 300;
- }
- memcpy(&namedata[ix = namedata_ix],name,len);
- namedata_ix += len;
- return(ix);
-} // end of AddNameData
-
-
-void SetVoiceStack(espeak_VOICE *v)
-{//================================
- SSML_STACK *sp;
- sp = &ssml_stack[0];
-
- if(v == NULL)
- {
- memset(sp,0,sizeof(ssml_stack[0]));
- return;
- }
- if(v->languages != NULL)
- strcpy(sp->language,v->languages);
- if(v->name != NULL)
- strcpy(sp->voice_name,v->name);
- sp->voice_variant = v->variant;
- sp->voice_age = v->age;
- sp->voice_gender = v->gender;
-}
-
-
-static int GetVoiceAttributes(wchar_t *pw, int tag_type)
-{//=====================================================
-// Determines whether voice attribute are specified in this tag, and if so, whether this means
-// a voice change.
-// If it's a closing tag, delete the top frame of the stack and determine whether this implies
-// a voice change.
-// Returns CLAUSE_BIT_VOICE if there is a voice change
-
- wchar_t *lang;
- wchar_t *gender;
- wchar_t *name;
- wchar_t *age;
- wchar_t *variant;
- const char *new_voice_id;
- SSML_STACK *ssml_sp;
-
- static const MNEM_TAB mnem_gender[] = {
- {"male", 1},
- {"female", 2},
- {"neutral", 3},
- {NULL, 0}};
-
- if(tag_type & SSML_CLOSE)
- {
- // delete a stack frame
- if(n_ssml_stack > 1)
- {
- n_ssml_stack--;
- }
- }
- else
- {
- // add a stack frame if any voice details are specified
- lang = GetSsmlAttribute(pw,"xml:lang");
-
- if(tag_type != SSML_VOICE)
- {
- // only expect an xml:lang attribute
- name = NULL;
- variant = NULL;
- age = NULL;
- gender = NULL;
- }
- else
- {
- name = GetSsmlAttribute(pw,"name");
- variant = GetSsmlAttribute(pw,"variant");
- age = GetSsmlAttribute(pw,"age");
- gender = GetSsmlAttribute(pw,"gender");
- }
-
- if((tag_type != SSML_VOICE) && (lang==NULL))
- return(0); // <s> or <p> without language spec, nothing to do
-
- ssml_sp = &ssml_stack[n_ssml_stack++];
-
- attrcopy_utf8(ssml_sp->language,lang,sizeof(ssml_sp->language));
- attrcopy_utf8(ssml_sp->voice_name,name,sizeof(ssml_sp->voice_name));
- ssml_sp->voice_variant = attrnumber(variant,1,0)-1;
- ssml_sp->voice_age = attrnumber(age,0,0);
- ssml_sp->voice_gender = attrlookup(gender,mnem_gender);
- ssml_sp->tag_type = tag_type;
- }
-
- new_voice_id = VoiceFromStack();
- if(strcmp(new_voice_id,current_voice_id) != 0)
- {
- // add an embedded command to change the voice
- strcpy(current_voice_id,new_voice_id);
- return(CLAUSE_BIT_VOICE); // change of voice
- }
-
- return(0);
-} // end of GetVoiceAttributes
-
-
-static void SetProsodyParameter(int param_type, wchar_t *attr1, PARAM_STACK *sp)
-{//=============================================================================
- int value;
- int sign;
-
- static const MNEM_TAB mnem_volume[] = {
- {"default",100},
- {"silent",0},
- {"x-soft",30},
- {"soft",65},
- {"medium",100},
- {"loud",150},
- {"x-loud",230},
- {NULL, -1}};
-
- static const MNEM_TAB mnem_rate[] = {
- {"default",100},
- {"x-slow",60},
- {"slow",80},
- {"medium",100},
- {"fast",120},
- {"x-fast",150},
- {NULL, -1}};
-
- static const MNEM_TAB mnem_pitch[] = {
- {"default",100},
- {"x-low",70},
- {"low",85},
- {"medium",100},
- {"high",110},
- {"x-high",120},
- {NULL, -1}};
-
- static const MNEM_TAB mnem_range[] = {
- {"default",100},
- {"x-low",20},
- {"low",50},
- {"medium",100},
- {"high",140},
- {"x-high",180},
- {NULL, -1}};
-
- static const MNEM_TAB *mnem_tabs[5] = {
- NULL, mnem_rate, mnem_volume, mnem_pitch, mnem_range };
-
-
- if((value = attrlookup(attr1,mnem_tabs[param_type])) >= 0)
- {
- // mnemonic specifies a value as a percentage of the base pitch/range/rate/volume
- sp->parameter[param_type] = (param_stack[0].parameter[param_type] * value)/100;
- }
- else
- {
- sign = attr_prosody_value(param_type,attr1,&value);
-
- if(sign == 0)
- sp->parameter[param_type] = value; // absolute value in Hz
- else
- if(sign == 2)
- {
- // change specified as percentage or in semitones
- sp->parameter[param_type] = (speech_parameters[param_type] * value)/100;
- }
- else
- {
- // change specified as plus or minus Hz
- sp->parameter[param_type] = speech_parameters[param_type] + (value*sign);
- }
- }
-} // end of SetProsodyParemeter
-
-
-
-static int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int *outix, int n_outbuf, int self_closing)
-{//==================================================================================================
-// xml_buf is the tag and attributes with a zero terminator in place of the original '>'
-// returns a clause terminator value.
-
- unsigned int ix;
- int index;
- int c;
- int tag_type;
- int value;
- int value2;
- int value3;
- int voice_change_flag;
- wchar_t *px;
- wchar_t *attr1;
- wchar_t *attr2;
- wchar_t *attr3;
- int terminator;
- char *uri;
- int param_type;
- char tag_name[40];
- char buf[80];
- PARAM_STACK *sp;
- SSML_STACK *ssml_sp;
-
- static const MNEM_TAB mnem_punct[] = {
- {"none", 1},
- {"all", 2},
- {"some", 3},
- {NULL, -1}};
-
- static const MNEM_TAB mnem_capitals[] = {
- {"no", 0},
- {"spelling", 2},
- {"icon", 1},
- {"pitch", 20}, // this is the amount by which to raise the pitch
- {NULL, -1}};
-
- static const MNEM_TAB mnem_interpret_as[] = {
- {"characters",SAYAS_CHARS},
- {"tts:char",SAYAS_SINGLE_CHARS},
- {"tts:key",SAYAS_KEY},
- {"tts:digits",SAYAS_DIGITS},
- {"telephone",SAYAS_DIGITS1},
- {NULL, -1}};
-
- static const MNEM_TAB mnem_sayas_format[] = {
- {"glyphs",1},
- {NULL, -1}};
-
- static const MNEM_TAB mnem_break[] = {
- {"none",0},
- {"x-weak",1},
- {"weak",2},
- {"medium",3},
- {"strong",4},
- {"x-strong",5},
- {NULL,-1}};
-
- static const MNEM_TAB mnem_emphasis[] = {
- {"none",1},
- {"reduced",2},
- {"moderate",3},
- {"strong",4},
- {NULL,-1}};
-
- static const char *prosody_attr[5] = {
- NULL, "rate", "volume", "pitch", "range" };
-
- for(ix=0; ix<(sizeof(tag_name)-1); ix++)
- {
- if(((c = xml_buf[ix]) == 0) || iswspace(c))
- break;
- tag_name[ix] = tolower((char)c);
- }
- tag_name[ix] = 0;
-
- px = &xml_buf[ix]; // the tag's attributes
-
- if(tag_name[0] == '/')
- {
- tag_type = LookupMnem(ssmltags,&tag_name[1]) + SSML_CLOSE; // closing tag
- }
- else
- {
- tag_type = LookupMnem(ssmltags,tag_name);
-
- if(self_closing && ignore_if_self_closing[tag_type])
- return(0);
- }
-
- voice_change_flag = 0;
- terminator = CLAUSE_NONE;
- ssml_sp = &ssml_stack[n_ssml_stack-1];
-
- switch(tag_type)
- {
- case SSML_STYLE:
- sp = PushParamStack(tag_type);
- attr1 = GetSsmlAttribute(px,"field");
- attr2 = GetSsmlAttribute(px,"mode");
-
-
- if(attrcmp(attr1,"punctuation")==0)
- {
- value = attrlookup(attr2,mnem_punct);
- sp->parameter[espeakPUNCTUATION] = value;
- }
- else
- if(attrcmp(attr1,"capital_letters")==0)
- {
- value = attrlookup(attr2,mnem_capitals);
- sp->parameter[espeakCAPITALS] = value;
- }
- ProcessParamStack(outbuf, outix);
- break;
-
- case SSML_PROSODY:
- sp = PushParamStack(tag_type);
-
- // look for attributes: rate, volume, pitch, range
- for(param_type=espeakRATE; param_type <= espeakRANGE; param_type++)
- {
- if((attr1 = GetSsmlAttribute(px,prosody_attr[param_type])) != NULL)
- {
- SetProsodyParameter(param_type, attr1, sp);
- }
- }
-
- ProcessParamStack(outbuf, outix);
- break;
-
- case SSML_EMPHASIS:
- sp = PushParamStack(tag_type);
- value = 3; // default is "moderate"
- if((attr1 = GetSsmlAttribute(px,"level")) != NULL)
- {
- value = attrlookup(attr1,mnem_emphasis);
- }
-
- if(translator->langopts.tone_language == 1)
- {
- static unsigned char emphasis_to_pitch_range[] = {50,50,40,70,90,90};
- static unsigned char emphasis_to_volume[] = {100,100,70,110,140,140};
- // tone language (eg.Chinese) do emphasis by increasing the pitch range.
- sp->parameter[espeakRANGE] = emphasis_to_pitch_range[value];
- sp->parameter[espeakVOLUME] = emphasis_to_volume[value];
- }
- else
- {
- sp->parameter[espeakEMPHASIS] = value;
- }
- ProcessParamStack(outbuf, outix);
- break;
-
- case SSML_STYLE + SSML_CLOSE:
- case SSML_PROSODY + SSML_CLOSE:
- case SSML_EMPHASIS + SSML_CLOSE:
- PopParamStack(tag_type, outbuf, outix);
- break;
-
- case SSML_SAYAS:
- attr1 = GetSsmlAttribute(px,"interpret-as");
- attr2 = GetSsmlAttribute(px,"format");
- attr3 = GetSsmlAttribute(px,"detail");
- value = attrlookup(attr1,mnem_interpret_as);
- value2 = attrlookup(attr2,mnem_sayas_format);
- if(value2 == 1)
- value = SAYAS_GLYPHS;
-
- value3 = attrnumber(attr3,0,0);
-
- if(value == SAYAS_DIGITS)
- {
- if(value3 <= 1)
- value = SAYAS_DIGITS1;
- else
- value = SAYAS_DIGITS + value3;
- }
-
- sprintf(buf,"%c%dY",CTRL_EMBEDDED,value);
- strcpy(&outbuf[*outix],buf);
- (*outix) += strlen(buf);
-
- sayas_mode = value; // punctuation doesn't end clause during SAY-AS
- break;
-
- case SSML_SAYAS + SSML_CLOSE:
- outbuf[(*outix)++] = CTRL_EMBEDDED;
- outbuf[(*outix)++] = 'Y';
- sayas_mode = 0;
- break;
-
- case SSML_SUB:
- if((attr1 = GetSsmlAttribute(px,"alias")) != NULL)
- {
- // use the alias rather than the text
- ignore_text = 1;
- (*outix) += attrcopy_utf8(&outbuf[*outix],attr1,n_outbuf-*outix);
- }
- break;
-
- case SSML_IGNORE_TEXT:
- ignore_text = 1;
- break;
-
- case SSML_SUB + SSML_CLOSE:
- case SSML_IGNORE_TEXT + SSML_CLOSE:
- ignore_text = 0;
- break;
-
- case SSML_MARK:
- if((attr1 = GetSsmlAttribute(px,"name")) != NULL)
- {
- // add name to circular buffer of marker names
- attrcopy_utf8(buf,attr1,sizeof(buf));
-
- if(strcmp(skip_marker,buf)==0)
- {
- // This is the marker we are waiting for before starting to speak
- clear_skipping_text = 1;
- skip_marker[0] = 0;
- return(CLAUSE_NONE);
- }
-
- if((index = AddNameData(buf,0)) >= 0)
- {
- sprintf(buf,"%c%dM",CTRL_EMBEDDED,index);
- strcpy(&outbuf[*outix],buf);
- (*outix) += strlen(buf);
- }
- }
- break;
-
- case SSML_AUDIO:
- sp = PushParamStack(tag_type);
-
- if((attr1 = GetSsmlAttribute(px,"src")) != NULL)
- {
- char fname[256];
- attrcopy_utf8(buf,attr1,sizeof(buf));
-
- if(uri_callback == NULL)
- {
- if((xmlbase != NULL) && (buf[0] != '/'))
- {
- sprintf(fname,"%s/%s",xmlbase,buf);
- index = LoadSoundFile2(fname);
- }
- else
- {
- index = LoadSoundFile2(buf);
- }
- if(index >= 0)
- {
- sprintf(buf,"%c%dI",CTRL_EMBEDDED,index);
- strcpy(&outbuf[*outix],buf);
- (*outix) += strlen(buf);
- sp->parameter[espeakSILENCE] = 1;
- }
- }
- else
- {
- if((index = AddNameData(buf,0)) >= 0)
- {
- uri = &namedata[index];
- if(uri_callback(1,uri,xmlbase) == 0)
- {
- sprintf(buf,"%c%dU",CTRL_EMBEDDED,index);
- strcpy(&outbuf[*outix],buf);
- (*outix) += strlen(buf);
- sp->parameter[espeakSILENCE] = 1;
- }
- }
- }
- }
- ProcessParamStack(outbuf, outix);
-
- if(self_closing)
- PopParamStack(tag_type, outbuf, outix);
- return(CLAUSE_NONE);
-
- case SSML_AUDIO + SSML_CLOSE:
- PopParamStack(tag_type, outbuf, outix);
- return(CLAUSE_NONE);
-
- case SSML_BREAK:
- value = 21;
- terminator = CLAUSE_NONE;
-
- if((attr1 = GetSsmlAttribute(px,"strength")) != NULL)
- {
- static int break_value[6] = {0,7,14,21,40,80}; // *10mS
- value = attrlookup(attr1,mnem_break);
- if(value < 3)
- {
- // adjust prepause on the following word
- sprintf(&outbuf[*outix],"%c%dB",CTRL_EMBEDDED,value);
- (*outix) += 3;
- terminator = 0;
- }
- value = break_value[value];
- }
- if((attr2 = GetSsmlAttribute(px,"time")) != NULL)
- {
- value = (attrnumber(attr2,0,1) * 25) / speed.speed_factor1; // compensate for speaking speed to keep constant pause length
-
- if(terminator == 0)
- terminator = CLAUSE_NONE;
- }
- if(terminator)
- {
- if(value > 0xfff)
- value = 0xfff;
- return(terminator + value);
- }
- break;
-
- case SSML_SPEAK:
- if((attr1 = GetSsmlAttribute(px,"xml:base")) != NULL)
- {
- attrcopy_utf8(buf,attr1,sizeof(buf));
- if((index = AddNameData(buf,0)) >= 0)
- {
- xmlbase = &namedata[index];
- }
- }
- if(GetVoiceAttributes(px, tag_type) == 0)
- return(0); // no voice change
- return(CLAUSE_VOICE);
-
- case SSML_VOICE:
- if(GetVoiceAttributes(px, tag_type) == 0)
- return(0); // no voice change
- return(CLAUSE_VOICE);
-
- case SSML_SPEAK + SSML_CLOSE:
- // unwind stack until the previous <voice> or <speak> tag
- while((n_ssml_stack > 1) && (ssml_stack[n_ssml_stack-1].tag_type != SSML_SPEAK))
- {
- n_ssml_stack--;
- }
- return(CLAUSE_PERIOD + GetVoiceAttributes(px, tag_type));
-
- case SSML_VOICE + SSML_CLOSE:
- // unwind stack until the previous <voice> or <speak> tag
- while((n_ssml_stack > 1) && (ssml_stack[n_ssml_stack-1].tag_type != SSML_VOICE))
- {
- n_ssml_stack--;
- }
-
-terminator=0; // ?? Sentence intonation, but no pause ??
- return(terminator + GetVoiceAttributes(px, tag_type));
-
- case HTML_BREAK:
- case HTML_BREAK + SSML_CLOSE:
- return(CLAUSE_COLON);
-
- case SSML_SENTENCE:
- if(ssml_sp->tag_type == SSML_SENTENCE)
- {
- // new sentence implies end-of-sentence
- voice_change_flag = GetVoiceAttributes(px, SSML_SENTENCE+SSML_CLOSE);
- }
- voice_change_flag |= GetVoiceAttributes(px, tag_type);
- return(CLAUSE_PARAGRAPH + voice_change_flag);
-
-
- case SSML_PARAGRAPH:
- if(ssml_sp->tag_type == SSML_SENTENCE)
- {
- // new paragraph implies end-of-sentence or end-of-paragraph
- voice_change_flag = GetVoiceAttributes(px, SSML_SENTENCE+SSML_CLOSE);
- }
- if(ssml_sp->tag_type == SSML_PARAGRAPH)
- {
- // new paragraph implies end-of-sentence or end-of-paragraph
- voice_change_flag |= GetVoiceAttributes(px, SSML_PARAGRAPH+SSML_CLOSE);
- }
- voice_change_flag |= GetVoiceAttributes(px, tag_type);
- return(CLAUSE_PARAGRAPH + voice_change_flag);
-
-
- case SSML_SENTENCE + SSML_CLOSE:
- if(ssml_sp->tag_type == SSML_SENTENCE)
- {
- // end of a sentence which specified a language
- voice_change_flag = GetVoiceAttributes(px, tag_type);
- }
- return(CLAUSE_PERIOD + voice_change_flag);
-
-
- case SSML_PARAGRAPH + SSML_CLOSE:
- if((ssml_sp->tag_type == SSML_SENTENCE) || (ssml_sp->tag_type == SSML_PARAGRAPH))
- {
- // End of a paragraph which specified a language.
- // (End-of-paragraph also implies end-of-sentence)
- return(GetVoiceAttributes(px, tag_type) + CLAUSE_PARAGRAPH);
- }
- return(CLAUSE_PARAGRAPH);
- }
- return(0);
-} // end of ProcessSsmlTag
-
-
-static MNEM_TAB xml_char_mnemonics[] = {
- {"gt",'>'},
- {"lt",'<'},
- {"amp", '&'},
- {"quot", '"'},
- {"nbsp", ' '},
- {"apos", '\''},
- {NULL,-1}};
-
-
-int ReadClause(Translator *tr, FILE *f_in, char *buf, short *charix, int *charix_top, int n_buf, int *tone_type)
-{//=============================================================================================================
-/* Find the end of the current clause.
- Write the clause into buf
-
- returns: clause type (bits 0-7: pause x10mS, bits 8-11 intonation type)
-
- Also checks for blank line (paragraph) as end-of-clause indicator.
-
- Does not end clause for:
- punctuation immediately followed by alphanumeric eg. 1.23 !Speak :path
- repeated punctuation, eg. ... !!!
-*/
- int c1=' '; // current character
- int c2; // next character
- int cprev=' '; // previous character
- int parag;
- int ix = 0;
- int j;
- int nl_count;
- int linelength = 0;
- int phoneme_mode = 0;
- int n_xml_buf;
- int terminator;
- int punct;
- int found;
- int any_alnum = 0;
- int self_closing;
- int punct_data;
- int stressed_word = 0;
- const char *p;
- wchar_t xml_buf[N_XML_BUF+1];
-
-#define N_XML_BUF2 20
- char xml_buf2[N_XML_BUF2+2]; // for &<name> and &<number> sequences
- static char ungot_string[N_XML_BUF2+4];
- static int ungot_string_ix = -1;
-
- if(clear_skipping_text)
- {
- skipping_text = 0;
- clear_skipping_text = 0;
- }
-
- tr->clause_upper_count = 0;
- tr->clause_lower_count = 0;
- end_of_input = 0;
- *tone_type = 0;
-
-f_input = f_in; // for GetC etc
-
- if(ungot_word != NULL)
- {
- strcpy(buf,ungot_word);
- ix += strlen(ungot_word);
- ungot_word = NULL;
- }
-
- if(ungot_char2 != 0)
- {
- c2 = ungot_char2;
- }
- else
- {
- c2 = GetC();
- }
-
- while(!Eof() || (ungot_char != 0) || (ungot_char2 != 0) || (ungot_string_ix >= 0))
- {
- if(!iswalnum(c1))
- {
- if((end_character_position > 0) && (count_characters > end_character_position))
- {
- end_of_input = 1;
- return(CLAUSE_EOF);
- }
-
- if((skip_characters > 0) && (count_characters > skip_characters))
- {
- // reached the specified start position
- // don't break a word
- clear_skipping_text = 1;
- skip_characters = 0;
- UngetC(c2);
- return(CLAUSE_NONE);
- }
- }
-
- cprev = c1;
- c1 = c2;
-
- if(ungot_string_ix >= 0)
- {
- if(ungot_string[ungot_string_ix] == 0)
- ungot_string_ix = -1;
- }
-
- if((ungot_string_ix == 0) && (ungot_char2 == 0))
- {
- c1 = ungot_string[ungot_string_ix++];
- }
- if(ungot_string_ix >= 0)
- {
- c2 = ungot_string[ungot_string_ix++];
- }
- else
- {
- c2 = GetC();
-
- if(Eof())
- {
- c2 = ' ';
- }
- }
- ungot_char2 = 0;
-
- if((option_ssml) && (phoneme_mode==0))
- {
- if((ssml_ignore_l_angle != '&') && (c1 == '&') && ((c2=='#') || ((c2 >= 'a') && (c2 <= 'z'))))
- {
- n_xml_buf = 0;
- c1 = c2;
- while(!Eof() && (iswalnum(c1) || (c1=='#')) && (n_xml_buf < N_XML_BUF2))
- {
- xml_buf2[n_xml_buf++] = c1;
- c1 = GetC();
- }
- xml_buf2[n_xml_buf] = 0;
- c2 = GetC();
- sprintf(ungot_string,"%s%c%c",&xml_buf2[0],c1,c2);
-
- if(c1 == ';')
- {
- if(xml_buf2[0] == '#')
- {
- // character code number
- if(xml_buf2[1] == 'x')
- found = sscanf(&xml_buf2[2],"%x",(unsigned int *)(&c1));
- else
- found = sscanf(&xml_buf2[1],"%d",&c1);
- }
- else
- {
- if((found = LookupMnem(xml_char_mnemonics,xml_buf2)) != -1)
- {
- c1 = found;
- if(c2 == 0)
- c2 = ' ';
- }
- }
- }
- else
- {
- found = -1;
- }
-
- if(found <= 0)
- {
- ungot_string_ix = 0;
- c1 = '&';
- c2 = ' ';
- }
-
- if((c1 <= 0x20) && ((sayas_mode == SAYAS_SINGLE_CHARS) || (sayas_mode == SAYAS_KEY)))
- {
- c1 += 0xe000; // move into unicode private usage area
- }
- }
- else
- if((c1 == '<') && (ssml_ignore_l_angle != '<'))
- {
- if(c2 == '!')
- {
- // a comment, ignore until closing '<'
- while(!Eof() && (c1 != '>'))
- {
- c1 = GetC();
- }
- c2 = ' ';
- }
- else
- if((c2 == '/') || iswalpha(c2))
- {
- // SSML Tag
- n_xml_buf = 0;
- c1 = c2;
- while(!Eof() && (c1 != '>') && (n_xml_buf < N_XML_BUF))
- {
- xml_buf[n_xml_buf++] = c1;
- c1 = GetC();
- }
- xml_buf[n_xml_buf] = 0;
- c2 = ' ';
-
- buf[ix++] = ' ';
-
- self_closing = 0;
- if(xml_buf[n_xml_buf-1] == '/')
- {
- // a self-closing tag
- xml_buf[n_xml_buf-1] = ' ';
- self_closing = 1;
- }
-
- terminator = ProcessSsmlTag(xml_buf,buf,ix,n_buf,self_closing);
-
- if(terminator != 0)
- {
- buf[ix] = ' ';
- buf[ix++] = 0;
-
- if(terminator & CLAUSE_BIT_VOICE)
- {
- // a change in voice, write the new voice name to the end of the buf
- p = current_voice_id;
- while((*p != 0) && (ix < (n_buf-1)))
- {
- buf[ix++] = *p++;
- }
- buf[ix++] = 0;
- }
- return(terminator);
- }
- continue;
- }
- }
- }
- ssml_ignore_l_angle=0;
-
- if(ignore_text)
- continue;
-
- if((c2=='\n') && (option_linelength == -1))
- {
- // single-line mode, return immediately on NL
- if((punct = lookupwchar(punct_chars,c1)) == 0)
- {
- charix[ix] = count_characters - clause_start_char;
- *charix_top = ix;
- ix += utf8_out(c1,&buf[ix]);
- terminator = CLAUSE_PERIOD; // line doesn't end in punctuation, assume period
- }
- else
- {
- terminator = punct_attributes[punct];
- }
- buf[ix] = ' ';
- buf[ix+1] = 0;
- return(terminator);
- }
-
- if((c1 == CTRL_EMBEDDED) || (c1 == ctrl_embedded))
- {
- // an embedded command. If it's a voice change, end the clause
- if(c2 == 'V')
- {
- buf[ix++] = 0; // end the clause at this point
- while(!iswspace(c1 = GetC()) && !Eof() && (ix < (n_buf-1)))
- buf[ix++] = c1; // add voice name to end of buffer, after the text
- buf[ix++] = 0;
- return(CLAUSE_VOICE);
- }
- else
- if(c2 == 'B')
- {
- // set the punctuation option from an embedded command
- // B0 B1 B<punct list><space>
- strcpy(&buf[ix]," ");
- ix += 3;
-
- if((c2 = GetC()) == '0')
- option_punctuation = 0;
- else
- {
- option_punctuation = 1;
- option_punctlist[0] = 0;
- if(c2 != '1')
- {
- // a list of punctuation characters to be spoken, terminated by space
- j = 0;
- while(!iswspace(c2) && !Eof())
- {
- option_punctlist[j++] = c2;
- c2 = GetC();
- buf[ix++] = ' ';
- }
- option_punctlist[j] = 0; // terminate punctuation list
- option_punctuation = 2;
- }
- }
- c2 = GetC();
- continue;
- }
- }
-
- linelength++;
-
- if(iswalnum(c1))
- any_alnum = 1;
- else
- {
- if(stressed_word)
- {
- stressed_word = 0;
- c1 = CHAR_EMPHASIS; // indicate this word is stressed
- UngetC(c2);
- c2 = ' ';
- }
-
- if(iswspace(c1))
- {
- char *p_word;
-
- if(tr->translator_name == 0x6a626f)
- {
- // language jbo : lojban
- // treat "i" or ".i" as end-of-sentence
- p_word = &buf[ix-1];
- if(p_word[0] == 'i')
- {
- if(p_word[-1] == '.')
- p_word--;
- if(p_word[-1] == ' ')
- {
- ungot_word = "i ";
- UngetC(c2);
- p_word[0] = 0;
- return(CLAUSE_PERIOD);
- }
- }
- }
- }
- }
-
- if(iswupper(c1))
- {
- tr->clause_upper_count++;
- if((option_capitals == 2) && (sayas_mode == 0) && !iswupper(cprev))
- {
- char text_buf[40];
- char text_buf2[30];
- if(LookupSpecial(tr, "_cap", text_buf2) != NULL)
- {
- sprintf(text_buf,"%s%s%s",tone_punct_on,text_buf2,tone_punct_off);
- j = strlen(text_buf);
- if((ix + j) < n_buf)
- {
- strcpy(&buf[ix],text_buf);
- ix += j;
- }
- }
- }
- }
- else
- if(iswalpha(c1))
- tr->clause_lower_count++;
-
- if(option_phoneme_input)
- {
- if(phoneme_mode > 0)
- phoneme_mode--;
- else
- if((c1 == '[') && (c2 == '['))
- phoneme_mode = -1; // input is phoneme mnemonics, so don't look for punctuation
- else
- if((c1 == ']') && (c2 == ']'))
- phoneme_mode = 2; // set phoneme_mode to zero after the next two characters
- }
-
- if(c1 == '\n')
- {
- parag = 0;
-
- // count consecutive newlines, ignoring other spaces
- while(!Eof() && iswspace(c2))
- {
- if(c2 == '\n')
- parag++;
- c2 = GetC();
- }
- if(parag > 0)
- {
- // 2nd newline, assume paragraph
- UngetC(c2);
-
- buf[ix] = ' ';
- buf[ix+1] = 0;
- if(parag > 3)
- parag = 3;
-if(option_ssml) parag=1;
- return((CLAUSE_PARAGRAPH-30) + 30*parag); // several blank lines, longer pause
- }
-
- if(linelength <= option_linelength)
- {
- // treat lines shorter than a specified length as end-of-clause
- UngetC(c2);
- buf[ix] = ' ';
- buf[ix+1] = 0;
- return(CLAUSE_COLON);
- }
-
- linelength = 0;
- }
-
- if(option_punctuation && (phoneme_mode==0) && (sayas_mode==0) && iswpunct(c1))
- {
- // option is set to explicitly speak punctuation characters
- // if a list of allowed punctuation has been set up, check whether the character is in it
- if((option_punctuation == 1) || (wcschr(option_punctlist,c1) != NULL))
- {
- if((terminator = AnnouncePunctuation(tr, c1, c2, buf, ix)) >= 0)
- return(terminator);
- }
- }
-
- if((phoneme_mode==0) && (sayas_mode==0) && ((punct = lookupwchar(punct_chars,c1)) != 0))
- {
- punct_data = punct_attributes[punct];
-
- if(punct_data & PUNCT_IN_WORD)
- {
- // Armenian punctuation inside a word
- stressed_word = 1;
- *tone_type = punct_data >> 12 & 0xf; // override the end-of-sentence type
- continue;
- }
-
- if((iswspace(c2) || (punct_data & 0x8000) || IsBracket(c2) || (c2=='?') || (c2=='-') || Eof()))
- {
- // note: (c2='?') is for when a smart-quote has been replaced by '?'
- buf[ix] = ' ';
- buf[ix+1] = 0;
-
- if((c1 == '.') && (cprev == '.'))
- {
- c1 = 0x2026;
- punct = 9; // elipsis
- }
-
- nl_count = 0;
- while(!Eof() && iswspace(c2))
- {
- if(c2 == '\n')
- nl_count++;
- c2 = GetC(); // skip past space(s)
- }
- if(!Eof())
- {
- UngetC(c2);
- }
-
- if((nl_count==0) && (c1 == '.'))
- {
- if(iswdigit(cprev) && (tr->langopts.numbers & 0x10000) && islower(c2))
- {
- // dot after a number indicates an ordinal number
- c2 = '.';
- continue;
- }
- if(iswlower(c2))
- {
- c2 = ' ';
- continue; // next word has no capital letter, this dot is probably from an abbreviation
- }
- if(any_alnum==0)
- {
- c2 = ' '; // no letters or digits yet, so probably not a sentence terminator
- continue;
- }
- }
-
- punct_data = punct_attributes[punct];
- if(nl_count > 1)
- {
- if((punct_data == CLAUSE_QUESTION) || (punct_data == CLAUSE_EXCLAMATION))
- return(punct_data + 35); // with a longer pause
- return(CLAUSE_PARAGRAPH);
- }
- return(punct_data); // only recognise punctuation if followed by a blank or bracket/quote
- }
- }
-
- if(speech_parameters[espeakSILENCE]==1)
- continue;
-
- j = ix+1;
- ix += utf8_out(c1,&buf[ix]); // buf[ix++] = c1;
- if(!iswspace(c1) && !IsBracket(c1))
- {
- charix[ix] = count_characters - clause_start_char;
- while(j < ix)
- charix[j++] = -1; // subsequent bytes of a multibyte character
- }
- *charix_top = ix;
-
- if(((ix > (n_buf-20)) && !IsAlpha(c1) && !iswdigit(c1)) || (ix >= (n_buf-2)))
- {
- // clause too long, getting near end of buffer, so break here
- // try to break at a word boundary (unless we actually reach the end of buffer).
- buf[ix] = ' ';
- buf[ix+1] = 0;
- UngetC(c2);
- return(CLAUSE_NONE);
- }
- }
-
- if(stressed_word)
- {
- ix += utf8_out(CHAR_EMPHASIS, &buf[ix]);
- }
- buf[ix] = ' ';
- buf[ix+1] = 0;
- return(CLAUSE_EOF); // end of file
-} // end of ReadClause
-
-
-void InitNamedata(void)
-{//====================
- namedata_ix = 0;
- if(namedata != NULL)
- {
- free(namedata);
- namedata = NULL;
- n_namedata = 0;
- }
-}
-
-
-void InitText2(void)
-{//=================
- int param;
-
- ungot_char = 0;
-
- n_ssml_stack =1;
- n_param_stack = 1;
- ssml_stack[0].tag_type = 0;
-
- for(param=0; param<N_SPEECH_PARAM; param++)
- speech_parameters[param] = param_stack[0].parameter[param]; // set all speech parameters to defaults
-
- option_punctuation = speech_parameters[espeakPUNCTUATION];
- option_capitals = speech_parameters[espeakCAPITALS];
-
- current_voice_id[0] = 0;
-
- ignore_text = 0;
- clear_skipping_text = 0;
- count_characters = -1;
- sayas_mode = 0;
-
- xmlbase = NULL;
-}
-
diff --git a/navit/support/espeak/setlengths.c b/navit/support/espeak/setlengths.c
deleted file mode 100755
index ed4421bf9..000000000
--- a/navit/support/espeak/setlengths.c
+++ /dev/null
@@ -1,673 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2005 to 2007 by Jonathan Duddington *
- * email: jonsd@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write see: *
- * <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-#include "StdAfx.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <wctype.h>
-
-#include "speak_lib.h"
-#include "speech.h"
-#include "phoneme.h"
-#include "synthesize.h"
-#include "voice.h"
-#include "translate.h"
-
-extern int GetAmplitude(void);
-
-
-// convert from words-per-minute to internal speed factor
-static unsigned char speed_lookup[290] = {
- 250, 246, 243, 239, 236, // 80
- 233, 229, 226, 223, 220, // 85
- 217, 214, 211, 208, 205, // 90
- 202, 197, 194, 192, 190, // 95
- 187, 185, 183, 180, 178, // 100
- 176, 174, 172, 170, 168, // 105
- 166, 164, 161, 159, 158, // 110
- 156, 154, 152, 150, 148, // 115
- 146, 145, 143, 141, 137, // 120
- 136, 135, 133, 132, 131, // 125
- 129, 128, 127, 126, 125, // 130
- 124, 122, 121, 120, 119, // 135
- 117, 116, 115, 114, 113, // 140
- 112, 111, 110, 108, 107, // 145
- 106, 105, 104, 103, 102, // 150
- 101, 100, 99, 98, 97, // 155
- 96, 95, 93, 92, 92, // 160
- 91, 90, 89, 89, 88, // 165
- 87, 87, 86, 85, 85, // 170
- 84, 83, 83, 82, 81, // 175
- 80, 80, 79, 78, 78, // 180
- 77, 76, 76, 75, 73, // 185
- 72, 72, 71, 71, 70, // 190
- 70, 69, 69, 68, 67, // 195
- 67, 66, 66, 65, 65, // 200
- 64, 64, 63, 63, 62, // 205
- 62, 61, 60, 60, 59, // 210
- 59, 58, 58, 57, 57, // 215
- 56, 56, 55, 55, 55, // 220
- 54, 54, 53, 53, 52, // 225
- 52, 51, 51, 50, 50, // 230
- 49, 49, 49, 48, 48, // 235
- 47, 47, 46, 46, 46, // 240
- 45, 45, 44, 44, 43, // 245
- 43, 43, 42, 42, 41, // 250
- 41, 41, 40, 40, 39, // 255
- 39, 39, 38, 38, 38, // 260
- 37, 37, 37, 36, 36, // 265
- 35, 35, 35, 34, 34, // 270
- 34, 33, 33, 33, 32, // 275
- 32, 32, 32, 31, 31, // 280
- 31, 30, 30, 30, 29, // 285
- 29, 29, 29, 28, 28, // 290
- 28, 28, 27, 27, 27, // 295
- 26, 26, 26, 26, 25, // 300
- 25, 25, 22, 22, 22, // 305
- 22, 22, 22, 22, 22, // 310
- 21, 21, 21, 21, 21, // 315
- 21, 20, 20, 20, 20, // 320
- 20, 15, 15, 15, 15, // 325
- 15, 15, 15, 15, 16, // 330
- 16, 16, 16, 15, 15, // 335
- 15, 15, 15, 15, 15, // 340
- 15, 17, 17, 16, 16, // 345
- 15, 15, 14, 14, 13, // 350
- 13, 12, 12, 11, 11, // 355
- 10, 10, 9, 8, 8, // 360
- 7, 6, 5, 5, 4, // 365
-};
-
-// speed_factor2 adjustments for speeds 370 to 390
-static unsigned char faster[] = {
-114,112,110,109,107,105,104,102,100,98, // 370-379
-96,94,92,90,88,85,83,80,78,75,72 }; //380-390
-
-static int speed1 = 130;
-static int speed2 = 121;
-static int speed3 = 118;
-
-
-
-void SetSpeed(int control)
-{//=======================
- int x;
- int s1;
- int wpm;
- int wpm2;
-
- wpm = embedded_value[EMBED_S];
- if(control == 2)
- wpm = embedded_value[EMBED_S2];
- wpm2 = wpm;
-
- if(wpm > 369) wpm = 369;
- if(wpm < 80) wpm = 80;
-
- x = speed_lookup[wpm-80];
-
- if(control & 1)
- {
- // set speed factors for different syllable positions within a word
- // these are used in CalcLengths()
- speed1 = (x * voice->speedf1)/256;
- speed2 = (x * voice->speedf2)/256;
- speed3 = (x * voice->speedf3)/256;
- }
-
- if(control & 2)
- {
- // these are used in synthesis file
- s1 = (x * voice->speedf1)/256;
- speed.speed_factor1 = (256 * s1)/115; // full speed adjustment, used for pause length
-if(speed.speed_factor1 < 15)
- speed.speed_factor1 = 15;
- if(wpm >= 170)
-// speed_factor2 = 100 + (166*s1)/128; // reduced speed adjustment, used for playing recorded sounds
- speed.speed_factor2 = 110 + (150*s1)/128; // reduced speed adjustment, used for playing recorded sounds
- else
- speed.speed_factor2 = 128 + (128*s1)/130; // = 215 at 170 wpm
-
- if(wpm2 > 369)
- {
- if(wpm2 > 390)
- wpm2 = 390;
- speed.speed_factor2 = faster[wpm2 - 370];
- }
- }
-
- speed.min_sample_len = 450;
- speed.speed_factor3 = 110; // controls the effect of FRFLAG_LEN_MOD reduce length change
-
- if(wpm2 >= 370)
- {
- // TESTING
- // use experimental fast settings if they have been specified in the Voice
- if(speed.fast_settings[0] > 0)
- speed.speed_factor1 = speed.fast_settings[0];
- if(speed.fast_settings[1] > 0)
- speed.speed_factor2 = speed.fast_settings[1];
- if(speed.fast_settings[2] > 0)
- speed.speed_factor3 = speed.fast_settings[2];
- }
-} // end of SetSpeed
-
-
-#ifdef deleted
-void SetAmplitude(int amp)
-{//=======================
- static unsigned char amplitude_factor[] = {0,5,6,7,9,11,14,17,21,26, 32, 38,44,50,56,63,70,77,84,91,100 };
-
- if((amp >= 0) && (amp <= 20))
- {
- option_amplitude = (amplitude_factor[amp] * 480)/256;
- }
-}
-#endif
-
-
-
-void SetParameter(int parameter, int value, int relative)
-{//======================================================
-// parameter: reset-all, amp, pitch, speed, linelength, expression, capitals, number grouping
-// relative 0=absolute 1=relative
-
- int new_value = value;
- int default_value;
-
- if(relative)
- {
- if(parameter < 5)
- {
- default_value = param_defaults[parameter];
- new_value = default_value + (default_value * value)/100;
- }
- }
- param_stack[0].parameter[parameter] = new_value;
-
- switch(parameter)
- {
- case espeakRATE:
- embedded_value[EMBED_S] = new_value;
- embedded_value[EMBED_S2] = new_value;
- SetSpeed(3);
- break;
-
- case espeakVOLUME:
- embedded_value[EMBED_A] = new_value;
- GetAmplitude();
- break;
-
- case espeakPITCH:
- if(new_value > 99) new_value = 99;
- if(new_value < 0) new_value = 0;
- embedded_value[EMBED_P] = new_value;
- break;
-
- case espeakRANGE:
- if(new_value > 99) new_value = 99;
- embedded_value[EMBED_R] = new_value;
- break;
-
- case espeakLINELENGTH:
- option_linelength = new_value;
- break;
-
- case espeakWORDGAP:
- option_wordgap = new_value;
- break;
-
- case espeakINTONATION:
- if((new_value & 0xff) != 0)
- translator->langopts.intonation_group = new_value & 0xff;
- option_tone_flags = new_value;
- break;
-
- default:
- break;
- }
-} // end of SetParameter
-
-
-
-static void DoEmbedded2(int *embix)
-{//================================
- // There were embedded commands in the text at this point
-
- unsigned int word;
-
- do {
- word = embedded_list[(*embix)++];
-
- if((word & 0x1f) == EMBED_S)
- {
- // speed
- SetEmbedded(word & 0x7f, word >> 8); // adjusts embedded_value[EMBED_S]
- SetSpeed(1);
- }
- } while((word & 0x80) == 0);
-}
-
-
-void CalcLengths(Translator *tr)
-{//==============================
- int ix;
- int ix2;
- PHONEME_LIST *prev;
- PHONEME_LIST *next;
- PHONEME_LIST *next2;
- PHONEME_LIST *next3;
- PHONEME_LIST *p;
- PHONEME_LIST *p2;
-
- int stress;
- int type;
- static int more_syllables=0;
- int pre_sonorant=0;
- int pre_voiced=0;
- int last_pitch = 0;
- int pitch_start;
- int length_mod;
- int len;
- int env2;
- int end_of_clause;
- int embedded_ix = 0;
- int min_drop;
- int emphasized;
- int tone_mod;
- unsigned char *pitch_env=NULL;
-
- for(ix=1; ix<n_phoneme_list; ix++)
- {
- prev = &phoneme_list[ix-1];
- p = &phoneme_list[ix];
- stress = p->stresslevel & 0x7;
- emphasized = p->stresslevel & 0x8;
-
- next = &phoneme_list[ix+1];
-
- if(p->synthflags & SFLAG_EMBEDDED)
- {
- DoEmbedded2(&embedded_ix);
- }
-
- type = p->type;
- if(p->synthflags & SFLAG_SYLLABLE)
- type = phVOWEL;
-
- switch(type)
- {
- case phPAUSE:
- last_pitch = 0;
- break;
-
- case phSTOP:
- last_pitch = 0;
- if(prev->type == phFRICATIVE)
- p->prepause = 20;
- else
- if((more_syllables > 0) || (stress < 4))
- p->prepause = 40;
- else
- p->prepause = 60;
-
- if(prev->type == phSTOP)
- p->prepause = 60;
-
- if((tr->langopts.word_gap & 0x10) && (p->newword))
- p->prepause = 60;
-
- if(p->ph->phflags & phLENGTHENSTOP)
- p->prepause += 30;
-
- if(p->synthflags & SFLAG_LENGTHEN)
- p->prepause += tr->langopts.long_stop;
- break;
-
- case phVFRICATIVE:
- if(next->type==phVOWEL)
- {
- pre_voiced = 1;
- } // drop through
- case phFRICATIVE:
- if(p->newword)
- p->prepause = 15;
-
- if(next->type==phPAUSE && prev->type==phNASAL && !(p->ph->phflags&phFORTIS))
- p->prepause = 25;
-
- if(prev->ph->phflags & phBRKAFTER)
- p->prepause = 30;
-
- if((p->ph->phflags & phSIBILANT) && next->type==phSTOP && !next->newword)
- {
- if(prev->type == phVOWEL)
- p->length = 200; // ?? should do this if it's from a prefix
- else
- p->length = 150;
- }
- else
- p->length = 256;
-
- if((tr->langopts.word_gap & 0x10) && (p->newword))
- p->prepause = 30;
-
- break;
-
- case phVSTOP:
- if(prev->type==phVFRICATIVE || prev->type==phFRICATIVE || (prev->ph->phflags & phSIBILANT) || (prev->type == phLIQUID))
- p->prepause = 30;
-
- if(next->type==phVOWEL || next->type==phLIQUID)
- {
- if((next->type==phVOWEL) || !next->newword)
- pre_voiced = 1;
-
- p->prepause = 40;
-
- if((prev->type == phPAUSE) || (prev->type == phVOWEL)) // || (prev->ph->mnemonic == ('/'*256+'r')))
- p->prepause = 0;
- else
- if(p->newword==0)
- {
- if(prev->type==phLIQUID)
- p->prepause = 20;
- if(prev->type==phNASAL)
- p->prepause = 12;
-
- if(prev->type==phSTOP && !(prev->ph->phflags & phFORTIS))
- p->prepause = 0;
- }
- }
- if((tr->langopts.word_gap & 0x10) && (p->newword) && (p->prepause < 20))
- p->prepause = 20;
-
- break;
-
- case phLIQUID:
- case phNASAL:
- p->amp = tr->stress_amps[1]; // unless changed later
- p->length = 256; // TEMPORARY
- min_drop = 0;
-
- if(p->newword)
- {
- if(prev->type==phLIQUID)
- p->prepause = 25;
- if(prev->type==phVOWEL)
- p->prepause = 12;
- }
-
- if(next->type==phVOWEL)
- {
- pre_sonorant = 1;
- }
- else
- if((prev->type==phVOWEL) || (prev->type == phLIQUID))
- {
- p->length = prev->length;
- p->pitch2 = last_pitch;
- if(p->pitch2 < 7)
- p->pitch2 = 7;
- p->pitch1 = p->pitch2 - 8;
- p->env = PITCHfall;
- pre_voiced = 0;
-
- if(p->type == phLIQUID)
- {
- p->length = speed1;
-//p->pitch1 = p->pitch2 - 20; // post vocalic [r/]
- }
-
- if(next->type == phVSTOP)
- {
- p->length = (p->length * 160)/100;
- }
- if(next->type == phVFRICATIVE)
- {
- p->length = (p->length * 120)/100;
- }
- }
- else
- {
- p->pitch2 = last_pitch;
- for(ix2=ix; ix2<n_phoneme_list; ix2++)
- {
- if(phoneme_list[ix2].type == phVOWEL)
- {
- p->pitch2 = phoneme_list[ix2].pitch2;
- break;
- }
- }
- p->pitch1 = p->pitch2-8;
- p->env = PITCHfall;
- pre_voiced = 0;
- }
- break;
-
- case phVOWEL:
- min_drop = 0;
- next2 = &phoneme_list[ix+2];
- next3 = &phoneme_list[ix+3];
-
- if(stress > 7) stress = 7;
-
- if(pre_sonorant)
- p->amp = tr->stress_amps[stress]-1;
- else
- p->amp = tr->stress_amps[stress];
-
- if(emphasized)
- p->amp = 25;
-
- if(ix >= (n_phoneme_list-3))
- {
- // last phoneme of a clause, limit its amplitude
- if(p->amp > tr->langopts.param[LOPT_MAXAMP_EOC])
- p->amp = tr->langopts.param[LOPT_MAXAMP_EOC];
- }
-
- // is the last syllable of a word ?
- more_syllables=0;
- end_of_clause = 0;
- for(p2 = p+1; p2->newword== 0; p2++)
- {
- if((p2->type == phVOWEL) && !(p2->ph->phflags & phNONSYLLABIC))
- more_syllables++;
-
- if(p2->ph->code == phonPAUSE_CLAUSE)
- end_of_clause = 2;
- }
- if(p2->ph->code == phonPAUSE_CLAUSE)
- end_of_clause = 2;
-
- if((p2->newword & 2) && (more_syllables==0))
- {
- end_of_clause = 2;
- }
-
- // calc length modifier
- if((next->ph->code == phonPAUSE_VSHORT) && (next2->type == phPAUSE))
- {
- // if PAUSE_VSHORT is followed by a pause, then use that
- next = next2;
- next2 = next3;
- next3 = &phoneme_list[ix+4];
- }
-
- if(more_syllables==0)
- {
- len = tr->langopts.length_mods0[next2->ph->length_mod *10+ next->ph->length_mod];
-
- if((next->newword) && (tr->langopts.word_gap & 0x20))
- {
- // consider as a pause + first phoneme of the next word
- length_mod = (len + tr->langopts.length_mods0[next->ph->length_mod *10+ 1])/2;
- }
- else
- length_mod = len;
- }
- else
- {
- length_mod = tr->langopts.length_mods[next2->ph->length_mod *10+ next->ph->length_mod];
-
- if((next->type == phNASAL) && (next2->type == phSTOP || next2->type == phVSTOP) && (next3->ph->phflags & phFORTIS))
- length_mod -= 15;
- }
-
- if(more_syllables==0)
- length_mod *= speed1;
- else
- if(more_syllables==1)
- length_mod *= speed2;
- else
- length_mod *= speed3;
-
- length_mod = length_mod / 128;
-
- if(length_mod < 8)
- length_mod = 8; // restrict how much lengths can be reduced
-
- if(stress >= 7)
- {
- // tonic syllable, include a constant component so it doesn't decrease directly with speed
- length_mod += 20;
- if(emphasized)
- length_mod += 10;
- }
- else
- if(emphasized)
- {
- length_mod += 20;
- }
-
- if((len = tr->stress_lengths[stress]) == 0)
- len = tr->stress_lengths[6];
-
- length_mod = (length_mod * len)/128;
-
- if(p->tone_ph != 0)
- {
- if((tone_mod = phoneme_tab[p->tone_ph]->std_length) > 0)
- {
- // a tone phoneme specifies a percentage change to the length
- length_mod = (length_mod * tone_mod) / 100;
- }
- }
-
- if(end_of_clause == 2)
- {
- // this is the last syllable in the clause, lengthen it - more for short vowels
- len = p->ph->std_length;
- if(tr->langopts.stress_flags & 0x40000)
- len=200; // don't lengthen short vowels more than long vowels at end-of-clause
- length_mod = length_mod * (256 + (280 - len)/3)/256;
- }
-
-if(p->type != phVOWEL)
-{
- length_mod = 256; // syllabic consonant
- min_drop = 8;
-}
- p->length = length_mod;
-
- // pre-vocalic part
- // set last-pitch
- env2 = p->env;
- if(env2 > 1) env2++; // version for use with preceding semi-vowel
-
- if(p->tone_ph != 0)
- {
- pitch_env = LookupEnvelope(phoneme_tab[p->tone_ph]->spect);
- }
- else
- {
- pitch_env = envelope_data[env2];
- }
-
- pitch_start = p->pitch1 + ((p->pitch2-p->pitch1)*pitch_env[0])/256;
-
- if(pre_sonorant || pre_voiced)
- {
- // set pitch for pre-vocalic part
- if(pitch_start == 1024)
- last_pitch = pitch_start; // pitch is not set
-
- if(pitch_start - last_pitch > 8) // was 9
- last_pitch = pitch_start - 8;
-
- prev->pitch1 = last_pitch;
- prev->pitch2 = pitch_start;
- if(last_pitch < pitch_start)
- {
- prev->env = PITCHrise;
- p->env = env2;
- }
- else
- {
- prev->env = PITCHfall;
- }
-
- prev->length = length_mod;
-
- prev->amp = p->amp;
- if((prev->type != phLIQUID) && (prev->amp > 18))
- prev->amp = 18;
- }
-
- // vowel & post-vocalic part
- next->synthflags &= ~SFLAG_SEQCONTINUE;
- if(next->type == phNASAL && next2->type != phVOWEL)
- next->synthflags |= SFLAG_SEQCONTINUE;
-
- if(next->type == phLIQUID)
- {
- next->synthflags |= SFLAG_SEQCONTINUE;
-
- if(next2->type == phVOWEL)
- {
- next->synthflags &= ~SFLAG_SEQCONTINUE;
- }
-
- if(next2->type != phVOWEL)
- {
- if(next->ph->mnemonic == ('/'*256+'r'))
- {
- next->synthflags &= ~SFLAG_SEQCONTINUE;
-// min_drop = 15;
- }
- }
- }
-
- if((min_drop > 0) && ((p->pitch2 - p->pitch1) < min_drop))
- {
- p->pitch1 = p->pitch2 - min_drop;
- if(p->pitch1 < 0)
- p->pitch1 = 0;
- }
-
- last_pitch = p->pitch1 + ((p->pitch2-p->pitch1)*envelope_data[p->env][127])/256;
- pre_sonorant = 0;
- pre_voiced = 0;
- break;
- }
- }
-} // end of CalcLengths
-
diff --git a/navit/support/espeak/sintab.h b/navit/support/espeak/sintab.h
deleted file mode 100755
index 08fc18f31..000000000
--- a/navit/support/espeak/sintab.h
+++ /dev/null
@@ -1,258 +0,0 @@
-short int sin_tab[2048] = {
- 0, -25, -50, -75, -100, -125, -150, -175,
- -201, -226, -251, -276, -301, -326, -351, -376,
- -401, -427, -452, -477, -502, -527, -552, -577,
- -602, -627, -652, -677, -702, -727, -752, -777,
- -802, -827, -852, -877, -902, -927, -952, -977,
- -1002, -1027, -1052, -1077, -1102, -1127, -1152, -1177,
- -1201, -1226, -1251, -1276, -1301, -1326, -1350, -1375,
- -1400, -1425, -1449, -1474, -1499, -1523, -1548, -1573,
- -1597, -1622, -1647, -1671, -1696, -1721, -1745, -1770,
- -1794, -1819, -1843, -1868, -1892, -1917, -1941, -1965,
- -1990, -2014, -2038, -2063, -2087, -2111, -2136, -2160,
- -2184, -2208, -2233, -2257, -2281, -2305, -2329, -2353,
- -2377, -2401, -2425, -2449, -2473, -2497, -2521, -2545,
- -2569, -2593, -2617, -2640, -2664, -2688, -2712, -2735,
- -2759, -2783, -2806, -2830, -2853, -2877, -2900, -2924,
- -2947, -2971, -2994, -3018, -3041, -3064, -3088, -3111,
- -3134, -3157, -3180, -3204, -3227, -3250, -3273, -3296,
- -3319, -3342, -3365, -3388, -3410, -3433, -3456, -3479,
- -3502, -3524, -3547, -3570, -3592, -3615, -3637, -3660,
- -3682, -3705, -3727, -3749, -3772, -3794, -3816, -3839,
- -3861, -3883, -3905, -3927, -3949, -3971, -3993, -4015,
- -4037, -4059, -4080, -4102, -4124, -4146, -4167, -4189,
- -4211, -4232, -4254, -4275, -4296, -4318, -4339, -4360,
- -4382, -4403, -4424, -4445, -4466, -4487, -4508, -4529,
- -4550, -4571, -4592, -4613, -4633, -4654, -4675, -4695,
- -4716, -4736, -4757, -4777, -4798, -4818, -4838, -4859,
- -4879, -4899, -4919, -4939, -4959, -4979, -4999, -5019,
- -5039, -5059, -5078, -5098, -5118, -5137, -5157, -5176,
- -5196, -5215, -5235, -5254, -5273, -5292, -5311, -5331,
- -5350, -5369, -5388, -5406, -5425, -5444, -5463, -5482,
- -5500, -5519, -5537, -5556, -5574, -5593, -5611, -5629,
- -5648, -5666, -5684, -5702, -5720, -5738, -5756, -5774,
- -5791, -5809, -5827, -5844, -5862, -5880, -5897, -5914,
- -5932, -5949, -5966, -5984, -6001, -6018, -6035, -6052,
- -6069, -6085, -6102, -6119, -6136, -6152, -6169, -6185,
- -6202, -6218, -6235, -6251, -6267, -6283, -6299, -6315,
- -6331, -6347, -6363, -6379, -6395, -6410, -6426, -6441,
- -6457, -6472, -6488, -6503, -6518, -6533, -6549, -6564,
- -6579, -6594, -6608, -6623, -6638, -6653, -6667, -6682,
- -6696, -6711, -6725, -6739, -6754, -6768, -6782, -6796,
- -6810, -6824, -6838, -6852, -6865, -6879, -6893, -6906,
- -6920, -6933, -6946, -6960, -6973, -6986, -6999, -7012,
- -7025, -7038, -7051, -7064, -7076, -7089, -7101, -7114,
- -7126, -7139, -7151, -7163, -7175, -7187, -7199, -7211,
- -7223, -7235, -7247, -7259, -7270, -7282, -7293, -7305,
- -7316, -7327, -7338, -7349, -7361, -7372, -7382, -7393,
- -7404, -7415, -7425, -7436, -7446, -7457, -7467, -7478,
- -7488, -7498, -7508, -7518, -7528, -7538, -7548, -7557,
- -7567, -7577, -7586, -7596, -7605, -7614, -7623, -7633,
- -7642, -7651, -7660, -7668, -7677, -7686, -7695, -7703,
- -7712, -7720, -7728, -7737, -7745, -7753, -7761, -7769,
- -7777, -7785, -7793, -7800, -7808, -7816, -7823, -7830,
- -7838, -7845, -7852, -7859, -7866, -7873, -7880, -7887,
- -7894, -7900, -7907, -7914, -7920, -7926, -7933, -7939,
- -7945, -7951, -7957, -7963, -7969, -7975, -7980, -7986,
- -7991, -7997, -8002, -8008, -8013, -8018, -8023, -8028,
- -8033, -8038, -8043, -8047, -8052, -8057, -8061, -8066,
- -8070, -8074, -8078, -8082, -8086, -8090, -8094, -8098,
- -8102, -8105, -8109, -8113, -8116, -8119, -8123, -8126,
- -8129, -8132, -8135, -8138, -8141, -8143, -8146, -8149,
- -8151, -8153, -8156, -8158, -8160, -8162, -8164, -8166,
- -8168, -8170, -8172, -8174, -8175, -8177, -8178, -8179,
- -8181, -8182, -8183, -8184, -8185, -8186, -8187, -8187,
- -8188, -8189, -8189, -8190, -8190, -8190, -8190, -8190,
- -8191, -8190, -8190, -8190, -8190, -8190, -8189, -8189,
- -8188, -8187, -8187, -8186, -8185, -8184, -8183, -8182,
- -8181, -8179, -8178, -8177, -8175, -8174, -8172, -8170,
- -8168, -8166, -8164, -8162, -8160, -8158, -8156, -8153,
- -8151, -8149, -8146, -8143, -8141, -8138, -8135, -8132,
- -8129, -8126, -8123, -8119, -8116, -8113, -8109, -8105,
- -8102, -8098, -8094, -8090, -8086, -8082, -8078, -8074,
- -8070, -8066, -8061, -8057, -8052, -8047, -8043, -8038,
- -8033, -8028, -8023, -8018, -8013, -8008, -8002, -7997,
- -7991, -7986, -7980, -7975, -7969, -7963, -7957, -7951,
- -7945, -7939, -7933, -7926, -7920, -7914, -7907, -7900,
- -7894, -7887, -7880, -7873, -7866, -7859, -7852, -7845,
- -7838, -7830, -7823, -7816, -7808, -7800, -7793, -7785,
- -7777, -7769, -7761, -7753, -7745, -7737, -7728, -7720,
- -7712, -7703, -7695, -7686, -7677, -7668, -7660, -7651,
- -7642, -7633, -7623, -7614, -7605, -7596, -7586, -7577,
- -7567, -7557, -7548, -7538, -7528, -7518, -7508, -7498,
- -7488, -7478, -7467, -7457, -7446, -7436, -7425, -7415,
- -7404, -7393, -7382, -7372, -7361, -7349, -7338, -7327,
- -7316, -7305, -7293, -7282, -7270, -7259, -7247, -7235,
- -7223, -7211, -7199, -7187, -7175, -7163, -7151, -7139,
- -7126, -7114, -7101, -7089, -7076, -7064, -7051, -7038,
- -7025, -7012, -6999, -6986, -6973, -6960, -6946, -6933,
- -6920, -6906, -6893, -6879, -6865, -6852, -6838, -6824,
- -6810, -6796, -6782, -6768, -6754, -6739, -6725, -6711,
- -6696, -6682, -6667, -6653, -6638, -6623, -6608, -6594,
- -6579, -6564, -6549, -6533, -6518, -6503, -6488, -6472,
- -6457, -6441, -6426, -6410, -6395, -6379, -6363, -6347,
- -6331, -6315, -6299, -6283, -6267, -6251, -6235, -6218,
- -6202, -6185, -6169, -6152, -6136, -6119, -6102, -6085,
- -6069, -6052, -6035, -6018, -6001, -5984, -5966, -5949,
- -5932, -5914, -5897, -5880, -5862, -5844, -5827, -5809,
- -5791, -5774, -5756, -5738, -5720, -5702, -5684, -5666,
- -5648, -5629, -5611, -5593, -5574, -5556, -5537, -5519,
- -5500, -5482, -5463, -5444, -5425, -5406, -5388, -5369,
- -5350, -5331, -5311, -5292, -5273, -5254, -5235, -5215,
- -5196, -5176, -5157, -5137, -5118, -5098, -5078, -5059,
- -5039, -5019, -4999, -4979, -4959, -4939, -4919, -4899,
- -4879, -4859, -4838, -4818, -4798, -4777, -4757, -4736,
- -4716, -4695, -4675, -4654, -4633, -4613, -4592, -4571,
- -4550, -4529, -4508, -4487, -4466, -4445, -4424, -4403,
- -4382, -4360, -4339, -4318, -4296, -4275, -4254, -4232,
- -4211, -4189, -4167, -4146, -4124, -4102, -4080, -4059,
- -4037, -4015, -3993, -3971, -3949, -3927, -3905, -3883,
- -3861, -3839, -3816, -3794, -3772, -3749, -3727, -3705,
- -3682, -3660, -3637, -3615, -3592, -3570, -3547, -3524,
- -3502, -3479, -3456, -3433, -3410, -3388, -3365, -3342,
- -3319, -3296, -3273, -3250, -3227, -3204, -3180, -3157,
- -3134, -3111, -3088, -3064, -3041, -3018, -2994, -2971,
- -2947, -2924, -2900, -2877, -2853, -2830, -2806, -2783,
- -2759, -2735, -2712, -2688, -2664, -2640, -2617, -2593,
- -2569, -2545, -2521, -2497, -2473, -2449, -2425, -2401,
- -2377, -2353, -2329, -2305, -2281, -2257, -2233, -2208,
- -2184, -2160, -2136, -2111, -2087, -2063, -2038, -2014,
- -1990, -1965, -1941, -1917, -1892, -1868, -1843, -1819,
- -1794, -1770, -1745, -1721, -1696, -1671, -1647, -1622,
- -1597, -1573, -1548, -1523, -1499, -1474, -1449, -1425,
- -1400, -1375, -1350, -1326, -1301, -1276, -1251, -1226,
- -1201, -1177, -1152, -1127, -1102, -1077, -1052, -1027,
- -1002, -977, -952, -927, -902, -877, -852, -827,
- -802, -777, -752, -727, -702, -677, -652, -627,
- -602, -577, -552, -527, -502, -477, -452, -427,
- -401, -376, -351, -326, -301, -276, -251, -226,
- -201, -175, -150, -125, -100, -75, -50, -25,
- 0, 25, 50, 75, 100, 125, 150, 175,
- 201, 226, 251, 276, 301, 326, 351, 376,
- 401, 427, 452, 477, 502, 527, 552, 577,
- 602, 627, 652, 677, 702, 727, 752, 777,
- 802, 827, 852, 877, 902, 927, 952, 977,
- 1002, 1027, 1052, 1077, 1102, 1127, 1152, 1177,
- 1201, 1226, 1251, 1276, 1301, 1326, 1350, 1375,
- 1400, 1425, 1449, 1474, 1499, 1523, 1548, 1573,
- 1597, 1622, 1647, 1671, 1696, 1721, 1745, 1770,
- 1794, 1819, 1843, 1868, 1892, 1917, 1941, 1965,
- 1990, 2014, 2038, 2063, 2087, 2111, 2136, 2160,
- 2184, 2208, 2233, 2257, 2281, 2305, 2329, 2353,
- 2377, 2401, 2425, 2449, 2473, 2497, 2521, 2545,
- 2569, 2593, 2617, 2640, 2664, 2688, 2712, 2735,
- 2759, 2783, 2806, 2830, 2853, 2877, 2900, 2924,
- 2947, 2971, 2994, 3018, 3041, 3064, 3088, 3111,
- 3134, 3157, 3180, 3204, 3227, 3250, 3273, 3296,
- 3319, 3342, 3365, 3388, 3410, 3433, 3456, 3479,
- 3502, 3524, 3547, 3570, 3592, 3615, 3637, 3660,
- 3682, 3705, 3727, 3749, 3772, 3794, 3816, 3839,
- 3861, 3883, 3905, 3927, 3949, 3971, 3993, 4015,
- 4037, 4059, 4080, 4102, 4124, 4146, 4167, 4189,
- 4211, 4232, 4254, 4275, 4296, 4318, 4339, 4360,
- 4382, 4403, 4424, 4445, 4466, 4487, 4508, 4529,
- 4550, 4571, 4592, 4613, 4633, 4654, 4675, 4695,
- 4716, 4736, 4757, 4777, 4798, 4818, 4838, 4859,
- 4879, 4899, 4919, 4939, 4959, 4979, 4999, 5019,
- 5039, 5059, 5078, 5098, 5118, 5137, 5157, 5176,
- 5196, 5215, 5235, 5254, 5273, 5292, 5311, 5331,
- 5350, 5369, 5388, 5406, 5425, 5444, 5463, 5482,
- 5500, 5519, 5537, 5556, 5574, 5593, 5611, 5629,
- 5648, 5666, 5684, 5702, 5720, 5738, 5756, 5774,
- 5791, 5809, 5827, 5844, 5862, 5880, 5897, 5914,
- 5932, 5949, 5966, 5984, 6001, 6018, 6035, 6052,
- 6069, 6085, 6102, 6119, 6136, 6152, 6169, 6185,
- 6202, 6218, 6235, 6251, 6267, 6283, 6299, 6315,
- 6331, 6347, 6363, 6379, 6395, 6410, 6426, 6441,
- 6457, 6472, 6488, 6503, 6518, 6533, 6549, 6564,
- 6579, 6594, 6608, 6623, 6638, 6653, 6667, 6682,
- 6696, 6711, 6725, 6739, 6754, 6768, 6782, 6796,
- 6810, 6824, 6838, 6852, 6865, 6879, 6893, 6906,
- 6920, 6933, 6946, 6960, 6973, 6986, 6999, 7012,
- 7025, 7038, 7051, 7064, 7076, 7089, 7101, 7114,
- 7126, 7139, 7151, 7163, 7175, 7187, 7199, 7211,
- 7223, 7235, 7247, 7259, 7270, 7282, 7293, 7305,
- 7316, 7327, 7338, 7349, 7361, 7372, 7382, 7393,
- 7404, 7415, 7425, 7436, 7446, 7457, 7467, 7478,
- 7488, 7498, 7508, 7518, 7528, 7538, 7548, 7557,
- 7567, 7577, 7586, 7596, 7605, 7614, 7623, 7633,
- 7642, 7651, 7660, 7668, 7677, 7686, 7695, 7703,
- 7712, 7720, 7728, 7737, 7745, 7753, 7761, 7769,
- 7777, 7785, 7793, 7800, 7808, 7816, 7823, 7830,
- 7838, 7845, 7852, 7859, 7866, 7873, 7880, 7887,
- 7894, 7900, 7907, 7914, 7920, 7926, 7933, 7939,
- 7945, 7951, 7957, 7963, 7969, 7975, 7980, 7986,
- 7991, 7997, 8002, 8008, 8013, 8018, 8023, 8028,
- 8033, 8038, 8043, 8047, 8052, 8057, 8061, 8066,
- 8070, 8074, 8078, 8082, 8086, 8090, 8094, 8098,
- 8102, 8105, 8109, 8113, 8116, 8119, 8123, 8126,
- 8129, 8132, 8135, 8138, 8141, 8143, 8146, 8149,
- 8151, 8153, 8156, 8158, 8160, 8162, 8164, 8166,
- 8168, 8170, 8172, 8174, 8175, 8177, 8178, 8179,
- 8181, 8182, 8183, 8184, 8185, 8186, 8187, 8187,
- 8188, 8189, 8189, 8190, 8190, 8190, 8190, 8190,
- 8191, 8190, 8190, 8190, 8190, 8190, 8189, 8189,
- 8188, 8187, 8187, 8186, 8185, 8184, 8183, 8182,
- 8181, 8179, 8178, 8177, 8175, 8174, 8172, 8170,
- 8168, 8166, 8164, 8162, 8160, 8158, 8156, 8153,
- 8151, 8149, 8146, 8143, 8141, 8138, 8135, 8132,
- 8129, 8126, 8123, 8119, 8116, 8113, 8109, 8105,
- 8102, 8098, 8094, 8090, 8086, 8082, 8078, 8074,
- 8070, 8066, 8061, 8057, 8052, 8047, 8043, 8038,
- 8033, 8028, 8023, 8018, 8013, 8008, 8002, 7997,
- 7991, 7986, 7980, 7975, 7969, 7963, 7957, 7951,
- 7945, 7939, 7933, 7926, 7920, 7914, 7907, 7900,
- 7894, 7887, 7880, 7873, 7866, 7859, 7852, 7845,
- 7838, 7830, 7823, 7816, 7808, 7800, 7793, 7785,
- 7777, 7769, 7761, 7753, 7745, 7737, 7728, 7720,
- 7712, 7703, 7695, 7686, 7677, 7668, 7660, 7651,
- 7642, 7633, 7623, 7614, 7605, 7596, 7586, 7577,
- 7567, 7557, 7548, 7538, 7528, 7518, 7508, 7498,
- 7488, 7478, 7467, 7457, 7446, 7436, 7425, 7415,
- 7404, 7393, 7382, 7372, 7361, 7349, 7338, 7327,
- 7316, 7305, 7293, 7282, 7270, 7259, 7247, 7235,
- 7223, 7211, 7199, 7187, 7175, 7163, 7151, 7139,
- 7126, 7114, 7101, 7089, 7076, 7064, 7051, 7038,
- 7025, 7012, 6999, 6986, 6973, 6960, 6946, 6933,
- 6920, 6906, 6893, 6879, 6865, 6852, 6838, 6824,
- 6810, 6796, 6782, 6768, 6754, 6739, 6725, 6711,
- 6696, 6682, 6667, 6653, 6638, 6623, 6608, 6594,
- 6579, 6564, 6549, 6533, 6518, 6503, 6488, 6472,
- 6457, 6441, 6426, 6410, 6395, 6379, 6363, 6347,
- 6331, 6315, 6299, 6283, 6267, 6251, 6235, 6218,
- 6202, 6185, 6169, 6152, 6136, 6119, 6102, 6085,
- 6069, 6052, 6035, 6018, 6001, 5984, 5966, 5949,
- 5932, 5914, 5897, 5880, 5862, 5844, 5827, 5809,
- 5791, 5774, 5756, 5738, 5720, 5702, 5684, 5666,
- 5648, 5629, 5611, 5593, 5574, 5556, 5537, 5519,
- 5500, 5482, 5463, 5444, 5425, 5406, 5388, 5369,
- 5350, 5331, 5311, 5292, 5273, 5254, 5235, 5215,
- 5196, 5176, 5157, 5137, 5118, 5098, 5078, 5059,
- 5039, 5019, 4999, 4979, 4959, 4939, 4919, 4899,
- 4879, 4859, 4838, 4818, 4798, 4777, 4757, 4736,
- 4716, 4695, 4675, 4654, 4633, 4613, 4592, 4571,
- 4550, 4529, 4508, 4487, 4466, 4445, 4424, 4403,
- 4382, 4360, 4339, 4318, 4296, 4275, 4254, 4232,
- 4211, 4189, 4167, 4146, 4124, 4102, 4080, 4059,
- 4037, 4015, 3993, 3971, 3949, 3927, 3905, 3883,
- 3861, 3839, 3816, 3794, 3772, 3749, 3727, 3705,
- 3682, 3660, 3637, 3615, 3592, 3570, 3547, 3524,
- 3502, 3479, 3456, 3433, 3410, 3388, 3365, 3342,
- 3319, 3296, 3273, 3250, 3227, 3204, 3180, 3157,
- 3134, 3111, 3088, 3064, 3041, 3018, 2994, 2971,
- 2947, 2924, 2900, 2877, 2853, 2830, 2806, 2783,
- 2759, 2735, 2712, 2688, 2664, 2640, 2617, 2593,
- 2569, 2545, 2521, 2497, 2473, 2449, 2425, 2401,
- 2377, 2353, 2329, 2305, 2281, 2257, 2233, 2208,
- 2184, 2160, 2136, 2111, 2087, 2063, 2038, 2014,
- 1990, 1965, 1941, 1917, 1892, 1868, 1843, 1819,
- 1794, 1770, 1745, 1721, 1696, 1671, 1647, 1622,
- 1597, 1573, 1548, 1523, 1499, 1474, 1449, 1425,
- 1400, 1375, 1350, 1326, 1301, 1276, 1251, 1226,
- 1201, 1177, 1152, 1127, 1102, 1077, 1052, 1027,
- 1002, 977, 952, 927, 902, 877, 852, 827,
- 802, 777, 752, 727, 702, 677, 652, 627,
- 602, 577, 552, 527, 502, 477, 452, 427,
- 401, 376, 351, 326, 301, 276, 251, 226,
- 201, 175, 150, 125, 100, 75, 50, 25,
- };
diff --git a/navit/support/espeak/speak.c b/navit/support/espeak/speak.c
deleted file mode 100755
index ab33a867b..000000000
--- a/navit/support/espeak/speak.c
+++ /dev/null
@@ -1,898 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2005 to 2007 by Jonathan Duddington *
- * email: jonsd@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write see: *
- * <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-#include "StdAfx.h"
-
-#include "speech.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef PLATFORM_DOS
-#ifdef PLATFORM_WINDOWS
-#include <windows.h>
-#include <winreg.h>
-#else
-#include <unistd.h>
-#endif
-#endif
-
-#ifndef NEED_GETOPT
-#include <getopt.h>
-#endif
-#include <time.h>
-#include <signal.h>
-#include <locale.h>
-#include <sys/stat.h>
-
-#include "speak_lib.h"
-#include "phoneme.h"
-#include "synthesize.h"
-#include "voice.h"
-#include "translate.h"
-
-
-
-extern void Write4Bytes(FILE *f, int value);
-char path_home[N_PATH_HOME]; // this is the espeak-data directory
-
-char filetype[5];
-char wavefile[200];
-int (* uri_callback)(int, const char *, const char *) = NULL;
-int (* phoneme_callback)(const char *) = NULL;
-
-FILE *f_wave = NULL;
-int quiet = 0;
-unsigned int samples_total = 0;
-unsigned int samples_split = 0;
-unsigned int wavefile_count = 0;
-int end_of_sentence = 0;
-
-static const char *help_text =
-"\nspeak [options] [\"<words>\"]\n\n"
-"-f <text file> Text file to speak\n"
-"--stdin Read text input from stdin instead of a file\n\n"
-"If neither -f nor --stdin, <words> are spoken, or if none then text is\n"
-"spoken from stdin, each line separately.\n\n"
-"-a <integer>\n"
-"\t Amplitude, 0 to 200, default is 100\n"
-"-g <integer>\n"
-"\t Word gap. Pause between words, units of 10mS at the default speed\n"
-"-l <integer>\n"
-"\t Line length. If not zero (which is the default), consider\n"
-"\t lines less than this length as end-of-clause\n"
-"-p <integer>\n"
-"\t Pitch adjustment, 0 to 99, default is 50\n"
-"-s <integer>\n"
-"\t Speed in words per minute 80 to 390, default is 170\n"
-"-v <voice name>\n"
-"\t Use voice file of this name from espeak-data/voices\n"
-"-w <wave file name>\n"
-"\t Write output to this WAV file, rather than speaking it directly\n"
-"-b\t Input text encoding, 1=UTF8, 2=8 bit, 4=16 bit \n"
-"-m\t Interpret SSML markup, and ignore other < > tags\n"
-"-q\t Quiet, don't produce any speech (may be useful with -x)\n"
-"-x\t Write phoneme mnemonics to stdout\n"
-"-X\t Write phonemes mnemonics and translation trace to stdout\n"
-"-z\t No final sentence pause at the end of the text\n"
-"--stdout Write speech output to stdout\n"
-"--compile=<voice name>\n"
-"\t Compile the pronunciation rules and dictionary in the current\n"
-"\t directory. =<voice name> is optional and specifies which language\n"
-"--path=\"<path>\"\n"
-"\t Specifies the directory containing the espeak-data directory\n"
-"--phonout=\"<filename>\"\n"
-"\t Write output from -x -X commands and mbrola phoneme data to this file\n"
-"--punct=\"<characters>\"\n"
-"\t Speak the names of punctuation characters during speaking. If\n"
-"\t =<characters> is omitted, all punctuation is spoken.\n"
-"--split=\"<minutes>\"\n"
-"\t Starts a new WAV file every <minutes>. Used with -w\n"
-"--voices=<language>\n"
-"\t List the available voices for the specified language.\n"
-"\t If <language> is omitted, then list all voices.\n"
-"-k <integer>\n"
-"\t Indicate capital letters with: 1=sound, 2=the word \"capitals\",\n"
-"\t higher values = a pitch increase (try -k20).\n";
-
-
-void DisplayVoices(FILE *f_out, char *language);
-
-USHORT voice_pcnt[N_PEAKS+1][3];
-
-
-
-int GetFileLength(const char *filename)
-{//====================================
- struct stat statbuf;
-
- if(stat(filename,&statbuf) != 0)
- return(0);
-
- if((statbuf.st_mode & S_IFMT) == S_IFDIR)
-// if(S_ISDIR(statbuf.st_mode))
- return(-2); // a directory
-
- return(statbuf.st_size);
-} // end of GetFileLength
-
-
-char *Alloc(int size)
-{//==================
- char *p;
- if((p = (char *)malloc(size)) == NULL)
- fprintf(stderr,"Can't allocate memory\n");
- return(p);
-}
-
-void Free(void *ptr)
-{//=================
- if(ptr != NULL)
- free(ptr);
-}
-
-
-void DisplayVoices(FILE *f_out, char *language)
-{//============================================
- int ix;
- const char *p;
- int len;
- int count;
- int scores = 0;
- const espeak_VOICE *v;
- const char *lang_name;
- char age_buf[12];
- const espeak_VOICE **voices;
- espeak_VOICE voice_select;
-
- static char genders[4] = {' ','M','F',' '};
-
- if((language != NULL) && (language[0] != 0))
- {
- // display only voices for the specified language, in order of priority
- voice_select.languages = language;
- voice_select.age = 0;
- voice_select.gender = 0;
- voice_select.name = NULL;
- voices = espeak_ListVoices(&voice_select);
- scores = 1;
- }
- else
- {
- voices = espeak_ListVoices(NULL);
- }
-
- fprintf(f_out,"Pty Language Age/Gender VoiceName File Other Langs\n");
-
- for(ix=0; (v = voices[ix]) != NULL; ix++)
- {
- count = 0;
- p = v->languages;
- while(*p != 0)
- {
- len = strlen(p+1);
- lang_name = p+1;
-
- if(v->age == 0)
- strcpy(age_buf," ");
- else
- sprintf(age_buf,"%3d",v->age);
-
- if(count==0)
- {
- fprintf(f_out,"%2d %-12s%s%c %-17s %-11s ",
- p[0],lang_name,age_buf,genders[v->gender],v->name,v->identifier);
- }
- else
- {
- fprintf(f_out,"(%s %d)",lang_name,p[0]);
- }
- count++;
- p += len+2;
- }
-// if(scores)
-// fprintf(f_out,"%3d ",v->score);
- fputc('\n',f_out);
- }
-} // end of DisplayVoices
-
-
-
-
-static int OpenWaveFile(const char *path, int rate)
-//=================================================
-{
- // Set the length of 0x7ffff000 for --stdout
- // This will be changed to the correct length for -w (write to file)
- static unsigned char wave_hdr[44] = {
- 'R','I','F','F',0x24,0xf0,0xff,0x7f,'W','A','V','E','f','m','t',' ',
- 0x10,0,0,0,1,0,1,0, 9,0x3d,0,0,0x12,0x7a,0,0,
- 2,0,0x10,0,'d','a','t','a', 0x00,0xf0,0xff,0x7f};
-
- if(path == NULL)
- return(2);
-
- if(strcmp(path,"stdout")==0)
- f_wave = stdout;
- else
- f_wave = fopen(path,"wb");
-
- if(f_wave != NULL)
- {
- fwrite(wave_hdr,1,24,f_wave);
- Write4Bytes(f_wave,rate);
- Write4Bytes(f_wave,rate * 2);
- fwrite(&wave_hdr[32],1,12,f_wave);
- return(0);
- }
- return(1);
-} // end of OpenWaveFile
-
-
-
-
-static void CloseWaveFile()
-//=========================
-{
- unsigned int pos;
-
- if((f_wave == NULL) || (f_wave == stdout))
- return;
-
- fflush(f_wave);
- pos = ftell(f_wave);
-
- fseek(f_wave,4,SEEK_SET);
- Write4Bytes(f_wave,pos - 8);
-
- fseek(f_wave,40,SEEK_SET);
- Write4Bytes(f_wave,pos - 44);
-
-
- fclose(f_wave);
- f_wave = NULL;
-
-} // end of CloseWaveFile
-
-
-
-
-void MarkerEvent(int type, unsigned int char_position, int value, unsigned char *out_ptr)
-{//======================================================================================
-// Do nothing in the command-line version.
- if(type == 2)
- end_of_sentence = 1;
-} // end of MarkerEvent
-
-
-static int WavegenFile(void)
-{//=========================
- int finished;
- unsigned char wav_outbuf[512];
- char fname[210];
-
- out_ptr = out_start = wav_outbuf;
- out_end = wav_outbuf + sizeof(wav_outbuf);
-
- finished = WavegenFill(0);
-
- if(quiet)
- return(finished);
-
- if(f_wave == NULL)
- {
- sprintf(fname,"%s_%.2d%s",wavefile,++wavefile_count,filetype);
- if(OpenWaveFile(fname, samplerate) != 0)
- return(1);
- }
-
- if(end_of_sentence)
- {
- end_of_sentence = 0;
- if((samples_split > 0 ) && (samples_total > samples_split))
- {
- CloseWaveFile();
- samples_total = 0;
- }
- }
-
- if(f_wave != NULL)
- {
- samples_total += (out_ptr - wav_outbuf)/2;
- fwrite(wav_outbuf, 1, out_ptr - wav_outbuf, f_wave);
- }
- return(finished);
-} // end of WavegenFile
-
-
-
-static void init_path(char *argv0, char *path_specified)
-{//=====================================================
-
- if(path_specified)
- {
- sprintf(path_home,"%s/espeak-data",path_specified);
- return;
- }
-
-#ifdef PLATFORM_WINDOWS
- HKEY RegKey;
- unsigned long size;
- unsigned long var_type;
- char *p;
- char *env;
- unsigned char buf[sizeof(path_home)-12];
-
-#if 0
- if(((env = getenv("ESPEAK_DATA_PATH")) != NULL) && ((strlen(env)+12) < sizeof(path_home)))
- {
- sprintf(path_home,"%s\\espeak-data",env);
- if(GetFileLength(path_home) == -2)
- return; // an espeak-data directory exists in the directory specified by environment variable
- }
-#endif
-
- strcpy(path_home,argv0);
- if((p = strrchr(path_home,'\\')) != NULL)
- {
- strcpy(&p[1],"espeak-data");
- if(GetFileLength(path_home) == -2)
- return; // an espeak-data directory exists in the same directory as the espeak program
- }
-
- // otherwise, look in the Windows Registry
- buf[0] = 0;
- RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Speech\\Voices\\Tokens\\eSpeak", 0, KEY_READ, &RegKey);
- size = sizeof(buf);
- var_type = REG_SZ;
- RegQueryValueEx(RegKey, "path", 0, &var_type, buf, &size);
-
- sprintf(path_home,"%s\\espeak-data",buf);
-#else
-#ifdef PLATFORM_DOS
- strcpy(path_home,PATH_ESPEAK_DATA);
-#else
- char *env;
-#if 0
- if((env = getenv("ESPEAK_DATA_PATH")) != NULL)
- {
- snprintf(path_home,sizeof(path_home),"%s/espeak-data",env);
- if(GetFileLength(path_home) == -2)
- return; // an espeak-data directory exists
- }
-#endif
-
-#if 0
- snprintf(path_home,sizeof(path_home),"%s/espeak-data",getenv("HOME"));
- if(access(path_home,R_OK) != 0)
- {
- strcpy(path_home,PATH_ESPEAK_DATA);
- }
-#endif
-#endif
-#endif
-}
-
-
-static int initialise(void)
-{//========================
- int param;
- int result;
-
- // It seems that the wctype functions don't work until the locale has been set
- // to something other than the default "C". Then, not only Latin1 but also the
- // other characters give the correct results with iswalpha() etc.
-#ifdef PLATFORM_RISCOS
- setlocale(LC_CTYPE,"ISO8859-1");
-#else
-#if 0
- if(setlocale(LC_CTYPE,"en_US.UTF-8") == NULL)
- {
- if(setlocale(LC_CTYPE,"UTF-8") == NULL)
- setlocale(LC_CTYPE,"");
- }
-#endif
-#endif
-
-
- WavegenInit(22050,0); // 22050
- if((result = LoadPhData()) != 1)
- {
- if(result == -1)
- {
- fprintf(stderr,"Failed to load espeak-data\n");
- exit(1);
- }
- else
- fprintf(stderr,"Wrong version of espeak-data 0x%x (expects 0x%x) at %s\n",result,version_phdata,path_home);
- }
- LoadConfig();
- SetVoiceStack(NULL);
- SynthesizeInit();
-
- for(param=0; param<N_SPEECH_PARAM; param++)
- param_stack[0].parameter[param] = param_defaults[param];
-
- return(0);
-}
-
-
-static void StopSpeak(int unused)
-{//==============================
-// signal(SIGINT,SIG_IGN);
- // DEBUG
-// printf("\n*** Interrupting speech output (use Ctrl-D to actually quit).\n");
- fflush(stdout);
- SpeakNextClause(NULL,NULL,5);
-// signal(SIGINT,StopSpeak);
-} // end of StopSpeak()
-
-#ifdef NEED_GETOPT
- struct option {
- char *name;
- int has_arg;
- int *flag;
- int val;
- };
- int optind;
- static int optional_argument;
- static const char *arg_opts = "abfgklpsvw"; // which options have arguments
- static char *opt_string="";
-#define no_argument 0
-#define required_argument 1
-#define optional_argument 2
-#endif
-
-int main (int argc, char **argv)
-//==============================
-{
- static struct option long_options[] =
- {
- /* These options set a flag. */
-// {"verbose", no_argument, &verbose_flag, 1},
-// {"brief", no_argument, &verbose_flag, 0},
-
- /* These options don't set a flag.
- We distinguish them by their indices. */
- {"help", no_argument, 0, 'h'},
- {"stdin", no_argument, 0, 0x100},
- {"compile-debug", optional_argument, 0, 0x101},
- {"compile", optional_argument, 0, 0x102},
- {"punct", optional_argument, 0, 0x103},
- {"voices", optional_argument, 0, 0x104},
- {"stdout", no_argument, 0, 0x105},
- {"split", optional_argument, 0, 0x106},
- {"path", required_argument, 0, 0x107},
- {"phonout", required_argument, 0, 0x108},
- {0, 0, 0, 0}
- };
-
- static const char *err_load = "Failed to read ";
-
- FILE *f_text=NULL;
- const char *p_text=NULL;
- char *data_path = NULL; // use default path for espeak-data
-
- int option_index = 0;
- int c;
- int value;
- int speed=170;
- int ix;
- char *optarg2;
- int amp = 100; // default
- int wordgap = 0;
- int speaking = 0;
- int flag_stdin = 0;
- int flag_compile = 0;
- int pitch_adjustment = 50;
- espeak_VOICE voice_select;
- char filename[200];
- char voicename[40];
- char dictname[40];
-
- voicename[0] = 0;
- mbrola_name[0] = 0;
- dictname[0] = 0;
- wavefile[0] = 0;
- filename[0] = 0;
- option_linelength = 0;
- option_phonemes = 0;
- option_waveout = 0;
- option_wordgap = 0;
- option_endpause = 1;
- option_phoneme_input = 1;
- option_multibyte = espeakCHARS_AUTO; // auto
- f_trans = stdout;
-
-#ifdef NEED_GETOPT
- optind = 1;
- opt_string = "";
- while(optind < argc)
- {
- int len;
- char *p;
-
- if((c = *opt_string) == 0)
- {
- opt_string = argv[optind];
- if(opt_string[0] != '-')
- break;
-
- optind++;
- opt_string++;
- c = *opt_string;
- }
- opt_string++;
- p = optarg2 = opt_string;
-
- if(c == '-')
- {
- opt_string="";
- for(ix=0; ;ix++)
- {
- if(long_options[ix].name == 0)
- break;
- len = strlen(long_options[ix].name);
- if(memcmp(long_options[ix].name,p,len)==0)
- {
- c = long_options[ix].val;
- optarg2 = NULL;
-
- if((long_options[ix].has_arg != 0) && (p[len]=='='))
- {
- optarg2 = &p[len+1];
- }
- break;
- }
- }
- }
- else
- if(strchr(arg_opts,c) != NULL)
- {
- opt_string="";
- if(optarg2[0]==0)
- {
- // the option's value is in the next argument
- optarg2 = argv[optind++];
- }
- }
-#else
- while(1)
- {
- c = getopt_long (argc, argv, "a:b:f:g:hk:l:p:qs:v:w:xXmz", // NOTE: also change arg_opts to indicate which commands have a numeric value
- long_options, &option_index);
-
- /* Detect the end of the options. */
- if (c == -1)
- break;
- optarg2 = optarg;
-#endif
-
- switch (c)
- {
- case 'b':
- // input character encoding, 8bit, 16bit, UTF8
- option_multibyte = espeakCHARS_8BIT;
- if((sscanf(optarg2,"%d",&value) == 1) && (value <= 4))
- option_multibyte= value;
- break;
-
- case 'h':
- printf("\nspeak text-to-speech: %s\n%s",version_string,help_text);
- exit(0);
- break;
-
- case 'k':
- option_capitals = atoi(optarg2);
- break;
-
- case 'x':
- option_phonemes = 1;
- break;
-
- case 'X':
- option_phonemes = 2;
- break;
-
- case 'm':
- option_ssml = 1;
- break;
-
- case 'p':
- pitch_adjustment = atoi(optarg2);
- if(pitch_adjustment > 99) pitch_adjustment = 99;
- break;
-
- case 'q':
- quiet = 1;
- break;
-
- case 'f':
- strncpy0(filename,optarg2,sizeof(filename));
- break;
-
- case 'l':
- value = 0;
- value = atoi(optarg2);
- option_linelength = value;
- break;
-
- case 'a':
- amp = atoi(optarg2);
- break;
-
- case 's':
- speed = atoi(optarg2);
- break;
-
- case 'g':
- wordgap = atoi(optarg2);
- break;
-
- case 'v':
- strncpy0(voicename,optarg2,sizeof(voicename));
- break;
-
- case 'w':
- option_waveout = 1;
- strncpy0(wavefile,optarg2,sizeof(wavefile));
- break;
-
- case 'z':
- option_endpause = 0;
- break;
-
- case 0x100: // --stdin
- flag_stdin = 1;
- break;
-
- case 0x105: // --stdout
- option_waveout = 1;
- strcpy(wavefile,"stdout");
- break;
-
- case 0x101: // --compile-debug
- case 0x102: // --compile
- if(optarg2 != NULL)
- strncpy0(voicename,optarg2,sizeof(voicename));
- flag_compile = c;
- break;
-
- case 0x103: // --punct
- option_punctuation = 1;
- if(optarg2 != NULL)
- {
- ix = 0;
- while((ix < N_PUNCTLIST) && ((option_punctlist[ix] = optarg2[ix]) != 0)) ix++;
- option_punctlist[N_PUNCTLIST-1] = 0;
- option_punctuation = 2;
- }
- break;
-
- case 0x104: // --voices
- init_path(argv[0],data_path);
- DisplayVoices(stdout,optarg2);
- exit(0);
-
- case 0x106: // -- split
- if(optarg2 == NULL)
- samples_split = 30; // default 30 minutes
- else
- samples_split = atoi(optarg2);
- break;
-
- case 0x107: // --path
- data_path = optarg2;
- break;
-
- case 0x108: // --phonout
- if((f_trans = fopen(optarg2,"w")) == NULL)
- {
- fprintf(stderr,"Can't write to: %s\n",optarg2);
- f_trans = stderr;
- }
- break;
-
- default:
- exit(0);
- }
- }
-
- init_path(argv[0],data_path);
- initialise();
-
-
- if(flag_compile)
- {
- LoadVoice(voicename,5);
-
-#ifdef PLATFORM_DOS
- char path_dsource[sizeof(path_home)+20];
- strcpy(path_dsource,path_home);
- path_dsource[strlen(path_home)-11] = 0; // remove "espeak-data" from the end
- strcat(path_dsource,"dictsource\\");
- CompileDictionary(path_dsource,dictionary_name,NULL,NULL, flag_compile & 0x1);
-#else
-#ifdef PLATFORM_WINDOWS
- char path_dsource[sizeof(path_home)+20];
- strcpy(path_dsource,path_home);
- path_dsource[strlen(path_home)-11] = 0; // remove "espeak-data" from the end
- strcat(path_dsource,"dictsource\\");
- CompileDictionary(path_dsource,dictionary_name,NULL,NULL, flag_compile & 0x1);
-#else
- CompileDictionary(NULL,dictionary_name,NULL,NULL, flag_compile & 0x1);
-#endif
-#endif
- exit(0);
- }
-
-
- if(voicename[0] == 0)
- strcpy(voicename,"default");
-
- if(SetVoiceByName(voicename) != EE_OK)
- {
- memset(&voice_select,0,sizeof(voice_select));
- voice_select.languages = voicename;
- if(SetVoiceByProperties(&voice_select) != EE_OK)
- {
- fprintf(stderr,"%svoice '%s'\n",err_load,voicename);
- exit(2);
- }
- }
-
- SetParameter(espeakRATE,speed,0);
- SetParameter(espeakVOLUME,amp,0);
- SetParameter(espeakCAPITALS,option_capitals,0);
- SetParameter(espeakPUNCTUATION,option_punctuation,0);
- SetParameter(espeakWORDGAP,wordgap,0);
-
- if(pitch_adjustment != 50)
- {
- SetParameter(espeakPITCH,pitch_adjustment,0);
- }
- DoVoiceChange(voice);
-
- if(filename[0]==0)
- {
- if((optind < argc) && (flag_stdin == 0))
- {
- // there's a non-option parameter, and no -f or --stdin
- // use it as text
- p_text = argv[optind];
- }
- else
- {
- f_text = stdin;
- if(flag_stdin == 0)
- option_linelength = -1; // single input lines on stdin
- }
- }
- else
- {
- f_text = fopen(filename,"r");
- }
-
- if((f_text == NULL) && (p_text == NULL))
- {
- fprintf(stderr,"%sfile '%s'\n",err_load,filename);
- exit(1);
- }
-
- if(option_waveout || quiet)
- {
- if(quiet)
- {
- // no sound output
- OpenWaveFile(NULL,samplerate);
- option_waveout = 1;
- }
- else
- {
- // write sound output to a WAV file
- samples_split = (samplerate * samples_split) * 60;
-
- if(samples_split)
- {
- // don't open the wav file until we start generating speech
- char *extn;
- extn = strrchr(wavefile,'.');
- if((extn != NULL) && ((wavefile + strlen(wavefile) - extn) <= 4))
- {
- strcpy(filetype,extn);
- *extn = 0;
- }
- }
- else
- if(OpenWaveFile(wavefile,samplerate) != 0)
- {
- fprintf(stderr,"Can't write to output file '%s'\n'",wavefile);
- exit(3);
- }
- }
-
- InitText(0);
- SpeakNextClause(f_text,p_text,0);
-
- ix = 1;
- for(;;)
- {
- if(WavegenFile() != 0)
- {
- if(ix == 0)
- break; // finished, wavegen command queue is empty
- }
-
- if(Generate(phoneme_list,&n_phoneme_list,1)==0)
- {
- ix = SpeakNextClause(NULL,NULL,1);
- }
- }
-
- CloseWaveFile();
- }
- else
- {
- // Silence on ^C or SIGINT
-// signal(SIGINT,StopSpeak);
-
- // output sound using portaudio
- WavegenInitSound();
-
- InitText(0);
- SpeakNextClause(f_text,p_text,0);
-
- if(option_quiet)
- {
- while(SpeakNextClause(NULL,NULL,1) != 0);
- return(0);
- }
-
-#ifdef USE_PORTAUDIO
- speaking = 1;
- while(speaking)
- {
- // NOTE: if nanosleep() isn't recognised on your system, try replacing
- // this by sleep(1);
-#ifdef PLATFORM_WINDOWS
- Sleep(300); // 0.3s
-#else
-#ifdef USE_NANOSLEEP
- struct timespec period;
- struct timespec remaining;
- period.tv_sec = 0;
- period.tv_nsec = 300000000; // 0.3 sec
- nanosleep(&period,&remaining);
-#else
- sleep(1);
-#endif
-#endif
- if(SynthOnTimer() != 0)
- speaking = 0;
- }
-#else
- fprintf(stderr,"-w option must be used because the program was built without a sound interface\n");
-#endif // USE_PORTAUDIO
- }
-
- if((f_trans != stdout) && (f_trans != stderr))
- fclose(f_trans); // needed for WinCe
- return(0);
-}
diff --git a/navit/support/espeak/speak_init.c b/navit/support/espeak/speak_init.c
deleted file mode 100644
index 06a34235f..000000000
--- a/navit/support/espeak/speak_init.c
+++ /dev/null
@@ -1,6 +0,0 @@
-#include "../../plugin.h"
-
-void
-plugin_init(void)
-{
-}
diff --git a/navit/support/espeak/speak_lib.c b/navit/support/espeak/speak_lib.c
deleted file mode 100644
index 85c1b39a3..000000000
--- a/navit/support/espeak/speak_lib.c
+++ /dev/null
@@ -1,1156 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2005 to 2007 by Jonathan Duddington *
- * email: jonsd@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write see: *
- * <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-#include "StdAfx.h"
-
-#include "stdio.h"
-#include "ctype.h"
-#include "string.h"
-#include "stdlib.h"
-#include "wchar.h"
-#include "locale.h"
-#include <assert.h>
-#include <time.h>
-
-#include "speech.h"
-
-#include <sys/stat.h>
-#ifdef PLATFORM_WINDOWS
-#include <windows.h>
-#else
-#include <unistd.h>
-#endif
-
-#include "speak_lib.h"
-#include "phoneme.h"
-#include "synthesize.h"
-#include "voice.h"
-#include "translate.h"
-#include "debug.h"
-
-#include "fifo.h"
-#include "event.h"
-#include "wave.h"
-
-unsigned char *outbuf=NULL;
-extern espeak_VOICE voice_selected;
-
-espeak_EVENT *event_list=NULL;
-int event_list_ix=0;
-int n_event_list;
-long count_samples;
-void* my_audio=NULL;
-
-static unsigned int my_unique_identifier=0;
-static void* my_user_data=NULL;
-static espeak_AUDIO_OUTPUT my_mode=AUDIO_OUTPUT_SYNCHRONOUS;
-static int synchronous_mode = 1;
-t_espeak_callback* synth_callback = NULL;
-int (* uri_callback)(int, const char *, const char *) = NULL;
-int (* phoneme_callback)(const char *) = NULL;
-
-char path_home[N_PATH_HOME]; // this is the espeak-data directory
-
-
-#ifdef USE_ASYNC
-
-static int dispatch_audio(short* outbuf, int length, espeak_EVENT* event)
-{//======================================================================
- ENTER("dispatch_audio");
-
- int a_wave_can_be_played = fifo_is_command_enabled();
-
-#ifdef DEBUG_ENABLED
- SHOW("*** dispatch_audio > uid=%d, [write=%p (%d bytes)], sample=%d, a_wave_can_be_played = %d\n",
- (event) ? event->unique_identifier : 0, wave_test_get_write_buffer(), 2*length,
- (event) ? event->sample : 0,
- a_wave_can_be_played);
-#endif
-
- switch(my_mode)
- {
- case AUDIO_OUTPUT_PLAYBACK:
- {
- if (outbuf && length && a_wave_can_be_played)
- {
- wave_write (my_audio, (char*)outbuf, 2*length);
- }
-
- while(a_wave_can_be_played) {
- // TBD: some event are filtered here but some insight might be given
- // TBD: in synthesise.cpp for avoiding to create WORDs with size=0.
- // TBD: For example sentence "or ALT)." returns three words
- // "or", "ALT" and "".
- // TBD: the last one has its size=0.
- if (event && (event->type == espeakEVENT_WORD) && (event->length==0))
- {
- break;
- }
- espeak_ERROR a_error = event_declare(event);
- if (a_error != EE_BUFFER_FULL)
- {
- break;
- }
- SHOW_TIME("dispatch_audio > EE_BUFFER_FULL\n");
- usleep(10000);
- a_wave_can_be_played = fifo_is_command_enabled();
- }
- }
- break;
-
- case AUDIO_OUTPUT_RETRIEVAL:
- if (synth_callback)
- {
- synth_callback(outbuf, length, event);
- }
- break;
-
- case AUDIO_OUTPUT_SYNCHRONOUS:
- case AUDIO_OUTPUT_SYNCH_PLAYBACK:
- break;
- }
-
- if (!a_wave_can_be_played)
- {
- SHOW_TIME("dispatch_audio > synth must be stopped!\n");
- }
-
- SHOW_TIME("LEAVE dispatch_audio\n");
-
- return (a_wave_can_be_played==0); // 1 = stop synthesis
-}
-
-
-
-static int create_events(short* outbuf, int length, espeak_EVENT* event, uint32_t the_write_pos)
-{//=====================================================================
- int finished;
- int i=0;
-
- // The audio data are written to the output device.
- // The list of events in event_list (index: event_list_ix) is read:
- // Each event is declared to the "event" object which stores them internally.
- // The event object is responsible of calling the external callback
- // as soon as the relevant audio sample is played.
-
- do
- { // for each event
- espeak_EVENT* event;
- if (event_list_ix == 0)
- {
- event = NULL;
- }
- else
- {
- event = event_list + i;
-#ifdef DEBUG_ENABLED
- SHOW("Synthesize: event->sample(%d) + %d = %d\n", event->sample, the_write_pos, event->sample + the_write_pos);
-#endif
- event->sample += the_write_pos;
- }
-#ifdef DEBUG_ENABLED
- SHOW("*** Synthesize: i=%d (event_list_ix=%d), length=%d\n",i,event_list_ix,length);
-#endif
- finished = dispatch_audio((short *)outbuf, length, event);
- length = 0; // the wave data are played once.
- i++;
- } while((i < event_list_ix) && !finished);
- return finished;
-}
-
-
-int sync_espeak_terminated_msg( uint unique_identifier, void* user_data)
-{//=====================================================================
- ENTER("sync_espeak_terminated_msg");
-
- int finished=0;
-
- memset(event_list, 0, 2*sizeof(espeak_EVENT));
-
- event_list[0].type = espeakEVENT_MSG_TERMINATED;
- event_list[0].unique_identifier = unique_identifier;
- event_list[0].user_data = user_data;
- event_list[1].type = espeakEVENT_LIST_TERMINATED;
- event_list[1].unique_identifier = unique_identifier;
- event_list[1].user_data = user_data;
-
- if (my_mode==AUDIO_OUTPUT_PLAYBACK)
- {
- while(1)
- {
- espeak_ERROR a_error = event_declare(event_list);
- if (a_error != EE_BUFFER_FULL)
- {
- break;
- }
- SHOW_TIME("sync_espeak_terminated_msg > EE_BUFFER_FULL\n");
- usleep(10000);
- }
- }
- else
- {
- if (synth_callback)
- {
- finished=synth_callback(NULL,0,event_list);
- }
- }
- return finished;
-}
-
-#endif
-
-
-static void select_output(espeak_AUDIO_OUTPUT output_type)
-{//=======================================================
- my_mode = output_type;
- my_audio = NULL;
- synchronous_mode = 1;
- option_waveout = 1; // inhibit portaudio callback from wavegen.cpp
-
- switch(my_mode)
- {
- case AUDIO_OUTPUT_PLAYBACK:
- synchronous_mode = 0;
-#ifdef USE_ASYNC
- wave_init();
- wave_set_callback_is_output_enabled( fifo_is_command_enabled);
- my_audio = wave_open("alsa");
- event_init();
-#endif
- break;
-
- case AUDIO_OUTPUT_RETRIEVAL:
- synchronous_mode = 0;
- break;
-
- case AUDIO_OUTPUT_SYNCHRONOUS:
- break;
-
- case AUDIO_OUTPUT_SYNCH_PLAYBACK:
- option_waveout = 0;
- WavegenInitSound();
- break;
- }
-} // end of select_output
-
-
-
-
-int GetFileLength(const char *filename)
-{//====================================
- struct stat statbuf;
-
- if(stat(filename,&statbuf) != 0)
- return(0);
-
- if((statbuf.st_mode & S_IFMT) == S_IFDIR)
- // if(S_ISDIR(statbuf.st_mode))
- return(-2); // a directory
-
- return(statbuf.st_size);
-} // end of GetFileLength
-
-
-char *Alloc(int size)
-{//==================
- char *p;
- if((p = (char *)malloc(size)) == NULL)
- fprintf(stderr,"Can't allocate memory\n"); // I was told that size+1 fixes a crash on 64-bit systems
- return(p);
-}
-
-void Free(void *ptr)
-{//=================
- if(ptr != NULL)
- free(ptr);
-}
-
-
-
-static void init_path(const char *path)
-{//====================================
-#ifdef PLATFORM_WINDOWS
- HKEY RegKey;
- unsigned long size;
- unsigned long var_type;
- char *env;
- unsigned char buf[sizeof(path_home)-13];
-
- if(path != NULL)
- {
- sprintf(path_home,"%s/espeak-data",path);
- return;
- }
-
- if((env = getenv("ESPEAK_DATA_PATH")) != NULL)
- {
- sprintf(path_home,"%s/espeak-data",env);
- if(GetFileLength(path_home) == -2)
- return; // an espeak-data directory exists
- }
-
- buf[0] = 0;
- RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Speech\\Voices\\Tokens\\eSpeak", 0, KEY_READ, &RegKey);
- size = sizeof(buf);
- var_type = REG_SZ;
- RegQueryValueExA(RegKey, "path", 0, &var_type, buf, &size);
-
- sprintf(path_home,"%s\\espeak-data",buf);
-
-#else
- char *env;
-
- if(path != NULL)
- {
- snprintf(path_home,sizeof(path_home),"%s/espeak-data",path);
- return;
- }
-
- // check for environment variable
- if((env = getenv("ESPEAK_DATA_PATH")) != NULL)
- {
- snprintf(path_home,sizeof(path_home),"%s/espeak-data",env);
- if(GetFileLength(path_home) == -2)
- return; // an espeak-data directory exists
- }
-
- snprintf(path_home,sizeof(path_home),"%s/espeak-data",getenv("HOME"));
- if(access(path_home,R_OK) != 0)
- {
- strcpy(path_home,PATH_ESPEAK_DATA);
- }
-#endif
-}
-
-static int initialise(void)
-{//========================
- int param;
- int result;
-
- LoadConfig();
- WavegenInit(22050,0); // 22050
- if((result = LoadPhData()) != 1)
- {
- if(result == -1)
- {
- fprintf(stderr,"Failed to load espeak-data\n");
- exit(1);
- }
- else
- fprintf(stderr,"Wrong version of espeak-data 0x%x (expects 0x%x) at %s\n",result,version_phdata,path_home);
- }
-
- memset(&voice_selected,0,sizeof(voice_selected));
- SetVoiceStack(NULL);
- SynthesizeInit();
- InitNamedata();
-
- for(param=0; param<N_SPEECH_PARAM; param++)
- param_stack[0].parameter[param] = param_defaults[param];
-
- return(0);
-}
-
-
-static espeak_ERROR Synthesize(unsigned int unique_identifier, const void *text, int flags)
-{//========================================================================================
- // Fill the buffer with output sound
- int length;
- int finished = 0;
- int count_buffers = 0;
-#ifdef USE_ASYNC
- uint32_t a_write_pos=0;
-#endif
-
-#ifdef DEBUG_ENABLED
- ENTER("Synthesize");
- if (text)
- {
- SHOW("Synthesize > uid=%d, flags=%d, >>>text=%s<<<\n", unique_identifier, flags, text);
- }
-#endif
-
- if((outbuf==NULL) || (event_list==NULL))
- return(EE_INTERNAL_ERROR); // espeak_Initialize() has not been called
-
- option_multibyte = flags & 7;
- option_ssml = flags & espeakSSML;
- option_phoneme_input = flags & espeakPHONEMES;
- option_endpause = flags & espeakENDPAUSE;
-
- count_samples = 0;
-
-#ifdef USE_ASYNC
- if(my_mode == AUDIO_OUTPUT_PLAYBACK)
- {
- a_write_pos = wave_get_write_position(my_audio);
- }
-#endif
-
- if(translator == NULL)
- {
- SetVoiceByName("default");
- }
-
- SpeakNextClause(NULL,text,0);
-
- if(my_mode == AUDIO_OUTPUT_SYNCH_PLAYBACK)
- {
- for(;;)
- {
-#ifdef PLATFORM_WINDOWS
- Sleep(300); // 0.3s
-#else
-#ifdef USE_NANOSLEEP
- struct timespec period;
- struct timespec remaining;
- period.tv_sec = 0;
- period.tv_nsec = 300000000; // 0.3 sec
- nanosleep(&period,&remaining);
-#else
- sleep(1);
-#endif
-#endif
- if(SynthOnTimer() != 0)
- break;
- }
- return(EE_OK);
- }
-
- for(;;)
- {
-#ifdef DEBUG_ENABLED
- SHOW("Synthesize > %s\n","for (next)");
-#endif
- out_ptr = outbuf;
- out_end = &outbuf[outbuf_size];
- event_list_ix = 0;
- WavegenFill(0);
-
- length = (out_ptr - outbuf)/2;
- count_samples += length;
- event_list[event_list_ix].type = espeakEVENT_LIST_TERMINATED; // indicates end of event list
- event_list[event_list_ix].unique_identifier = my_unique_identifier;
- event_list[event_list_ix].user_data = my_user_data;
-
- count_buffers++;
- if (my_mode==AUDIO_OUTPUT_PLAYBACK)
- {
-#ifdef USE_ASYNC
- finished = create_events((short *)outbuf, length, event_list, a_write_pos);
- length = 0; // the wave data are played once.
-#endif
- }
- else
- {
- finished = synth_callback((short *)outbuf, length, event_list);
- }
- if(finished)
- {
- SpeakNextClause(NULL,0,2); // stop
- break;
- }
-
- if(Generate(phoneme_list,&n_phoneme_list,1)==0)
- {
- if(WcmdqUsed() == 0)
- {
- // don't process the next clause until the previous clause has finished generating speech.
- // This ensures that <audio> tag (which causes end-of-clause) is at a sound buffer boundary
-
- event_list[0].type = espeakEVENT_LIST_TERMINATED;
- event_list[0].unique_identifier = my_unique_identifier;
- event_list[0].user_data = my_user_data;
-
- if(SpeakNextClause(NULL,NULL,1)==0)
- {
-#ifdef USE_ASYNC
- if (my_mode==AUDIO_OUTPUT_PLAYBACK)
- {
- dispatch_audio(NULL, 0, NULL); // TBD: test case
- }
- else
- {
- synth_callback(NULL, 0, event_list); // NULL buffer ptr indicates end of data
- }
-#else
- synth_callback(NULL, 0, event_list); // NULL buffer ptr indicates end of data
-#endif
- break;
- }
- }
- }
- }
- return(EE_OK);
-} // end of Synthesize
-
-#ifdef DEBUG_ENABLED
-static const char* label[] = {
- "END_OF_EVENT_LIST",
- "WORD",
- "SENTENCE",
- "MARK",
- "PLAY",
- "END"};
-#endif
-
-
-void MarkerEvent(int type, unsigned int char_position, int value, unsigned char *out_ptr)
-{//======================================================================================
- // type: 1=word, 2=sentence, 3=named mark, 4=play audio, 5=end
- ENTER("MarkerEvent");
- espeak_EVENT *ep;
- double time;
-
- if((event_list == NULL) || (event_list_ix >= (n_event_list-2)))
- return;
-
- ep = &event_list[event_list_ix++];
- ep->type = (espeak_EVENT_TYPE)type;
- ep->unique_identifier = my_unique_identifier;
- ep->user_data = my_user_data;
- ep->text_position = char_position & 0xffffff;
- ep->length = char_position >> 24;
-
- time = ((double)(count_samples + mbrola_delay + (out_ptr - out_start)/2)*1000.0)/samplerate;
- ep->audio_position = (int)(time);
- ep->sample = (count_samples + mbrola_delay + (out_ptr - out_start)/2);
-
-#ifdef DEBUG_ENABLED
- SHOW("MarkerEvent > count_samples=%d, out_ptr=%x, out_start=0x%x\n",count_samples, out_ptr, out_start);
- SHOW("*** MarkerEvent > type=%s, uid=%d, text_pos=%d, length=%d, audio_position=%d, sample=%d\n",
- label[ep->type], ep->unique_identifier, ep->text_position, ep->length,
- ep->audio_position, ep->sample);
-#endif
-
- if((type == espeakEVENT_MARK) || (type == espeakEVENT_PLAY))
- ep->id.name = &namedata[value];
- else
- ep->id.number = value;
-} // end of MarkerEvent
-
-
-
-
-espeak_ERROR sync_espeak_Synth(unsigned int unique_identifier, const void *text, size_t size,
- unsigned int position, espeak_POSITION_TYPE position_type,
- unsigned int end_position, unsigned int flags, void* user_data)
-{//===========================================================================
-
-#ifdef DEBUG_ENABLED
- ENTER("sync_espeak_Synth");
- 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);
-#endif
-
- espeak_ERROR aStatus;
-
- InitText(flags);
- my_unique_identifier = unique_identifier;
- my_user_data = user_data;
-
- switch(position_type)
- {
- case POS_CHARACTER:
- skip_characters = position;
- break;
-
- case POS_WORD:
- skip_words = position;
- break;
-
- case POS_SENTENCE:
- skip_sentences = position;
- break;
-
- }
- if(skip_characters || skip_words || skip_sentences)
- skipping_text = 1;
-
- end_character_position = end_position;
-
- aStatus = Synthesize(unique_identifier, text, flags);
- #ifdef USE_ASYNC
- wave_flush(my_audio);
- #endif
-
- SHOW_TIME("LEAVE sync_espeak_Synth");
- return aStatus;
-} // end of sync_espeak_Synth
-
-
-
-
-espeak_ERROR sync_espeak_Synth_Mark(unsigned int unique_identifier, const void *text, size_t size,
- const char *index_mark, unsigned int end_position,
- unsigned int flags, void* user_data)
-{//=========================================================================
- espeak_ERROR aStatus;
-
- InitText(flags);
-
- my_unique_identifier = unique_identifier;
- my_user_data = user_data;
-
- if(index_mark != NULL)
- {
- strncpy0(skip_marker, index_mark, sizeof(skip_marker));
- skipping_text = 1;
- }
-
- end_character_position = end_position;
-
-
- aStatus = Synthesize(unique_identifier, text, flags | espeakSSML);
- SHOW_TIME("LEAVE sync_espeak_Synth_Mark");
-
- return (aStatus);
-} // end of sync_espeak_Synth_Mark
-
-
-
-void sync_espeak_Key(const char *key)
-{//==================================
- // symbolic name, symbolicname_character - is there a system resource of symbolic names per language?
- int letter;
- int ix;
-
- ix = utf8_in(&letter,key);
- if(key[ix] == 0)
- {
- // a single character
- sync_espeak_Char(letter);
- return;
- }
-
- my_unique_identifier = 0;
- my_user_data = NULL;
- Synthesize(0, key,0); // speak key as a text string
-}
-
-
-void sync_espeak_Char(wchar_t character)
-{//=====================================
- // is there a system resource of character names per language?
- char buf[80];
- my_unique_identifier = 0;
- my_user_data = NULL;
-
- sprintf(buf,"<say-as interpret-as=\"tts:char\">&#%d;</say-as>",character);
- Synthesize(0, buf,espeakSSML);
-}
-
-
-
-void sync_espeak_SetPunctuationList(const wchar_t *punctlist)
-{//==========================================================
- // Set the list of punctuation which are spoken for "some".
- my_unique_identifier = 0;
- my_user_data = NULL;
-
- wcsncpy(option_punctlist, punctlist, N_PUNCTLIST);
- option_punctlist[N_PUNCTLIST-1] = 0;
-} // end of sync_espeak_SetPunctuationList
-
-
-
-
-#pragma GCC visibility push(default)
-
-
-ESPEAK_API void espeak_SetSynthCallback(t_espeak_callback* SynthCallback)
-{//======================================================================
- ENTER("espeak_SetSynthCallback");
- synth_callback = SynthCallback;
-#ifdef USE_ASYNC
- event_set_callback(synth_callback);
-#endif
-}
-
-ESPEAK_API void espeak_SetUriCallback(int (* UriCallback)(int, const char*, const char *))
-{//=======================================================================================
- ENTER("espeak_SetUriCallback");
- uri_callback = UriCallback;
-}
-
-
-ESPEAK_API void espeak_SetPhonemeCallback(int (* PhonemeCallback)(const char*))
-{//===========================================================================
- phoneme_callback = PhonemeCallback;
-}
-
-ESPEAK_API int espeak_Initialize(espeak_AUDIO_OUTPUT output_type, int buf_length, const char *path, int options)
-{//=============================================================================================================
-ENTER("espeak_Initialize");
- int param;
-
- // It seems that the wctype functions don't work until the locale has been set
- // to something other than the default "C". Then, not only Latin1 but also the
- // other characters give the correct results with iswalpha() etc.
-#ifdef PLATFORM_RISCOS
- setlocale(LC_CTYPE,"ISO8859-1");
-#else
- if(setlocale(LC_CTYPE,"en_US.UTF-8") == NULL)
- {
- if(setlocale(LC_CTYPE,"UTF-8") == NULL)
- setlocale(LC_CTYPE,"");
- }
-#endif
-
- init_path(path);
- initialise();
- select_output(output_type);
-
- // buflength is in mS, allocate 2 bytes per sample
- if(buf_length == 0)
- buf_length = 200;
- outbuf_size = (buf_length * samplerate)/500;
- outbuf = (unsigned char*)realloc(outbuf,outbuf_size);
- if((out_start = outbuf) == NULL)
- return(EE_INTERNAL_ERROR);
-
- // allocate space for event list. Allow 200 events per second.
- // Add a constant to allow for very small buf_length
- n_event_list = (buf_length*200)/1000 + 20;
- if((event_list = (espeak_EVENT *)realloc(event_list,sizeof(espeak_EVENT) * n_event_list)) == NULL)
- return(EE_INTERNAL_ERROR);
-
- option_phonemes = 0;
- option_phoneme_events = (options & 1);
-
- SetVoiceByName("default");
-
- for(param=0; param<N_SPEECH_PARAM; param++)
- param_stack[0].parameter[param] = param_defaults[param];
-
- SetParameter(espeakRATE,170,0);
- SetParameter(espeakVOLUME,100,0);
- SetParameter(espeakCAPITALS,option_capitals,0);
- SetParameter(espeakPUNCTUATION,option_punctuation,0);
- SetParameter(espeakWORDGAP,0,0);
- DoVoiceChange(voice);
-
-#ifdef USE_ASYNC
- fifo_init();
-#endif
-
- return(samplerate);
-}
-
-
-
-ESPEAK_API espeak_ERROR espeak_Synth(const void *text, size_t size,
- unsigned int position,
- espeak_POSITION_TYPE position_type,
- unsigned int end_position, unsigned int flags,
- unsigned int* unique_identifier, void* user_data)
-{//=====================================================================================
-#ifdef DEBUG_ENABLED
- ENTER("espeak_Synth");
- 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);
-#endif
-
- espeak_ERROR a_error=EE_INTERNAL_ERROR;
- static unsigned int temp_identifier;
-
- if (unique_identifier == NULL)
- {
- unique_identifier = &temp_identifier;
- }
- *unique_identifier = 0;
-
- if(synchronous_mode)
- {
- return(sync_espeak_Synth(0,text,size,position,position_type,end_position,flags,user_data));
- }
-
-#ifdef USE_ASYNC
- // Create the text command
- t_espeak_command* c1 = create_espeak_text(text, size, position, position_type, end_position, flags, user_data);
-
- // Retrieve the unique identifier
- *unique_identifier = c1->u.my_text.unique_identifier;
-
- // Create the "terminated msg" command (same uid)
- t_espeak_command* c2 = create_espeak_terminated_msg(*unique_identifier, user_data);
-
- // Try to add these 2 commands (single transaction)
- if (c1 && c2)
- {
- a_error = fifo_add_commands(c1, c2);
- if (a_error != EE_OK)
- {
- delete_espeak_command(c1);
- delete_espeak_command(c2);
- c1=c2=NULL;
- }
- }
- else
- {
- delete_espeak_command(c1);
- delete_espeak_command(c2);
- }
-
-#endif
- return a_error;
-} // end of espeak_Synth
-
-
-
-ESPEAK_API espeak_ERROR espeak_Synth_Mark(const void *text, size_t size,
- const char *index_mark,
- unsigned int end_position,
- unsigned int flags,
- unsigned int* unique_identifier,
- void* user_data)
-{//=========================================================================
-#ifdef DEBUG_ENABLED
- ENTER("espeak_Synth_Mark");
- SHOW("espeak_Synth_Mark > index_mark=%s, end_position=%d, flags=%d, text=%s\n", index_mark, end_position, flags, text);
-#endif
-
- espeak_ERROR a_error=EE_OK;
- static unsigned int temp_identifier;
-
- if (unique_identifier == NULL)
- {
- unique_identifier = &temp_identifier;
- }
- *unique_identifier = 0;
-
- if(synchronous_mode)
- {
- return(sync_espeak_Synth_Mark(0,text,size,index_mark,end_position,flags,user_data));
- }
-
-#ifdef USE_ASYNC
- // Create the mark command
- t_espeak_command* c1 = create_espeak_mark(text, size, index_mark, end_position,
- flags, user_data);
-
- // Retrieve the unique identifier
- *unique_identifier = c1->u.my_mark.unique_identifier;
-
- // Create the "terminated msg" command (same uid)
- t_espeak_command* c2 = create_espeak_terminated_msg(*unique_identifier, user_data);
-
- // Try to add these 2 commands (single transaction)
- if (c1 && c2)
- {
- a_error = fifo_add_commands(c1, c2);
- if (a_error != EE_OK)
- {
- delete_espeak_command(c1);
- delete_espeak_command(c2);
- c1=c2=NULL;
- }
- }
- else
- {
- delete_espeak_command(c1);
- delete_espeak_command(c2);
- }
-
-#endif
- return a_error;
-} // end of espeak_Synth_Mark
-
-
-
-ESPEAK_API espeak_ERROR espeak_Key(const char *key)
-{//================================================
- ENTER("espeak_Key");
- // symbolic name, symbolicname_character - is there a system resource of symbolicnames per language
-
- espeak_ERROR a_error = EE_OK;
-
- if(synchronous_mode)
- {
- sync_espeak_Key(key);
- return(EE_OK);
- }
-
-#ifdef USE_ASYNC
- t_espeak_command* c = create_espeak_key( key, NULL);
- a_error = fifo_add_command(c);
- if (a_error != EE_OK)
- {
- delete_espeak_command(c);
- }
-
-#endif
- return a_error;
-}
-
-
-ESPEAK_API espeak_ERROR espeak_Char(wchar_t character)
-{//===========================================
- ENTER("espeak_Char");
- // is there a system resource of character names per language?
-
-#ifdef USE_ASYNC
- espeak_ERROR a_error;
-
- if(synchronous_mode)
- {
- sync_espeak_Char(character);
- return(EE_OK);
- }
-
- t_espeak_command* c = create_espeak_char( character, NULL);
- a_error = fifo_add_command(c);
- if (a_error != EE_OK)
- {
- delete_espeak_command(c);
- }
- return a_error;
-#else
- sync_espeak_Char(character);
- return(EE_OK);
-#endif
-}
-
-
-ESPEAK_API espeak_ERROR espeak_SetVoiceByName(const char *name)
-{//============================================================
- ENTER("espeak_SetVoiceByName");
-
-//#ifdef USE_ASYNC
-// I don't think there's a need to queue change voice requests
-#ifdef deleted
- espeak_ERROR a_error;
-
- if(synchronous_mode)
- {
- return(SetVoiceByName(name));
- }
-
- t_espeak_command* c = create_espeak_voice_name(name);
- a_error = fifo_add_command(c);
- if (a_error != EE_OK)
- {
- delete_espeak_command(c);
- }
- return a_error;
-#else
- return(SetVoiceByName(name));
-#endif
-} // end of espeak_SetVoiceByName
-
-
-
-ESPEAK_API espeak_ERROR espeak_SetVoiceByProperties(espeak_VOICE *voice_selector)
-{//==============================================================================
- ENTER("espeak_SetVoiceByProperties");
-
-//#ifdef USE_ASYNC
-#ifdef deleted
- espeak_ERROR a_error;
-
- if(synchronous_mode)
- {
- return(SetVoiceByProperties(voice_selector));
- }
-
- t_espeak_command* c = create_espeak_voice_spec( voice_selector);
- a_error = fifo_add_command(c);
- if (a_error != EE_OK)
- {
- delete_espeak_command(c);
- }
- return a_error;
-#else
- return(SetVoiceByProperties(voice_selector));
-#endif
-} // end of espeak_SetVoiceByProperties
-
-
-ESPEAK_API int espeak_GetParameter(espeak_PARAMETER parameter, int current)
-{//========================================================================
- ENTER("espeak_GetParameter");
- // current: 0=default value, 1=current value
- if(current)
- {
- return(param_stack[0].parameter[parameter]);
- }
- else
- {
- return(param_defaults[parameter]);
- }
-} // end of espeak_GetParameter
-
-
-ESPEAK_API espeak_ERROR espeak_SetParameter(espeak_PARAMETER parameter, int value, int relative)
-{//=============================================================================================
- ENTER("espeak_SetParameter");
-
-#ifdef USE_ASYNC
- espeak_ERROR a_error;
-
- if(synchronous_mode)
- {
- SetParameter(parameter,value,relative);
- return(EE_OK);
- }
-
- t_espeak_command* c = create_espeak_parameter(parameter, value, relative);
-
- a_error = fifo_add_command(c);
- if (a_error != EE_OK)
- {
- delete_espeak_command(c);
- }
- return a_error;
-#else
- SetParameter(parameter,value,relative);
- return(EE_OK);
-#endif
-}
-
-
-ESPEAK_API espeak_ERROR espeak_SetPunctuationList(const wchar_t *punctlist)
-{//================================================================
- ENTER("espeak_SetPunctuationList");
- // Set the list of punctuation which are spoken for "some".
-
-#ifdef USE_ASYNC
- espeak_ERROR a_error;
-
- if(synchronous_mode)
- {
- sync_espeak_SetPunctuationList(punctlist);
- return(EE_OK);
- }
-
- t_espeak_command* c = create_espeak_punctuation_list( punctlist);
- a_error = fifo_add_command(c);
- if (a_error != EE_OK)
- {
- delete_espeak_command(c);
- }
- return a_error;
-#else
- sync_espeak_SetPunctuationList(punctlist);
- return(EE_OK);
-#endif
-} // end of espeak_SetPunctuationList
-
-
-ESPEAK_API void espeak_SetPhonemeTrace(int value, FILE *stream)
-{//============================================================
- ENTER("espeak_SetPhonemes");
- /* Controls the output of phoneme symbols for the text
- value=0 No phoneme output (default)
- value=1 Output the translated phoneme symbols for the text
- value=2 as (1), but also output a trace of how the translation was done (matching rules and list entries)
- */
- option_phonemes = value;
- f_trans = stream;
- if(stream == NULL)
- f_trans = stderr;
-
-} // end of espeak_SetPhonemes
-
-
-ESPEAK_API void espeak_CompileDictionary(const char *path, FILE *log, int flags)
-{//=============================================================================
- ENTER("espeak_CompileDictionary");
- CompileDictionary(path, dictionary_name, log, NULL, flags);
-} // end of espeak_CompileDirectory
-
-
-ESPEAK_API espeak_ERROR espeak_Cancel(void)
-{//===============================
-#ifdef USE_ASYNC
- ENTER("espeak_Cancel");
- fifo_stop();
- event_clear_all();
-
- if(my_mode == AUDIO_OUTPUT_PLAYBACK)
- {
- wave_close(my_audio);
- }
- SHOW_TIME("espeak_Cancel > LEAVE");
-#endif
- embedded_value[EMBED_T] = 0; // reset echo for pronunciation announcements
- return EE_OK;
-} // end of espeak_Cancel
-
-
-ESPEAK_API int espeak_IsPlaying(void)
-{//==================================
-// ENTER("espeak_IsPlaying");
-#ifdef USE_ASYNC
- if((my_mode == AUDIO_OUTPUT_PLAYBACK) && wave_is_busy(my_audio))
- return(1);
-
- return(fifo_is_busy());
-#else
- return(0);
-#endif
-} // end of espeak_IsPlaying
-
-
-ESPEAK_API espeak_ERROR espeak_Synchronize(void)
-{//=============================================
-#ifdef USE_ASYNC
- SHOW_TIME("espeak_Synchronize > ENTER");
- while (espeak_IsPlaying())
- {
- usleep(20000);
- }
-#endif
- SHOW_TIME("espeak_Synchronize > LEAVE");
- return EE_OK;
-} // end of espeak_Synchronize
-
-
-extern void FreePhData(void);
-
-ESPEAK_API espeak_ERROR espeak_Terminate(void)
-{//===========================================
- ENTER("espeak_Terminate");
-#ifdef USE_ASYNC
- fifo_stop();
- fifo_terminate();
- event_terminate();
-
- if(my_mode == AUDIO_OUTPUT_PLAYBACK)
- {
- wave_close(my_audio);
- wave_terminate();
- }
-
-#endif
- Free(event_list);
- event_list = NULL;
- Free(outbuf);
- outbuf = NULL;
- FreePhData();
-
- return EE_OK;
-} // end of espeak_Terminate
-
-ESPEAK_API const char *espeak_Info(void)
-{//=======================================
- return(version_string);
-}
-
-#pragma GCC visibility pop
-
-
diff --git a/navit/support/espeak/speak_lib.h b/navit/support/espeak/speak_lib.h
deleted file mode 100644
index 25c24c173..000000000
--- a/navit/support/espeak/speak_lib.h
+++ /dev/null
@@ -1,601 +0,0 @@
-#ifndef SPEAK_LIB_H
-#define SPEAK_LIB_H
-/***************************************************************************
- * Copyright (C) 2005 to 2007 by Jonathan Duddington *
- * email: jonsd@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, see: *
- * <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-
-/*************************************************************/
-/* This is the header file for the library version of espeak */
-/* */
-/*************************************************************/
-
-#include <stdio.h>
-#include <wchar.h>
-#define ESPEAK_API_REVISION 5
-/*
-Revision 2
- Added parameter "options" to eSpeakInitialize()
-
-Revision 3
- Added espeakWORDGAP to espeak_PARAMETER
-
-Revision 4
- Added flags parameter to espeak_CompileDictionary()
-
-Revision 5
- Added espeakCHARS_16BIT
-*/
- /********************/
- /* Initialization */
- /********************/
-
-
-typedef enum {
- espeakEVENT_LIST_TERMINATED = 0, // Retrieval mode: terminates the event list.
- espeakEVENT_WORD = 1, // Start of word
- espeakEVENT_SENTENCE, // Start of sentence
- espeakEVENT_MARK, // Mark
- espeakEVENT_PLAY, // Audio element
- espeakEVENT_END, // End of sentence or clause
- espeakEVENT_MSG_TERMINATED, // End of message
- espeakEVENT_PHONEME // Phoneme, if enabled in espeak_Initialize()
-} espeak_EVENT_TYPE;
-
-
-
-typedef struct {
- espeak_EVENT_TYPE type;
- unsigned int unique_identifier; // message identifier (or 0 for key or character)
- int text_position; // the number of characters from the start of the text
- int length; // word length, in characters (for espeakEVENT_WORD)
- int audio_position; // the time in mS within the generated speech output data
- int sample; // sample id (internal use)
- void* user_data; // pointer supplied by the calling program
- union {
- int number; // used for WORD and SENTENCE events. For PHONEME events this is the phoneme mnemonic.
- const char *name; // used for MARK and PLAY events. UTF8 string
- } id;
-} espeak_EVENT;
-/*
- When a message is supplied to espeak_synth, the request is buffered and espeak_synth returns. When the message is really processed, the callback function will be repetedly called.
-
-
- In RETRIEVAL mode, the callback function supplies to the calling program the audio data and an event list terminated by 0 (LIST_TERMINATED).
-
- In PLAYBACK mode, the callback function is called as soon as an event happens.
-
- For example suppose that the following message is supplied to espeak_Synth:
- "hello, hello."
-
-
- * Once processed in RETRIEVAL mode, it could lead to 3 calls of the callback function :
-
- ** Block 1:
- <audio data> +
- List of events: SENTENCE + WORD + LIST_TERMINATED
-
- ** Block 2:
- <audio data> +
- List of events: WORD + END + LIST_TERMINATED
-
- ** Block 3:
- no audio data
- List of events: MSG_TERMINATED + LIST_TERMINATED
-
-
- * Once processed in PLAYBACK mode, it could lead to 5 calls of the callback function:
-
- ** SENTENCE
- ** WORD (call when the sounds are actually played)
- ** WORD
- ** END (call when the end of sentence is actually played.)
- ** MSG_TERMINATED
-
-
- The MSG_TERMINATED event is the last event. It can inform the calling program to clear the user data related to the message.
- So if the synthesis must be stopped, the callback function is called for each pending message with the MSG_TERMINATED event.
-
- A MARK event indicates a <mark> element in the text.
- A PLAY event indicates an <audio> element in the text, for which the calling program should play the named sound file.
-*/
-
-
-
-typedef enum {
- POS_CHARACTER = 1,
- POS_WORD,
- POS_SENTENCE
-} espeak_POSITION_TYPE;
-
-
-typedef enum {
- /* PLAYBACK mode: plays the audio data, supplies events to the calling program*/
- AUDIO_OUTPUT_PLAYBACK,
-
- /* RETRIEVAL mode: supplies audio data and events to the calling program */
- AUDIO_OUTPUT_RETRIEVAL,
-
- /* SYNCHRONOUS mode: as RETRIEVAL but doesn't return until synthesis is completed */
- AUDIO_OUTPUT_SYNCHRONOUS,
-
- /* Synchronous playback */
- AUDIO_OUTPUT_SYNCH_PLAYBACK
-
-} espeak_AUDIO_OUTPUT;
-
-
-typedef enum {
- EE_OK=0,
- EE_INTERNAL_ERROR=-1,
- EE_BUFFER_FULL=1,
- EE_NOT_FOUND=2
-} espeak_ERROR;
-
-
-#ifdef __cplusplus
-extern "C"
-#endif
-int espeak_Initialize(espeak_AUDIO_OUTPUT output, int buflength, const char *path, int options);
-/* Must be called before any synthesis functions are called.
- output: the audio data can either be played by eSpeak or passed back by the SynthCallback function.
-
- buflength: The length in mS of sound buffers passed to the SynthCallback function.
-
- path: The directory which contains the espeak-data directory, or NULL for the default location.
-
- options: bit 0: 1=allow espeakEVENT_PHONEME events.
-
-
- Returns: sample rate in Hz, or -1 (EE_INTERNAL_ERROR).
-*/
-
-typedef int (t_espeak_callback)(short*, int, espeak_EVENT*);
-
-#ifdef __cplusplus
-extern "C"
-#endif
-void espeak_SetSynthCallback(t_espeak_callback* SynthCallback);
-/* Must be called before any synthesis functions are called.
- This specifies a function in the calling program which is called when a buffer of
- speech sound data has been produced.
-
-
- The callback function is of the form:
-
-int SynthCallback(short *wav, int numsamples, espeak_EVENT *events);
-
- wav: is the speech sound data which has been produced.
- NULL indicates that the synthesis has been completed.
-
- numsamples: is the number of entries in wav. This number may vary, may be less than
- the value implied by the buflength parameter given in espeak_Initialize, and may
- sometimes be zero (which does NOT indicate end of synthesis).
-
- events: an array of espeak_EVENT items which indicate word and sentence events, and
- also the occurance if <mark> and <audio> elements within the text. The list of
- events is terminated by an event of type = 0.
-
-
- Callback returns: 0=continue synthesis, 1=abort synthesis.
-*/
-
-#ifdef __cplusplus
-extern "C"
-#endif
-void espeak_SetUriCallback(int (*UriCallback)(int, const char*, const char*));
-/* This function may be called before synthesis functions are used, in order to deal with
- <audio> tags. It specifies a callback function which is called when an <audio> element is
- encountered and allows the calling program to indicate whether the sound file which
- is specified in the <audio> element is available and is to be played.
-
- The callback function is of the form:
-
-int UriCallback(int type, const char *uri, const char *base);
-
- type: type of callback event. Currently only 1= <audio> element
-
- uri: the "src" attribute from the <audio> element
-
- base: the "xml:base" attribute (if any) from the <speak> element
-
- Return: 1=don't play the sound, but speak the text alternative.
- 0=place a PLAY event in the event list at the point where the <audio> element
- occurs. The calling program can then play the sound at that point.
-*/
-
-
- /********************/
- /* Synthesis */
- /********************/
-
-
-#define espeakCHARS_AUTO 0
-#define espeakCHARS_UTF8 1
-#define espeakCHARS_8BIT 2
-#define espeakCHARS_WCHAR 3
-#define espeakCHARS_16BIT 4
-
-#define espeakSSML 0x10
-#define espeakPHONEMES 0x100
-#define espeakENDPAUSE 0x1000
-#define espeakKEEP_NAMEDATA 0x2000
-
-#ifdef __cplusplus
-extern "C"
-#endif
-espeak_ERROR espeak_Synth(const void *text,
- size_t size,
- unsigned int position,
- espeak_POSITION_TYPE position_type,
- unsigned int end_position,
- unsigned int flags,
- unsigned int* unique_identifier,
- void* user_data);
-/* Synthesize speech for the specified text. The speech sound data is passed to the calling
- program in buffers by means of the callback function specified by espeak_SetSynthCallback(). The command is asynchronous: it is internally buffered and returns as soon as possible. If espeak_Initialize was previously called with AUDIO_OUTPUT_PLAYBACK as argument, the sound data are played by eSpeak.
-
- text: The text to be spoken, terminated by a zero character. It may be either 8-bit characters,
- wide characters (wchar_t), or UTF8 encoding. Which of these is determined by the "flags"
- parameter.
-
- size: Equal to (or greatrer than) the size of the text data, in bytes. This is used in order
- to allocate internal storage space for the text. This value is not used for
- AUDIO_OUTPUT_SYNCHRONOUS mode.
-
- position: The position in the text where speaking starts. Zero indicates speak from the
- start of the text.
-
- position_type: Determines whether "position" is a number of characters, words, or sentences.
- Values:
-
- end_position: If set, this gives a character position at which speaking will stop. A value
- of zero indicates no end position.
-
- flags: These may be OR'd together:
- Type of character codes, one of:
- espeakCHARS_UTF8 UTF8 encoding
- espeakCHARS_8BIT The 8 bit ISO-8859 character set for the particular language.
- espeakCHARS_AUTO 8 bit or UTF8 (this is the default)
- espeakCHARS_WCHAR Wide characters (wchar_t)
-
- espeakSSML Elements within < > are treated as SSML elements, or if not recognised are ignored.
-
- espeakPHONEMES Text within [[ ]] is treated as phonemes codes (in espeak's Hirshenbaum encoding).
-
- espeakENDPAUSE If set then a sentence pause is added at the end of the text. If not set then
- this pause is suppressed.
-
- unique_identifier: message identifier; helpful for identifying later
- data supplied to the callback.
-
- user_data: pointer which will be passed to the callback function.
-
- Return: EE_OK: operation achieved
- EE_BUFFER_FULL: the command can not be buffered;
- you may try after a while to call the function again.
- EE_INTERNAL_ERROR.
-*/
-
-#ifdef __cplusplus
-extern "C"
-#endif
-espeak_ERROR espeak_Synth_Mark(const void *text,
- size_t size,
- const char *index_mark,
- unsigned int end_position,
- unsigned int flags,
- unsigned int* unique_identifier,
- void* user_data);
-/* Synthesize speech for the specified text. Similar to espeak_Synth() but the start position is
- specified by the name of a <mark> element in the text.
-
- index_mark: The "name" attribute of a <mark> element within the text which specified the
- point at which synthesis starts. UTF8 string.
-
- For the other parameters, see espeak_Synth()
-
- Return: EE_OK: operation achieved
- EE_BUFFER_FULL: the command can not be buffered;
- you may try after a while to call the function again.
- EE_INTERNAL_ERROR.
-*/
-
-#ifdef __cplusplus
-extern "C"
-#endif
-espeak_ERROR espeak_Key(const char *key_name);
-/* Speak the name of a keyboard key.
- If key_name is a single character, it speaks the name of the character.
- Otherwise, it speaks key_name as a text string.
-
- Return: EE_OK: operation achieved
- EE_BUFFER_FULL: the command can not be buffered;
- you may try after a while to call the function again.
- EE_INTERNAL_ERROR.
-*/
-
-#ifdef __cplusplus
-extern "C"
-#endif
-espeak_ERROR espeak_Char(wchar_t character);
-/* Speak the name of the given character
-
- Return: EE_OK: operation achieved
- EE_BUFFER_FULL: the command can not be buffered;
- you may try after a while to call the function again.
- EE_INTERNAL_ERROR.
-*/
-
-
-
-
- /***********************/
- /* Speech Parameters */
- /***********************/
-
-typedef enum {
- espeakSILENCE=0, /* internal use */
- espeakRATE=1,
- espeakVOLUME=2,
- espeakPITCH=3,
- espeakRANGE=4,
- espeakPUNCTUATION=5,
- espeakCAPITALS=6,
- espeakWORDGAP=7,
- espeakOPTIONS=8, // reserved for misc. options. not yet used
- espeakINTONATION=9,
-
- espeakRESERVED1=10,
- espeakRESERVED2=11,
- espeakEMPHASIS, /* internal use */
- espeakLINELENGTH, /* internal use */
- espeakVOICETYPE, // internal, 1=mbrola
- N_SPEECH_PARAM /* last enum */
-} espeak_PARAMETER;
-
-typedef enum {
- espeakPUNCT_NONE=0,
- espeakPUNCT_ALL=1,
- espeakPUNCT_SOME=2
-} espeak_PUNCT_TYPE;
-
-#ifdef __cplusplus
-extern "C"
-#endif
-espeak_ERROR espeak_SetParameter(espeak_PARAMETER parameter, int value, int relative);
-/* Sets the value of the specified parameter.
- relative=0 Sets the absolute value of the parameter.
- relative=1 Sets a relative value of the parameter.
-
- parameter:
- espeakRATE: speaking speed in word per minute.
-
- espeakVOLUME: volume in range 0-100 0=silence
-
- espeakPITCH: base pitch, range 0-100. 50=normal
-
- espeakRANGE: pitch range, range 0-100. 0-monotone, 50=normal
-
- espeakPUNCTUATION: which punctuation characters to announce:
- value in espeak_PUNCT_TYPE (none, all, some),
- see espeak_GetParameter() to specify which characters are announced.
-
- espeakCAPITALS: announce capital letters by:
- 0=none,
- 1=sound icon,
- 2=spelling,
- 3 or higher, by raising pitch. This values gives the amount in Hz by which the pitch
- of a word raised to indicate it has a capital letter.
-
- espeakWORDGAP: pause between words, units of 10mS (at the default speed)
-
- Return: EE_OK: operation achieved
- EE_BUFFER_FULL: the command can not be buffered;
- you may try after a while to call the function again.
- EE_INTERNAL_ERROR.
-*/
-
-#ifdef __cplusplus
-extern "C"
-#endif
-int espeak_GetParameter(espeak_PARAMETER parameter, int current);
-/* current=0 Returns the default value of the specified parameter.
- current=1 Returns the current value of the specified parameter, as set by SetParameter()
-*/
-
-#ifdef __cplusplus
-extern "C"
-#endif
-espeak_ERROR espeak_SetPunctuationList(const wchar_t *punctlist);
-/* Specified a list of punctuation characters whose names are to be spoken when the
- value of the Punctuation parameter is set to "some".
-
- punctlist: A list of character codes, terminated by a zero character.
-
- Return: EE_OK: operation achieved
- EE_BUFFER_FULL: the command can not be buffered;
- you may try after a while to call the function again.
- EE_INTERNAL_ERROR.
-*/
-
-#ifdef __cplusplus
-extern "C"
-#endif
-void espeak_SetPhonemeTrace(int value, FILE *stream);
-/* Controls the output of phoneme symbols for the text
- value=0 No phoneme output (default)
- value=1 Output the translated phoneme symbols for the text
- value=2 as (1), but also output a trace of how the translation was done (matching rules and list entries)
-
- stream output stream for the phoneme symbols (and trace). If stream=NULL then it uses stdout.
-*/
-
-#ifdef __cplusplus
-extern "C"
-#endif
-void espeak_CompileDictionary(const char *path, FILE *log, int flags);
-/* Compile pronunciation dictionary for a language which corresponds to the currently
- selected voice. The required voice should be selected before calling this function.
-
- path: The directory which contains the language's '_rules' and '_list' files.
- 'path' should end with a path separator character ('/').
- log: Stream for error reports and statistics information. If log=NULL then stderr will be used.
-
- flags: Bit 0: include source line information for debug purposes (This is displayed with the
- -X command line option).
-*/
- /***********************/
- /* Voice Selection */
- /***********************/
-
-
-// voice table
-typedef struct {
- const char *name; // a given name for this voice. UTF8 string.
- const char *languages; // list of pairs of (byte) priority + (string) language (and dialect qualifier)
- const char *identifier; // the filename for this voice within espeak-data/voices
- unsigned char gender; // 0=none 1=male, 2=female,
- unsigned char age; // 0=not specified, or age in years
- unsigned char variant; // only used when passed as a parameter to espeak_SetVoiceByProperties
- unsigned char xx1; // for internal use
- int score; // for internal use
- void *spare; // for internal use
-} espeak_VOICE;
-
-/* Note: The espeak_VOICE structure is used for two purposes:
- 1. To return the details of the available voices.
- 2. As a parameter to espeak_SetVoiceByProperties() in order to specify selection criteria.
-
- In (1), the "languages" field consists of a list of (UTF8) language names for which this voice
- may be used, each language name in the list is terminated by a zero byte and is also preceded by
- a single byte which gives a "priority" number. The list of languages is terminated by an
- additional zero byte.
-
- A language name consists of a language code, optionally followed by one or more qualifier (dialect)
- names separated by hyphens (eg. "en-uk"). A voice might, for example, have languages "en-uk" and
- "en". Even without "en" listed, voice would still be selected for the "en" language (because
- "en-uk" is related) but at a lower priority.
-
- The priority byte indicates how the voice is preferred for the language. A low number indicates a
- more preferred voice, a higher number indicates a less preferred voice.
-
- In (2), the "languages" field consists simply of a single (UTF8) language name, with no preceding
- priority byte.
-*/
-
-#ifdef __cplusplus
-extern "C"
-#endif
-const espeak_VOICE **espeak_ListVoices(espeak_VOICE *voice_spec);
-/* Reads the voice files from espeak-data/voices and creates an array of espeak_VOICE pointers.
- The list is terminated by a NULL pointer
-
- If voice_spec is NULL then all voices are listed.
- If voice spec is give, then only the voices which are compatible with the voice_spec
- are listed, and they are listed in preference order.
-*/
-
-#ifdef __cplusplus
-extern "C"
-#endif
-espeak_ERROR espeak_SetVoiceByName(const char *name);
-/* Searches for a voice with a matching "name" field. Language is not considered.
- "name" is a UTF8 string.
-
- Return: EE_OK: operation achieved
- EE_BUFFER_FULL: the command can not be buffered;
- you may try after a while to call the function again.
- EE_INTERNAL_ERROR.
-*/
-
-#ifdef __cplusplus
-extern "C"
-#endif
-espeak_ERROR espeak_SetVoiceByProperties(espeak_VOICE *voice_spec);
-/* An espeak_VOICE structure is used to pass criteria to select a voice. Any of the following
- fields may be set:
-
- name NULL, or a voice name
-
- languages NULL, or a single language string (with optional dialect), eg. "en-uk", or "en"
-
- gender 0=not specified, 1=male, 2=female
-
- age 0=not specified, or an age in years
-
- variant After a list of candidates is produced, scored and sorted, "variant" is used to index
- that list and choose a voice.
- variant=0 takes the top voice (i.e. best match). variant=1 takes the next voice, etc
-*/
-
-#ifdef __cplusplus
-extern "C"
-#endif
-espeak_VOICE *espeak_GetCurrentVoice(void);
-/* Returns the espeak_VOICE data for the currently selected voice.
- This is not affected by temporary voice changes caused by SSML elements such as <voice> and <s>
-*/
-
-#ifdef __cplusplus
-extern "C"
-#endif
-espeak_ERROR espeak_Cancel(void);
-/* Stop immediately synthesis and audio output of the current text. When this
- function returns, the audio output is fully stopped and the synthesizer is ready to
- synthesize a new message.
-
- Return: EE_OK: operation achieved
- EE_INTERNAL_ERROR.
-*/
-
-
-#ifdef __cplusplus
-extern "C"
-#endif
-int espeak_IsPlaying(void);
-/* Returns 1 if audio is played, 0 otherwise.
-*/
-
-#ifdef __cplusplus
-extern "C"
-#endif
-espeak_ERROR espeak_Synchronize(void);
-/* This function returns when all data have been spoken.
- Return: EE_OK: operation achieved
- EE_INTERNAL_ERROR.
-*/
-
-#ifdef __cplusplus
-extern "C"
-#endif
-espeak_ERROR espeak_Terminate(void);
-/* last function to be called.
- Return: EE_OK: operation achieved
- EE_INTERNAL_ERROR.
-*/
-
-
-#ifdef __cplusplus
-extern "C"
-#endif
-const char *espeak_Info(void);
-/* Returns the version number string.
- The parameter is for future use, and should be set to NULL
-*/
-#endif
diff --git a/navit/support/espeak/speech.h b/navit/support/espeak/speech.h
deleted file mode 100755
index 9673b0c8b..000000000
--- a/navit/support/espeak/speech.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2005 to 2007 by Jonathan Duddington *
- * email: jonsd@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write see: *
- * <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-
-#include <sys/types.h>
-
-// conditional compilation options
-#define INCLUDE_KLATT
-
-#if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN
-#define ARCH_BIG
-#endif
-
-/* #define PLATFORM_POSIX */
-#define PATHSEP '/'
-// USE_PORTAUDIO or USE_PULSEAUDIO are now defined in the makefile
-//#define USE_PORTAUDIO
-//#define USE_PULSEAUDIO
-#define USE_NANOSLEEP
-//#define ESPEAK_API extern "C"
-
-#ifdef LIBRARY
-#define USE_ASYNC
-//#define USE_MBROLA_LIB
-#endif
-
-#ifdef _ESPEAKEDIT
-#define USE_PORTAUDIO
-#define USE_ASYNC
-#define LOG_FRAMES // write keyframe info to log-espeakedit
-#endif
-
-// will look for espeak_data directory here, and also in user's home directory
-#ifndef PATH_ESPEAK_DATA
- #define PATH_ESPEAK_DATA "/usr/share/espeak-data"
-#endif
-
-typedef unsigned short USHORT;
-typedef unsigned char UCHAR;
-typedef double DOUBLEX;
-
-
-
-
-typedef struct {
- const char *mnem;
- int value;
-} MNEM_TAB;
-int LookupMnem(MNEM_TAB *table, char *string);
-
-
-#ifdef PLATFORM_WINDOWS
-#define N_PATH_HOME 220
-#define ESPEAK_API
-#else
-#define N_PATH_HOME 150
-#ifdef __cplusplus
-#define ESPEAK_API extern "C"
-#else
-#define ESPEAK_API
-#endif
-#endif
-
-extern char path_home[N_PATH_HOME]; // this is the espeak-data directory
-
-extern void strncpy0(char *to,const char *from, int size);
-int GetFileLength(const char *filename);
-char *Alloc(int size);
-void Free(void *ptr);
-
diff --git a/navit/support/espeak/synth_mbrola.c b/navit/support/espeak/synth_mbrola.c
deleted file mode 100755
index 1055f549f..000000000
--- a/navit/support/espeak/synth_mbrola.c
+++ /dev/null
@@ -1,760 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2005 to 2007 by Jonathan Duddington *
- * email: jonsd@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write see: *
- * <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-#include "StdAfx.h"
-
-#include <stdio.h>
-#include <ctype.h>
-#include <wctype.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-#include "speak_lib.h"
-#include "speech.h"
-#include "phoneme.h"
-#include "synthesize.h"
-#include "translate.h"
-#include "voice.h"
-
-extern int Read4Bytes(FILE *f);
-extern void SetPitch2(voice_t *voice, int pitch1, int pitch2, int *pitch_base, int *pitch_range);
-
-#ifdef USE_MBROLA_LIB
-
-extern unsigned char *outbuf;
-
-#ifndef PLATFORM_WINDOWS
-
-#include "mbrolib.h"
-void * mb_handle;
-
-#else
-#include <windows.h>
-typedef void (WINAPI *PROCVV)(void);
-typedef void (WINAPI *PROCVI)(int);
-typedef void (WINAPI *PROCVF)(float);
-typedef int (WINAPI *PROCIV)();
-typedef int (WINAPI *PROCIC) (char *);
-typedef int (WINAPI *PROCISI)(short *,int);
-typedef char* (WINAPI *PROCVCI)(char *,int);
-
-PROCIC init_MBR;
-PROCIC write_MBR;
-PROCIV flush_MBR;
-PROCISI read_MBR;
-PROCVV close_MBR;
-PROCVV reset_MBR;
-PROCIV lastError_MBR;
-PROCVCI lastErrorStr_MBR;
-PROCVI setNoError_MBR;
-PROCVI setFreq_MBR;
-PROCVF setVolumeRatio_MBR;
-
-
-
-HINSTANCE hinstDllMBR = NULL;
-
-
-BOOL load_MBR()
-{
- if(hinstDllMBR != NULL)
- return TRUE; // already loaded
-
- if (!(hinstDllMBR=LoadLibraryA("mbrola.dll")))
- return FALSE;
- init_MBR =(PROCIC) GetProcAddress(hinstDllMBR,"init_MBR");
- write_MBR =(PROCIC) GetProcAddress(hinstDllMBR,"write_MBR");
- flush_MBR =(PROCIV) GetProcAddress(hinstDllMBR,"flush_MBR");
- read_MBR =(PROCISI) GetProcAddress(hinstDllMBR,"read_MBR");
- close_MBR =(PROCVV) GetProcAddress(hinstDllMBR,"close_MBR");
- reset_MBR =(PROCVV) GetProcAddress(hinstDllMBR,"reset_MBR");
- lastError_MBR =(PROCIV) GetProcAddress(hinstDllMBR,"lastError_MBR");
- lastErrorStr_MBR =(PROCVCI) GetProcAddress(hinstDllMBR,"lastErrorStr_MBR");
- setNoError_MBR =(PROCVI) GetProcAddress(hinstDllMBR,"setNoError_MBR");
- setVolumeRatio_MBR =(PROCVF) GetProcAddress(hinstDllMBR,"setVolumeRatio_MBR");
- return TRUE;
-}
-
-
-void unload_MBR()
-{
- if (hinstDllMBR)
- {
- FreeLibrary (hinstDllMBR);
- hinstDllMBR=NULL;
- }
-}
-
-#endif // windows
-#endif // USE_MBROLA_LIB
-
-
-static MBROLA_TAB *mbrola_tab = NULL;
-static int mbrola_control = 0;
-
-
-
-
-espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int srate)
-{//===================================================================================
-// Load a phoneme name translation table from espeak-data/mbrola
-
- int size;
- int ix;
- int *pw;
- FILE *f_in;
- char path[sizeof(path_home)+15];
-
- mbrola_name[0] = 0;
- mbrola_delay = 0;
-
- if(mbrola_voice == NULL)
- {
- samplerate = samplerate_native;
- SetParameter(espeakVOICETYPE,0,0);
- return(EE_OK);
- }
-
- sprintf(path,"%s/mbrola/%s",path_home,mbrola_voice);
-#ifdef USE_MBROLA_LIB
-#ifdef PLATFORM_WINDOWS
- if(load_MBR() == FALSE) // load mbrola.dll
- return(EE_INTERNAL_ERROR);
-
- if(init_MBR(path) != 0) // initialise the required mbrola voice
- return(EE_NOT_FOUND);
-
- setNoError_MBR(1); // don't stop on phoneme errors
-#else
- mb_handle = mbrolib_init(srate);
- mbrolib_parameter m_parameters;
-
- if(mb_handle == NULL)
- return(EE_INTERNAL_ERROR);
-
- MBROLIB_ERROR a_status = mbrolib_set_voice(mb_handle, mbrola_voice);
- if(a_status != MBROLIB_OK)
- return(EE_NOT_FOUND);
-#endif // not windows
-#endif // USE_MBROLA_LIB
-
- // read eSpeak's mbrola phoneme translation data, eg. en1_phtrans
- sprintf(path,"%s/mbrola_ph/%s",path_home,phtrans);
- size = GetFileLength(path);
- if((f_in = fopen(path,"r")) == NULL)
- return(EE_NOT_FOUND);
-
- if((mbrola_tab = (MBROLA_TAB *)realloc(mbrola_tab,size)) == NULL)
- {
- fclose(f_in);
- return(EE_INTERNAL_ERROR);
- }
-
- mbrola_control = Read4Bytes(f_in);
- pw = (int *)mbrola_tab;
- for(ix=4; ix<size; ix+=4)
- {
- *pw++ = Read4Bytes(f_in);
- }
- fread(mbrola_tab,size,1,f_in);
- fclose(f_in);
-
-
-#ifdef USE_MBROLA_LIB
-#ifdef PLATFORM_WINDOWS
- setVolumeRatio_MBR((float)(mbrola_control & 0xff) /16.0f);
-#else
- mbrolib_get_parameter(mb_handle,&m_parameters);
- m_parameters.ignore_error = 1;
- m_parameters.volume_ratio = (float)(mbrola_control & 0xff) /16.0;
- mbrolib_set_parameter(mb_handle,&m_parameters);
-#endif // not windows
-#endif // USE_MBROLA_LIB
-
- option_quiet = 1;
- samplerate = srate;
- if(srate == 22050)
- SetParameter(espeakVOICETYPE,0,0);
- else
- SetParameter(espeakVOICETYPE,1,0);
- strcpy(mbrola_name,mbrola_voice);
- mbrola_delay = 3800; // improve synchronization of events
- return(EE_OK);
-} // end of LoadMbrolaTable
-
-
-static int GetMbrName(PHONEME_LIST *plist, PHONEME_TAB *ph, PHONEME_TAB *ph_prev, PHONEME_TAB *ph_next, int *name2, int *split, int *control)
-{//==========================================================================================================================================
-// Look up a phoneme in the mbrola phoneme name translation table
-// It may give none, 1, or 2 mbrola phonemes
- int mnem = ph->mnemonic;
- MBROLA_TAB *pr;
- PHONEME_TAB *other_ph;
- int found = 0;
-
- // control
- // bit 0 skip the next phoneme
- // bit 1 match this and Previous phoneme
- // bit 2 only at the start of a word
- // bit 3 don't match two phonemes across a word boundary
-
- pr = mbrola_tab;
- while(pr->name != 0)
- {
- if(mnem == pr->name)
- {
- if(pr->next_phoneme == 0)
- found = 1;
- else
- if((pr->next_phoneme == ':') && (plist->synthflags & SFLAG_LENGTHEN))
- {
- found = 1;
- }
- else
- {
- if(pr->control & 2)
- other_ph = ph_prev;
- else
- if((pr->control & 8) && ((plist+1)->newword))
- other_ph = phoneme_tab[phPAUSE]; // don't match the next phoneme over a word boundary
- else
- other_ph = ph_next;
-
- if((pr->next_phoneme == other_ph->mnemonic) ||
- ((pr->next_phoneme == 2) && (other_ph->type == phVOWEL)) ||
- ((pr->next_phoneme == '_') && (other_ph->type == phPAUSE)))
- {
- found = 1;
- }
- }
-
- if((pr->control & 4) && (plist->newword == 0)) // only at start of word
- found = 0;
-
- if(found)
- {
- *name2 = pr->mbr_name2;
- *split = pr->percent;
- *control = pr->control;
- return(pr->mbr_name);
- }
- }
-
- pr++;
- }
- *name2=0;
- *split=0;
- *control=0;
- return(mnem);
-}
-
-
-static char *WritePitch(int env, int pitch1, int pitch2, int split, int final)
-{//===========================================================================
-// final=1: only give the final pitch value.
- int x;
- int ix;
- int pitch_base;
- int pitch_range;
- int p1,p2,p_end;
- unsigned char *pitch_env;
- int max = -1;
- int min = 999;
- int y_max=0;
- int y_min=0;
- int env100 = 80; // apply the pitch change only over this proportion of the mbrola phoneme(s)
- int y2;
- int y[4];
- int env_split;
- char buf[50];
- static char output[50];
-
- output[0] = 0;
- pitch_env = envelope_data[env];
-
-
- SetPitch2(voice, pitch1, pitch2, &pitch_base, &pitch_range);
-
-
- env_split = (split * 128)/100;
- if(env_split < 0)
- env_split = 0-env_split;
-
- // find max and min in the pitch envelope
- for(x=0; x<128; x++)
- {
- if(pitch_env[x] > max)
- {
- max = pitch_env[x];
- y_max = x;
- }
- if(pitch_env[x] < min)
- {
- min = pitch_env[x];
- y_min = x;
- }
- }
- // set an additional pitch point half way through the phoneme.
- // but look for a maximum or a minimum and use that instead
- y[2] = 64;
- if((y_max > 0) && (y_max < 127))
- {
- y[2] = y_max;
- }
- if((y_min > 0) && (y_min < 127))
- {
- y[2] = y_min;
- }
- y[1] = y[2] / 2;
- y[3] = y[2] + (127 - y[2])/2;
-
- // set initial pitch
- p1 = ((pitch_env[0]*pitch_range)>>8) + pitch_base; // Hz << 12
- p_end = ((pitch_env[127]*pitch_range)>>8) + pitch_base;
-
-
- if(split >= 0)
- {
- sprintf(buf," 0 %d",p1/4096);
- strcat(output,buf);
- }
-
- // don't use intermediate pitch points for linear rise and fall
- if(env > 1)
- {
- for(ix=1; ix<4; ix++)
- {
- p2 = ((pitch_env[y[ix]]*pitch_range)>>8) + pitch_base;
-
- if(split > 0)
- {
- y2 = (y[ix] * env100)/env_split;
- }
- else
- if(split < 0)
- {
- y2 = ((y[ix]-env_split) * env100)/env_split;
- }
- else
- {
- y2 = (y[ix] * env100)/128;
- }
- if((y2 > 0) && (y2 <= env100))
- {
- sprintf(buf," %d %d",y2,p2/4096);
- strcat(output,buf);
- }
- }
- }
-
- p_end = p_end/4096;
- if(split <= 0)
- {
- sprintf(buf," %d %d",env100,p_end);
- strcat(output,buf);
- }
- if(env100 < 100)
- {
- sprintf(buf," %d %d",100,p_end);
- strcat(output,buf);
- }
- strcat(output,"\n");
-
- if(final)
- sprintf(output,"\t100 %d\n",p_end);
- return(output);
-} // end of WritePitch
-
-
-#ifdef USE_MBROLA_LIB
-
-static void MbrolaMarker(int type, int char_posn, int length, int value)
-{//=====================================================================
-
- MarkerEvent(type,(char_posn & 0xffffff) | (length << 24),value,outbuf);
-
-}
-
-
-static void MbrolaEmbedded(int &embix, int sourceix)
-{//=================================================
- // There were embedded commands in the text at this point
- unsigned int word; // bit 7=last command for this word, bits 5,6 sign, bits 0-4 command
- unsigned int value;
- int command;
- int sign=0;
-
- do {
- word = embedded_list[embix++];
- value = word >> 8;
- command = word & 0x1f;
-
- if((word & 0x60) == 0x60)
- sign = -1;
- else
- if((word & 0x60) == 0x40)
- sign = 1;
-
- if(command < N_EMBEDDED_VALUES)
- {
- if(sign == 0)
- embedded_value[command] = value;
- else
- embedded_value[command] += (value * sign);
- }
-
- switch(command & 0x1f)
- {
- case EMBED_M: // named marker
- MbrolaMarker(espeakEVENT_MARK, (sourceix & 0x7ff) + clause_start_char, 0, value);
- break;
- }
- } while ((word & 0x80) == 0);
-}
-
-
-#ifdef PLATFORM_WINDOWS
-static int MbrolaSynth(char *p_mbrola)
-{//===================================
-// p_mbrola is a string of mbrola pho lines - Windows
- int len;
- int finished;
- int result=0;
-
- if(synth_callback == NULL)
- return(1);
-
- if(p_mbrola == NULL)
- flush_MBR();
- else
- result = write_MBR(p_mbrola);
-
-
- finished = 0;
- while(!finished && ((len = read_MBR((short *)outbuf, outbuf_size/2)) > 0))
- {
- out_ptr = outbuf + len*2;
-
- if(event_list)
- {
- event_list[event_list_ix].type = espeakEVENT_LIST_TERMINATED; // indicates end of event list
- event_list[event_list_ix].user_data = 0;
- }
- count_samples += len;
- finished = synth_callback((short *)outbuf, len, event_list);
- event_list_ix=0;
- }
-
- if(finished)
- {
- // cancelled by user, discard any unused mbrola speech
- flush_MBR();
- while((len = read_MBR((short *)outbuf, outbuf_size/2)) > 0);
- }
- return(finished);
-} // end of SynthMbrola
-#else
-
-static int MbrolaSynth(char *p_mbrola)
-{//===================================
-// p_mbrola is a string of mbrola pho lines - Linux
-
-// This is wrong
-// It must be called from WavegenFill()
-
- int len;
- int finished;
- int result=0;
-
- if(synth_callback == NULL)
- return(1);
-
- if(p_mbrola == NULL)
- mbrolib_flush(mb_handle);
- else
- result = mbrolib_write(mb_handle,p_mbrola,strlen(p_mbrola));
-
-
- finished = 0;
- while(!finished && (mbrolib_read(mb_handle, (short *)out_ptr, (out_end - out_ptr)/2, &len) == MBROLIB_OK))
- {
- if(len == 0)
- break;
-
- out_ptr += (len*2);
-
- if(event_list)
- {
- event_list[event_list_ix].type = espeakEVENT_LIST_TERMINATED; // indicates end of event list
- event_list[event_list_ix].user_data = 0;
- }
- count_samples += len;
- finished = synth_callback((short *)outbuf, len, event_list);
- event_list_ix=0;
- }
-
- if(finished)
- {
- // cancelled by user, discard any unused mbrola speech
- mbrolib_flush(mb_handle);
- while(mbrolib_read(mb_handle, (short *)outbuf, outbuf_size/2, &len) == MBROLIB_OK)
- {
- if(len == 0)
- break;
- }
- }
- return(finished);
-} // end of SynthMbrola
-#endif // not windows
-#endif // USE_MBROLA_LIB
-
-
-
-void MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, FILE *f_mbrola)
-{//======================================================================
-// Generate a mbrola pho file
- unsigned int name;
- int phix;
- int len;
- int len1;
- PHONEME_TAB *ph;
- PHONEME_TAB *ph_next;
- PHONEME_TAB *ph_prev;
- PHONEME_LIST *p;
- PHONEME_LIST *next;
- PHONEME_LIST *prev;
- int pause = 0;
- int released;
- int name2;
- int control;
- int done;
- int len_percent;
- const char *final_pitch;
- char buf[80];
- char mbr_buf[120];
-
-#ifdef USE_MBROLA_LIB
- int embedded_ix=0;
- int word_count=0;
-
- event_list_ix = 0;
- out_ptr = outbuf;
-#ifdef PLATFORM_WINDOWS
- setNoError_MBR(1); // don't stop on phoneme errors
-#endif
-#else
-// fprintf(f_mbrola,";; v=%.2f\n",(float)(mbrola_control & 0xff)/16.0); // ;; v= has no effect on mbrola
-#endif
-
- for(phix=1; phix < n_phonemes; phix++)
- {
- mbr_buf[0] = 0;
-
- p = &plist[phix];
- next = &plist[phix+1];
- prev = &plist[phix-1];
- ph = p->ph;
- ph_prev = plist[phix-1].ph;
- ph_next = plist[phix+1].ph;
-
-#ifdef USE_MBROLA_LIB
- if(p->synthflags & SFLAG_EMBEDDED)
- {
- MbrolaEmbedded(embedded_ix, p->sourceix);
- }
- if(p->newword & 4)
- MbrolaMarker(espeakEVENT_SENTENCE, (p->sourceix & 0x7ff) + clause_start_char, 0, count_sentences);
-
- if(p->newword & 1)
- MbrolaMarker(espeakEVENT_WORD, (p->sourceix & 0x7ff) + clause_start_char, p->sourceix >> 11, clause_start_word + word_count++);
-#endif
-
- name = GetMbrName(p,ph,ph_prev,ph_next,&name2,&len_percent,&control);
- if(control & 1)
- phix++;
-
- if(name == 0)
- continue; // ignore this phoneme
-
- if((ph->type == phPAUSE) && (name == ph->mnemonic))
- {
- // a pause phoneme, which has not been changed by the translation
- name = '_';
- len = (p->length * speed.speed_factor1)/256;
-// if(len == 0) continue;
- if(len == 0)
- len = 1;
- }
- else
- len = (80 * speed.speed_factor2)/256;
-
-#ifdef USE_MBROLA_LIB
- MbrolaMarker(espeakEVENT_PHONEME, (p->sourceix & 0x7ff) + clause_start_char, 0, ph->mnemonic);
-#endif
-
- sprintf(buf,"%s\t",WordToString(name));
- strcat(mbr_buf,buf);
-
- if(name2 == '_')
- {
- // add a pause after this phoneme
- pause = PauseLength(len_percent,0);
- name2 = 0;
- }
-
- done = 0;
- final_pitch = "";
-
- switch(ph->type)
- {
- case phVOWEL:
- len = ph->std_length;
- if(p->synthflags & SFLAG_LENGTHEN)
- len += phoneme_tab[phonLENGTHEN]->std_length; // phoneme was followed by an extra : symbol
-
- if(ph_next->type == phPAUSE)
- len += 50; // lengthen vowels before a pause
- len = (len * p->length)/256;
-
- if(name2 == 0)
- {
- sprintf(buf,"%d\t%s", len, WritePitch(p->env,p->pitch1,p->pitch2,0,0));
- strcat(mbr_buf,buf);
- }
- else
- {
- len1 = (len * len_percent)/100;
- sprintf(buf,"%d\t%s", len1, WritePitch(p->env,p->pitch1,p->pitch2,len_percent,0));
- strcat(mbr_buf,buf);
-
- sprintf(buf,"%s\t%d\t%s", WordToString(name2), len-len1, WritePitch(p->env,p->pitch1,p->pitch2,-len_percent,0));
- strcat(mbr_buf,buf);
- }
- done = 1;
- break;
-
- case phSTOP:
- released = 0;
- if(next->type==phVOWEL) released = 1;
- if(next->type==phLIQUID && !next->newword) released = 1;
-
- if(released)
- len = DoSample(p->ph,next->ph,2,0,-1);
- else
- len = DoSample(p->ph,phoneme_tab[phonPAUSE],2,0,-1);
- len = (len * 1000)/samplerate; // convert to mS
- len += PauseLength(p->prepause,1);
- break;
-
- case phVSTOP:
- len = (80 * speed.speed_factor2)/256;
- break;
-
- case phFRICATIVE:
- len = 0;
- if(p->synthflags & SFLAG_LENGTHEN)
- len = DoSample(ph,ph_next,2,p->length,-1); // play it twice for [s:] etc.
- len += DoSample(ph,ph_next,2,p->length,-1);
-
- len = (len * 1000)/samplerate; // convert to mS
- break;
-
- case phNASAL:
- if(next->type != phVOWEL)
- {
- len = DoSpect(p->ph,prev->ph,phoneme_tab[phonPAUSE],2,p,-1);
- len = (len * 1000)/samplerate;
- if(next->type == phPAUSE)
- len += 50;
- final_pitch = WritePitch(p->env,p->pitch1,p->pitch2,0,1);
- }
- break;
-
- case phLIQUID:
- if(next->type == phPAUSE)
- {
- len += 50;
- final_pitch = WritePitch(p->env,p->pitch1,p->pitch2,0,1);
- }
- break;
- }
-
- if(!done)
- {
- if(name2 != 0)
- {
- len1 = (len * len_percent)/100;
- sprintf(buf,"%d\n%s\t",len1,WordToString(name2));
- strcat(mbr_buf,buf);
- len -= len1;
- }
- sprintf(buf,"%d%s\n",len,final_pitch);
- strcat(mbr_buf,buf);
- }
-
- if(pause)
- {
- sprintf(buf,"_ \t%d\n",PauseLength(pause,0));
- strcat(mbr_buf,buf);
- pause = 0;
- }
-
- if(f_mbrola)
- {
- fwrite(mbr_buf,1,strlen(mbr_buf),f_mbrola); // write .pho to a file
- }
- else
- {
-#ifdef USE_MBROLA_LIB
- if(MbrolaSynth(mbr_buf) != 0)
- return;
-#endif
- }
- }
-
-#ifdef USE_MBROLA_LIB
- MbrolaSynth(NULL);
-#endif
-} // end of MbrolaTranslate
-
-
-#ifdef TEST_MBROLA
-
-static PHONEME_LIST mbrola_phlist;
-static int mbrola_n_ph;
-static int mbrola_phix;
-
-
-int MbrolaFill(int fill_zeros)
-{//===========================
-}
-
-int MbrolaGenerate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
-{//==================================================================
- if(resume == 0)
- {
- mbrola_phlist = phoneme_list;
- mbrola_n_ph = n_ph;
- mbrola_phix = 0;
- }
-
- resume(0); // finished phoneme list
-}
-#endif
diff --git a/navit/support/espeak/synthdata.c b/navit/support/espeak/synthdata.c
deleted file mode 100755
index 4f8234beb..000000000
--- a/navit/support/espeak/synthdata.c
+++ /dev/null
@@ -1,682 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2005 to 2007 by Jonathan Duddington *
- * email: jonsd@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, see: *
- * <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-
-#include "StdAfx.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <wctype.h>
-#include <string.h>
-
-
-#include "speak_lib.h"
-#include "speech.h"
-#include "phoneme.h"
-#include "synthesize.h"
-#include "voice.h"
-#include "translate.h"
-#include "wave.h"
-
-const char *version_string = "1.41.01 25.Aug.09";
-const int version_phdata = 0x014100;
-
-int option_device_number = -1;
-
-// copy the current phoneme table into here
-int n_phoneme_tab;
-int current_phoneme_table;
-PHONEME_TAB *phoneme_tab[N_PHONEME_TAB];
-unsigned char phoneme_tab_flags[N_PHONEME_TAB]; // bit 0: not inherited
-
-static unsigned int *phoneme_index=NULL;
-char *spects_data=NULL;
-unsigned char *wavefile_data=NULL;
-static unsigned char *phoneme_tab_data = NULL;
-
-int n_phoneme_tables;
-PHONEME_TAB_LIST phoneme_tab_list[N_PHONEME_TABS];
-int phoneme_tab_number = 0;
-
-int wavefile_ix; // a wavefile to play along with the synthesis
-int wavefile_amp;
-int wavefile_ix2;
-int wavefile_amp2;
-
-int seq_len_adjust;
-int vowel_transition[4];
-int vowel_transition0;
-int vowel_transition1;
-
-int FormantTransition2(frameref_t *seq, int *n_frames, unsigned int data1, unsigned int data2, PHONEME_TAB *other_ph, int which);
-
-
-
-static char *ReadPhFile(void *ptr, const char *fname)
-{//==================================================
- FILE *f_in;
- char *p;
- unsigned int length;
- char buf[sizeof(path_home)+40];
-
- sprintf(buf,"%s%c%s",path_home,PATHSEP,fname);
- length = GetFileLength(buf);
-
- if((f_in = fopen(buf,"rb")) == NULL)
- {
- fprintf(stderr,"Can't read data file: '%s'\n",buf);
- return(NULL);
- }
-
- if(ptr != NULL)
- Free(ptr);
-
- if((p = Alloc(length)) == NULL)
- {
- fclose(f_in);
- return(NULL);
- }
- if(fread(p,1,length,f_in) != length)
- {
- fclose(f_in);
- return(NULL);
- }
-
- fclose(f_in);
- return(p);
-} // end of ReadPhFile
-
-
-int LoadPhData()
-{//=============
- int ix;
- int n_phonemes;
- int version;
- int result = 1;
- unsigned char *p;
-
- if((phoneme_tab_data = (unsigned char *)ReadPhFile((void *)(phoneme_tab_data),"phontab")) == NULL)
- return(-1);
- if((phoneme_index = (unsigned int *)ReadPhFile((void *)(phoneme_index),"phonindex")) == NULL)
- return(-1);
- if((spects_data = ReadPhFile((void *)(spects_data),"phondata")) == NULL)
- return(-1);
- wavefile_data = (unsigned char *)spects_data;
-
- // read the version number from the first 4 bytes of phondata
- version = 0;
- for(ix=0; ix<4; ix++)
- {
- version += (wavefile_data[ix] << (ix*8));
- }
-
- if(version != version_phdata)
- {
- result = version;
- }
-
- // set up phoneme tables
- p = phoneme_tab_data;
- n_phoneme_tables = p[0];
- p+=4;
-
- for(ix=0; ix<n_phoneme_tables; ix++)
- {
- n_phonemes = p[0];
- phoneme_tab_list[ix].n_phonemes = p[0];
- phoneme_tab_list[ix].includes = p[1];
- p += 4;
- memcpy(phoneme_tab_list[ix].name,p,N_PHONEME_TAB_NAME);
- p += N_PHONEME_TAB_NAME;
- phoneme_tab_list[ix].phoneme_tab_ptr = (PHONEME_TAB *)p;
- p += (n_phonemes * sizeof(PHONEME_TAB));
- }
-
- if(phoneme_tab_number >= n_phoneme_tables)
- phoneme_tab_number = 0;
-
- return(result);
-} // end of LoadPhData
-
-
-void FreePhData(void)
-{//==================
- Free(phoneme_tab_data);
- Free(phoneme_index);
- Free(spects_data);
- phoneme_tab_data=NULL;
- phoneme_index=NULL;
- spects_data=NULL;
-}
-
-
-int PhonemeCode(unsigned int mnem)
-{//===============================
- int ix;
-
- for(ix=0; ix<n_phoneme_tab; ix++)
- {
- if(phoneme_tab[ix] == NULL)
- continue;
- if(phoneme_tab[ix]->mnemonic == mnem)
- return(phoneme_tab[ix]->code);
- }
- return(0);
-}
-
-
-int LookupPhonemeString(const char *string)
-{//========================================
- int ix;
- unsigned char c;
- unsigned int mnem;
-
- // Pack up to 4 characters into a word
- mnem = 0;
- for(ix=0; ix<4; ix++)
- {
- if(string[ix]==0) break;
- c = string[ix];
- mnem |= (c << (ix*8));
- }
-
- return(PhonemeCode(mnem));
-}
-
-
-
-static unsigned int LookupSound2(int index, unsigned int other_phcode, int control)
-{//================================================================================
-// control=1 get formant transition data only
-
- unsigned int code;
- unsigned int value, value2;
-
- while((value = phoneme_index[index++]) != 0)
- {
- if((code = (value & 0xff)) == other_phcode)
- {
- while(((value2 = phoneme_index[index]) != 0) && ((value2 & 0xff) < 8))
- {
- switch(value2 & 0xff)
- {
- case 0:
- // next entry is a wavefile to be played along with the synthesis
- if(control==0)
- {
- wavefile_ix = value2 >> 8;
- }
- break;
- case 1:
- if(control==0)
- {
- seq_len_adjust = value2 >> 8;
- }
- break;
- case 2:
- if(control==0)
- {
- seq_len_adjust = value2 >> 8;
- seq_len_adjust = -seq_len_adjust;
- }
- break;
- case 3:
- if(control==0)
- {
- wavefile_amp = value2 >> 8;
- }
- break;
- case 4:
- // formant transition data, 2 words
- vowel_transition[0] = value2 >> 8;
- vowel_transition[1] = phoneme_index[index++ + 1];
- break;
- case 5:
- // formant transition data, 2 words
- vowel_transition[2] = value2 >> 8;
- vowel_transition[3] = phoneme_index[index++ + 1];
- break;
- }
- index++;
- }
- return(value >> 8);
- }
- else
- if((code == 4) || (code == 5))
- {
- // formant transition data, ignore next word of data
- index++;
- }
- }
- return(3); // not found
-} // end of LookupSound2
-
-
-unsigned int LookupSound(PHONEME_TAB *this_ph, PHONEME_TAB *other_ph, int which, int *match_level, int control)
-{//============================================================================================================
- // follows, 1 other_ph preceeds this_ph, 2 other_ph follows this_ph
- // control: 1= get formant transition data only
- int spect_list;
- int spect_list2;
- int s_list;
- unsigned char virtual_ph;
- int result;
- int level=0;
- unsigned int other_code;
- unsigned int other_virtual;
-
- if(control==0)
- {
- wavefile_ix = 0;
- wavefile_amp = 32;
- seq_len_adjust = 0;
- }
- memset(vowel_transition,0,sizeof(vowel_transition));
-
- other_code = other_ph->code;
- if(phoneme_tab[other_code]->type == phPAUSE)
- other_code = phonPAUSE_SHORT; // use this version of Pause for matching
-
- if(which==1)
- {
- spect_list = this_ph->after;
- virtual_ph = this_ph->start_type;
- spect_list2 = phoneme_tab[virtual_ph]->after;
- other_virtual = other_ph->end_type;
- }
- else
- {
- spect_list = this_ph->before;
- virtual_ph = this_ph->end_type;
- spect_list2 = phoneme_tab[virtual_ph]->before;
- other_virtual = other_ph->start_type;
- }
-
- result = 3;
- // look for ph1-ph2 combination
- if((s_list = spect_list) != 0)
- {
- if((result = LookupSound2(s_list,other_code,control)) != 3)
- {
- level = 2;
- }
- else
- if(other_virtual != 0)
- {
- if((result = LookupSound2(spect_list,other_virtual,control)) != 3)
- {
- level = 1;
- }
- }
- }
- // not found, look in a virtual phoneme if one is given for this phoneme
- if((result==3) && (virtual_ph != 0) && ((s_list = spect_list2) != 0))
- {
- if((result = LookupSound2(s_list,other_code,control)) != 3)
- {
- level = 1;
- }
- else
- if(other_virtual != 0)
- {
- if((result = LookupSound2(spect_list2,other_virtual,control)) != 3)
- {
- level = 1;
- }
- }
- }
-
- if(match_level != NULL)
- *match_level = level;
-
- if(result==0)
- return(0); // NULL was given in the phoneme source
-
- // note: values = 1 indicates use the default for this phoneme, even though we found a match
- // which set a secondary reference
- if(result >= 4)
- {
- // values 1-3 can be used for special codes
- // 1 = DFT from the phoneme source file
- return(result);
- }
-
- // no match found for other_ph, return the default
- return(LookupSound2(this_ph->spect,phonPAUSE,control));
-
-} // end of LookupSound
-
-
-
-frameref_t *LookupSpect(PHONEME_TAB *this_ph, PHONEME_TAB *prev_ph, PHONEME_TAB *next_ph,
- int which, int *match_level, int *n_frames, PHONEME_LIST *plist)
-{//=========================================================================================================
- int ix;
- int nf;
- int nf1;
- int seq_break;
- frameref_t *frames;
- int length1;
- int length_std;
- int length_factor;
- SPECT_SEQ *seq, *seq2;
- SPECT_SEQK *seqk, *seqk2;
- PHONEME_TAB *next2_ph;
- frame_t *frame;
- static frameref_t frames_buf[N_SEQ_FRAMES];
-
- PHONEME_TAB *other_ph;
- if(which == 1)
- other_ph = prev_ph;
- else
- other_ph = next_ph;
-
- if((ix = LookupSound(this_ph,other_ph,which,match_level,0)) < 4)
- return(NULL);
- seq = (SPECT_SEQ *)(&spects_data[ix]);
- seqk = (SPECT_SEQK *)seq;
- nf = seq->n_frames;
-
-
- if(nf >= N_SEQ_FRAMES)
- nf = N_SEQ_FRAMES - 1;
-
- seq_break = 0;
- length1 = 0;
-
- for(ix=0; ix<nf; ix++)
- {
- if(seq->frame[0].frflags & FRFLAG_KLATT)
- frame = &seqk->frame[ix];
- else
- frame = (frame_t *)&seq->frame[ix];
- frames_buf[ix].frame = frame;
- frames_buf[ix].frflags = frame->frflags;
- frames_buf[ix].length = frame->length;
- if(frame->frflags & FRFLAG_VOWEL_CENTRE)
- seq_break = ix;
- }
-
- frames = &frames_buf[0];
- if(seq_break > 0)
- {
- if(which==1)
- {
- nf = seq_break + 1;
- }
- else
- {
- frames = &frames_buf[seq_break]; // body of vowel, skip past initial frames
- nf -= seq_break;
- }
- }
-
- // do we need to modify a frame for blending with a consonant?
- if(this_ph->type == phVOWEL)
- {
- if((which==2) && ((frames[nf-1].frflags & FRFLAG_BREAK) == 0))
- {
- // lookup formant transition for the following phoneme
-
- if((*match_level == 0) || (next_ph->type == phNASAL))
- {
- LookupSound(next_ph,this_ph,1,NULL,1);
- seq_len_adjust += FormantTransition2(frames,&nf,vowel_transition[2],vowel_transition[3],next_ph,which);
- }
- else
- if(next_ph->phflags == phVOWEL2)
- {
- // not really a consonant, rather a coloured vowel
- if(LookupSound(next_ph,this_ph,1,NULL,1) == 0)
- {
- next2_ph = plist[2].ph;
- LookupSound(next2_ph,next_ph,1,NULL,1);
- seq_len_adjust += FormantTransition2(frames,&nf,vowel_transition[2],vowel_transition[3],next2_ph,which);
- }
- }
- }
- else
- {
- if(*match_level == 0)
- seq_len_adjust = FormantTransition2(frames,&nf,vowel_transition0,vowel_transition1,prev_ph,which);
- }
- }
-
- nf1 = nf - 1;
- for(ix=0; ix<nf1; ix++)
- length1 += frames[ix].length;
-
-
- if((wavefile_ix != 0) && ((wavefile_ix & 0x800000)==0))
- {
- // a secondary reference has been returned, which is not a wavefile
- // add these spectra to the main sequence
- seq2 = (SPECT_SEQ *)(&spects_data[wavefile_ix]);
- seqk2 = (SPECT_SEQK *)seq2;
-
- // first frame of the addition just sets the length of the last frame of the main seq
- nf--;
- for(ix=0; ix<seq2->n_frames; ix++)
- {
- if(seq2->frame[0].frflags & FRFLAG_KLATT)
- frame = &seqk2->frame[ix];
- else
- frame = (frame_t *)&seq2->frame[ix];
-
- frames[nf].length = frame->length;
- if(ix > 0)
- {
- frames[nf].frame = frame;
- frames[nf].frflags = frame->frflags;
- }
- nf++;
- }
- wavefile_ix = 0;
- }
-
- if((this_ph->type == phVOWEL) && (length1 > 0))
- {
- if(which==2)
- {
- // adjust the length of the main part to match the standard length specified for the vowel
- // less the front part of the vowel and any added suffix
-
- length_std = this_ph->std_length + seq_len_adjust - 45;
- if(length_std < 10)
- length_std = 10;
- if(plist->synthflags & SFLAG_LENGTHEN)
- length_std += phoneme_tab[phonLENGTHEN]->std_length; // phoneme was followed by an extra : symbol
-
-// can adjust vowel length for stressed syllables here
-
-
- length_factor = (length_std * 256)/ length1;
-
- for(ix=0; ix<nf1; ix++)
- {
- frames[ix].length = (frames[ix].length * length_factor)/256;
- }
- }
- else
- {
- // front of a vowel
- if(*match_level == 0)
- {
- // allow very short vowels to have shorter front parts
- if(this_ph->std_length < 130)
- frames[0].length = (frames[0].length * this_ph->std_length)/130;
- }
-
- if(seq_len_adjust != 0)
- {
- length_std = 0;
- for(ix=0; ix<nf1; ix++)
- {
- length_std += frames[ix].length;
- }
- length_factor = ((length_std + seq_len_adjust) * 256)/length_std;
- for(ix=0; ix<nf1; ix++)
- {
- frames[ix].length = (frames[ix].length * length_factor)/256;
- }
- }
- }
- }
-
- *n_frames = nf;
- return(frames);
-} // end of LookupSpect
-
-
-unsigned char *LookupEnvelope(int ix)
-{//================================
- if(ix==0)
- return(NULL);
- return((unsigned char *)&spects_data[phoneme_index[ix]]);
-}
-
-
-static void SetUpPhonemeTable(int number, int recursing)
-{//=====================================================
- int ix;
- int includes;
- int ph_code;
- PHONEME_TAB *phtab;
-
- if(recursing==0)
- {
- memset(phoneme_tab_flags,0,sizeof(phoneme_tab_flags));
- }
-
- if((includes = phoneme_tab_list[number].includes) > 0)
- {
- // recursively include base phoneme tables
- SetUpPhonemeTable(includes-1,1);
- }
-
- // now add the phonemes from this table
- phtab = phoneme_tab_list[number].phoneme_tab_ptr;
- for(ix=0; ix<phoneme_tab_list[number].n_phonemes; ix++)
- {
- ph_code = phtab[ix].code;
- phoneme_tab[ph_code] = &phtab[ix];
- if(ph_code > n_phoneme_tab)
- n_phoneme_tab = ph_code;
-
- if(recursing == 0)
- phoneme_tab_flags[ph_code] |= 1; // not inherited
- }
-} // end of SetUpPhonemeTable
-
-
-void SelectPhonemeTable(int number)
-{//================================
- n_phoneme_tab = 0;
- SetUpPhonemeTable(number,0); // recursively for included phoneme tables
- n_phoneme_tab++;
- current_phoneme_table = number;
-} // end of SelectPhonemeTable
-
-
-int LookupPhonemeTable(const char *name)
-{//=====================================
- int ix;
-
- for(ix=0; ix<n_phoneme_tables; ix++)
- {
- if(strcmp(name,phoneme_tab_list[ix].name)==0)
- {
- phoneme_tab_number = ix;
- break;
- }
- }
- if(ix == n_phoneme_tables)
- return(-1);
-
- return(ix);
-}
-
-
-int SelectPhonemeTableName(const char *name)
-{//=========================================
-// Look up a phoneme set by name, and select it if it exists
-// Returns the phoneme table number
- int ix;
-
- if((ix = LookupPhonemeTable(name)) == -1)
- return(-1);
-
- SelectPhonemeTable(ix);
- return(ix);
-} // end of DelectPhonemeTableName
-
-
-
-
-void LoadConfig(void)
-{//==================
-// Load configuration file, if one exists
- char buf[sizeof(path_home)+10];
- FILE *f;
- int ix;
- char c1;
- char *p;
- char string[200];
-
- for(ix=0; ix<N_SOUNDICON_SLOTS; ix++)
- {
- soundicon_tab[ix].filename = NULL;
- soundicon_tab[ix].data = NULL;
- }
-
- sprintf(buf,"%s%c%s",path_home,PATHSEP,"config");
- if((f = fopen(buf,"r"))==NULL)
- {
- return;
- }
-
- while(fgets(buf,sizeof(buf),f)!=NULL)
- {
- if(memcmp(buf,"tone",4)==0)
- {
- ReadTonePoints(&buf[5],tone_points);
- }
- else
- if(memcmp(buf,"pa_device",9)==0)
- {
- sscanf(&buf[7],"%d",&option_device_number);
- }
- else
- if(memcmp(buf,"soundicon",9)==0)
- {
- ix = sscanf(&buf[10],"_%c %s",&c1,string);
- if(ix==2)
- {
- soundicon_tab[n_soundicon_tab].name = c1;
- p = Alloc(strlen(string)+1);
- strcpy(p,string);
- soundicon_tab[n_soundicon_tab].filename = p;
- soundicon_tab[n_soundicon_tab++].length = 0;
- }
- }
- }
- fclose(f);
-} // end of LoadConfig
-
diff --git a/navit/support/espeak/synthesize.c b/navit/support/espeak/synthesize.c
deleted file mode 100755
index 3a48b1d72..000000000
--- a/navit/support/espeak/synthesize.c
+++ /dev/null
@@ -1,1658 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2005 to 2007 by Jonathan Duddington *
- * email: jonsd@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, see: *
- * <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-#include "StdAfx.h"
-
-#include <stdio.h>
-#include <ctype.h>
-#include <wctype.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-#include "speak_lib.h"
-#include "speech.h"
-#include "phoneme.h"
-#include "synthesize.h"
-#include "voice.h"
-#include "translate.h"
-
-
-extern FILE *f_log;
-static void SmoothSpect(void);
-
-
-// list of phonemes in a clause
-int n_phoneme_list=0;
-PHONEME_LIST phoneme_list[N_PHONEME_LIST];
-
-int mbrola_delay;
-char mbrola_name[20];
-
-SPEED_FACTORS speed;
-
-static int last_pitch_cmd;
-static int last_amp_cmd;
-static frame_t *last_frame;
-static int last_wcmdq;
-static int pitch_length;
-static int amp_length;
-static int modn_flags;
-
-static int syllable_start;
-static int syllable_end;
-static int syllable_centre;
-
-static voice_t *new_voice=NULL;
-
-int n_soundicon_tab=N_SOUNDICON_SLOTS;
-SOUND_ICON soundicon_tab[N_SOUNDICON_TAB];
-
-#define RMS_GLOTTAL1 35 // vowel before glottal stop
-#define RMS_START 28 // 28
-
-#define VOWEL_FRONT_LENGTH 50
-
-#define long(x) ((long)(x))
-
-// a dummy phoneme_list entry which looks like a pause
-static PHONEME_LIST next_pause;
-
-
-const char *WordToString(unsigned int word)
-{//========================================
-// Convert a phoneme mnemonic word into a string
- int ix;
- static char buf[5];
-
- for(ix=0; ix<3; ix++)
- buf[ix] = word >> (ix*8);
- buf[4] = 0;
- return(buf);
-}
-
-
-
-void SynthesizeInit()
-{//==================
- last_pitch_cmd = 0;
- last_amp_cmd = 0;
- last_frame = NULL;
- syllable_centre = -1;
-
- // initialise next_pause, a dummy phoneme_list entry
-// next_pause.ph = phoneme_tab[phonPAUSE]; // this must be done after voice selection
- next_pause.type = phPAUSE;
- next_pause.newword = 0;
-}
-
-
-
-static void EndAmplitude(void)
-{//===========================
- if(amp_length > 0)
- {
- if(wcmdq[last_amp_cmd][1] == 0)
- wcmdq[last_amp_cmd][1] = amp_length;
- amp_length = 0;
- }
-}
-
-
-
-static void EndPitch(int voice_break)
-{//==================================
- // posssible end of pitch envelope, fill in the length
- if((pitch_length > 0) && (last_pitch_cmd >= 0))
- {
- if(wcmdq[last_pitch_cmd][1] == 0)
- wcmdq[last_pitch_cmd][1] = pitch_length;
- pitch_length = 0;
- }
-
- if(voice_break)
- {
- last_wcmdq = -1;
- last_frame = NULL;
- syllable_end = wcmdq_tail;
- SmoothSpect();
- syllable_centre = -1;
- memset(vowel_transition,0,sizeof(vowel_transition));
- }
-} // end of Synthesize::EndPitch
-
-
-
-static void DoAmplitude(int amp, unsigned char *amp_env)
-{//=====================================================
- long *q;
-
- last_amp_cmd = wcmdq_tail;
- amp_length = 0; // total length of vowel with this amplitude envelope
-
- q = wcmdq[wcmdq_tail];
- q[0] = WCMD_AMPLITUDE;
- q[1] = 0; // fill in later from amp_length
- q[2] = (long)amp_env;
- q[3] = amp;
- WcmdqInc();
-} // end of Synthesize::DoAmplitude
-
-
-
-static void DoPitch(unsigned char *env, int pitch1, int pitch2)
-{//============================================================
- long *q;
-
- EndPitch(0);
-
- if(pitch1 == 1024)
- {
- // pitch was not set
- pitch1 = 24;
- pitch2 = 33;
- env = envelope_data[PITCHfall];
- }
- last_pitch_cmd = wcmdq_tail;
- pitch_length = 0; // total length of spect with this pitch envelope
-
- if(pitch2 < 0)
- pitch2 = 0;
-
- q = wcmdq[wcmdq_tail];
- q[0] = WCMD_PITCH;
- q[1] = 0; // length, fill in later from pitch_length
- q[2] = (long)env;
- q[3] = (pitch1 << 16) + pitch2;
- WcmdqInc();
-} // end of Synthesize::DoPitch
-
-
-
-int PauseLength(int pause, int control)
-{//====================================
- int len;
-
- if(control == 0)
- len = (pause * speed.speed_factor1)/256;
- else
- len = (pause * speed.speed_factor2)/256;
-
- if(len < 5) len = 5; // mS, limit the amount to which pauses can be shortened
- return(len);
-}
-
-
-static void DoPause(int length, int control)
-{//=========================================
-// control = 1, less shortening at fast speeds
- int len;
-
- len = PauseLength(length, control);
-
- len = (len * samplerate) / 1000; // convert from mS to number of samples
-
- EndPitch(1);
- wcmdq[wcmdq_tail][0] = WCMD_PAUSE;
- wcmdq[wcmdq_tail][1] = len;
- WcmdqInc();
- last_frame = NULL;
-} // end of Synthesize::DoPause
-
-
-extern int seq_len_adjust; // temporary fix to advance the start point for playing the wav sample
-
-
-static int DoSample2(int index, int which, int length_mod, int amp)
-{//================================================================
- int length;
- int length1;
- int format;
- int min_length;
- int start=0;
- long *q;
- unsigned char *p;
-
- index = index & 0x7fffff;
- p = &wavefile_data[index];
- format = p[2];
- length1 = (p[1] * 256);
- length1 += p[0]; // length in bytes
-
- if(seq_len_adjust > 0)
- {
- start = (seq_len_adjust * samplerate)/1000;
- if(format == 0)
- start *= 2;
- length1 -= start;
- index += start;
- }
-
-
- if(length_mod > 0)
- length = (length1 * length_mod) / 256;
- else
- length = length1;
-
-
- length = (length * speed.speed_factor2)/256;
- min_length = speed.min_sample_len;
- if(format==0)
- min_length *= 2;
-
- if(length < min_length)
- length = min_length;
-
- if(length > length1)
- length = length1; // don't exceed wavefile length
-
- if(format==0)
- length /= 2; // 2 byte samples
-
-
- index += 4;
-
- if(amp >= 0)
- {
- last_wcmdq = wcmdq_tail;
- q = wcmdq[wcmdq_tail];
- if(which & 0x100)
- q[0] = WCMD_WAVE2; // mix this with synthesised wave
- else
- q[0] = WCMD_WAVE;
- q[1] = length; // length in samples
- q[2] = long(&wavefile_data[index]);
- q[3] = format + (amp << 8);
- WcmdqInc();
- }
- return(length);
-} // end of Synthesize::DoSample2
-
-
-int DoSample(PHONEME_TAB *ph1, PHONEME_TAB *ph2, int which, int length_mod, int amp)
-{//====================== ==========================================================
- int index;
- int match_level;
- int amp2;
- int result;
-
- EndPitch(1);
- index = LookupSound(ph1,ph2,which & 0xff,&match_level,0);
- if((index & 0x800000) == 0)
- return(0); // not wavefile data
-
- amp2 = wavefile_amp;
- if(amp != 0)
- amp2 = (amp * wavefile_amp)/20;
-
- if(amp == -1)
- amp2 = amp;
-
- result = DoSample2(index,which,length_mod,amp2);
- last_frame = NULL;
- return(result);
-} // end of Synthesize::DoSample
-
-
-
-
-static frame_t *AllocFrame()
-{//=========================
- // Allocate a temporary spectrum frame for the wavegen queue. Use a pool which is big
- // enough to use a round-robin without checks.
- // Only needed for modifying spectra for blending to consonants
-
-#define N_FRAME_POOL N_WCMDQ
- static int ix=0;
- static frame_t frame_pool[N_FRAME_POOL];
-
- ix++;
- if(ix >= N_FRAME_POOL)
- ix = 0;
- return(&frame_pool[ix]);
-}
-
-
-static void set_frame_rms(frame_t *fr, int new_rms)
-{//=================================================
-// Each frame includes its RMS amplitude value, so to set a new
-// RMS just adjust the formant amplitudes by the appropriate ratio
-
- int x;
- int h;
- int ix;
-
- static const short sqrt_tab[200] = {
- 0, 64, 90,110,128,143,156,169,181,192,202,212,221,230,239,247,
- 256,263,271,278,286,293,300,306,313,320,326,332,338,344,350,356,
- 362,367,373,378,384,389,394,399,404,409,414,419,424,429,434,438,
- 443,448,452,457,461,465,470,474,478,483,487,491,495,499,503,507,
- 512,515,519,523,527,531,535,539,543,546,550,554,557,561,565,568,
- 572,576,579,583,586,590,593,596,600,603,607,610,613,617,620,623,
- 627,630,633,636,640,643,646,649,652,655,658,662,665,668,671,674,
- 677,680,683,686,689,692,695,698,701,704,706,709,712,715,718,721,
- 724,726,729,732,735,738,740,743,746,749,751,754,757,759,762,765,
- 768,770,773,775,778,781,783,786,789,791,794,796,799,801,804,807,
- 809,812,814,817,819,822,824,827,829,832,834,836,839,841,844,846,
- 849,851,853,856,858,861,863,865,868,870,872,875,877,879,882,884,
- 886,889,891,893,896,898,900,902};
-
- if(voice->klattv[0])
- {
- if(new_rms == -1)
- {
- fr->klattp[KLATT_AV] = 50;
- }
- return;
- }
-
- if(fr->rms == 0) return; // check for divide by zero
- x = (new_rms * 64)/fr->rms;
- if(x >= 200) x = 199;
-
- x = sqrt_tab[x]; // sqrt(new_rms/fr->rms)*0x200;
-
- for(ix=0; ix < 8; ix++)
- {
- h = fr->fheight[ix] * x;
- fr->fheight[ix] = h/0x200;
- }
-} /* end of set_frame_rms */
-
-
-
-static void formants_reduce_hf(frame_t *fr, int level)
-{//====================================================
-// change height of peaks 2 to 8, percentage
- int ix;
- int x;
-
- if(voice->klattv[0])
- return;
-
- for(ix=2; ix < 8; ix++)
- {
- x = fr->fheight[ix] * level;
- fr->fheight[ix] = x/100;
- }
-}
-
-
-static frame_t *CopyFrame(frame_t *frame1, int copy)
-{//=================================================
-// create a copy of the specified frame in temporary buffer
- frame_t *frame2;
-
- if((copy==0) && (frame1->frflags & FRFLAG_COPIED))
- {
- // this frame has already been copied in temporary rw memory
- return(frame1);
- }
-
- frame2 = AllocFrame();
- if(frame2 != NULL)
- {
- memcpy(frame2,frame1,sizeof(frame_t));
- frame2->length = 0;
- frame2->frflags |= FRFLAG_COPIED;
- }
- return(frame2);
-}
-
-
-static frame_t *DuplicateLastFrame(frameref_t *seq, int n_frames, int length)
-{//==========================================================================
- frame_t *fr;
-
- seq[n_frames-1].length = length;
- fr = CopyFrame(seq[n_frames-1].frame,1);
- seq[n_frames].frame = fr;
- seq[n_frames].length = 0;
- return fr;
-}
-
-
-static void AdjustFormants(frame_t *fr, int target, int min, int max, int f1_adj, int f3_adj, int hf_reduce, int flags)
-{//====================================================================================================================
- int x;
-
-//hf_reduce = 70; // ?? using fixed amount rather than the parameter??
-
- target = (target * voice->formant_factor)/256;
-
- x = (target - fr->ffreq[2]) / 2;
- if(x > max) x = max;
- if(x < min) x = min;
- fr->ffreq[2] += x;
- fr->ffreq[3] += f3_adj;
-
- if(flags & 0x20)
- {
- f3_adj = -f3_adj; //. reverse direction for f4,f5 change
- }
- fr->ffreq[4] += f3_adj;
- fr->ffreq[5] += f3_adj;
-
- if(f1_adj==1)
- {
- x = (235 - fr->ffreq[1]);
- if(x < -100) x = -100;
- if(x > -60) x = -60;
- fr->ffreq[1] += x;
- }
- if(f1_adj==2)
- {
- x = (235 - fr->ffreq[1]);
- if(x < -300) x = -300;
- if(x > -150) x = -150;
- fr->ffreq[1] += x;
- fr->ffreq[0] += x;
- }
- if(f1_adj==3)
- {
- x = (100 - fr->ffreq[1]);
- if(x < -400) x = -400;
- if(x > -300) x = -400;
- fr->ffreq[1] += x;
- fr->ffreq[0] += x;
- }
- formants_reduce_hf(fr,hf_reduce);
-}
-
-
-static int VowelCloseness(frame_t *fr)
-{//===================================
-// return a value 0-3 depending on the vowel's f1
- int f1;
-
- if((f1 = fr->ffreq[1]) < 300)
- return(3);
- if(f1 < 400)
- return(2);
- if(f1 < 500)
- return(1);
- return(0);
-}
-
-
-int FormantTransition2(frameref_t *seq, int *n_frames, unsigned int data1, unsigned int data2, PHONEME_TAB *other_ph, int which)
-{//==============================================================================================================================
- int ix;
- int formant;
- int next_rms;
-
- int len;
- int rms;
- int f1;
- int f2;
- int f2_min;
- int f2_max;
- int f3_adj;
- int f3_amp;
- int flags;
- int vcolour;
-
-#define N_VCOLOUR 2
-// percentage change for each formant in 256ths
-static short vcolouring[N_VCOLOUR][5] = {
- {243,272,256,256,256}, // palatal consonant follows
- {256,256,240,240,240}, // retroflex
-};
-
- frame_t *fr = NULL;
-
- if(*n_frames < 2)
- return(0);
-
- len = (data1 & 0x3f) * 2;
- rms = (data1 >> 6) & 0x3f;
- flags = (data1 >> 12);
-
- f2 = (data2 & 0x3f) * 50;
- f2_min = (((data2 >> 6) & 0x1f) - 15) * 50;
- f2_max = (((data2 >> 11) & 0x1f) - 15) * 50;
- f3_adj = (((data2 >> 16) & 0x1f) - 15) * 50;
- f3_amp = ((data2 >> 21) & 0x1f) * 8;
- f1 = ((data2 >> 26) & 0x7);
- vcolour = (data2 >> 29);
-
-// fprintf(stderr,"FMT%d %3s %3d-%3d f1=%d f2=%4d %4d %4d f3=%4d %3d\n",
-// which,WordToString(other_ph->mnemonic),len,rms,f1,f2,f2_min,f2_max,f3_adj,f3_amp);
-
- if(other_ph->mnemonic == '?')
- flags |= 8;
-
- if(which == 1)
- {
- /* entry to vowel */
- fr = CopyFrame(seq[0].frame,0);
- seq[0].frame = fr;
- seq[0].length = VOWEL_FRONT_LENGTH;
- if(len > 0)
- seq[0].length = len;
- seq[0].frflags |= FRFLAG_LEN_MOD; // reduce length modification
- fr->frflags |= FRFLAG_LEN_MOD;
-
- next_rms = seq[1].frame->rms;
-
-if(voice->klattv[0])
-{
- fr->klattp[KLATT_AV] = 53; // reduce the amplituide of the start of a vowel
-}
- if(f2 != 0)
- {
- if(rms & 0x20)
- {
- set_frame_rms(fr,(next_rms * (rms & 0x1f))/30);
- }
- AdjustFormants(fr, f2, f2_min, f2_max, f1, f3_adj, f3_amp, flags);
-
- if((rms & 0x20) == 0)
- {
- set_frame_rms(fr,rms*2);
- }
- }
- else
- {
- if(flags & 8)
- set_frame_rms(fr,(next_rms*24)/32);
- else
- set_frame_rms(fr,RMS_START);
- }
-
- if(flags & 8)
- {
-// set_frame_rms(fr,next_rms - 5);
- modn_flags = 0x800 + (VowelCloseness(fr) << 8);
- }
- }
- else
- {
- // exit from vowel
- rms = rms*2;
- if((f2 != 0) || (flags != 0))
- {
-
- if(flags & 8)
- {
- fr = CopyFrame(seq[*n_frames-1].frame,0);
- seq[*n_frames-1].frame = fr;
- rms = RMS_GLOTTAL1;
-
- // degree of glottal-stop effect depends on closeness of vowel (indicated by f1 freq)
- modn_flags = 0x400 + (VowelCloseness(fr) << 8);
- }
- else
- {
- fr = DuplicateLastFrame(seq,(*n_frames)++,len);
- if(len > 36)
- seq_len_adjust += (len - 36);
-
- if(f2 != 0)
- {
- AdjustFormants(fr, f2, f2_min, f2_max, f1, f3_adj, f3_amp, flags);
- }
- }
-
- set_frame_rms(fr,rms);
-
- if((vcolour > 0) && (vcolour <= N_VCOLOUR))
- {
- for(ix=0; ix<*n_frames; ix++)
- {
- fr = CopyFrame(seq[ix].frame,0);
- seq[ix].frame = fr;
-
- for(formant=1; formant<=5; formant++)
- {
- int x;
- x = fr->ffreq[formant] * vcolouring[vcolour-1][formant-1];
- fr->ffreq[formant] = x / 256;
- }
- }
- }
- }
- }
-
- if(fr != NULL)
- {
- if(flags & 4)
- fr->frflags |= FRFLAG_FORMANT_RATE;
- if(flags & 2)
- fr->frflags |= FRFLAG_BREAK; // don't merge with next frame
- }
-
- if(flags & 0x40)
- DoPause(12,0); // add a short pause after the consonant
-
- if(flags & 16)
- return(len);
- return(0);
-} // end of FormantTransition2
-
-
-
-static void SmoothSpect(void)
-{//==========================
- // Limit the rate of frequence change of formants, to reduce chirping
-
- long *q;
- frame_t *frame;
- frame_t *frame2;
- frame_t *frame1;
- frame_t *frame_centre;
- int ix;
- int len;
- int pk;
- int modified;
- int allowed;
- int diff;
-
- if(syllable_start == syllable_end)
- return;
-
- if((syllable_centre < 0) || (syllable_centre == syllable_start))
- {
- syllable_start = syllable_end;
- return;
- }
-
- q = wcmdq[syllable_centre];
- frame_centre = (frame_t *)q[2];
-
- // backwards
- ix = syllable_centre -1;
- frame = frame2 = frame_centre;
- for(;;)
- {
- if(ix < 0) ix = N_WCMDQ-1;
- q = wcmdq[ix];
-
- if(q[0] == WCMD_PAUSE || q[0] == WCMD_WAVE)
- break;
-
- if(q[0] <= WCMD_SPECT2)
- {
- len = q[1] & 0xffff;
-
- frame1 = (frame_t *)q[3];
- if(frame1 == frame)
- {
- q[3] = (long)frame2;
- frame1 = frame2;
- }
- else
- break; // doesn't follow on from previous frame
-
- frame = frame2 = (frame_t *)q[2];
- modified = 0;
-
- if(frame->frflags & FRFLAG_BREAK)
- break;
-
- if(frame->frflags & FRFLAG_FORMANT_RATE)
- len = (len * 12)/10; // allow slightly greater rate of change for this frame (was 12/10)
-
- for(pk=0; pk<6; pk++)
- {
- int f1, f2;
-
- if((frame->frflags & FRFLAG_BREAK_LF) && (pk < 3))
- continue;
-
- f1 = frame1->ffreq[pk];
- f2 = frame->ffreq[pk];
-
- // backwards
- if((diff = f2 - f1) > 0)
- {
- allowed = f1*2 + f2;
- }
- else
- {
- allowed = f1 + f2*2;
- }
-
- // the allowed change is specified as percentage (%*10) of the frequency
- // take "frequency" as 1/3 from the lower freq
- allowed = (allowed * formant_rate[pk])/3000;
- allowed = (allowed * len)/256;
-
- if(diff > allowed)
- {
- if(modified == 0)
- {
- frame2 = CopyFrame(frame,0);
- modified = 1;
- }
- frame2->ffreq[pk] = frame1->ffreq[pk] + allowed;
- q[2] = (long)frame2;
- }
- else
- if(diff < -allowed)
- {
- if(modified == 0)
- {
- frame2 = CopyFrame(frame,0);
- modified = 1;
- }
- frame2->ffreq[pk] = frame1->ffreq[pk] - allowed;
- q[2] = (long)frame2;
- }
- }
- }
-
- if(ix == syllable_start)
- break;
- ix--;
- }
-
- // forwards
- ix = syllable_centre;
-
- frame = NULL;
- for(;;)
- {
- q = wcmdq[ix];
-
- if(q[0] == WCMD_PAUSE || q[0] == WCMD_WAVE)
- break;
-
- if(q[0] <= WCMD_SPECT2)
- {
-
- len = q[1] & 0xffff;
-
- frame1 = (frame_t *)q[2];
- if(frame != NULL)
- {
- if(frame1 == frame)
- {
- q[2] = (long)frame2;
- frame1 = frame2;
- }
- else
- break; // doesn't follow on from previous frame
- }
-
- frame = frame2 = (frame_t *)q[3];
- modified = 0;
-
- if(frame1->frflags & FRFLAG_BREAK)
- break;
-
- if(frame1->frflags & FRFLAG_FORMANT_RATE)
- len = (len *6)/5; // allow slightly greater rate of change for this frame
-
- for(pk=0; pk<6; pk++)
- {
- int f1, f2;
- f1 = frame1->ffreq[pk];
- f2 = frame->ffreq[pk];
-
- // forwards
- if((diff = f2 - f1) > 0)
- {
- allowed = f1*2 + f2;
- }
- else
- {
- allowed = f1 + f2*2;
- }
- allowed = (allowed * formant_rate[pk])/3000;
- allowed = (allowed * len)/256;
-
- if(diff > allowed)
- {
- if(modified == 0)
- {
- frame2 = CopyFrame(frame,0);
- modified = 1;
- }
- frame2->ffreq[pk] = frame1->ffreq[pk] + allowed;
- q[3] = (long)frame2;
- }
- else
- if(diff < -allowed)
- {
- if(modified == 0)
- {
- frame2 = CopyFrame(frame,0);
- modified = 1;
- }
- frame2->ffreq[pk] = frame1->ffreq[pk] - allowed;
- q[3] = (long)frame2;
- }
- }
- }
-
- ix++;
- if(ix >= N_WCMDQ) ix = 0;
- if(ix == syllable_end)
- break;
- }
-
- syllable_start = syllable_end;
-} // end of SmoothSpect
-
-
-static void StartSyllable(void)
-{//============================
- // start of syllable, if not already started
- if(syllable_end == syllable_start)
- syllable_end = wcmdq_tail;
-}
-
-
-int DoSpect(PHONEME_TAB *this_ph, PHONEME_TAB *prev_ph, PHONEME_TAB *next_ph,
- int which, PHONEME_LIST *plist, int modulation)
-{//===================================================================================
- // which 1 start of phoneme, 2 body and end
- // length_mod: 256 = 100%
- // modulation: -1 = don't write to wcmdq
-
- int n_frames;
- frameref_t *frames;
- int frameix;
- frame_t *frame1;
- frame_t *frame2;
- frame_t *fr;
- int ix;
- long *q;
- int len;
- int match_level;
- int frame_length;
- int frame1_length;
- int frame2_length;
- int length_factor;
- int length_mod;
- int total_len = 0;
- static int wave_flag = 0;
- int wcmd_spect = WCMD_SPECT;
-
- length_mod = plist->length;
- if(length_mod==0) length_mod=256;
-
-if(which==1)
-{
- // limit the shortening of sonorants before shortened (eg. unstressed vowels)
- if((this_ph->type==phLIQUID) || (prev_ph->type==phLIQUID) || (prev_ph->type==phNASAL))
- {
- if(length_mod < (len = translator->langopts.param[LOPT_SONORANT_MIN]))
- {
- length_mod = len;
- }
- }
-}
-
- modn_flags = 0;
- frames = LookupSpect(this_ph,prev_ph,next_ph,which,&match_level,&n_frames, plist);
- if(frames == NULL)
- return(0); // not found
-
- frame1 = frames[0].frame;
- frame1_length = frames[0].length;
- if(voice->klattv[0])
- wcmd_spect = WCMD_KLATT;
-
- if(wavefile_ix == 0)
- {
- if(wave_flag)
- {
- // cancel any wavefile that was playing previously
- wcmd_spect = WCMD_SPECT2;
- if(voice->klattv[0])
- wcmd_spect = WCMD_KLATT2;
- wave_flag = 0;
- }
- else
- {
- wcmd_spect = WCMD_SPECT;
- if(voice->klattv[0])
- wcmd_spect = WCMD_KLATT;
- }
- }
-
- if(last_frame != NULL)
- {
- if(((last_frame->length < 2) || (last_frame->frflags & FRFLAG_VOWEL_CENTRE))
- && !(last_frame->frflags & FRFLAG_BREAK))
- {
- // last frame of previous sequence was zero-length, replace with first of this sequence
- wcmdq[last_wcmdq][3] = (long)frame1;
-
- if(last_frame->frflags & FRFLAG_BREAK_LF)
- {
- // but flag indicates keep HF peaks in last segment
- fr = CopyFrame(frame1,1);
- for(ix=3; ix < 8; ix++)
- {
- if(ix < 7)
- fr->ffreq[ix] = last_frame->ffreq[ix];
- fr->fheight[ix] = last_frame->fheight[ix];
- }
- wcmdq[last_wcmdq][3] = (long)fr;
- }
- }
- }
-
- if((this_ph->type == phVOWEL) && (which == 2))
- {
- SmoothSpect(); // process previous syllable
-
- // remember the point in the output queue of the centre of the vowel
- syllable_centre = wcmdq_tail;
- }
-
- frame_length = frame1_length;
- for(frameix=1; frameix<n_frames; frameix++)
- {
- frame2 = frames[frameix].frame;
- frame2_length = frames[frameix].length;
-
- if((wavefile_ix != 0) && ((frame1->frflags & FRFLAG_DEFER_WAV)==0))
- {
- // there is a wave file to play along with this synthesis
- seq_len_adjust = 0;
- DoSample2(wavefile_ix,which+0x100,0,wavefile_amp);
- wave_flag = 1;
- wavefile_ix = 0;
- }
-
- length_factor = length_mod;
- if(frame1->frflags & FRFLAG_LEN_MOD) // reduce effect of length mod
- {
- length_factor = (length_mod*(256-speed.speed_factor3) + 256*speed.speed_factor3)/256;
- }
- len = (frame_length * samplerate)/1000;
- len = (len * length_factor)/256;
-
- if(modulation >= 0)
- {
- if(frame1->frflags & FRFLAG_MODULATE)
- {
- modulation = 6;
- }
- if((frameix == n_frames-1) && (modn_flags & 0xf00))
- modulation |= modn_flags; // before or after a glottal stop
- }
-
- pitch_length += len;
- amp_length += len;
-
- if(frame_length < 2)
- {
- last_frame = NULL;
- frame_length = frame2_length;
- frame1 = frame2;
- }
- else
- {
- last_wcmdq = wcmdq_tail;
-
- if(modulation >= 0)
- {
- q = wcmdq[wcmdq_tail];
- q[0] = wcmd_spect;
- q[1] = len + (modulation << 16);
- q[2] = long(frame1);
- q[3] = long(frame2);
-
- WcmdqInc();
- }
- last_frame = frame1 = frame2;
- frame_length = frame2_length;
- total_len += len;
- }
- }
- return(total_len);
-} // end of Synthesize::DoSpect
-
-
-static void DoMarker(int type, int char_posn, int length, int value)
-{//=================================================================
-// This could be used to return an index to the word currently being spoken
-// Type 1=word, 2=sentence, 3=named marker, 4=play audio, 5=end
- wcmdq[wcmdq_tail][0] = WCMD_MARKER;
- wcmdq[wcmdq_tail][1] = type;
- wcmdq[wcmdq_tail][2] = (char_posn & 0xffffff) | (length << 24);
- wcmdq[wcmdq_tail][3] = value;
- WcmdqInc();
-
-} // end of Synthesize::DoMarker
-
-
-void DoVoiceChange(voice_t *v)
-{//===========================
-// allocate memory for a copy of the voice data, and free it in wavegenfill()
- voice_t *v2;
-
- v2 = (voice_t *)malloc(sizeof(voice_t));
- memcpy(v2,v,sizeof(voice_t));
- wcmdq[wcmdq_tail][0] = WCMD_VOICE;
- wcmdq[wcmdq_tail][1] = (long)(v2);
- WcmdqInc();
-}
-
-
-static void DoEmbedded(int *embix, int sourceix)
-{//=============================================
- // There were embedded commands in the text at this point
- unsigned int word; // bit 7=last command for this word, bits 5,6 sign, bits 0-4 command
- unsigned int value;
- int command;
-
- do {
- word = embedded_list[(*embix)++];
- value = word >> 8;
- command = word & 0x7f;
-
- switch(command & 0x1f)
- {
- case EMBED_S: // speed
- SetEmbedded((command & 0x60) + EMBED_S2,value); // adjusts embedded_value[EMBED_S2]
- SetSpeed(2);
- break;
-
- case EMBED_I: // play dynamically loaded wav data (sound icon)
- if((int)value < n_soundicon_tab)
- {
- if(soundicon_tab[value].length != 0)
- {
- DoPause(10,0); // ensure a break in the speech
- wcmdq[wcmdq_tail][0] = WCMD_WAVE;
- wcmdq[wcmdq_tail][1] = soundicon_tab[value].length;
- wcmdq[wcmdq_tail][2] = (long)soundicon_tab[value].data + 44; // skip WAV header
- wcmdq[wcmdq_tail][3] = 0x1500; // 16 bit data, amp=21
- WcmdqInc();
- }
- }
- break;
-
- case EMBED_M: // named marker
- DoMarker(espeakEVENT_MARK, (sourceix & 0x7ff) + clause_start_char, 0, value);
- break;
-
- case EMBED_U: // play sound
- DoMarker(espeakEVENT_PLAY, count_characters+1, 0, value); // always occurs at end of clause
- break;
-
- default:
- DoPause(10,0); // ensure a break in the speech
- wcmdq[wcmdq_tail][0] = WCMD_EMBEDDED;
- wcmdq[wcmdq_tail][1] = command;
- wcmdq[wcmdq_tail][2] = value;
- WcmdqInc();
- break;
- }
- } while ((word & 0x80) == 0);
-}
-
-
-
-int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
-{//============================================================
- static int ix;
- static int embedded_ix;
- static int word_count;
- PHONEME_LIST *prev;
- PHONEME_LIST *next;
- PHONEME_LIST *next2;
- PHONEME_LIST *p;
- int released;
- int stress;
- int modulation;
- int pre_voiced;
- int free_min;
- unsigned char *pitch_env=NULL;
- unsigned char *amp_env;
- PHONEME_TAB *ph;
- PHONEME_TAB *prev_ph;
- static int sourceix=0;
-
-#ifdef TEST_MBROLA
- if(mbrola_name[0] != 0)
- return(MbrolaGenerate(phoneme_list,n_ph,resume));
-#endif
-
- if(option_quiet)
- return(0);
-
- if(resume == 0)
- {
- ix = 1;
- embedded_ix=0;
- word_count = 0;
- pitch_length = 0;
- amp_length = 0;
- last_frame = NULL;
- last_wcmdq = -1;
- syllable_start = wcmdq_tail;
- syllable_end = wcmdq_tail;
- syllable_centre = -1;
- last_pitch_cmd = -1;
- memset(vowel_transition,0,sizeof(vowel_transition));
- }
-
- while(ix < (*n_ph))
- {
- p = &phoneme_list[ix];
-
- if(p->type == phPAUSE)
- free_min = 5;
- else
- if(p->type != phVOWEL)
- free_min = 10; // we need less Q space for non-vowels, and we need to generate phonemes after a vowel so that the pitch_length is filled in
- else
- free_min = MIN_WCMDQ; // 22
-
- if(WcmdqFree() <= free_min)
- return(1); // wait
-
- prev = &phoneme_list[ix-1];
- next = &phoneme_list[ix+1];
- next2 = &phoneme_list[ix+2];
-
- if(p->synthflags & SFLAG_EMBEDDED)
- {
- DoEmbedded(&embedded_ix, p->sourceix);
- }
-
- if(p->newword)
- {
- if(translator->langopts.param[LOPT_WORD_MERGE] == 0)
- last_frame = NULL;
-
- sourceix = (p->sourceix & 0x7ff) + clause_start_char;
-
- if(p->newword & 4)
- DoMarker(espeakEVENT_SENTENCE, sourceix, 0, count_sentences); // start of sentence
-
-// if(p->newword & 2)
-// DoMarker(espeakEVENT_END, count_characters, 0, count_sentences); // end of clause
-
- if(p->newword & 1)
- DoMarker(espeakEVENT_WORD, sourceix, p->sourceix >> 11, clause_start_word + word_count++);
- }
-
- EndAmplitude();
-
- if(p->prepause > 0)
- DoPause(p->prepause,1);
-
- if(option_phoneme_events && (p->type != phVOWEL))
- {
- // Note, for vowels, do the phoneme event after the vowel-start
- DoMarker(espeakEVENT_PHONEME, sourceix, 0, p->ph->mnemonic);
- }
-
- switch(p->type)
- {
- case phPAUSE:
- DoPause(p->length,0);
- break;
-
- case phSTOP:
- released = 0;
- if(next->type==phVOWEL) released = 1;
- if(next->type==phLIQUID && !next->newword) released = 1;
-
- if(released)
- DoSample(p->ph,next->ph,2,0,0);
- else
- DoSample(p->ph,phoneme_tab[phonPAUSE],2,0,0);
- break;
-
- case phFRICATIVE:
- if(p->synthflags & SFLAG_LENGTHEN)
- DoSample(p->ph,next->ph,2,p->length,0); // play it twice for [s:] etc.
- DoSample(p->ph,next->ph,2,p->length,0);
- break;
-
- case phVSTOP:
- pre_voiced = 0;
- if(next->type==phVOWEL)
- {
- DoAmplitude(p->amp,NULL);
- DoPitch(envelope_data[p->env],p->pitch1,p->pitch2);
- pre_voiced = 1;
- }
- else
- if((next->type==phLIQUID) && !next->newword)
- {
- DoAmplitude(next->amp,NULL);
- DoPitch(envelope_data[next->env],next->pitch1,next->pitch2);
- pre_voiced = 1;
- }
- else
- {
- if(last_pitch_cmd < 0)
- {
- DoAmplitude(next->amp,NULL);
- DoPitch(envelope_data[p->env],p->pitch1,p->pitch2);
- }
- }
-
- if((prev->type==phVOWEL) || (prev->ph->phflags & phVOWEL2))
- {
- // a period of voicing before the release
- DoSpect(p->ph,phoneme_tab[phonSCHWA],next->ph,1,p,0);
- if(p->synthflags & SFLAG_LENGTHEN)
- {
- DoPause(20,0);
- DoSpect(p->ph,phoneme_tab[phonSCHWA],next->ph,1,p,0);
- }
- }
- else
- {
- if(p->synthflags & SFLAG_LENGTHEN)
- {
- DoPause(50,0);
- }
- }
-
- if(pre_voiced)
- {
- // followed by a vowel, or liquid + vowel
- StartSyllable();
- DoSpect(p->ph,prev->ph,next->ph,2,p,0);
- }
- else
- {
-// if((prev->type != phVOWEL) && ((prev->ph->phflags & phVOICED)==0) && ((next->ph->phflags & phVOICED)==0))
-// DoSpect(p->ph,prev->ph,phoneme_tab[phonPAUSE_SHORT],2,p,0);
-// else
- DoSpect(p->ph,prev->ph,phoneme_tab[phonPAUSE],2,p,0);
-// DoSpect(p->ph,prev->ph,next->ph,2,p,0);
- }
- break;
-
- case phVFRICATIVE:
- if(next->type==phVOWEL)
- {
- DoAmplitude(p->amp,NULL);
- DoPitch(envelope_data[p->env],p->pitch1,p->pitch2);
- }
- else
- if(next->type==phLIQUID)
- {
- DoAmplitude(next->amp,NULL);
- DoPitch(envelope_data[next->env],next->pitch1,next->pitch2);
- }
- else
- {
- if(last_pitch_cmd < 0)
- {
- DoAmplitude(p->amp,NULL);
- DoPitch(envelope_data[p->env],p->pitch1,p->pitch2);
- }
- }
-
- if((next->type==phVOWEL) || ((next->type==phLIQUID)) && (next->newword==0)) // ?? test 14.Aug.2007
- {
- StartSyllable();
- if(p->synthflags & SFLAG_LENGTHEN)
- DoSpect(p->ph,prev->ph,next->ph,2,p,0);
- DoSpect(p->ph,prev->ph,next->ph,2,p,0);
- }
- else
- {
- if(p->synthflags & SFLAG_LENGTHEN)
- DoSpect(p->ph,prev->ph,phoneme_tab[phonPAUSE],2,p,0);
- DoSpect(p->ph,prev->ph,phoneme_tab[phonPAUSE],2,p,0);
- }
- break;
-
- case phNASAL:
- if(!(p->synthflags & SFLAG_SEQCONTINUE))
- {
- DoAmplitude(p->amp,NULL);
- DoPitch(envelope_data[p->env],p->pitch1,p->pitch2);
- }
-
- if(prev->type==phNASAL)
- {
- last_frame = NULL;
- }
-
- if(next->type==phVOWEL)
- {
- StartSyllable();
- DoSpect(p->ph,prev->ph,next->ph,1,p,0);
- }
- else
- if(prev->type==phVOWEL && (p->synthflags & SFLAG_SEQCONTINUE))
- {
- DoSpect(p->ph,prev->ph,phoneme_tab[phonPAUSE],2,p,0);
- }
- else
- {
- last_frame = NULL; // only for nasal ?
- if(next->type == phLIQUID)
- DoSpect(p->ph,prev->ph,phoneme_tab[phonSONORANT],2,p,0);
- else
- DoSpect(p->ph,prev->ph,phoneme_tab[phonPAUSE],2,p,0);
- last_frame = NULL;
- }
-
- break;
-
- case phLIQUID:
- modulation = 0;
- if(p->ph->phflags & phTRILL)
- modulation = 5;
-
- prev_ph = prev->ph;
-// if(p->newword)
-// prev_ph = phoneme_tab[phonPAUSE]; // pronounce fully at the start of a word
-
- if(!(p->synthflags & SFLAG_SEQCONTINUE))
- {
- DoAmplitude(p->amp,NULL);
- DoPitch(envelope_data[p->env],p->pitch1,p->pitch2);
- }
-
- if(prev->type==phNASAL)
- {
- last_frame = NULL;
- }
-
- if(next->type==phVOWEL)
- {
- StartSyllable();
- DoSpect(p->ph,prev_ph,next->ph,1,p,modulation); // (,)r
- }
- else
- if(prev->type==phVOWEL && (p->synthflags & SFLAG_SEQCONTINUE))
- {
- DoSpect(p->ph,prev_ph,next->ph,1,p,modulation);
- }
- else
- {
- DoSpect(p->ph,prev_ph,next->ph,1,p,modulation);
- }
-
- break;
-
- case phVOWEL:
- ph = p->ph;
- stress = p->stresslevel & 0xf;
-
- // vowel transition from the preceding phoneme
- vowel_transition0 = vowel_transition[0];
- vowel_transition1 = vowel_transition[1];
-
- pitch_env = envelope_data[p->env];
- amp_env = NULL;
- if(p->tone_ph != 0)
- {
- pitch_env = LookupEnvelope(phoneme_tab[p->tone_ph]->spect);
- amp_env = LookupEnvelope(phoneme_tab[p->tone_ph]->after);
- }
-
- StartSyllable();
-
- modulation = 2;
- if(stress <= 1)
- modulation = 1; // 16ths
- else
- if(stress >= 7)
- modulation = 3;
-
- if(prev->type == phVSTOP || prev->type == phVFRICATIVE)
- {
- DoAmplitude(p->amp,amp_env);
- DoPitch(pitch_env,p->pitch1,p->pitch2); // don't use prevocalic rising tone
- DoSpect(ph,prev->ph,next->ph,1,p,modulation);
- }
- else
- if(prev->type==phLIQUID || prev->type==phNASAL)
- {
- DoAmplitude(p->amp,amp_env);
- DoSpect(ph,prev->ph,next->ph,1,p,modulation); // continue with pre-vocalic rising tone
- DoPitch(pitch_env,p->pitch1,p->pitch2);
- }
- else
- {
- if(!(p->synthflags & SFLAG_SEQCONTINUE))
- {
- DoAmplitude(p->amp,amp_env);
- DoPitch(pitch_env,p->pitch1,p->pitch2);
- }
-
- DoSpect(ph,prev->ph,next->ph,1,p,modulation);
- }
-
- if(option_phoneme_events)
- {
- DoMarker(espeakEVENT_PHONEME, sourceix, 0, p->ph->mnemonic);
- }
-
- DoSpect(p->ph,prev->ph,next->ph,2,p,modulation);
-
- memset(vowel_transition,0,sizeof(vowel_transition));
- break;
- }
- ix++;
- }
- EndPitch(1);
- if(*n_ph > 0)
- {
- DoMarker(espeakEVENT_END, count_characters, 0, count_sentences); // end of clause
- *n_ph = 0;
- }
-
- return(0); // finished the phoneme list
-} // end of Generate
-
-
-
-
-static int timer_on = 0;
-static int paused = 0;
-
-int SynthOnTimer()
-{//===============
- if(!timer_on)
- {
- return(WavegenCloseSound());
- }
-
- do {
- if(WcmdqUsed() > 0)
- WavegenOpenSound();
-
- if(Generate(phoneme_list,&n_phoneme_list,1)==0)
- {
- SpeakNextClause(NULL,NULL,1);
- }
- } while(skipping_text);
-
- return(0);
-}
-
-
-int SynthStatus()
-{//==============
- return(timer_on | paused);
-}
-
-
-
-int SpeakNextClause(FILE *f_in, const void *text_in, int control)
-{//==============================================================
-// Speak text from file (f_in) or memory (text_in)
-// control 0: start
-// either f_in or text_in is set, the other must be NULL
-
-// The other calls have f_in and text_in = NULL
-// control 1: speak next text
-// 2: stop
-// 3: pause (toggle)
-// 4: is file being read (0=no, 1=yes)
-// 5: interrupt and flush current text.
-
- int clause_tone;
- char *voice_change;
- static FILE *f_text=NULL;
- static const void *p_text=NULL;
-
- if(control == 4)
- {
- if((f_text == NULL) && (p_text == NULL))
- return(0);
- else
- return(1);
- }
-
- if(control == 2)
- {
- // stop speaking
- timer_on = 0;
- p_text = NULL;
- if(f_text != NULL)
- {
- fclose(f_text);
- f_text=NULL;
- }
- n_phoneme_list = 0;
- WcmdqStop();
-
- embedded_value[EMBED_T] = 0;
- return(0);
- }
-
- if(control == 3)
- {
- // toggle pause
- if(paused == 0)
- {
- timer_on = 0;
- paused = 2;
- }
- else
- {
- WavegenOpenSound();
- timer_on = 1;
- paused = 0;
- Generate(phoneme_list,&n_phoneme_list,0); // re-start from beginning of clause
- }
- return(0);
- }
-
- if(control == 5)
- {
- // stop speaking, but continue looking for text
- n_phoneme_list = 0;
- WcmdqStop();
- return(0);
- }
-
- if((f_in != NULL) || (text_in != NULL))
- {
- f_text = f_in;
- p_text = text_in;
- timer_on = 1;
- paused = 0;
- }
-
- if((f_text==NULL) && (p_text==NULL))
- {
- skipping_text = 0;
- timer_on = 0;
- return(0);
- }
-
- if((f_text != NULL) && feof(f_text))
- {
- timer_on = 0;
- fclose(f_text);
- f_text=NULL;
- return(0);
- }
-
- if(current_phoneme_table != voice->phoneme_tab_ix)
- {
- SelectPhonemeTable(voice->phoneme_tab_ix);
- }
-
- // read the next clause from the input text file, translate it, and generate
- // entries in the wavegen command queue
- p_text = TranslateClause(translator, f_text, p_text, &clause_tone, &voice_change);
-
- CalcPitches(translator, clause_tone);
- CalcLengths(translator);
-
- GetTranslatedPhonemeString(translator->phon_out,sizeof(translator->phon_out));
- if(option_phonemes > 0)
- {
- fprintf(f_trans,"%s\n",translator->phon_out);
-
- if(!iswalpha(0x010d))
- {
- // check that c-caron is recognized as an alphabetic character
- fprintf(stderr,"Warning: Accented letters are not recognized, eg: U+010D\nSet LC_CTYPE to a UTF-8 locale\n");
- }
- }
- if(phoneme_callback != NULL)
- {
- phoneme_callback(translator->phon_out);
- }
-
-
- if(skipping_text)
- {
- n_phoneme_list = 0;
- return(1);
- }
-
- if(mbrola_name[0] != 0)
- {
-#ifdef USE_MBROLA_LIB
- MbrolaTranslate(phoneme_list,n_phoneme_list,NULL);
-#else
- {
- FILE *f_mbrola;
- if((f_mbrola = f_trans) == stderr)
- f_mbrola = stdout;
- MbrolaTranslate(phoneme_list,n_phoneme_list,f_mbrola);
- }
-#endif
- }
-
- Generate(phoneme_list,&n_phoneme_list,0);
- WavegenOpenSound();
-
- if(voice_change != NULL)
- {
- // voice change at the end of the clause (i.e. clause was terminated by a voice change)
- new_voice = LoadVoiceVariant(voice_change,0); // add a Voice instruction to wavegen at the end of the clause
- }
-
- if(new_voice)
- {
- // finished the current clause, now change the voice if there was an embedded
- // change voice command at the end of it (i.e. clause was broken at the change voice command)
- DoVoiceChange(voice);
- new_voice = NULL;
- }
-
- return(1);
-} // end of SpeakNextClause
-
diff --git a/navit/support/espeak/synthesize.h b/navit/support/espeak/synthesize.h
deleted file mode 100755
index 193b93297..000000000
--- a/navit/support/espeak/synthesize.h
+++ /dev/null
@@ -1,377 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2005 to 2007 by Jonathan Duddington *
- * email: jonsd@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write see: *
- * <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-
-#define N_PHONEME_LIST 1000 // enough for source[N_TR_SOURCE] full of text, else it will truncate
-
-#define MAX_HARMONIC 400 // 400 * 50Hz = 20 kHz, more than enough
-#define N_SEQ_FRAMES 25 // max frames in a spectrum sequence (real max is ablut 8)
-#define STEPSIZE 64 // 2.9mS at 22 kHz sample rate
-
-#define PITCHfall 0
-#define PITCHrise 1
-
-// flags set for frames within a spectrum sequence
-#define FRFLAG_KLATT 0x01 // this frame includes extra data for Klatt synthesizer
-#define FRFLAG_VOWEL_CENTRE 0x02 // centre point of vowel
-#define FRFLAG_LEN_MOD 0x04 // reduce effect of length adjustment
-#define FRFLAG_BREAK_LF 0x08 // but keep f3 upwards
-#define FRFLAG_BREAK 0x10 // don't merge with next frame
-#define FRFLAG_BREAK_2 0x18 // FRFLAG_BREAK_LF or FRFLAG_BREAK
-#define FRFLAG_FORMANT_RATE 0x20 // Flag5 allow increased rate of change of formant freq
-#define FRFLAG_MODULATE 0x40 // Flag6 modulate amplitude of some cycles to give trill
-#define FRFLAG_DEFER_WAV 0x80 // Flag7 defer mixing WAV until the next frame
-#define FRFLAG_COPIED 0x8000 // This frame has been copied into temporary rw memory
-
-#define SFLAG_SEQCONTINUE 0x01 // a liquid or nasal after a vowel, but not followed by a vowel
-#define SFLAG_EMBEDDED 0x02 // there are embedded commands before this phoneme
-#define SFLAG_SYLLABLE 0x04 // vowel or syllabic consonant
-#define SFLAG_LENGTHEN 0x08 // lengthen symbol : included after this phoneme
-#define SFLAG_DICTIONARY 0x10 // the pronunciation of this word was listed in the xx_list dictionary
-#define SFLAG_SWITCHED_LANG 0x20 // this word uses phonemes from a different language
-#define SFLAG_PROMOTE_STRESS 0x40 // this unstressed word can be promoted to stressed
-
-// embedded command numbers
-#define EMBED_P 1 // pitch
-#define EMBED_S 2 // speed (used in setlengths)
-#define EMBED_A 3 // amplitude/volume
-#define EMBED_R 4 // pitch range/expression
-#define EMBED_H 5 // echo/reverberation
-#define EMBED_T 6 // different tone for announcing punctuation
-#define EMBED_I 7 // sound icon
-#define EMBED_S2 8 // speed (used in synthesize)
-#define EMBED_Y 9 // say-as commands
-#define EMBED_M 10 // mark name
-#define EMBED_U 11 // audio uri
-#define EMBED_B 12 // break
-#define EMBED_F 13 // emphasis
-
-#define N_EMBEDDED_VALUES 14
-extern int embedded_value[N_EMBEDDED_VALUES];
-extern int embedded_default[N_EMBEDDED_VALUES];
-
-
-#define N_PEAKS 9
-#define N_MARKERS 8
-
-#define N_KLATTP 10 // this affects the phoneme data file format
-#define N_KLATTP2 14 // used in vowel files, with extra parameters for future extensions
-
-#define KLATT_AV 0
-#define KLATT_FNZ 1 // nasal zero freq
-#define KLATT_Tilt 2
-#define KLATT_Aspr 3
-#define KLATT_Skew 4
-
-#define KLATT_Kopen 5
-#define KLATT_AVp 6
-#define KLATT_Fric 7
-#define KLATT_FricBP 8
-#define KLATT_Turb 9
-
-
-
-typedef struct { // 44 bytes
- short frflags;
- short ffreq[7];
- unsigned char length;
- unsigned char rms;
- unsigned char fheight[8];
- unsigned char fwidth[6]; // width/4 f0-5
- unsigned char fright[3]; // width/4 f0-2
- unsigned char bw[4]; // Klatt bandwidth BNZ /2, f1,f2,f3
- unsigned char klattp[5]; // AV, FNZ, Tilt, Aspr, Skew
- unsigned char klattp2[5]; // continuation of klattp[], Avp, Fric, FricBP, Turb
- unsigned char klatt_ap[7]; // Klatt parallel amplitude
- unsigned char klatt_bp[7]; // Klatt parallel bandwidth /2
-} frame_t; // with extra Klatt parameters for parallel resonators
-
-typedef struct { // 44 bytes
- short frflags;
- short ffreq[7];
- unsigned char length;
- unsigned char rms;
- unsigned char fheight[8];
- unsigned char fwidth[6]; // width/4 f0-5
- unsigned char fright[3]; // width/4 f0-2
- unsigned char bw[4]; // Klatt bandwidth BNZ /2, f1,f2,f3
- unsigned char klattp[5]; // AV, FNZ, Tilt, Aspr, Skew
-} frame_t2; // TESTING
-
-
-#ifdef deleted
-typedef struct {
- short frflags;
- unsigned char length;
- unsigned char rms;
- short ffreq[9];
- unsigned char fheight[9];
- unsigned char fwidth[6]; // width/4
- unsigned char fright[6]; // width/4
- unsigned char fwidth6, fright6;
- unsigned char klattp[N_KLATTP];
-} frame_t;
-
-typedef struct { // 43 bytes
- short frflags;
- unsigned char length;
- unsigned char rms;
- short ffreq[9];
- unsigned char fheight[9];
- unsigned char fwidth[6]; // width/4
- unsigned char fright[6]; // width/4
-} frame_t2; // the original, without Klatt additions, used for file "phondata"
-#endif
-
-
-
-// formant data used by wavegen
-typedef struct {
- int freq; // Hz<<16
- int height; // height<<15
- int left; // Hz<<16
- int right; // Hz<<16
- DOUBLEX freq1; // floating point versions of the above
- DOUBLEX height1;
- DOUBLEX left1;
- DOUBLEX right1;
- DOUBLEX freq_inc; // increment by this every 64 samples
- DOUBLEX height_inc;
- DOUBLEX left_inc;
- DOUBLEX right_inc;
-} wavegen_peaks_t;
-
-typedef struct {
-unsigned char *pitch_env;
-int pitch; // pitch Hz*256
-int pitch_ix; // index into pitch envelope (*256)
-int pitch_inc; // increment to pitch_ix
-int pitch_base; // Hz*256 low, before modified by envelope
-int pitch_range; // Hz*256 range of envelope
-
-unsigned char *mix_wavefile; // wave file to be added to synthesis
-int n_mix_wavefile; // length in bytes
-int mix_wave_scale; // 0=2 byte samples
-int mix_wave_amp;
-int mix_wavefile_ix;
-
-int amplitude;
-int amplitude_v;
-int prev_was_synth; // previous sound was synthesized (not a played wave or pause)
-} WGEN_DATA;
-
-
-typedef struct {
- double a;
- double b;
- double c;
- double x1;
- double x2;
-} RESONATOR;
-
-
-typedef struct {
- short length_total; // not used
- unsigned char n_frames;
- unsigned char flags;
- frame_t2 frame[N_SEQ_FRAMES]; // max. frames in a spectrum sequence
-} SPECT_SEQ; // sequence of espeak formant frames
-
-typedef struct {
- short length_total; // not used
- unsigned char n_frames;
- unsigned char flags;
- frame_t frame[N_SEQ_FRAMES]; // max. frames in a spectrum sequence
-} SPECT_SEQK; // sequence of klatt formants frames
-
-
-typedef struct {
- short length;
- short frflags;
- frame_t *frame;
-} frameref_t;
-
-
-typedef struct {
- PHONEME_TAB *ph;
- unsigned char env; // pitch envelope number
- unsigned char stresslevel;
- unsigned char type;
- unsigned char prepause;
- unsigned char amp;
- unsigned char tone_ph; // tone phoneme to use with this vowel
- unsigned char newword; // bit 0=start of word, bit 1=end of clause, bit 2=start of sentence
- unsigned char synthflags;
- short length; // length_mod
- short pitch1; // pitch, 0-4095 within the Voice's pitch range
- short pitch2;
- unsigned short sourceix; // ix into the original source text string, only set at the start of a word
-} PHONEME_LIST;
-
-
-typedef struct {
- int name;
- int length;
- char *data;
- char *filename;
-} SOUND_ICON;
-
-typedef struct {
- int name;
- unsigned int next_phoneme;
- int mbr_name;
- int mbr_name2;
- int percent; // percentage length of first component
- int control;
-} MBROLA_TAB;
-
-typedef struct {
- int speed_factor1;
- int speed_factor2;
- int speed_factor3;
- int min_sample_len;
- int fast_settings[8];
-} SPEED_FACTORS;
-
-
-// phoneme table
-extern PHONEME_TAB *phoneme_tab[N_PHONEME_TAB];
-
-// list of phonemes in a clause
-extern int n_phoneme_list;
-extern PHONEME_LIST phoneme_list[N_PHONEME_LIST];
-extern unsigned int embedded_list[];
-
-extern unsigned char env_fall[128];
-extern unsigned char env_rise[128];
-extern unsigned char env_frise[128];
-
-#define MAX_PITCH_VALUE 101
-extern unsigned char pitch_adjust_tab[MAX_PITCH_VALUE+1];
-
-// queue of commands for wavegen
-#define WCMD_KLATT 1
-#define WCMD_KLATT2 2
-#define WCMD_SPECT 3
-#define WCMD_SPECT2 4
-#define WCMD_PAUSE 5
-#define WCMD_WAVE 6
-#define WCMD_WAVE2 7
-#define WCMD_AMPLITUDE 8
-#define WCMD_PITCH 9
-#define WCMD_MARKER 10
-#define WCMD_VOICE 11
-#define WCMD_EMBEDDED 12
-
-
-#define N_WCMDQ 160
-#define MIN_WCMDQ 22 // need this many free entries before adding new phoneme
-
-extern long wcmdq[N_WCMDQ][4];
-extern int wcmdq_head;
-extern int wcmdq_tail;
-
-// from Wavegen file
-int WcmdqFree();
-void WcmdqStop();
-int WcmdqUsed();
-void WcmdqInc();
-int WavegenOpenSound();
-int WavegenCloseSound();
-int WavegenInitSound();
-void WavegenInit(int rate, int wavemult_fact);
-float polint(float xa[],float ya[],int n,float x);
-int WavegenFill(int fill_zeros);
-void MarkerEvent(int type, unsigned int char_position, int value, unsigned char *out_ptr);
-
-
-extern unsigned char *wavefile_data;
-extern int samplerate;
-extern int samplerate_native;
-
-extern int wavefile_ix;
-extern int wavefile_amp;
-extern int wavefile_ix2;
-extern int wavefile_amp2;
-extern int vowel_transition[4];
-extern int vowel_transition0, vowel_transition1;
-
-extern int mbrola_delay;
-extern char mbrola_name[20];
-
-// from synthdata file
-unsigned int LookupSound(PHONEME_TAB *ph1, PHONEME_TAB *ph2, int which, int *match_level, int control);
-frameref_t *LookupSpect(PHONEME_TAB *ph1, PHONEME_TAB *prev_ph, PHONEME_TAB *next_ph, int which, int *match_level, int *n_frames, PHONEME_LIST *plist);
-
-unsigned char *LookupEnvelope(int ix);
-int LoadPhData();
-
-void SynthesizeInit(void);
-int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume);
-void MakeWave2(PHONEME_LIST *p, int n_ph);
-int SynthOnTimer(void);
-int SpeakNextClause(FILE *f_text, const void *text_in, int control);
-int SynthStatus(void);
-void SetSpeed(int control);
-void SetEmbedded(int control, int value);
-void SelectPhonemeTable(int number);
-int SelectPhonemeTableName(const char *name);
-
-void Write4Bytes(FILE *f, int value);
-int Read4Bytes(FILE *f);
-int CompileDictionary(const char *dsource, const char *dict_name, FILE *log, char *err_name,int flags);
-
-
-extern unsigned char *envelope_data[18];
-extern int formant_rate[]; // max rate of change of each formant
-extern SPEED_FACTORS speed;
-
-extern long count_samples;
-extern int outbuf_size;
-extern unsigned char *out_ptr;
-extern unsigned char *out_start;
-extern unsigned char *out_end;
-extern int event_list_ix;
-extern espeak_EVENT *event_list;
-extern t_espeak_callback* synth_callback;
-extern int option_log_frames;
-extern const char *version_string;
-extern const int version_phdata;
-
-#define N_SOUNDICON_TAB 80 // total entries in soundicon_tab
-#define N_SOUNDICON_SLOTS 4 // number of slots reserved for dynamic loading of audio files
-extern int n_soundicon_tab;
-extern SOUND_ICON soundicon_tab[N_SOUNDICON_TAB];
-
-espeak_ERROR SetVoiceByName(const char *name);
-espeak_ERROR SetVoiceByProperties(espeak_VOICE *voice_selector);
-espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int srate);
-void SetParameter(int parameter, int value, int relative);
-void MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, FILE *f_mbrola);
-//int MbrolaSynth(char *p_mbrola);
-int DoSample(PHONEME_TAB *ph1, PHONEME_TAB *ph2, int which, int length_mod, int amp);
-int DoSpect(PHONEME_TAB *this_ph, PHONEME_TAB *prev_ph, PHONEME_TAB *next_ph,
- int which, PHONEME_LIST *plist, int modulation);
-int PauseLength(int pause, int control);
-int LookupPhonemeTable(const char *name);
-
-void InitBreath(void);
-
-void KlattInit();
-int Wavegen_Klatt2(int length, int modulation, int resume, frame_t *fr1, frame_t *fr2);
diff --git a/navit/support/espeak/tr_languages.c b/navit/support/espeak/tr_languages.c
deleted file mode 100644
index 83d1c8041..000000000
--- a/navit/support/espeak/tr_languages.c
+++ /dev/null
@@ -1,1335 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2005 to 2007 by Jonathan Duddington *
- * email: jonsd@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, see: *
- * <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-#include "StdAfx.h"
-
-#include <stdio.h>
-#include <ctype.h>
-#include <wctype.h>
-#include <stdlib.h>
-#include <string.h>
-#include <locale.h>
-
-#include <wctype.h>
-
-#include "speak_lib.h"
-#include "speech.h"
-#include "phoneme.h"
-#include "synthesize.h"
-#include "translate.h"
-
-
-
-#define L_qa 0x716100
-#define L_grc 0x677263 // grc Ancient Greek
-#define L_jbo 0x6a626f // jbo Lojban
-#define L_pap 0x706170 // pap Papiamento
-#define L_zhy 0x7a6879 // zhy
-
-// start of unicode pages for character sets
-#define OFFSET_GREEK 0x380
-#define OFFSET_CYRILLIC 0x420
-#define OFFSET_ARMENIAN 0x530
-#define OFFSET_DEVANAGARI 0x900
-#define OFFSET_BENGALI 0x980
-#define OFFSET_TAMIL 0xb80
-#define OFFSET_KANNADA 0xc80
-#define OFFSET_MALAYALAM 0xd00
-#define OFFSET_KOREAN 0x1100
-
-static void Translator_Russian(Translator *tr);
-
-static void SetLetterVowel(Translator *tr, int c)
-{//==============================================
- tr->letter_bits[c] = (tr->letter_bits[c] & 0x40) | 0x81; // keep value for group 6 (front vowels e,i,y)
-}
-
-static void ResetLetterBits(Translator *tr, int groups)
-{//====================================================
-// Clear all the specified groups
- unsigned int ix;
- unsigned int mask;
-
- mask = ~groups;
-
- for(ix=0; ix<sizeof(tr->letter_bits); ix++)
- {
- tr->letter_bits[ix] &= mask;
- }
-}
-
-static void SetLetterBits(Translator *tr, int group, const char *string)
-{//=====================================================================
- int bits;
- unsigned char c;
-
- bits = (1L << group);
- while((c = *string++) != 0)
- tr->letter_bits[c] |= bits;
-}
-
-static void SetLetterBitsRange(Translator *tr, int group, int first, int last)
-{//===========================================================================
- int bits;
- int ix;
-
- bits = (1L << group);
- for(ix=first; ix<=last; ix++)
- {
- tr->letter_bits[ix] |= bits;
- }
-}
-
-
-static Translator* NewTranslator(void)
-{//===================================
- Translator *tr;
- int ix;
- static const unsigned char stress_amps2[] = {17,17, 20,20, 20,22, 22,20 };
- static const short stress_lengths2[8] = {182,140, 220,220, 220,240, 260,280};
- static const wchar_t empty_wstring[1] = {0};
- static const wchar_t punct_in_word[2] = {'\'', 0}; // allow hyphen within words
-
- tr = (Translator *)Alloc(sizeof(Translator));
- if(tr == NULL)
- return(NULL);
-
- tr->charset_a0 = charsets[1]; // ISO-8859-1, this is for when the input is not utf8
- dictionary_name[0] = 0;
- tr->dict_condition=0;
- tr->data_dictrules = NULL; // language_1 translation rules file
- tr->data_dictlist = NULL; // language_2 dictionary lookup file
-
- tr->transpose_offset = 0;
-
- // only need lower case
- tr->letter_bits_offset = 0;
- memset(tr->letter_bits,0,sizeof(tr->letter_bits));
- memset(tr->letter_groups,0,sizeof(tr->letter_groups));
-
- // 0-5 sets of characters matched by A B C E F G in pronunciation rules
- // these may be set differently for different languages
- SetLetterBits(tr,0,"aeiou"); // A vowels, except y
- SetLetterBits(tr,1,"bcdfgjklmnpqstvxz"); // B hard consonants, excluding h,r,w
- SetLetterBits(tr,2,"bcdfghjklmnpqrstvwxz"); // C all consonants
- SetLetterBits(tr,3,"hlmnr"); // H 'soft' consonants
- SetLetterBits(tr,4,"cfhkpqstx"); // F voiceless consonants
- SetLetterBits(tr,5,"bdgjlmnrvwyz"); // G voiced
- SetLetterBits(tr,6,"eiy"); // Letter group Y, front vowels
- SetLetterBits(tr,7,"aeiouy"); // vowels, including y
-
-
- tr->char_plus_apostrophe = empty_wstring;
- tr->punct_within_word = punct_in_word;
-
- for(ix=0; ix<8; ix++)
- {
- tr->stress_amps[ix] = stress_amps2[ix];
- tr->stress_amps_r[ix] = stress_amps2[ix] - 1;
- tr->stress_lengths[ix] = stress_lengths2[ix];
- }
- memset(&(tr->langopts),0,sizeof(tr->langopts));
-
- tr->langopts.stress_rule = 2;
- tr->langopts.unstressed_wd1 = 1;
- tr->langopts.unstressed_wd2 = 3;
- tr->langopts.param[LOPT_SONORANT_MIN] = 95;
- tr->langopts.param[LOPT_MAXAMP_EOC] = 19;
- tr->langopts.param[LOPT_UNPRONOUNCABLE] = 's'; // don't count this character at start of word
- tr->langopts.max_initial_consonants = 3;
- tr->langopts.replace_chars = NULL;
- tr->langopts.ascii_language = ""; // Non-Latin alphabet languages, use this language to speak Latin words, default is English
-
- SetLengthMods(tr,201);
-// tr->langopts.length_mods = length_mods_en;
-// tr->langopts.length_mods0 = length_mods_en0;
-
- tr->langopts.long_stop = 100;
-
- tr->langopts.max_roman = 49;
- tr->langopts.thousands_sep = ',';
- tr->langopts.decimal_sep = '.';
-
- memcpy(tr->punct_to_tone, punctuation_to_tone, sizeof(tr->punct_to_tone));
-
- return(tr);
-}
-
-
-static const unsigned int replace_cyrillic_latin[] =
- {0x430,'a',
- 0x431,'b',
- 0x446,'c',
- 0x45b,0x107,
- 0x447,0x10d,
- 0x45f,'d'+(0x17e<<16),
- 0x455,'d'+('z'<<16),
- 0x434,'d',
- 0x452,0x111,
- 0x435,'e',
- 0x444,'f',
- 0x433,'g',
- 0x445,'h',
- 0x438,'i',
- 0x458,'j',
- 0x43a,'k',
- 0x459,'l'+('j'<<16),
- 0x43b,'l',
- 0x43c,'m',
- 0x45a,'n'+('j'<<16),
- 0x43d,'n',
- 0x43e,'o',
- 0x43f,'p',
- 0x440,'r',
- 0x441,'s',
- 0x448,0x161,
- 0x442,'t',
- 0x443,'u',
- 0x432,'v',
- 0x437,'z',
- 0x436,0x17e,
- 0x453,0x111,
- 0x45c,0x107,
-0}; // ѓ ѕ ќ
-
-
-void SetIndicLetters(Translator *tr)
-{//=================================
- // Set letter types for Indic scripts, Devanagari, Tamill, etc
- static const char dev_consonants2[] = {0x02,0x03,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f};
-
- memset(tr->letter_bits,0,sizeof(tr->letter_bits));
- SetLetterBitsRange(tr,LETTERGP_A,0x04,0x14); // vowel letters only
- SetLetterBitsRange(tr,LETTERGP_B,0x3e,0x4d); // vowel signs, and virama
-
- SetLetterBitsRange(tr,LETTERGP_C,0x15,0x39); // the main consonant range
- SetLetterBits(tr,LETTERGP_C,dev_consonants2); // + additional consonants
-
- SetLetterBitsRange(tr,LETTERGP_Y,0x04,0x14); // vowel letters
- SetLetterBitsRange(tr,LETTERGP_Y,0x3e,0x4c); // + vowel signs
-
- tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words
-}
-
-void SetupTranslator(Translator *tr, const short *lengths, const unsigned char *amps)
-{//==================================================================================
- if(lengths != NULL)
- memcpy(tr->stress_lengths,lengths,sizeof(tr->stress_lengths));
- if(amps != NULL)
- memcpy(tr->stress_amps,amps,sizeof(tr->stress_amps));
-}
-
-
-Translator *SelectTranslator(const char *name)
-{//===========================================
- int name2 = 0;
- Translator *tr;
-
- static const unsigned char stress_amps_sk[8] = {17,17, 20,20, 20,22, 22,21 };
- static const short stress_lengths_sk[8] = {190,190, 210,210, 0,0, 210,210};
-
- // convert name string into a word of up to 4 characters, for the switch()
- while(*name != 0)
- name2 = (name2 << 8) + *name++;
-
- tr = NewTranslator();
-
- switch(name2)
- {
- case L('a','f'):
- {
- static const short stress_lengths_af[8] = {170,140, 220,220, 0, 0, 250,270};
- SetupTranslator(tr,stress_lengths_af,NULL);
-
- tr->langopts.stress_rule = 0;
- tr->langopts.vowel_pause = 0x30;
- tr->langopts.param[LOPT_DIERESES] = 1;
- tr->langopts.param[LOPT_PREFIXES] = 1;
- SetLetterVowel(tr,'y'); // add 'y' to vowels
-
- tr->langopts.numbers = 0x8d1 + NUM_ROMAN;
- tr->langopts.accents = 1;
- }
- break;
-
- case L('b','n'): // Bengali
- {
- static const short stress_lengths_bn[8] = {180, 180, 210, 210, 0, 0, 230, 240};
- static const unsigned char stress_amps_bn[8] = {18,18, 18,18, 20,20, 22,22 };
-
- SetupTranslator(tr,stress_lengths_bn,stress_amps_bn);
- tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
-
- tr->langopts.stress_rule = 0;
- tr->langopts.stress_flags = 0x10004; // use 'diminished' for unstressed final syllable
- tr->letter_bits_offset = OFFSET_BENGALI;
- SetIndicLetters(tr); // call this after setting OFFSET_BENGALI
- SetLetterBitsRange(tr,LETTERGP_F,0x3e,0x4c); // vowel signs, but not virama
-
- tr->langopts.numbers = 0x1;
- tr->langopts.numbers2 = NUM2_100000;
- }
- break;
-
- case L('c','y'): // Welsh
- {
- static const short stress_lengths_cy[8] = {170,220, 180,180, 0, 0, 250,270};
- static const unsigned char stress_amps_cy[8] = {17,15, 18,18, 0,0, 22,20 }; // 'diminished' is used to mark a quieter, final unstressed syllable
-
- SetupTranslator(tr,stress_lengths_cy,stress_amps_cy);
-
- tr->charset_a0 = charsets[14]; // ISO-8859-14
-// tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
- tr->langopts.stress_rule = 2;
-// tr->langopts.intonation_group = 4;
-
- // 'diminished' is an unstressed final syllable
- tr->langopts.stress_flags = 0x6 | 0x10;
- tr->langopts.unstressed_wd1 = 0;
- tr->langopts.unstressed_wd2 = 2;
- tr->langopts.param[LOPT_SONORANT_MIN] = 120; // limit the shortening of sonorants before short vowels
-
- tr->langopts.numbers = 0x401;
-
- SetLetterVowel(tr,'w'); // add letter to vowels and remove from consonants
- SetLetterVowel(tr,'y');
- }
- break;
-
- case L('d','a'): // Danish
- {
- static const short stress_lengths_da[8] = {160,140, 200,200, 0,0, 220,210};
- SetupTranslator(tr,stress_lengths_da,NULL);
-
- tr->langopts.stress_rule = 0;
- SetLetterVowel(tr,'y');
- tr->langopts.numbers = 0x10c59;
- }
- break;
-
-
- case L('d','e'):
- {
- static const short stress_lengths_de[8] = {150,130, 200,200, 0, 0, 260,275};
- tr->langopts.stress_rule = 0;
- tr->langopts.word_gap = 0x8; // don't use linking phonemes
- tr->langopts.vowel_pause = 0x30;
- tr->langopts.param[LOPT_PREFIXES] = 1;
- memcpy(tr->stress_lengths,stress_lengths_de,sizeof(tr->stress_lengths));
-
- tr->langopts.numbers = 0x11419 + NUM_ROMAN;
- SetLetterVowel(tr,'y');
- }
- break;
-
- case L('e','n'):
- {
- static const short stress_lengths_en[8] = {182,140, 220,220, 0,0, 248,275};
- SetupTranslator(tr,stress_lengths_en,NULL);
-
- tr->langopts.stress_rule = 0;
- tr->langopts.numbers = 0x841 + NUM_ROMAN;
- tr->langopts.param[LOPT_COMBINE_WORDS] = 2; // allow "mc" to cmbine with the following word
- }
- break;
-
- case L('e','l'): // Greek
- case L_grc: // Ancient Greek
- {
- static const short stress_lengths_el[8] = {155, 180, 210, 210, 0, 0, 270, 300};
- static const unsigned char stress_amps_el[8] = {15,12, 20,20, 20,22, 22,21 }; // 'diminished' is used to mark a quieter, final unstressed syllable
-
- // character codes offset by 0x380
- static const char el_vowels[] = {0x10,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x35,0x37,0x39,0x3f,0x45,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0};
- static const char el_fvowels[] = {0x2d,0x2e,0x2f,0x35,0x37,0x39,0x45,0x4d,0}; // ε η ι υ έ ή ί ύ
- static const char el_voiceless[]= {0x38,0x3a,0x3e,0x40,0x42,0x43,0x44,0x46,0x47,0}; // θ κ ξ π ς σ τ φ χ
- static const char el_consonants[]={0x32,0x33,0x34,0x36,0x38,0x3a,0x3b,0x3c,0x3d,0x3e,0x40,0x41,0x42,0x43,0x44,0x46,0x47,0x48,0};
- static const wchar_t el_char_apostrophe[] = {0x3c3,0}; // σ
-
- SetupTranslator(tr,stress_lengths_el,stress_amps_el);
-
- tr->charset_a0 = charsets[7]; // ISO-8859-7
- tr->char_plus_apostrophe = el_char_apostrophe;
-
- tr->letter_bits_offset = OFFSET_GREEK;
- memset(tr->letter_bits,0,sizeof(tr->letter_bits));
- SetLetterBits(tr,LETTERGP_A,el_vowels);
- SetLetterBits(tr,LETTERGP_B,el_voiceless);
- SetLetterBits(tr,LETTERGP_C,el_consonants);
- SetLetterBits(tr,LETTERGP_Y,el_fvowels); // front vowels: ε η ι υ
-
- tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
- tr->langopts.stress_rule = 2;
- tr->langopts.stress_flags = 0x6; // mark unstressed final syllables as diminished
- tr->langopts.unstressed_wd1 = 0;
- tr->langopts.unstressed_wd2 = 2;
- tr->langopts.param[LOPT_SONORANT_MIN] = 130; // limit the shortening of sonorants before short vowels
-
- tr->langopts.numbers = 0x109;
- tr->langopts.numbers2 = 0x2; // variant form of numbers before thousands
-
- if(name2 == L_grc)
- {
- // ancient greek
- tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1;
- }
- }
- break;
-
- case L('e','o'):
- {
- static const short stress_lengths_eo[8] = {145, 145, 230, 170, 0, 0, 360, 370};
- static const unsigned char stress_amps_eo[] = {16,14, 20,20, 20,22, 22,21 };
- static const wchar_t eo_char_apostrophe[2] = {'l',0};
-
- SetupTranslator(tr,stress_lengths_eo,stress_amps_eo);
-
- tr->charset_a0 = charsets[3]; // ISO-8859-3
- tr->char_plus_apostrophe = eo_char_apostrophe;
-
- tr->langopts.word_gap = 1;
- tr->langopts.vowel_pause = 2;
- tr->langopts.stress_rule = 2;
- tr->langopts.stress_flags = 0x6 | 0x10;
- tr->langopts.unstressed_wd1 = 3;
- tr->langopts.unstressed_wd2 = 2;
-
- tr->langopts.numbers = 0x1409 + NUM_ROMAN;
- }
- break;
-
- case L('e','s'): // Spanish
- case L('c','a'): // Catalan
- case L_pap: // Papiamento
- {
- static const short stress_lengths_es[8] = {180, 210, 190, 190, 0, 0, 230, 260};
-// static const short stress_lengths_es[8] = {170, 200, 180, 180, 0, 0, 220, 250};
- static const unsigned char stress_amps_es[8] = {16,12, 18,18, 20,20, 20,20 }; // 'diminished' is used to mark a quieter, final unstressed syllable
- static const wchar_t ca_punct_within_word[] = {'\'',0xb7,0}; // ca: allow middle-dot within word
-
- SetupTranslator(tr,stress_lengths_es,stress_amps_es);
-
- tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
- tr->langopts.stress_rule = 2;
-
- // stress last syllable if it doesn't end in vowel or "s" or "n"
- // 'diminished' is an unstressed final syllable
- tr->langopts.stress_flags = 0x200 | 0x6 | 0x10;
- tr->langopts.unstressed_wd1 = 0;
- tr->langopts.unstressed_wd2 = 2;
- tr->langopts.param[LOPT_SONORANT_MIN] = 120; // limit the shortening of sonorants before short vowels
-
- tr->langopts.numbers = 0x529 + NUM_ROMAN + NUM_ROMAN_AFTER;
-
- if(name2 == L('c','a'))
- {
- tr->punct_within_word = ca_punct_within_word;
- tr->langopts.stress_flags = 0x200 | 0x6 | 0x30; // stress last syllable unless word ends with a vowel
- }
- else
- if(name2 == L_pap)
- {
- tr->langopts.stress_flags = 0x100 | 0x6 | 0x30; // stress last syllable unless word ends with a vowel
- }
- }
- break;
-
-
- case L('e','u'): // basque
- {
- static const short stress_lengths_eu[8] = {200, 200, 200, 200, 0, 0, 210, 230}; // very weak stress
- static const unsigned char stress_amps_eu[8] = {16,16, 18,18, 18,18, 18,18 };
- SetupTranslator(tr,stress_lengths_eu,stress_amps_eu);
- tr->langopts.stress_rule = 1; // ?? second syllable ??
- tr->langopts.numbers = 0x569 + NUM_VIGESIMAL;
- }
- break;
-
-
- case L('f','i'): // Finnish
- {
- static const unsigned char stress_amps_fi[8] = {18,16, 22,22, 20,22, 22,22 };
- static const short stress_lengths_fi[8] = {150,180, 200,200, 0,0, 210,250};
-
- SetupTranslator(tr,stress_lengths_fi,stress_amps_fi);
-
- tr->langopts.stress_rule = 0;
- tr->langopts.stress_flags = 0x56; // move secondary stress from light to a following heavy syllable
- tr->langopts.param[LOPT_IT_DOUBLING] = 1;
- tr->langopts.long_stop = 130;
-
- tr->langopts.numbers = 0x1009;
- SetLetterVowel(tr,'y');
-// tr->langopts.max_initial_consonants = 2; // BUT foreign words may have 3
- tr->langopts.spelling_stress = 1;
- tr->langopts.intonation_group = 3; // less intonation, don't raise pitch at comma
- }
- break;
-
-
- case L('f','r'): // french
- {
- static const short stress_lengths_fr[8] = {190, 170, 190, 200, 0, 0, 235, 240};
- static const unsigned char stress_amps_fr[8] = {18,16, 20,20, 20,22, 22,21 };
-
- SetupTranslator(tr,stress_lengths_fr,stress_amps_fr);
- tr->langopts.stress_rule = 3; // stress on final syllable
- tr->langopts.stress_flags = 0x0024; // don't use secondary stress
- tr->langopts.param[LOPT_IT_LENGTHEN] = 1; // remove lengthen indicator from unstressed syllables
-
- tr->langopts.numbers = 0x1509 + 0x8000 + (NUM_NOPAUSE | NUM_ROMAN | NUM_VIGESIMAL);
- SetLetterVowel(tr,'y');
- }
- break;
-
-#ifdef deleted
- case L('g','a'): // Irish Gaelic
- {
- tr->langopts.stress_rule = 1;
- }
- break;
-#endif
-
- case L('h','i'): // Hindi
- case L('n','e'): // Nepali
- {
- static const short stress_lengths_hi[8] = {190, 190, 210, 210, 0, 0, 230, 250};
- static const unsigned char stress_amps_hi[8] = {17,14, 20,19, 20,22, 22,21 };
-
- SetupTranslator(tr,stress_lengths_hi,stress_amps_hi);
- tr->charset_a0 = charsets[19]; // ISCII
- tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
-
- tr->langopts.stress_rule = 6; // stress on last heaviest syllable, excluding final syllable
- tr->langopts.stress_flags = 0x10004; // use 'diminished' for unstressed final syllable
- tr->langopts.numbers = 0x011;
- tr->langopts.numbers2 = NUM2_100000;
- tr->letter_bits_offset = OFFSET_DEVANAGARI;
- SetIndicLetters(tr);
- }
- break;
-
-
- case L('h','r'): // Croatian
- case L('b','s'): // Bosnian
- case L('s','r'): // Serbian
- {
- static const unsigned char stress_amps_hr[8] = {17,17, 20,20, 20,22, 22,21 };
- static const short stress_lengths_hr[8] = {180,160, 200,200, 0,0, 220,230};
- static const short stress_lengths_sr[8] = {160,150, 200,200, 0,0, 250,260};
-
- if(name2 == L('s','r'))
- SetupTranslator(tr,stress_lengths_sr,stress_amps_hr);
- else
- SetupTranslator(tr,stress_lengths_hr,stress_amps_hr);
- tr->charset_a0 = charsets[2]; // ISO-8859-2
-
- tr->langopts.stress_rule = 0;
- tr->langopts.stress_flags = 0x10;
- tr->langopts.param[LOPT_REGRESSIVE_VOICING] = 0x3;
- tr->langopts.max_initial_consonants = 5;
- tr->langopts.spelling_stress = 1;
- tr->langopts.accents = 1;
-
- tr->langopts.numbers = 0x140d + 0x4000 + NUM_ROMAN_UC;
- tr->langopts.numbers2 = 0x4a; // variant numbers before thousands,milliards
- tr->langopts.replace_chars = replace_cyrillic_latin;
-
- SetLetterVowel(tr,'y');
- SetLetterVowel(tr,'r');
- }
- break;
-
-
- case L('h','u'): // Hungarian
- {
- static const unsigned char stress_amps_hu[8] = {17,17, 19,19, 20,22, 22,21 };
- static const short stress_lengths_hu[8] = {185,195, 195,190, 0,0, 210,220};
-
- SetupTranslator(tr,stress_lengths_hu,stress_amps_hu);
- tr->charset_a0 = charsets[2]; // ISO-8859-2
-
- tr->langopts.vowel_pause = 0x20;
- tr->langopts.stress_rule = 0;
- tr->langopts.stress_flags = 0x8036;
- tr->langopts.unstressed_wd1 = 2;
-// tr->langopts.param[LOPT_REGRESSIVE_VOICING] = 0x4; // don't propagate over word boundaries
- tr->langopts.param[LOPT_IT_DOUBLING] = 1;
- tr->langopts.param[LOPT_COMBINE_WORDS] = 99; // combine some prepositions with the following word
-
- tr->langopts.numbers = 0x1009 + 0xa000 + NUM_ROMAN + 0x10000;
- SetLetterVowel(tr,'y');
- tr->langopts.spelling_stress = 1;
-SetLengthMods(tr,3); // all equal
- }
- break;
-
- case L('h','y'): // Armenian
- {
- static const short stress_lengths_hy[8] = {250, 200, 250, 250, 0, 0, 250, 250};
- static const char hy_vowels[] = {0x31, 0x35, 0x37, 0x38, 0x3b, 0x48, 0x55, 0};
- static const char hy_consonants[] = {0x32,0x33,0x34,0x36,0x39,0x3a,0x3c,0x3d,0x3e,0x3f,
- 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x56,0};
-
- SetupTranslator(tr,stress_lengths_hy,NULL);
- tr->langopts.stress_rule = 3; // default stress on final syllable
-
- tr->letter_bits_offset = OFFSET_ARMENIAN;
- memset(tr->letter_bits,0,sizeof(tr->letter_bits));
- SetLetterBits(tr,LETTERGP_A,hy_vowels);
- SetLetterBits(tr,LETTERGP_C,hy_consonants);
- tr->langopts.max_initial_consonants = 6;
- tr->langopts.numbers = 0x409;
-// tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words
- }
- break;
-
- case L('i','d'): // Indonesian
- {
- static const short stress_lengths_id[8] = {160, 200, 180, 180, 0, 0, 220, 240};
- static const unsigned char stress_amps_id[8] = {16,18, 18,18, 20,22, 22,21 };
-
- SetupTranslator(tr,stress_lengths_id,stress_amps_id);
- tr->langopts.stress_rule = 2;
- tr->langopts.numbers = 0x1009 + NUM_ROMAN;
- tr->langopts.stress_flags = 0x6 | 0x10;
- tr->langopts.accents = 2; // "capital" after letter name
- }
- break;
-
- case L('i','s'): // Icelandic
- {
- static const short stress_lengths_is[8] = {180,160, 200,200, 0,0, 240,250};
- static const wchar_t is_lettergroup_B[] = {'c','f','h','k','p','t','x',0xfe,0}; // voiceless conants, including 'þ' ?? 's'
-
- SetupTranslator(tr,stress_lengths_is,NULL);
- tr->langopts.stress_rule = 0;
- tr->langopts.stress_flags = 0x10;
- tr->langopts.param[LOPT_IT_LENGTHEN] = 0x11; // remove lengthen indicator from unstressed vowels
- tr->langopts.param[LOPT_REDUCE] = 2;
-
- ResetLetterBits(tr,0x18);
- SetLetterBits(tr,4,"kpst"); // Letter group F
- SetLetterBits(tr,3,"jvr"); // Letter group H
- tr->letter_groups[1] = is_lettergroup_B;
- SetLetterVowel(tr,'y');
- tr->langopts.numbers = 0x8e9;
- tr->langopts.numbers2 = 0x2;
- }
- break;
-
- case L('i','t'): // Italian
- {
- static const short stress_lengths_it[8] = {150, 140, 170, 170, 0, 0, 300, 330};
- static const unsigned char stress_amps_it[8] = {15,14, 19,19, 20,22, 22,20 };
-
- SetupTranslator(tr,stress_lengths_it,stress_amps_it);
-
- tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
- tr->langopts.stress_rule = 2;
- tr->langopts.stress_flags = 0x10 | 0x20000;
- tr->langopts.vowel_pause = 1;
- tr->langopts.unstressed_wd1 = 2;
- tr->langopts.unstressed_wd2 = 2;
- tr->langopts.param[LOPT_IT_LENGTHEN] = 2; // remove lengthen indicator from unstressed or non-penultimate syllables
- tr->langopts.param[LOPT_IT_DOUBLING] = 2; // double the first consonant if the previous word ends in a stressed vowel
- tr->langopts.param[LOPT_SONORANT_MIN] = 130; // limit the shortening of sonorants before short vowels
- tr->langopts.param[LOPT_REDUCE] = 1; // reduce vowels even if phonemes are specified in it_list
- tr->langopts.param[LOPT_ALT] = 2; // call ApplySpecialAttributes2() if a word has $alt or $alt2
- tr->langopts.numbers = 0x2709 + NUM_ROMAN;
- tr->langopts.accents = 2; // Say "Capital" after the letter.
- SetLetterVowel(tr,'y');
- }
- break;
-
- case L_jbo: // Lojban
- {
- static const short stress_lengths_jbo[8] = {145,145, 170,160, 0,0, 330,350};
- static const wchar_t jbo_punct_within_word[] = {'.',',','\'',0x2c8,0}; // allow period and comma within a word, also stress marker (from LOPT_CAPS_IN_WORD)
-
- SetupTranslator(tr,stress_lengths_jbo,NULL);
- tr->langopts.stress_rule = 2;
- tr->langopts.vowel_pause = 0x20c; // pause before a word which starts with a vowel, or after a word which ends in a consonant
-// tr->langopts.word_gap = 1;
- tr->punct_within_word = jbo_punct_within_word;
- tr->langopts.param[LOPT_CAPS_IN_WORD] = 2; // capitals indicate stressed syllables
- SetLetterVowel(tr,'y');
- }
- break;
-
- case L('k','o'): // Korean, TEST
- {
- static const char ko_ivowels[] = {0x63,0x64,0x67,0x68,0x6d,0x72,0x74,0x75,0}; // y and i vowels
- static const unsigned char ko_voiced[] = {0x02,0x05,0x06,0xab,0xaf,0xb7,0xbc,0}; // voiced consonants, l,m,n,N
-
- tr->letter_bits_offset = OFFSET_KOREAN;
- memset(tr->letter_bits,0,sizeof(tr->letter_bits));
- SetLetterBitsRange(tr,LETTERGP_A,0x61,0x75);
- SetLetterBits(tr,LETTERGP_Y,ko_ivowels);
- SetLetterBits(tr,LETTERGP_G,(const char *)ko_voiced);
-
- tr->langopts.stress_rule = 8; // ?? 1st syllable if it is heavy, else 2nd syllable
- tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words
- tr->langopts.numbers = 0x0401;
- }
- break;
-
- case L('k','u'): // Kurdish
- {
- static const unsigned char stress_amps_ku[8] = {18,18, 20,20, 20,22, 22,21 };
- static const short stress_lengths_ku[8] = {180,180, 190,180, 0,0, 230,240};
-
- SetupTranslator(tr,stress_lengths_ku,stress_amps_ku);
- tr->charset_a0 = charsets[9]; // ISO-8859-9 - Latin5
-
- tr->langopts.stress_rule = 7; // stress on the last syllable, before any explicitly unstressed syllable
-
- tr->langopts.numbers = 0x100461;
- tr->langopts.max_initial_consonants = 2;
- }
- break;
-
- case L('l','a'): //Latin
- {
- tr->charset_a0 = charsets[4]; // ISO-8859-4, includes a,e,i,o,u-macron
- tr->langopts.stress_rule = 2;
- tr->langopts.stress_flags = 0x20;
- tr->langopts.unstressed_wd1 = 0;
- tr->langopts.unstressed_wd2 = 2;
- tr->langopts.param[LOPT_DIERESES] = 1;
- tr->langopts.numbers = 0x1 + NUM_ROMAN;
- tr->langopts.max_roman = 5000;
- }
- break;
-
- case L('l','v'): // latvian
- {
- static const unsigned char stress_amps_lv[8] = {17,13, 20,20, 20,22, 22,21 };
- static const short stress_lengths_lv[8] = {180,130, 210,210, 0,0, 210,210};
-
- SetupTranslator(tr,stress_lengths_lv,stress_amps_lv);
-
- tr->langopts.stress_rule = 0;
- tr->langopts.spelling_stress = 1;
- tr->charset_a0 = charsets[4]; // ISO-8859-4
- tr->langopts.numbers = 0x409 + 0x8000 + 0x10000;
- tr->langopts.stress_flags = 0x16 + 0x40000;
- }
- break;
-
- case L('m','k'): // Macedonian
- {
- static wchar_t vowels_cyrillic[] = {0x440, // also include 'р' [R]
- 0x430,0x435,0x438,0x439,0x43e,0x443,0x44b,0x44d,0x44e,0x44f,0x450,0x451,0x456,0x457,0x45d,0x45e,0};
- static const unsigned char stress_amps_mk[8] = {17,17, 20,20, 20,22, 22,21 };
- static const short stress_lengths_mk[8] = {180,160, 200,200, 0,0, 220,230};
-
- SetupTranslator(tr,stress_lengths_mk,stress_amps_mk);
- tr->charset_a0 = charsets[5]; // ISO-8859-5
- tr->letter_groups[0] = vowels_cyrillic;
-
- tr->langopts.stress_rule = 4; // antipenultimate
- tr->langopts.numbers = 0x0429 + 0x4000;
- tr->langopts.numbers2 = 0x8a; // variant numbers before thousands,milliards
- }
- break;
-
-
- case L('n','l'): // Dutch
- {
- static const short stress_lengths_nl[8] = {160,135, 210,210, 0, 0, 260,280};
-
- tr->langopts.stress_rule = 0;
- tr->langopts.vowel_pause = 1;
- tr->langopts.param[LOPT_DIERESES] = 1;
- tr->langopts.param[LOPT_PREFIXES] = 1;
- SetLetterVowel(tr,'y');
-
- tr->langopts.numbers = 0x11c19;
- memcpy(tr->stress_lengths,stress_lengths_nl,sizeof(tr->stress_lengths));
- }
- break;
-
- case L('n','o'): // Norwegian
- {
- static const short stress_lengths_no[8] = {160,140, 200,200, 0,0, 220,210};
-
- SetupTranslator(tr,stress_lengths_no,NULL);
- tr->langopts.stress_rule = 0;
- SetLetterVowel(tr,'y');
- tr->langopts.numbers = 0x11849;
- }
- break;
-
- case L('o','m'):
- {
- static const unsigned char stress_amps_om[] = {18,15, 20,20, 20,22, 22,22 };
- static const short stress_lengths_om[8] = {200,200, 200,200, 0,0, 200,200};
-
- SetupTranslator(tr,stress_lengths_om,stress_amps_om);
- tr->langopts.stress_rule = 2;
- tr->langopts.stress_flags = 0x16 + 0x80000;
- }
- break;
-
- case L('p','l'): // Polish
- {
- static const short stress_lengths_pl[8] = {160, 190, 175, 175, 0, 0, 200, 210};
- static const unsigned char stress_amps_pl[8] = {17,13, 19,19, 20,22, 22,21 }; // 'diminished' is used to mark a quieter, final unstressed syllable
-
- SetupTranslator(tr,stress_lengths_pl,stress_amps_pl);
-
- tr->charset_a0 = charsets[2]; // ISO-8859-2
- tr->langopts.stress_rule = 2;
- tr->langopts.stress_flags = 0x6; // mark unstressed final syllables as diminished
- tr->langopts.param[LOPT_REGRESSIVE_VOICING] = 0x8;
- tr->langopts.max_initial_consonants = 7; // for example: wchrzczony :)
- tr->langopts.numbers=0x1009 + 0x4000;
- tr->langopts.numbers2=0x40;
- tr->langopts.param[LOPT_COMBINE_WORDS] = 4 + 0x100; // combine 'nie' (marked with $alt2) with some 1-syllable (and 2-syllable) words (marked with $alt)
- SetLetterVowel(tr,'y');
- }
- break;
-
- case L('p','t'): // Portuguese
- {
- static const short stress_lengths_pt[8] = {180, 125, 210, 210, 0, 0, 270, 295};
- static const unsigned char stress_amps_pt[8] = {16,13, 19,19, 20,22, 22,21 }; // 'diminished' is used to mark a quieter, final unstressed syllable
-
- SetupTranslator(tr,stress_lengths_pt,stress_amps_pt);
- tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
-
- tr->langopts.stress_rule = 3; // stress on final syllable
- tr->langopts.stress_flags = 0x6 | 0x10 | 0x20000;
- tr->langopts.numbers = 0x069 + 0x4000 + NUM_ROMAN;
- SetLetterVowel(tr,'y');
- ResetLetterBits(tr,0x2);
- SetLetterBits(tr,1,"bcdfgjkmnpqstvxz"); // B hard consonants, excluding h,l,r,w,y
- }
- break;
-
- case L('r','o'): // Romanian
- {
- static const short stress_lengths_ro[8] = {170, 170, 180, 180, 0, 0, 240, 260};
- static const unsigned char stress_amps_ro[8] = {15,13, 18,18, 20,22, 22,21 };
-
- SetupTranslator(tr,stress_lengths_ro,stress_amps_ro);
-
- tr->langopts.stress_rule = 2;
- tr->langopts.stress_flags = 0x100 + 0x6;
-
- tr->charset_a0 = charsets[2]; // ISO-8859-2
- tr->langopts.numbers = 0x1029+0x6000 + NUM_ROMAN;
- tr->langopts.numbers2 = 0x1e; // variant numbers before all thousandplex
- }
- break;
-
- case L('r','u'): // Russian
- Translator_Russian(tr);
- break;
-
- case L('r','w'): // Kiryarwanda
- {
- tr->langopts.stress_rule = 2;
- tr->langopts.stress_flags = 0x16;
- tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
-
- tr->langopts.numbers = 0x61 + 0x100000 + 0x4000;
- tr->langopts.numbers2 = 0x200; // say "thousands" before its number
- }
- break;
-
- case L('s','k'): // Slovak
- case L('c','s'): // Czech
- {
- static const char *sk_voiced = "bdgjlmnrvwzaeiouy";
-
- SetupTranslator(tr,stress_lengths_sk,stress_amps_sk);
- tr->charset_a0 = charsets[2]; // ISO-8859-2
-
- tr->langopts.stress_rule = 0;
- tr->langopts.stress_flags = 0x16;
- tr->langopts.param[LOPT_REGRESSIVE_VOICING] = 0x3;
- tr->langopts.max_initial_consonants = 5;
- tr->langopts.spelling_stress = 1;
- tr->langopts.param[LOPT_COMBINE_WORDS] = 4; // combine some prepositions with the following word
-
- tr->langopts.numbers = 0x0401 + 0x4000 + NUM_ROMAN;
- tr->langopts.numbers2 = 0x100;
- tr->langopts.thousands_sep = 0; //no thousands separator
- tr->langopts.decimal_sep = ',';
-
- if(name2 == L('c','s'))
- {
- tr->langopts.numbers2 = 0x108; // variant numbers before milliards
- }
-
- SetLetterVowel(tr,'y');
- SetLetterVowel(tr,'r');
- ResetLetterBits(tr,0x20);
- SetLetterBits(tr,5,sk_voiced);
- }
- break;
-
- case L('s','q'): // Albanian
- {
- static const short stress_lengths_sq[8] = {150, 150, 180, 180, 0, 0, 300, 300};
- static const unsigned char stress_amps_sq[8] = {16,12, 16,16, 20,20, 21,19 };
-
- SetupTranslator(tr,stress_lengths_sq,stress_amps_sq);
-
- tr->langopts.stress_rule = 2;
- tr->langopts.stress_flags = 0x16 + 0x100;
- SetLetterVowel(tr,'y');
- tr->langopts.numbers = 0x69 + 0x8000;
- tr->langopts.accents = 2; // "capital" after letter name
- }
- break;
-
-
- case L('s','v'): // Swedish
- {
- static const unsigned char stress_amps_sv[] = {16,16, 20,20, 20,22, 22,21 };
- static const short stress_lengths_sv[8] = {160,135, 220,220, 0,0, 250,280};
- SetupTranslator(tr,stress_lengths_sv,stress_amps_sv);
-
- tr->langopts.stress_rule = 0;
- SetLetterVowel(tr,'y');
- tr->langopts.numbers = 0x1909;
- tr->langopts.accents = 1;
- }
- break;
-
- case L('s','w'): // Swahili
- {
- static const short stress_lengths_sw[8] = {160, 170, 200, 200, 0, 0, 320, 340};
- static const unsigned char stress_amps_sw[] = {16,12, 19,19, 20,22, 22,21 };
-
- SetupTranslator(tr,stress_lengths_sw,stress_amps_sw);
- tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
-
- tr->langopts.vowel_pause = 1;
- tr->langopts.stress_rule = 2;
- tr->langopts.stress_flags = 0x6 | 0x10;
-
- tr->langopts.numbers = 0x4e1;
- tr->langopts.numbers2 = NUM2_100000a;
- }
- break;
-
- case L('t','a'): // Tamil
- case L('m','l'): // Malayalam
- case L('k','n'): // Kannada
- case L('m','r'): // Marathi
- {
- static const short stress_lengths_ta[8] = {200, 200, 210, 210, 0, 0, 230, 230};
- static const unsigned char stress_amps_ta[8] = {18,18, 18,18, 20,20, 22,22 };
-
- SetupTranslator(tr,stress_lengths_ta,stress_amps_ta);
- tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
-
- tr->langopts.stress_rule = 0;
- tr->langopts.stress_flags = 0x10004; // use 'diminished' for unstressed final syllable
- tr->letter_bits_offset = OFFSET_TAMIL;
-
- if(name2 == L('m','r'))
- {
- tr->letter_bits_offset = OFFSET_DEVANAGARI;
- }
- else
- if(name2 == L('m','l'))
- {
- tr->letter_bits_offset = OFFSET_MALAYALAM;
- }
- else
- if(name2 == L('k','n'))
- {
- tr->letter_bits_offset = OFFSET_KANNADA;
- tr->langopts.numbers = 0x1;
- tr->langopts.numbers2 = NUM2_100000;
- }
- tr->langopts.param[LOPT_WORD_MERGE] = 1; // don't break vowels betwen words
- SetIndicLetters(tr); // call this after setting OFFSET_
- }
- break;
-
-#ifdef deleted
- case L('t','h'): // Thai
- {
- static const short stress_lengths_th[8] = {230,150, 230,230, 230,0, 230,250};
- static const unsigned char stress_amps_th[] = {22,16, 22,22, 22,22, 22,22 };
-
- SetupTranslator(tr,stress_lengths_th,stress_amps_th);
-
- tr->langopts.stress_rule = 0; // stress on final syllable of a "word"
- tr->langopts.stress_flags = 2; // don't automatically set diminished stress (may be set in the intonation module)
- tr->langopts.tone_language = 1; // Tone language, use CalcPitches_Tone() rather than CalcPitches()
- tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
-// tr->langopts.tone_numbers = 1; // a number after letters indicates a tone number (eg. pinyin or jyutping)
- tr->langopts.word_gap = 0x21; // length of a final vowel is less dependent on the next consonant, don't merge consonant with next word
- }
- break;
-#endif
-
- case L('t','r'): // Turkish
- {
- static const unsigned char stress_amps_tr[8] = {18,18, 20,20, 20,22, 22,21 };
- static const short stress_lengths_tr[8] = {190,190, 190,190, 0,0, 250,270};
-
- SetupTranslator(tr,stress_lengths_tr,stress_amps_tr);
- tr->charset_a0 = charsets[9]; // ISO-8859-9 - Latin5
-
- tr->langopts.stress_rule = 7; // stress on the last syllable, before any explicitly unstressed syllable
- tr->langopts.stress_flags = 0x20; //no automatic secondary stress
-
- tr->langopts.numbers = 0x1509 + 0x4000;
- tr->langopts.max_initial_consonants = 2;
- }
- break;
-
- case L('v','i'): // Vietnamese
- {
- static const short stress_lengths_vi[8] = {150, 150, 180, 180, 210, 230, 230, 240};
- static const unsigned char stress_amps_vi[] = {16,16, 16,16, 22,22, 22,22 };
- static wchar_t vowels_vi[] = {
- 0x61, 0xe0, 0xe1, 0x1ea3, 0xe3, 0x1ea1, // a
- 0x103, 0x1eb1, 0x1eaf, 0x1eb3, 0x1eb5, 0x1eb7, // ă
- 0xe2, 0x1ea7, 0x1ea5, 0x1ea9, 0x1eab, 0x1ead, // â
- 0x65, 0xe8, 0xe9, 0x1ebb, 0x1ebd, 0x1eb9, // e
- 0xea, 0x1ec1, 0x1ebf, 0x1ec3, 0x1ec5, 0x1ec7, // i
- 0x69, 0xec, 0xed, 0x1ec9, 0x129, 0x1ecb, // i
- 0x6f, 0xf2, 0xf3, 0x1ecf, 0xf5, 0x1ecd, // o
- 0xf4, 0x1ed3, 0x1ed1, 0x1ed5, 0x1ed7, 0x1ed9, // ô
- 0x1a1, 0x1edd, 0x1edb, 0x1edf, 0x1ee1, 0x1ee3, // ơ
- 0x75, 0xf9, 0xfa, 0x1ee7, 0x169, 0x1ee5, // u
- 0x1b0, 0x1eeb, 0x1ee9, 0x1eed, 0x1eef, 0x1ef1, // ư
- 0x79, 0x1ef3, 0xfd, 0x1ef7, 0x1ef9, 0x1e, 0 }; // y
-
- SetupTranslator(tr,stress_lengths_vi,stress_amps_vi);
- tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
-
- tr->langopts.stress_rule = 0;
- tr->langopts.word_gap = 0x21; // length of a final vowel is less dependent on the next consonant, don't merge consonant with next word
-// tr->langopts.vowel_pause = 4;
- tr->letter_groups[0] = vowels_vi;
- tr->langopts.tone_language = 1; // Tone language, use CalcPitches_Tone() rather than CalcPitches()
- tr->langopts.unstressed_wd1 = 2;
- tr->langopts.numbers = 0x0049 + 0x8000;
-
- }
- break;
-
- case L('z','h'):
- case L_zhy:
- {
- static const short stress_lengths_zh[8] = {230,150, 230,230, 230,0, 240,250}; // 1=tone5. end-of-sentence, 6=tone 1&4, 7=tone 2&3
- static const unsigned char stress_amps_zh[] = {22,16, 22,22, 22,22, 22,22 };
-
- SetupTranslator(tr,stress_lengths_zh,stress_amps_zh);
-
- tr->langopts.stress_rule = 3; // stress on final syllable of a "word"
- tr->langopts.stress_flags = 2; // don't automatically set diminished stress (may be set in the intonation module)
- tr->langopts.vowel_pause = 0;
- tr->langopts.tone_language = 1; // Tone language, use CalcPitches_Tone() rather than CalcPitches()
- tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
- tr->langopts.tone_numbers = 1; // a number after letters indicates a tone number (eg. pinyin or jyutping)
- tr->langopts.ideographs = 1;
- tr->langopts.word_gap = 0x21; // length of a final vowel is less dependent on the next consonant, don't merge consonant with next word
- if(name2 == L('z','h'))
- {
- tr->langopts.textmode = 1;
- tr->langopts.listx = 1; // compile zh_listx after zh_list
- }
- }
- break;
-
- default:
- tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words
- break;
- }
-
- tr->translator_name = name2;
-
- if(tr->langopts.numbers & 0x8)
- {
- // use . and ; for thousands and decimal separators
- tr->langopts.thousands_sep = '.';
- tr->langopts.decimal_sep = ',';
- }
- if(tr->langopts.numbers & 0x4)
- {
- tr->langopts.thousands_sep = 0; // don't allow thousands separator, except space
- }
- return(tr);
-} // end of SelectTranslator
-
-
-
-//**********************************************************************************************************
-
-
-
-static void Translator_Russian(Translator *tr)
-{//===========================================
- static const unsigned char stress_amps_ru[] = {16,16, 18,18, 20,24, 24,22 };
- static const short stress_lengths_ru[8] = {150,140, 220,220, 0,0, 260,280};
-
-
- // character codes offset by 0x420
- static const char ru_vowels[] = {0x10,0x15,0x31,0x18,0x1e,0x23,0x2b,0x2d,0x2e,0x2f,0};
- static const char ru_consonants[] = {0x11,0x12,0x13,0x14,0x16,0x17,0x19,0x1a,0x1b,0x1c,0x1d,0x1f,0x20,0x21,0x22,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2c,0};
- static const char ru_soft[] = {0x2c,0x19,0x27,0x29,0}; // letter group B [k ts; s;]
- static const char ru_hard[] = {0x2a,0x16,0x26,0x28,0}; // letter group H [S Z ts]
- static const char ru_nothard[] = {0x11,0x12,0x13,0x14,0x17,0x19,0x1a,0x1b,0x1c,0x1d,0x1f,0x20,0x21,0x22,0x24,0x25,0x27,0x29,0x2c,0};
- static const char ru_voiced[] = {0x11,0x12,0x13,0x14,0x16,0x17,0}; // letter group G (voiced obstruents)
- static const char ru_ivowels[] = {0x2c,0x15,0x31,0x18,0x2e,0x2f,0}; // letter group Y (iotated vowels & soft-sign)
-
- SetupTranslator(tr,stress_lengths_ru,stress_amps_ru);
-
- tr->charset_a0 = charsets[18]; // KOI8-R
- tr->transpose_offset = 0x42f; // convert cyrillic from unicode into range 0x01 to 0x22
- tr->transpose_min = 0x430;
- tr->transpose_max = 0x451;
-
- tr->letter_bits_offset = OFFSET_CYRILLIC;
- memset(tr->letter_bits,0,sizeof(tr->letter_bits));
- SetLetterBits(tr,0,ru_vowels);
- SetLetterBits(tr,1,ru_soft);
- SetLetterBits(tr,2,ru_consonants);
- SetLetterBits(tr,3,ru_hard);
- SetLetterBits(tr,4,ru_nothard);
- SetLetterBits(tr,5,ru_voiced);
- SetLetterBits(tr,6,ru_ivowels);
- SetLetterBits(tr,7,ru_vowels);
-
- tr->langopts.param[LOPT_UNPRONOUNCABLE] = 0x432; // [v] don't count this character at start of word
- tr->langopts.param[LOPT_REGRESSIVE_VOICING] = 1;
- tr->langopts.param[LOPT_REDUCE] = 2;
- tr->langopts.stress_rule = 5;
- tr->langopts.stress_flags = 0x0020; // waas 0x1010
-
- tr->langopts.numbers = 0x0409;
- tr->langopts.numbers2 = 0xc2; // variant numbers before thousands
- tr->langopts.phoneme_change = 1;
- tr->langopts.testing = 2;
-
-} // end of Translator_Russian
-
-
-
-/*
-typedef struct {
- int flags;
- unsigned char stress; // stress level of this vowel
- unsigned char stress_highest; // the highest stress level of a vowel in this word
- unsigned char n_vowels; // number of vowels in the word
- unsigned char vowel_this; // syllable number of this vowel (counting from 1)
- unsigned char vowel_stressed; // syllable number of the highest stressed vowel
-} CHANGEPH;
-*/
-
-
-#define RUSSIAN2
-#ifdef RUSSIAN2
-
-int ChangePhonemes_ru(Translator *tr, PHONEME_LIST2 *phlist, int n_ph, int index, PHONEME_TAB *ph, CHANGEPH *ch)
-{//=============================================================================================================
-// Called for each phoneme in the phoneme list, to allow a language to make changes
-// ph The current phoneme
-
- int variant;
- int vowelix;
- int stressed;
- int soft;
- PHONEME_TAB *prev, *next;
-
- if(ch->flags & 8)
- return(0); // full phoneme translation has already been given
- // Russian vowel softening and reduction rules
-
- if(ph->type == phVOWEL)
- {
- int prestressed = ch->vowel_stressed==ch->vowel_this+1; // the next vowel after this has the main stress
-
- #define N_VOWELS_RU 11
- static unsigned int vowels_ru[N_VOWELS_RU] = {'a','V','O','I',PH('I','#'),PH('E','#'),PH('E','2'),
-PH('V','#'),PH('I','3'),PH('I','2'),PH('E','3')};
-
-
- static unsigned int vowel_replace[N_VOWELS_RU][6] = {
- // stressed, soft, soft-stressed, j+stressed, j+soft, j+soft-stressed
- /*0*/ {'A', 'I', PH('j','a'), 'a', 'a', 'a'}, // a Uses 3,4,5 columns.
- /*1*/ {'A', 'V', PH('j','a'), 'a', 'V', 'a'}, // V Uses 3,4,5 columns.
- /*2*/ {'o', '8', '8', 'o', '8', '8'}, // O
- /*3*/ {'i', 'I', 'i', 'a', 'I', 'a'}, // I Uses 3,4,5 columns.
- /*4*/ {'i', PH('I','#'), 'i', 'i', PH('I','#'), 'i'}, // I#
- /*5*/ {'E', PH('E','#'), 'E', 'e', PH('E','#'), 'e'}, // E#
- /*6*/ {'E', PH('E','2'), 'E', 'e', PH('E','2'), 'e'}, // E2 Uses 3,4,5 columns.
- /*7*/ {PH('j','a'), 'V', PH('j','a'), 'A', 'V', 'A'}, // V#
- /*8*/ {PH('j','a'), 'I', PH('j','a'), 'e', 'I', 'e'}, // I3 Uses 3,4,5 columns.
- /*9*/ {'e', 'I', 'e', 'e', 'I', 'e'}, // I2
- /*10*/ {'e', PH('E', '2'), 'e', 'e', PH('E','2'), 'e'} // E3
- };
-
- prev = phoneme_tab[phlist[index-1].phcode];
- next = phoneme_tab[phlist[index+1].phcode];
-
- // lookup the vowel name to get an index into the vowel_replace[] table
- for(vowelix=0; vowelix<N_VOWELS_RU; vowelix++)
- {
- if(vowels_ru[vowelix] == ph->mnemonic)
- break;
- }
- if(vowelix == N_VOWELS_RU)
- return(0);
-
- if(prestressed)
- {
- if((vowelix==6)&&(prev->mnemonic=='j'))
- vowelix=8;
- if(vowelix==1)
- vowelix=0;
- if(vowelix==4)
- vowelix=3;
- if(vowelix==6)
- vowelix=5;
- if(vowelix==7)
- vowelix=8;
- if(vowelix==10)
- vowelix=9;
- }
- // do we need a variant of this vowel, depending on the stress and adjacent phonemes ?
- variant = -1;
- stressed = ch->flags & 2;
- soft=prev->phflags & phPALATAL;
-
- if (soft && stressed)
- variant = 2; else
- if (stressed)
- variant = 0; else
- if (soft)
- variant = 1;
- if(variant >= 0)
- {
- if(prev->mnemonic == 'j')
- variant += 3;
-
- phlist[index].phcode = PhonemeCode(vowel_replace[vowelix][variant]);
- }
- else
- {
- phlist[index].phcode = PhonemeCode(vowels_ru[vowelix]);
- }
- }
-
- return(0);
-}
-#else
-
-
-int ChangePhonemes_ru(Translator *tr, PHONEME_LIST2 *phlist, int n_ph, int index, PHONEME_TAB *ph, CHANGEPH *ch)
-{//=============================================================================================================
-// Called for each phoneme in the phoneme list, to allow a language to make changes
-// flags: bit 0=1 last phoneme in a word
-// bit 1=1 this is the highest stressed vowel in the current word
-// bit 2=1 after the highest stressed vowel in the current word
-// bit 3=1 the phonemes were specified explicitly, or found from an entry in the xx_list dictionary
-// ph The current phoneme
-
- int variant;
- int vowelix;
- PHONEME_TAB *prev, *next;
-
- if(ch->flags & 8)
- return(0); // full phoneme translation has already been given
-
- // Russian vowel softening and reduction rules
- if(ph->type == phVOWEL)
- {
- #define N_VOWELS_RU 7
- static unsigned char vowels_ru[N_VOWELS_RU] = {'a','A','o','E','i','u','y'};
-
- // each line gives: soft, reduced, soft-reduced, post-tonic
- static unsigned short vowel_replace[N_VOWELS_RU][4] = {
- {'&', 'V', 'I', 'V'}, // a
- {'&', 'V', 'I', 'V'}, // A
- {'8', 'V', 'I', 'V'}, // o
- {'e', 'I', 'I', 'I'}, // E
- {'i', 'I', 'I', 'I'}, // i
- {'u'+('"'<<8), 'U', 'U', 'U'}, // u
- {'y', 'Y', 'Y', 'Y'}}; // y
-
- prev = phoneme_tab[phlist[index-1].phcode];
- next = phoneme_tab[phlist[index+1].phcode];
-
-if(prev->mnemonic == 'j')
- return(0);
-
- // lookup the vowel name to get an index into the vowel_replace[] table
- for(vowelix=0; vowelix<N_VOWELS_RU; vowelix++)
- {
- if(vowels_ru[vowelix] == ph->mnemonic)
- break;
- }
- if(vowelix == N_VOWELS_RU)
- return(0);
-
- // do we need a variant of this vowel, depending on the stress and adjacent phonemes ?
- variant = -1;
- if(ch->flags & 2)
- {
- // a stressed vowel
- if((prev->phflags & phPALATAL) && ((next->phflags & phPALATAL) || phoneme_tab[phlist[index+2].phcode]->mnemonic == ';'))
- {
- // between two palatal consonants, use the soft variant
- variant = 0;
- }
- }
- else
- {
- // an unstressed vowel
- if(prev->phflags & phPALATAL)
- {
- variant = 2; // unstressed soft
- }
- else
- if((ph->mnemonic == 'o') && ((prev->phflags & phPLACE) == phPLACE_pla))
- {
- variant = 2; // unstressed soft ([o] vowel following: ш ж
- }
- else
- if(ch->flags & 4)
- {
- variant = 3; // post tonic
- }
- else
- {
- variant = 1; // unstressed
- }
- }
- if(variant >= 0)
- {
- phlist[index].phcode = PhonemeCode(vowel_replace[vowelix][variant]);
- }
- }
-
- return(0);
-}
-#endif
-
diff --git a/navit/support/espeak/translate.c b/navit/support/espeak/translate.c
deleted file mode 100755
index 4891644cd..000000000
--- a/navit/support/espeak/translate.c
+++ /dev/null
@@ -1,2800 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2005 to 2007 by Jonathan Duddington *
- * email: jonsd@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, see: *
- * <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-#include "StdAfx.h"
-
-#include <stdio.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <wctype.h>
-#include <wchar.h>
-
-#include "speak_lib.h"
-#include "speech.h"
-#include "phoneme.h"
-#include "synthesize.h"
-#include "voice.h"
-#include "translate.h"
-
-#define WORD_STRESS_CHAR '*'
-
-
-Translator *translator = NULL; // the main translator
-Translator *translator2 = NULL; // secondary translator for certain words
-static char translator2_language[20] = {0};
-
-FILE *f_trans = NULL; // phoneme output text
-int option_tone2 = 0;
-int option_tone_flags = 0; // bit 8=emphasize allcaps, bit 9=emphasize penultimate stress
-int option_phonemes = 0;
-int option_phoneme_events = 0;
-int option_quiet = 0;
-int option_endpause = 0; // suppress pause after end of text
-int option_capitals = 0;
-int option_punctuation = 0;
-int option_sayas = 0;
-static int option_sayas2 = 0; // used in translate_clause()
-static int option_emphasis = 0; // 0=normal, 1=normal, 2=weak, 3=moderate, 4=strong
-int option_ssml = 0;
-int option_phoneme_input = 0; // allow [[phonemes]] in input
-int option_phoneme_variants = 0; // 0= don't display phoneme variant mnemonics
-int option_wordgap = 0;
-
-static int count_sayas_digits;
-int skip_sentences;
-int skip_words;
-int skip_characters;
-char skip_marker[N_MARKER_LENGTH];
-int skipping_text; // waiting until word count, sentence count, or named marker is reached
-int end_character_position;
-int count_sentences;
-int count_words;
-int clause_start_char;
-int clause_start_word;
-int new_sentence;
-static int word_emphasis = 0; // set if emphasis level 3 or 4
-static int embedded_flag = 0; // there are embedded commands to be applied to the next phoneme, used in TranslateWord2()
-
-static int prev_clause_pause=0;
-static int max_clause_pause = 0;
-int pre_pause;
-
-
-// these were previously in translator class
-char word_phonemes[N_WORD_PHONEMES]; // a word translated into phoneme codes
-int n_ph_list2;
-PHONEME_LIST2 ph_list2[N_PHONEME_LIST]; // first stage of text->phonemes
-
-
-
-wchar_t option_punctlist[N_PUNCTLIST]={0};
-char ctrl_embedded = '\001'; // to allow an alternative CTRL for embedded commands
-int option_multibyte=espeakCHARS_AUTO; // 0=auto, 1=utf8, 2=8bit, 3=wchar, 4=16bit
-
-// these are overridden by defaults set in the "speak" file
-int option_linelength = 0;
-
-#define N_EMBEDDED_LIST 250
-static int embedded_ix;
-static int embedded_read;
-unsigned int embedded_list[N_EMBEDDED_LIST];
-
-// the source text of a single clause (UTF8 bytes)
-#define N_TR_SOURCE 700
-static char source[N_TR_SOURCE+40]; // extra space for embedded command & voice change info at end
-
-int n_replace_phonemes;
-REPLACE_PHONEMES replace_phonemes[N_REPLACE_PHONEMES];
-
-
-// brackets, also 0x2014 to 0x021f which don't need to be in this list
-static const unsigned short brackets[] = {
-'(',')','[',']','{','}','<','>','"','\'','`',
-0xab,0xbb, // double angle brackets
-0x300a,0x300b, // double angle brackets (ideograph)
-0};
-
-// other characters which break a word, but don't produce a pause
-static const unsigned short breaks[] = {'_', 0};
-
-// treat these characters as spaces, in addition to iswspace()
-static const wchar_t chars_space[] = {0x2500,0}; // box drawing horiz
-
-
-// Translate character codes 0xA0 to 0xFF into their unicode values
-// ISO_8859_1 is set as default
-static const unsigned short ISO_8859_1[0x60] = {
- 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, // a0
- 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, // a8
- 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, // b0
- 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, // b8
- 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, // c0
- 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, // c8
- 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, // d0
- 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, // d8
- 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, // e0
- 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, // e8
- 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, // f0
- 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff, // f8
-};
-
-static const unsigned short ISO_8859_2[0x60] = {
- 0x00a0, 0x0104, 0x02d8, 0x0141, 0x00a4, 0x013d, 0x015a, 0x00a7, // a0
- 0x00a8, 0x0160, 0x015e, 0x0164, 0x0179, 0x00ad, 0x017d, 0x017b, // a8
- 0x00b0, 0x0105, 0x02db, 0x0142, 0x00b4, 0x013e, 0x015b, 0x02c7, // b0
- 0x00b8, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c, // b8
- 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, // c0
- 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e, // c8
- 0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, // d0
- 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df, // d8
- 0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, // e0
- 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f, // e8
- 0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, // f0
- 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9, // f8
-};
-
-static const unsigned short ISO_8859_3[0x60] = {
- 0x00a0, 0x0126, 0x02d8, 0x00a3, 0x00a4, 0x0000, 0x0124, 0x00a7, // a0
- 0x00a8, 0x0130, 0x015e, 0x011e, 0x0134, 0x00ad, 0x0000, 0x017b, // a8
- 0x00b0, 0x0127, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x0125, 0x00b7, // b0
- 0x00b8, 0x0131, 0x015f, 0x011f, 0x0135, 0x00bd, 0x0000, 0x017c, // b8
- 0x00c0, 0x00c1, 0x00c2, 0x0000, 0x00c4, 0x010a, 0x0108, 0x00c7, // c0
- 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, // c8
- 0x0000, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x0120, 0x00d6, 0x00d7, // d0
- 0x011c, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x016c, 0x015c, 0x00df, // d8
- 0x00e0, 0x00e1, 0x00e2, 0x0000, 0x00e4, 0x010b, 0x0109, 0x00e7, // e0
- 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, // e8
- 0x0000, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x0121, 0x00f6, 0x00f7, // f0
- 0x011d, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x016d, 0x015d, 0x02d9, // f8
-};
-
-static const unsigned short ISO_8859_4[0x60] = {
- 0x00a0, 0x0104, 0x0138, 0x0156, 0x00a4, 0x0128, 0x013b, 0x00a7, // a0
- 0x00a8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00ad, 0x017d, 0x00af, // a8
- 0x00b0, 0x0105, 0x02db, 0x0157, 0x00b4, 0x0129, 0x013c, 0x02c7, // b0
- 0x00b8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014a, 0x017e, 0x014b, // b8
- 0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, // c0
- 0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x012a, // c8
- 0x0110, 0x0145, 0x014c, 0x0136, 0x00d4, 0x00d5, 0x00d6, 0x00d7, // d0
- 0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x0168, 0x016a, 0x00df, // d8
- 0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, // e0
- 0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b, // e8
- 0x0111, 0x0146, 0x014d, 0x0137, 0x00f4, 0x00f5, 0x00f6, 0x00f7, // f0
- 0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x0169, 0x016b, 0x02d9, // f8
-};
-
-static const unsigned short ISO_8859_5[0x60] = {
- 0x00a0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, // a0 Cyrillic
- 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x00ad, 0x040e, 0x040f, // a8
- 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, // b0
- 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, // b8
- 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, // c0
- 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, // c8
- 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, // d0
- 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, // d8
- 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, // e0
- 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, // e8
- 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, // f0
- 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x00a7, 0x045e, 0x045f, // f8
-};
-
-static const unsigned short ISO_8859_7[0x60] = {
- 0x00a0, 0x2018, 0x2019, 0x00a3, 0x20ac, 0x20af, 0x00a6, 0x00a7, // a0 Greek
- 0x00a8, 0x00a9, 0x037a, 0x00ab, 0x00ac, 0x00ad, 0x0000, 0x2015, // a8
- 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x0384, 0x0385, 0x0386, 0x00b7, // b0
- 0x0388, 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f, // b8
- 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, // c0
- 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, // c8
- 0x03a0, 0x03a1, 0x0000, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, // d0
- 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af, // d8
- 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, // e0
- 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, // e8
- 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, // f0
- 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0x0000, // f8
-};
-
-static const unsigned short ISO_8859_9[0x60] = {
- 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, // a0
- 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, // a8
- 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, // b0
- 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, // b8
- 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, // c0
- 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, // c8
- 0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, // d0
- 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df, // d8
- 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, // e0
- 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, // e8
- 0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, // f0
- 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff, // f8
-};
-
-static const unsigned short ISO_8859_14[0x60] = {
- 0x00a0, 0x1e02, 0x1e03, 0x00a3, 0x010a, 0x010b, 0x1e0a, 0x00a7, // a0 Welsh
- 0x1e80, 0x00a9, 0x1e82, 0x1e0b, 0x1ef2, 0x00ad, 0x00ae, 0x0178, // a8
- 0x1e1e, 0x1e1f, 0x0120, 0x0121, 0x1e40, 0x1e41, 0x00b6, 0x1e56, // b0
- 0x1e81, 0x1e57, 0x1e83, 0x1e60, 0x1ef3, 0x1e84, 0x1e85, 0x1e61, // b8
- 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, // c0
- 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, // c8
- 0x0174, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x1e6a, // d0
- 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x0176, 0x00df, // d8
- 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, // e0
- 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, // e8
- 0x0175, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x1e6b, // f0
- 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x0177, 0x00ff, // f8
-};
-
-static const unsigned short KOI8_R[0x60] = {
- 0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556, // a0 Russian
- 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x255c, 0x255d, 0x255e, // a8
- 0x255f, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565, // b0
- 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x256b, 0x256c, 0x00a9, // b8
- 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, // c0
- 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, // c8
- 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, // d0
- 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, // d8
- 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, // e0
- 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, // e8
- 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, // f0
- 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a, // f8
-};
-
-static const unsigned short ISCII[0x60] = {
- 0x0020, 0x0901, 0x0902, 0x0903, 0x0905, 0x0906, 0x0907, 0x0908, // a0
- 0x0909, 0x090a, 0x090b, 0x090e, 0x090f, 0x0910, 0x090d, 0x0912, // a8
- 0x0913, 0x0914, 0x0911, 0x0915, 0x0916, 0x0917, 0x0918, 0x0919, // b0
- 0x091a, 0x091b, 0x091c, 0x091d, 0x091e, 0x091f, 0x0920, 0x0921, // b8
- 0x0922, 0x0923, 0x0924, 0x0925, 0x0926, 0x0927, 0x0928, 0x0929, // c0
- 0x092a, 0x092b, 0x092c, 0x092d, 0x092e, 0x092f, 0x095f, 0x0930, // c8
- 0x0931, 0x0932, 0x0933, 0x0934, 0x0935, 0x0936, 0x0937, 0x0938, // d0
- 0x0939, 0x0020, 0x093e, 0x093f, 0x0940, 0x0941, 0x0942, 0x0943, // d8
- 0x0946, 0x0947, 0x0948, 0x0945, 0x094a, 0x094b, 0x094c, 0x0949, // e0
- 0x094d, 0x093c, 0x0964, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, // e8
- 0x0020, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, // f0
- 0x0037, 0x0038, 0x0039, 0x20, 0x20, 0x20, 0x20, 0x20, // f8
-};
-
-const unsigned short *charsets[N_CHARSETS] = {
- ISO_8859_1,
- ISO_8859_1,
- ISO_8859_2,
- ISO_8859_3,
- ISO_8859_4,
- ISO_8859_5,
- ISO_8859_1,
- ISO_8859_7,
- ISO_8859_1,
- ISO_8859_9,
- ISO_8859_1,
- ISO_8859_1,
- ISO_8859_1,
- ISO_8859_1,
- ISO_8859_14,
- ISO_8859_1,
- ISO_8859_1,
- ISO_8859_1,
- KOI8_R, // 18
- ISCII };
-
-// Tables of the relative lengths of vowels, depending on the
-// type of the two phonemes that follow
-// indexes are the "length_mod" value for the following phonemes
-
-// use this table if vowel is not the last in the word
-static unsigned char length_mods_en[100] = {
-/* a , t s n d z r N <- next */
- 100,120,100,105,100,110,110,100, 95, 100, /* a <- next2 */
- 105,120,105,110,125,130,135,115,125, 100, /* , */
- 105,120, 75,100, 75,105,120, 85, 75, 100, /* t */
- 105,120, 85,105, 95,115,120,100, 95, 100, /* s */
- 110,120, 95,105,100,115,120,100,100, 100, /* n */
- 105,120,100,105, 95,115,120,110, 95, 100, /* d */
- 105,120,100,105,105,122,125,110,105, 100, /* z */
- 105,120,100,105,105,122,125,110,105, 100, /* r */
- 105,120, 95,105,100,115,120,110,100, 100, /* N */
- 100,120,100,100,100,100,100,100,100, 100 }; // SPARE
-
-// as above, but for the last syllable in a word
-static unsigned char length_mods_en0[100] = {
-/* a , t s n d z r N <- next */
- 100,150,100,105,110,115,110,110,110, 100, /* a <- next2 */
- 105,150,105,110,125,135,140,115,135, 100, /* , */
- 105,150, 90,105, 90,122,135,100, 90, 100, /* t */
- 105,150,100,105,100,122,135,100,100, 100, /* s */
- 105,150,100,105,105,115,135,110,105, 100, /* n */
- 105,150,100,105,105,122,130,120,125, 100, /* d */
- 105,150,100,105,110,122,125,115,110, 100, /* z */
- 105,150,100,105,105,122,135,120,105, 100, /* r */
- 105,150,100,105,105,115,135,110,105, 100, /* N */
- 100,100,100,100,100,100,100,100,100, 100 }; // SPARE
-
-
-static unsigned char length_mods_equal[100] = {
-/* a , t s n d z r N <- next */
- 110,110,110,110,110,110,110,110,110, 110, /* a <- next2 */
- 110,110,110,110,110,110,110,110,110, 110, /* , */
- 110,110,110,110,110,110,110,110,110, 110, /* t */
- 110,110,110,110,110,110,110,110,110, 110, /* s */
- 110,110,110,110,110,110,110,110,110, 110, /* n */
- 110,110,110,110,110,110,110,110,110, 110, /* d */
- 110,110,110,110,110,110,110,110,110, 110, /* z */
- 110,110,110,110,110,110,110,110,110, 110, /* r */
- 110,110,110,110,110,110,110,110,110, 110, /* N */
- 110,110,110,110,110,110,110,110,110, 110 }; // SPARE
-
-
-static unsigned char *length_mod_tabs[6] = {
- length_mods_en,
- length_mods_en, // 1
- length_mods_en0, // 2
- length_mods_equal, // 3
- length_mods_equal, // 4
- length_mods_equal // 5
- };
-
-
-void SetLengthMods(Translator *tr, int value)
-{//==========================================
- int value2;
-
- tr->langopts.length_mods0 = tr->langopts.length_mods = length_mod_tabs[value % 100];
- if((value2 = value / 100) != 0)
- {
- tr->langopts.length_mods0 = length_mod_tabs[value2];
- }
-}
-
-
-int IsAlpha(unsigned int c)
-{//========================
-// Replacement for iswalph() which also checks for some in-word symbols
-
- if(iswalpha(c))
- return(1);
-
- if((c >= 0x901) && (c <= 0xdf7))
- {
- // Indic scripts: Devanagari, Tamil, etc
- if((c & 0x7f) < 0x64)
- return(1);
- return(0);
- }
-
- if((c >= 0x300) && (c <= 0x36f))
- return(1); // combining accents
-
- if((c >= 0x1100) && (c <= 0x11ff))
- return(1); //Korean jamo
-
- if((c > 0x3040) && (c <= 0xa700))
- return(1); // Chinese/Japanese. Should never get here, but Mac OS 10.4's iswalpha seems to be broken, so just make sure
-
- return(0);
-}
-
-static int IsDigit09(unsigned int c)
-{//=========================
- if((c >= '0') && (c <= '9'))
- return(1);
- return(0);
-}
-
-int IsDigit(unsigned int c)
-{//========================
- if(iswdigit(c))
- return(1);
-
- if((c >= 0x966) && (c <= 0x96f))
- return(1);
-
- return(0);
-}
-
-int IsSpace(unsigned int c)
-{//========================
- if(c == 0)
- return(0);
- if(wcschr(chars_space,c))
- return(1);
- return(iswspace(c));
-}
-
-
-void DeleteTranslator(Translator *tr)
-{//==================================
- if(tr->data_dictlist != NULL)
- Free(tr->data_dictlist);
- Free(tr);
-}
-
-
-int lookupwchar(const unsigned short *list,int c)
-{//==============================================
-// Is the character c in the list ?
- int ix;
-
- for(ix=0; list[ix] != 0; ix++)
- {
- if(list[ix] == c)
- return(ix+1);
- }
- return(0);
-}
-
-int IsBracket(int c)
-{//=================
- if((c >= 0x2014) && (c <= 0x201f))
- return(1);
- return(lookupwchar(brackets,c));
-}
-
-
-int utf8_out(unsigned int c, char *buf)
-{//====================================
-// write a unicode character into a buffer as utf8
-// returns the number of bytes written
- int n_bytes;
- int j;
- int shift;
- static char unsigned code[4] = {0,0xc0,0xe0,0xf0};
-
- if(c < 0x80)
- {
- buf[0] = c;
- return(1);
- }
- if(c >= 0x110000)
- {
- buf[0] = ' '; // out of range character code
- return(1);
- }
- if(c < 0x0800)
- n_bytes = 1;
- else
- if(c < 0x10000)
- n_bytes = 2;
- else
- n_bytes = 3;
-
- shift = 6*n_bytes;
- buf[0] = code[n_bytes] | (c >> shift);
- for(j=0; j<n_bytes; j++)
- {
- shift -= 6;
- buf[j+1] = 0x80 + ((c >> shift) & 0x3f);
- }
- return(n_bytes+1);
-} // end of utf8_out
-
-
-int utf8_nbytes(const char *buf)
-{//=============================
-// Returns the number of bytes for the first UTF-8 character in buf
- unsigned char c = (unsigned char)buf[0];
- if(c < 0x80)
- return(1);
- if(c < 0xe0)
- return(2);
- if(c < 0xf0)
- return(3);
- return(4);
-}
-
-
-int utf8_in2(int *c, const char *buf, int backwards)
-{//=================================================
-// Read a unicode characater from a UTF8 string
-// Returns the number of UTF8 bytes used.
-// backwards: set if we are moving backwards through the UTF8 string
- int c1;
- int n_bytes;
- int ix;
- static const unsigned char mask[4] = {0xff,0x1f,0x0f,0x07};
-
- // find the start of the next/previous character
- while((*buf & 0xc0) == 0x80)
- {
- // skip over non-initial bytes of a multi-byte utf8 character
- if(backwards)
- buf--;
- else
- buf++;
- }
-
- n_bytes = 0;
-
- if((c1 = *buf++) & 0x80)
- {
- if((c1 & 0xe0) == 0xc0)
- n_bytes = 1;
- else
- if((c1 & 0xf0) == 0xe0)
- n_bytes = 2;
- else
- if((c1 & 0xf8) == 0xf0)
- n_bytes = 3;
-
- c1 &= mask[n_bytes];
- for(ix=0; ix<n_bytes; ix++)
- {
- c1 = (c1 << 6) + (*buf++ & 0x3f);
- }
- }
- *c = c1;
- return(n_bytes+1);
-}
-
-
-int utf8_in(int *c, const char *buf)
-{//=================================
-// Read a unicode characater from a UTF8 string
-// Returns the number of UTF8 bytes used.
- return(utf8_in2(c,buf,0));
-}
-
-
-char *strchr_w(const char *s, int c)
-{//=================================
-// return NULL for any non-ascii character
- if(c >= 0x80)
- return(NULL);
- return(strchr((char *)s,c)); // (char *) is needed for Borland compiler
-}
-
-
-
-
-int TranslateWord(Translator *tr, char *word1, int next_pause, WORD_TAB *wtab)
-{//===========================================================================
-// word1 is terminated by space (0x20) character
-
- int length;
- int word_length;
- int ix;
- int posn;
- int pfix;
- int n_chars;
- unsigned int dictionary_flags[2];
- unsigned int dictionary_flags2[2];
- int end_type=0;
- int prefix_type=0;
- char *wordx;
- char phonemes[N_WORD_PHONEMES];
- char *ph_limit;
- char *phonemes_ptr;
- char prefix_phonemes[N_WORD_PHONEMES];
- char end_phonemes[N_WORD_PHONEMES];
- char word_copy[N_WORD_BYTES];
- char prefix_chars[N_WORD_BYTES];
- int found=0;
- int end_flags;
- char c_temp; // save a character byte while we temporarily replace it with space
- int first_char;
- int last_char = 0;
- int unpron_length;
- int add_plural_suffix = 0;
- int prefix_flags = 0;
- int confirm_prefix;
- int spell_word;
- int stress_bits;
- int emphasize_allcaps = 0;
- int wflags = wtab->flags;
- int wmark = wtab->wmark;
-
- // translate these to get pronunciations of plural 's' suffix (different forms depending on
- // the preceding letter
- static char word_zz[4] = {0,'z','z',0};
- static char word_iz[4] = {0,'i','z',0};
- static char word_ss[4] = {0,'s','s',0};
-
- dictionary_flags[0] = 0;
- dictionary_flags[1] = 0;
- dictionary_flags2[0] = 0;
- dictionary_flags2[1] = 0;
- dictionary_skipwords = 0;
-
- prefix_phonemes[0] = 0;
- end_phonemes[0] = 0;
- ph_limit = &phonemes[N_WORD_PHONEMES];
-
- // count the length of the word
- wordx = word1;
- utf8_in(&first_char,wordx);
- word_length = 0;
- while((*wordx != 0) && (*wordx != ' '))
- {
- wordx += utf8_in(&last_char,wordx);
- word_length++;
- }
-
- // try an initial lookup in the dictionary list, we may find a pronunciation specified, or
- // we may just find some flags
- spell_word = 0;
- if(option_sayas == SAYAS_KEY)
- {
- if(word_length == 1)
- spell_word = 4;
- }
-
- if(option_sayas & 0x10)
- {
- // SAYAS_CHAR, SAYAS_GYLPH, or SAYAS_SINGLE_CHAR
- spell_word = option_sayas & 0xf; // 2,3,4
- }
- else
- {
- found = LookupDictList(tr, &word1, phonemes, dictionary_flags, FLAG_ALLOW_TEXTMODE, wtab); // the original word
- if(dictionary_flags[0] & FLAG_TEXTMODE)
- {
- first_char = word1[0];
- stress_bits = dictionary_flags[0] & 0x7f;
- found = LookupDictList(tr, &word1, phonemes, dictionary_flags2, 0, wtab); // the text replacement
- if(dictionary_flags2[0]!=0)
- {
- dictionary_flags[0] = dictionary_flags2[0];
- dictionary_flags[1] = dictionary_flags2[1];
- if(stress_bits != 0)
- {
- // keep any stress information from the original word
- dictionary_flags[0] = (dictionary_flags[0] & ~0x7f) | stress_bits;
- }
- }
- }
- else
- if((found==0) && (dictionary_flags[0] & FLAG_SKIPWORDS))
- {
- // grouped words, but no translation. Join the words with hyphens.
- wordx = word1;
- ix = 0;
- while(ix < dictionary_skipwords)
- {
- if(*wordx == ' ')
- {
- *wordx = '-';
- ix++;
- }
- wordx++;
- }
- }
-
- // if textmode, LookupDictList() replaces word1 by the new text and returns found=0
-
- if(phonemes[0] == phonSWITCH)
- {
- // change to another language in order to translate this word
- strcpy(word_phonemes,phonemes);
- return(0);
- }
-
-if((wmark > 0) && (wmark < 8))
-{
- // the stressed syllable has been specified in the text (TESTING)
- dictionary_flags[0] = (dictionary_flags[0] & ~0xf) | wmark;
-}
-
- if(!found && (dictionary_flags[0] & FLAG_ABBREV))
- {
- // the word has $abbrev flag, but no pronunciation specified. Speak as individual letters
- spell_word = 1;
- }
-
- if(!found && iswdigit(first_char))
- {
- Lookup(tr,"_0lang",word_phonemes);
- if(word_phonemes[0] == phonSWITCH)
- return(0);
-
- found = TranslateNumber(tr,word1,phonemes,dictionary_flags,wflags);
- }
-
- if(!found & ((wflags & FLAG_UPPERS) != FLAG_FIRST_UPPER))
- {
- // either all upper or all lower case
-
- if((tr->langopts.numbers & NUM_ROMAN) || ((tr->langopts.numbers & NUM_ROMAN_UC) && (wflags & FLAG_ALL_UPPER)))
- {
- if((found = TranslateRoman(tr, word1, phonemes)) != 0)
- dictionary_flags[0] |= FLAG_ABBREV; // prevent emphasis if capitals
- }
- }
-
- if((wflags & FLAG_ALL_UPPER) && (word_length > 1)&& iswalpha(first_char))
- {
- if((option_tone_flags & OPTION_EMPHASIZE_ALLCAPS) && !(dictionary_flags[0] & FLAG_ABBREV))
- {
- // emphasize words which are in capitals
- emphasize_allcaps = FLAG_EMPHASIZED;
- }
- else
- if(!found && !(dictionary_flags[0] & FLAG_SKIPWORDS) && (word_length<4) && (tr->clause_lower_count > 3)
- && (tr->clause_upper_count <= tr->clause_lower_count))
- {
- // An upper case word in a lower case clause. This could be an abbreviation.
- spell_word = 1;
- }
- }
- }
-
- if(spell_word > 0)
- {
- // Speak as individual letters
- wordx = word1;
- posn = 0;
- phonemes[0] = 0;
- end_type = 0;
-
- while(*wordx != ' ')
- {
- wordx += TranslateLetter(tr,wordx, phonemes,spell_word, word_length);
- posn++;
- if(phonemes[0] == phonSWITCH)
- {
- // change to another language in order to translate this word
- strcpy(word_phonemes,phonemes);
- if(word_length > 1)
- return(FLAG_SPELLWORD); // a mixture of languages, retranslate as individual letters, separated by spaces
- return(0);
- }
- }
- SetSpellingStress(tr,phonemes,spell_word,posn);
- }
- else
- if(found == 0)
- {
- // word's pronunciation is not given in the dictionary list, although
- // dictionary_flags may have ben set there
-
- posn = 0;
- length = 999;
- wordx = word1;
-
- while(((length < 3) && (length > 0))|| (word_length > 1 && Unpronouncable(tr,wordx)))
- {
- char *p;
- // This word looks "unpronouncable", so speak letters individually until we
- // find a remainder that we can pronounce.
- emphasize_allcaps = 0;
- wordx += TranslateLetter(tr,wordx,phonemes,0, word_length);
- posn++;
- if(phonemes[0] == phonSWITCH)
- {
- // change to another language in order to translate this word
- strcpy(word_phonemes,phonemes);
- if(strcmp(&phonemes[1],"en")==0)
- return(FLAG_SPELLWORD); // _^_en must have been set in TranslateLetter(), not *_rules
- return(0);
- }
-
- p = &wordx[word_length-3]; // this looks wrong. Doesn't consider multi-byte chars.
- if(memcmp(p,"'s ",3) == 0)
- {
- // remove a 's suffix and pronounce this separately (not as an individual letter)
- add_plural_suffix = 1;
- p[0] = ' ';
- p[1] = ' ';
- last_char = p[-1];
- }
-
- length=0;
- while(wordx[length] != ' ') length++;
- if(length > 0)
- wordx[-1] = ' '; // prevent this affecting the pronunciation of the pronuncable part
- }
- SetSpellingStress(tr,phonemes,0,posn);
-
- // anything left ?
- if(*wordx != ' ')
- {
- // Translate the stem
- unpron_length = strlen(phonemes);
- end_type = TranslateRules(tr, wordx, phonemes, N_WORD_PHONEMES, end_phonemes, wflags, dictionary_flags);
-
- if(phonemes[0] == phonSWITCH)
- {
- // change to another language in order to translate this word
- strcpy(word_phonemes,phonemes);
- return(0);
- }
-
- if((phonemes[0] == 0) && (end_phonemes[0] == 0))
- {
- int wc;
- // characters not recognised, speak them individually
-
- utf8_in(&wc, wordx);
- if((word_length == 1) && IsAlpha(wc))
- {
- posn = 0;
- while((*wordx != ' ') && (*wordx != 0))
- {
- wordx += TranslateLetter(tr,wordx, phonemes, 4, word_length);
- posn++;
- if(phonemes[0] == phonSWITCH)
- {
- // change to another language in order to translate this word
- strcpy(word_phonemes,phonemes);
- return(0);
- }
- }
- SetSpellingStress(tr,phonemes,spell_word,posn);
- }
- }
-
- c_temp = wordx[-1];
-
- found = 0;
- confirm_prefix = 1;
- while(end_type & SUFX_P)
- {
- // Found a standard prefix, remove it and retranslate
-
- if(confirm_prefix && !(end_type & SUFX_B))
- {
- int end2;
- char phonemes2[N_WORD_PHONEMES];
- char end_phonemes2[N_WORD_PHONEMES];
-
- // remove any standard suffix and confirm that the prefix is still recognised
- phonemes2[0] = 0;
- end2 = TranslateRules(tr, wordx, phonemes2, N_WORD_PHONEMES, end_phonemes2, wflags|FLAG_NO_PREFIX|FLAG_NO_TRACE, dictionary_flags);
- if(end2)
- {
- RemoveEnding(tr, wordx, end2, word_copy);
- end_type = TranslateRules(tr, wordx, phonemes, N_WORD_PHONEMES, end_phonemes, wflags|FLAG_NO_TRACE, dictionary_flags);
- memcpy(wordx,word_copy,strlen(word_copy));
- if((end_type & SUFX_P) == 0)
- {
- // after removing the suffix, the prefix is no longer recognised.
- // Keep the suffix, but don't use the prefix
- end_type = end2;
- strcpy(phonemes,phonemes2);
- strcpy(end_phonemes,end_phonemes2);
- if(option_phonemes == 2)
- {
- DecodePhonemes(end_phonemes,end_phonemes2);
- fprintf(f_trans," suffix [%s]\n\n",end_phonemes2);
- }
- }
- confirm_prefix = 0;
- continue;
- }
- }
-
- prefix_type = end_type;
-
- if(prefix_type & SUFX_V)
- {
- tr->expect_verb = 1; // use the verb form of the word
- }
-
- wordx[-1] = c_temp;
-
- if((prefix_type & SUFX_B) == 0)
- {
- for(ix=(prefix_type & 0xf); ix>0; ix--) // num. of characters to remove
- {
- wordx++;
- while((*wordx & 0xc0) == 0x80) wordx++; // for multibyte characters
- }
- }
- else
- {
- pfix = 1;
- prefix_chars[0] = 0;
- n_chars = prefix_type & 0x3f;
-
- for(ix=0; ix < n_chars; ix++) // num. of bytes to remove
- {
- prefix_chars[pfix++] = *wordx++;
-
- if((prefix_type & SUFX_B) && (ix == (n_chars-1)))
- {
- prefix_chars[pfix-1] = 0; // discard the last character of the prefix, this is the separator character
- }
- }
- prefix_chars[pfix] = 0;
- }
- c_temp = wordx[-1];
- wordx[-1] = ' ';
- confirm_prefix = 1;
-
- if(prefix_type & SUFX_B)
- {
-// SUFX_B is used for Turkish, tr_rules contains "(Pb£
- // retranslate the prefix part
- char *wordpf;
- char prefix_phonemes2[12];
-
- strncpy0(prefix_phonemes2,end_phonemes,sizeof(prefix_phonemes2));
- wordpf = &prefix_chars[1];
- found = LookupDictList(tr, &wordpf, phonemes, dictionary_flags, SUFX_P, wtab); // without prefix
- if(found == 0)
- {
- end_type = TranslateRules(tr, wordpf, phonemes, N_WORD_PHONEMES, end_phonemes, 0, dictionary_flags);
- sprintf(prefix_phonemes,"%s%s%s",phonemes,end_phonemes,prefix_phonemes2);
- }
- prefix_flags = 1;
- }
- else
- {
- strcat(prefix_phonemes,end_phonemes);
- }
- end_phonemes[0] = 0;
-
- end_type = 0;
- found = LookupDictList(tr, &wordx, phonemes, dictionary_flags2, SUFX_P, wtab); // without prefix
- if(dictionary_flags[0]==0)
- {
- dictionary_flags[0] = dictionary_flags2[0];
- dictionary_flags[1] = dictionary_flags2[1];
- }
- else
- prefix_flags = 1;
- if(found == 0)
- {
- end_type = TranslateRules(tr, wordx, phonemes, N_WORD_PHONEMES, end_phonemes, 0, dictionary_flags);
-
- if(phonemes[0] == phonSWITCH)
- {
- // change to another language in order to translate this word
- wordx[-1] = c_temp;
- strcpy(word_phonemes,phonemes);
- return(0);
- }
- }
- }
-
- if((end_type != 0) && !(end_type & SUFX_P))
- {
-char phonemes2[N_WORD_PHONEMES];
-strcpy(phonemes2,phonemes);
-
- // The word has a standard ending, re-translate without this ending
- end_flags = RemoveEnding(tr, wordx, end_type, word_copy);
-
- phonemes_ptr = &phonemes[unpron_length];
- phonemes_ptr[0] = 0;
-
- if(prefix_phonemes[0] != 0)
- {
- // lookup the stem without the prefix removed
- wordx[-1] = c_temp;
- found = LookupDictList(tr, &word1, phonemes_ptr, dictionary_flags2, end_flags, wtab); // include prefix, but not suffix
- wordx[-1] = ' ';
- if(dictionary_flags[0]==0)
- {
- dictionary_flags[0] = dictionary_flags2[0];
- dictionary_flags[1] = dictionary_flags2[1];
- }
- if(found)
- prefix_phonemes[0] = 0; // matched whole word, don't need prefix now
-
- if((found==0) && (dictionary_flags2[0] != 0))
- prefix_flags = 1;
- }
- if(found == 0)
- {
- found = LookupDictList(tr, &wordx, phonemes_ptr, dictionary_flags2, end_flags, wtab); // without prefix and suffix
- if(phonemes_ptr[0] == phonSWITCH)
- {
- // change to another language in order to translate this word
- memcpy(wordx,word_copy,strlen(word_copy));
- strcpy(word_phonemes,phonemes_ptr);
- return(0);
- }
- if(dictionary_flags[0]==0)
- {
- dictionary_flags[0] = dictionary_flags2[0];
- dictionary_flags[1] = dictionary_flags2[1];
- }
- }
- if(found == 0)
- {
- if(end_type & SUFX_Q)
- {
- // don't retranslate, use the original lookup result
- strcpy(phonemes,phonemes2);
-
- // language specific changes
- ApplySpecialAttribute(tr,phonemes,dictionary_flags[0]);
- }
- else
- {
- if(end_flags & FLAG_SUFX)
- TranslateRules(tr, wordx, phonemes, N_WORD_PHONEMES, NULL,wflags | FLAG_SUFFIX_REMOVED, dictionary_flags);
- else
- TranslateRules(tr, wordx, phonemes, N_WORD_PHONEMES, NULL,wflags,dictionary_flags);
-
- if(phonemes[0] == phonSWITCH)
- {
- // change to another language in order to translate this word
- strcpy(word_phonemes,phonemes);
- memcpy(wordx,word_copy,strlen(word_copy));
- wordx[-1] = c_temp;
- return(0);
- }
- }
- }
-
- if((end_type & SUFX_T) == 0)
- {
- // the default is to add the suffix and then determine the word's stress pattern
- AppendPhonemes(tr,phonemes, N_WORD_PHONEMES, end_phonemes);
- end_phonemes[0] = 0;
- }
- }
- wordx[-1] = c_temp;
- }
- }
-
- if((add_plural_suffix) || (wflags & FLAG_HAS_PLURAL))
- {
- // s or 's suffix, append [s], [z] or [Iz] depending on previous letter
- if(last_char == 'f')
- TranslateRules(tr, &word_ss[1], phonemes, N_WORD_PHONEMES, NULL, 0, NULL);
- else
- if((last_char==0) || (strchr_w("hsx",last_char)==NULL))
- TranslateRules(tr, &word_zz[1], phonemes, N_WORD_PHONEMES, NULL, 0, NULL);
- else
- TranslateRules(tr, &word_iz[1], phonemes, N_WORD_PHONEMES, NULL, 0, NULL);
- }
-
- wflags |= emphasize_allcaps;
-
-
- /* determine stress pattern for this word */
- /******************************************/
- /* NOTE: this also adds a single PAUSE if the previous word ended
- in a primary stress, and this one starts with one */
- if(prefix_flags || (strchr(prefix_phonemes,phonSTRESS_P)!=NULL))
- {
- if((tr->langopts.param[LOPT_PREFIXES]) || (prefix_type & SUFX_T))
- {
- char *p;
- // German, keep a secondary stress on the stem
- SetWordStress(tr, phonemes, &dictionary_flags[0], 3, 0);
-
- // reduce all but the first primary stress
- ix=0;
- for(p=prefix_phonemes; *p != 0; p++)
- {
- if(*p == phonSTRESS_P)
- {
- if(ix==0)
- ix=1;
- else
- *p = phonSTRESS_3;
- }
- }
- strcpy(word_phonemes,prefix_phonemes);
- strcat(word_phonemes,phonemes);
- SetWordStress(tr, word_phonemes, &dictionary_flags[0], -1, 0);
- }
- else
- {
- // stress position affects the whole word, including prefix
- strcpy(word_phonemes,prefix_phonemes);
- strcat(word_phonemes,phonemes);
- SetWordStress(tr, word_phonemes, &dictionary_flags[0], -1, tr->prev_last_stress);
- }
- }
- else
- {
- if(prefix_phonemes[0] == 0)
- SetWordStress(tr, phonemes, &dictionary_flags[0], -1, tr->prev_last_stress);
- else
- SetWordStress(tr, phonemes, &dictionary_flags[0], -1, 0);
- strcpy(word_phonemes,prefix_phonemes);
- strcat(word_phonemes,phonemes);
- }
-
- if(end_phonemes[0] != 0)
- {
- // a suffix had the SUFX_T option set, add the suffix after the stress pattern has been determined
- strcat(word_phonemes,end_phonemes);
- }
-
- if(wflags & FLAG_LAST_WORD)
- {
- // don't use $brk pause before the last word of a sentence
- // (but allow it for emphasis, see below
- dictionary_flags[0] &= ~FLAG_PAUSE1;
- }
-
- if(wflags & FLAG_EMPHASIZED2)
- {
- // A word is indicated in the source text as stressed
- // Give it stress level 6 (for the intonation module)
- ChangeWordStress(tr,word_phonemes,6);
-
- if(wflags & FLAG_EMPHASIZED)
- dictionary_flags[0] |= FLAG_PAUSE1; // precede by short pause
- }
- else
- if(wtab[dictionary_skipwords].flags & FLAG_LAST_WORD)
- {
- // the word has attribute to stress or unstress when at end of clause
- if(dictionary_flags[0] & (FLAG_STRESS_END | FLAG_STRESS_END2))
- ChangeWordStress(tr,word_phonemes,4);
- else
- if(dictionary_flags[0] & FLAG_UNSTRESS_END)
- ChangeWordStress(tr,word_phonemes,3);
- }
-
- // dictionary flags for this word give a clue about which alternative pronunciations of
- // following words to use.
- if(end_type & SUFX_F)
- {
- // expect a verb form, with or without -s suffix
- tr->expect_verb = 2;
- tr->expect_verb_s = 2;
- }
-
- if(dictionary_flags[1] & FLAG_PASTF)
- {
- /* expect perfect tense in next two words */
- tr->expect_past = 3;
- tr->expect_verb = 0;
- tr->expect_noun = 0;
- }
- else
- if(dictionary_flags[1] & FLAG_VERBF)
- {
- /* expect a verb in the next word */
- tr->expect_verb = 2;
- tr->expect_verb_s = 0; /* verb won't have -s suffix */
- tr->expect_noun = 0;
- }
- else
- if(dictionary_flags[1] & FLAG_VERBSF)
- {
- // expect a verb, must have a -s suffix
- tr->expect_verb = 0;
- tr->expect_verb_s = 2;
- tr->expect_past = 0;
- tr->expect_noun = 0;
- }
- else
- if(dictionary_flags[1] & FLAG_NOUNF)
- {
- /* not expecting a verb next */
- tr->expect_noun = 2;
- tr->expect_verb = 0;
- tr->expect_verb_s = 0;
- tr->expect_past = 0;
- }
-
- if((wordx[0] != 0) && (!(dictionary_flags[1] & FLAG_VERB_EXT)))
- {
- if(tr->expect_verb > 0)
- tr->expect_verb--;
-
- if(tr->expect_verb_s > 0)
- tr->expect_verb_s--;
-
- if(tr->expect_noun >0)
- tr->expect_noun--;
-
- if(tr->expect_past > 0)
- tr->expect_past--;
- }
-
- if((word_length == 1) && iswalpha(first_char) && (first_char != 'i'))
- {
-// English Specific !!!!
- // any single letter before a dot is an abbreviation, except 'I'
- dictionary_flags[0] |= FLAG_DOT;
- }
-
- if((tr->langopts.param[LOPT_ALT] & 2) && ((dictionary_flags[0] & (FLAG_ALT_TRANS | FLAG_ALT2_TRANS)) != 0))
- {
- ApplySpecialAttribute2(tr,word_phonemes,dictionary_flags[0]);
- }
-
- return(dictionary_flags[0]);
-} // end of TranslateWord
-
-
-
-static void SetPlist2(PHONEME_LIST2 *p, unsigned char phcode)
-{//==========================================================
- p->phcode = phcode;
- p->stress = 0;
- p->tone_number = 0;
- p->synthflags = embedded_flag;
- p->sourceix = 0;
- embedded_flag = 0;
-}
-
-static int CountSyllables(unsigned char *phonemes)
-{//===============================================
- int count = 0;
- int phon;
- while((phon = *phonemes++) != 0)
- {
- if(phoneme_tab[phon]->type == phVOWEL)
- count++;
- }
- return(count);
-}
-
-
-int SetTranslator2(const char *new_language)
-{//=========================================
-// Set translator2 to a second language
- int new_phoneme_tab;
-
- if((new_phoneme_tab = SelectPhonemeTableName(new_language)) >= 0)
- {
- if((translator2 != NULL) && (strcmp(new_language,translator2_language) != 0))
- {
- // we already have an alternative translator, but not for the required language, delete it
- DeleteTranslator(translator2);
- translator2 = NULL;
- }
-
- if(translator2 == NULL)
- {
- translator2 = SelectTranslator(new_language);
- strcpy(translator2_language,new_language);
-
- if(LoadDictionary(translator2, new_language, 0) != 0)
- {
- SelectPhonemeTable(voice->phoneme_tab_ix); // revert to original phoneme table
- new_phoneme_tab = -1;
- translator2_language[0] = 0;
- }
- }
- }
- return(new_phoneme_tab);
-} // end of SetTranslator2
-
-
-
-static int TranslateWord2(Translator *tr, char *word, WORD_TAB *wtab, int pre_pause, int next_pause)
-{//=================================================================================================
- int flags=0;
- int stress;
- int next_stress;
- int next_tone=0;
- unsigned char *p;
- int srcix;
- int embedded_cmd;
- int value;
- int found_dict_flag;
- unsigned char ph_code;
- PHONEME_LIST2 *plist2;
- PHONEME_TAB *ph;
- int max_stress;
- int max_stress_ix=0;
- int prev_vowel = -1;
- int pitch_raised = 0;
- int switch_phonemes = -1;
- int first_phoneme = 1;
- int source_ix;
- int len;
- int ix;
- int sylimit; // max. number of syllables in a word to be combined with a preceding preposition
- const char *new_language;
- unsigned char bad_phoneme[4];
- int word_flags;
- int word_copy_len;
- char word_copy[N_WORD_BYTES+1];
-
- len = wtab->length;
- if(len > 31) len = 31;
- source_ix = (wtab->sourceix & 0x7ff) | (len << 11); // bits 0-10 sourceix, bits 11-15 word length
-
- word_flags = wtab[0].flags;
- if(word_flags & FLAG_EMBEDDED)
- {
- embedded_flag = SFLAG_EMBEDDED;
-
- do
- {
- embedded_cmd = embedded_list[embedded_read++];
- value = embedded_cmd >> 8;
-
- switch(embedded_cmd & 0x1f)
- {
- case EMBED_Y:
- option_sayas = value;
- break;
-
- case EMBED_F:
- option_emphasis = value;
- break;
-
- case EMBED_B:
- // break command
- if(value == 0)
- pre_pause = 0; // break=none
- else
- pre_pause += value;
- break;
- }
- } while((embedded_cmd & 0x80) == 0);
- }
-
- if(word[0] == 0)
- {
- // nothing to translate
- word_phonemes[0] = 0;
- return(0);
- }
-
- // after a $pause word attribute, ignore a $pause attribute on the next two words
- if(tr->prepause_timeout > 0)
- tr->prepause_timeout--;
-
- if((option_sayas & 0xf0) == 0x10)
- {
- if(!(word_flags & FLAG_FIRST_WORD))
- {
- // SAYAS_CHARS, SAYAS_GLYPHS, or SAYAS_SINGLECHARS. Pause between each word.
- pre_pause += 4;
- }
- }
-
- if(word_flags & FLAG_FIRST_UPPER)
- {
- if((option_capitals > 2) && (embedded_ix < N_EMBEDDED_LIST-6))
- {
- // indicate capital letter by raising pitch
- if(embedded_flag)
- embedded_list[embedded_ix-1] &= ~0x80; // already embedded command before this word, remove terminator
- if((pitch_raised = option_capitals) == 3)
- pitch_raised = 20; // default pitch raise for capitals
- embedded_list[embedded_ix++] = EMBED_P+0x40+0x80 + (pitch_raised << 8); // raise pitch
- embedded_flag = SFLAG_EMBEDDED;
- }
- }
-
- p = (unsigned char *)word_phonemes;
- if(word_flags & FLAG_PHONEMES)
- {
- // The input is in phoneme mnemonics, not language text
- int c1;
- char lang_name[12];
-
- if(memcmp(word,"_^_",3)==0)
- {
- // switch languages
- word+=3;
- for(ix=0;;)
- {
- c1 = *word++;
- if((c1==' ') || (c1==0))
- break;
- lang_name[ix++] = tolower(c1);
- }
- lang_name[ix] = 0;
-
- if((ix = LookupPhonemeTable(lang_name)) > 0)
- {
- SelectPhonemeTable(ix);
- word_phonemes[0] = phonSWITCH;
- word_phonemes[1] = ix;
- word_phonemes[2] = 0;
- }
- }
- else
- {
- EncodePhonemes(word,word_phonemes,bad_phoneme);
- }
- flags = FLAG_FOUND;
- }
- else
- {
- int c2;
- ix = 0;
- while(((c2 = word_copy[ix] = word[ix]) != ' ') && (c2 != 0) && (ix < N_WORD_BYTES)) ix++;
- word_copy_len = ix;
-
- flags = TranslateWord(translator, word, next_pause, wtab);
-
- if(flags & FLAG_SPELLWORD)
- {
- // re-translate the word as individual letters, separated by spaces
- memcpy(word, word_copy, word_copy_len);
- return(flags);
- }
-
- if((flags & FLAG_ALT2_TRANS) && ((sylimit = tr->langopts.param[LOPT_COMBINE_WORDS]) > 0))
- {
- char *p2;
- int ok = 1;
- int flags2;
- int c_word2;
- char ph_buf[N_WORD_PHONEMES];
-
- // LANG=cs,sk
- // combine a preposition with the following word
- p2 = word;
- while(*p2 != ' ') p2++;
-
- utf8_in(&c_word2, p2+1); // first character of the next word;
- if(!iswalpha(c_word2))
- {
- ok =0;
- }
-
- if(ok != 0)
- {
- if(sylimit & 0x100)
- {
- // only if the second word has $alt attribute
- strcpy(ph_buf,word_phonemes);
- flags2 = TranslateWord(translator, p2+1, 0, wtab+1);
- if((flags2 & FLAG_ALT_TRANS) == 0)
- {
- ok = 0;
- strcpy(word_phonemes,ph_buf);
- }
- }
-
- if((sylimit & 0x200) && ((wtab+1)->flags & FLAG_LAST_WORD))
- {
- // not if the next word is end-of-sentence
- ok = 0;
- }
- }
-
- if(ok)
- {
- *p2 = '-'; // replace next space by hyphen
- flags = TranslateWord(translator, word, next_pause, wtab); // translate the combined word
- if(CountSyllables(p) > (sylimit & 0xf))
- {
- // revert to separate words
- *p2 = ' ';
- flags = TranslateWord(translator, word, next_pause, wtab);
- }
- else
- {
- flags |= FLAG_SKIPWORDS;
- dictionary_skipwords = 1;
- }
- }
- }
-
- if(p[0] == phonSWITCH)
- {
- // this word uses a different language
- memcpy(word, word_copy, word_copy_len);
-
- new_language = (char *)(&p[1]);
- if(new_language[0]==0)
- new_language = "en";
-
- switch_phonemes = SetTranslator2(new_language);
-
- if(switch_phonemes >= 0)
- {
- // re-translate the word using the new translator
- flags = TranslateWord(translator2, word, next_pause, wtab);
-// strcpy((char *)p,translator2->word_phonemes);
- if(p[0] == phonSWITCH)
- {
- // the second translator doesn't want to process this word
- switch_phonemes = -1;
- }
- }
- if(switch_phonemes < 0)
- {
- // language code is not recognised or 2nd translator won't translate it
- p[0] = phonSCHWA; // just say something
- p[1] = phonSCHWA;
- p[2] = 0;
- }
- }
-
- if(!(word_flags & FLAG_HYPHEN))
- {
- if(flags & FLAG_PAUSE1)
- {
- if(pre_pause < 1)
- pre_pause = 1;
- }
- if((flags & FLAG_PREPAUSE) && ((word_flags && FLAG_LAST_WORD) == 0) && (tr->prepause_timeout == 0))
- {
- // the word is marked in the dictionary list with $pause
- if(pre_pause < 4) pre_pause = 4;
- tr->prepause_timeout = 3;
- }
- }
-
- if((option_emphasis >= 3) && (pre_pause < 1))
- pre_pause = 1;
- }
-
- plist2 = &ph_list2[n_ph_list2];
- stress = 0;
- next_stress = 0;
- srcix = 0;
- max_stress = -1;
-
- found_dict_flag = 0;
- if(flags & FLAG_FOUND)
- found_dict_flag = SFLAG_DICTIONARY;
-
- while((pre_pause > 0) && (n_ph_list2 < N_PHONEME_LIST-4))
- {
- // add pause phonemes here. Either because of punctuation (brackets or quotes) in the
- // text, or because the word is marked in the dictionary lookup as a conjunction
- if(pre_pause > 1)
- {
- SetPlist2(&ph_list2[n_ph_list2++],phonPAUSE);
- pre_pause -= 2;
- }
- else
- {
- SetPlist2(&ph_list2[n_ph_list2++],phonPAUSE_NOLINK);
- pre_pause--;
- }
- tr->end_stressed_vowel = 0; // forget about the previous word
- tr->prev_dict_flags = 0;
- }
-
- if((option_capitals==1) && (word_flags & FLAG_FIRST_UPPER))
- {
- SetPlist2(&ph_list2[n_ph_list2++],phonPAUSE_SHORT);
- SetPlist2(&ph_list2[n_ph_list2++],phonCAPITAL);
- if((word_flags & FLAG_ALL_UPPER) && IsAlpha(word[1]))
- {
- // word > 1 letter and all capitals
- SetPlist2(&ph_list2[n_ph_list2++],phonPAUSE_SHORT);
- SetPlist2(&ph_list2[n_ph_list2++],phonCAPITAL);
- }
- }
-
- if(switch_phonemes >= 0)
- {
- // this word uses a different phoneme table
- SetPlist2(&ph_list2[n_ph_list2],phonSWITCH);
- ph_list2[n_ph_list2++].tone_number = switch_phonemes; // temporary phoneme table number
- }
-
- // remove initial pause from a word if it follows a hyphen
- if((word_flags & FLAG_HYPHEN) && (phoneme_tab[*p]->type == phPAUSE))
- p++;
-
- while(((ph_code = *p++) != 0) && (n_ph_list2 < N_PHONEME_LIST-4))
- {
- if(ph_code == 255)
- continue; // unknown phoneme
-
- // Add the phonemes to the first stage phoneme list (ph_list2)
- ph = phoneme_tab[ph_code];
-
- if(ph_code == phonSWITCH)
- {
- ph_list2[n_ph_list2].phcode = ph_code;
- ph_list2[n_ph_list2].sourceix = 0;
- ph_list2[n_ph_list2].synthflags = embedded_flag;
- ph_list2[n_ph_list2++].tone_number = *p++;
- }
- else
- if(ph->type == phSTRESS)
- {
- // don't add stress phonemes codes to the list, but give their stress
- // value to the next vowel phoneme
- // std_length is used to hold stress number or (if >10) a tone number for a tone language
- if(ph->spect == 0)
- next_stress = ph->std_length;
- else
- {
- // for tone languages, the tone number for a syllable follows the vowel
- if(prev_vowel >= 0)
- {
- ph_list2[prev_vowel].tone_number = ph_code;
- }
- else
- {
- next_tone = ph_code; // no previous vowel, apply to the next vowel
- }
- }
- }
- else
- if(ph_code == phonSYLLABIC)
- {
- // mark the previous phoneme as a syllabic consonant
- prev_vowel = n_ph_list2-1;
- ph_list2[prev_vowel].synthflags |= SFLAG_SYLLABLE;
- ph_list2[prev_vowel].stress = next_stress;
- }
- else
- if(ph_code == phonLENGTHEN)
- {
- ph_list2[n_ph_list2-1].synthflags |= SFLAG_LENGTHEN;
- }
- else
- if(ph_code == phonEND_WORD)
- {
- // a || symbol in a phoneme string was used to indicate a word boundary
- // Don't add this phoneme to the list, but make sure the next phoneme has
- // a newword indication
- srcix = source_ix+1;
- }
- else
- if(ph_code == phonX1)
- {
- // a language specific action
- if(tr->langopts.param[LOPT_IT_DOUBLING])
- {
- flags |= FLAG_DOUBLING;
- }
- }
- else
- {
- ph_list2[n_ph_list2].phcode = ph_code;
- ph_list2[n_ph_list2].tone_number = 0;
- ph_list2[n_ph_list2].synthflags = embedded_flag | found_dict_flag;
- embedded_flag = 0;
- ph_list2[n_ph_list2].sourceix = srcix;
- srcix = 0;
-
- if(ph->type == phVOWEL)
- {
- stress = next_stress;
- next_stress = 0;
-
- if((prev_vowel >= 0) && (n_ph_list2-1) != prev_vowel)
- ph_list2[n_ph_list2-1].stress = stress; // set stress for previous consonant
-
- ph_list2[n_ph_list2].synthflags |= SFLAG_SYLLABLE;
- prev_vowel = n_ph_list2;
-
- if(stress > max_stress)
- {
- max_stress = stress;
- max_stress_ix = n_ph_list2;
- }
- if(next_tone != 0)
- {
- ph_list2[n_ph_list2].tone_number = next_tone;
- next_tone=0;
- }
- }
- else
- {
- if(first_phoneme && tr->langopts.param[LOPT_IT_DOUBLING])
- {
- if(((tr->prev_dict_flags & FLAG_DOUBLING) && (tr->langopts.param[LOPT_IT_DOUBLING] & 1)) ||
- (tr->end_stressed_vowel && (tr->langopts.param[LOPT_IT_DOUBLING] & 2)))
- {
- // italian, double the initial consonant if the previous word ends with a
- // stressed vowel, or is marked with a flag
- ph_list2[n_ph_list2].synthflags |= SFLAG_LENGTHEN;
- }
- }
- }
-
- ph_list2[n_ph_list2].stress = stress;
- n_ph_list2++;
- first_phoneme = 0;
- }
- }
- // don't set new-word if there is a hyphen before it
- if((word_flags & FLAG_HYPHEN) == 0)
- {
- plist2->sourceix = source_ix;
- }
-
- tr->end_stressed_vowel = 0;
- if((stress >= 4) && (phoneme_tab[ph_list2[n_ph_list2-1].phcode]->type == phVOWEL))
- {
- tr->end_stressed_vowel = 1; // word ends with a stressed vowel
- }
-
- if(switch_phonemes >= 0)
- {
- // this word uses a different phoneme table, now switch back
- SelectPhonemeTable(voice->phoneme_tab_ix);
- SetPlist2(&ph_list2[n_ph_list2],phonSWITCH);
- ph_list2[n_ph_list2++].tone_number = voice->phoneme_tab_ix; // original phoneme table number
- }
-
-
- if(pitch_raised > 0)
- {
- embedded_list[embedded_ix++] = EMBED_P+0x60+0x80 + (pitch_raised << 8); // lower pitch
- SetPlist2(&ph_list2[n_ph_list2],phonPAUSE_SHORT);
- ph_list2[n_ph_list2++].synthflags = SFLAG_EMBEDDED;
- }
-
- if(flags & FLAG_STRESS_END2)
- {
- // this's word's stress could be increased later
- ph_list2[max_stress_ix].synthflags |= SFLAG_PROMOTE_STRESS;
- }
-
- tr->prev_dict_flags = flags;
- return(flags);
-} // end of TranslateWord2
-
-
-
-static int EmbeddedCommand(unsigned int *source_index)
-{//===================================================
- // An embedded command to change the pitch, volume, etc.
- // returns number of commands added to embedded_list
-
- // pitch,speed,amplitude,expression,reverb,tone,voice,sayas
- const char *commands = "PSARHTIVYMUBF";
- int value = -1;
- int sign = 0;
- unsigned char c;
- char *p;
- int cmd;
-
- c = source[*source_index];
- if(c == '+')
- {
- sign = 0x40;
- (*source_index)++;
- }
- else
- if(c == '-')
- {
- sign = 0x60;
- (*source_index)++;
- }
-
- if(isdigit(source[*source_index]))
- {
- value = atoi(&source[*source_index]);
- while(isdigit(source[*source_index]))
- source_index++;
- }
-
- c = source[(*source_index)++];
- if(embedded_ix >= (N_EMBEDDED_LIST - 2))
- return(0); // list is full
-
- if((p = strchr_w(commands,c)) == NULL)
- return(0);
- cmd = (p - commands)+1;
- if(value == -1)
- {
- value = embedded_default[cmd];
- sign = 0;
- }
-
- if(cmd == EMBED_Y)
- {
- option_sayas2 = value;
- count_sayas_digits = 0;
- }
- if(cmd == EMBED_F)
- {
- if(value >= 3)
- word_emphasis = FLAG_EMPHASIZED;
- else
- word_emphasis = 0;
- }
-
- embedded_list[embedded_ix++] = cmd + sign + (value << 8);
- return(1);
-} // end of EmbeddedCommand
-
-
-
-static int SubstituteChar(Translator *tr, unsigned int c, unsigned int next_in, int *insert)
-{//=========================================================================================
- int ix;
- unsigned int word;
- unsigned int new_c, c2, c_lower;
- int upper_case = 0;
- static int ignore_next = 0;
- const unsigned int *replace_chars;
-
- if(ignore_next)
- {
- ignore_next = 0;
- return(8);
- }
- if(c == 0) return(0);
-
- if((replace_chars = tr->langopts.replace_chars) == NULL)
- return(c);
-
- // there is a list of character codes to be substituted with alternative codes
-
- if(iswupper(c_lower = c))
- {
- c_lower = towlower(c);
- upper_case = 1;
- }
-
- new_c = 0;
- for(ix=0; (word = replace_chars[ix]) != 0; ix+=2)
- {
- if(c_lower == (word & 0xffff))
- {
- if((word >> 16) == 0)
- {
- new_c = replace_chars[ix+1];
- break;
- }
- if((word >> 16) == (unsigned int)towlower(next_in))
- {
- new_c = replace_chars[ix+1];
- ignore_next = 1;
- break;
- }
- }
- }
-
- if(new_c == 0)
- return(c); // no substitution
-
- if(new_c & 0xffe00000)
- {
- // there is a second character to be inserted
- // don't convert the case of the second character unless the next letter is also upper case
- c2 = new_c >> 16;
- if(upper_case && iswupper(next_in))
- c2 = towupper(c2);
- *insert = c2;
- new_c &= 0xffff;
- }
-
- if(upper_case)
- new_c = towupper(new_c);
- return(new_c);
-
-}
-
-
-static int TranslateChar(Translator *tr, char *ptr, int prev_in, unsigned int c, unsigned int next_in, int *insert)
-{//================================================================================================================
- // To allow language specific examination and replacement of characters
-
- int code;
- int initial;
- int medial;
- int final;
- int next2;
-
- static const unsigned char hangul_compatibility[0x34] = {
- 0, 0x00,0x01,0xaa,0x02,0xac,0xad,0x03,
- 0x04,0x05,0xb0,0xb1,0xb2,0xb3,0xb4,0xb4,
- 0xb6,0x06,0x07,0x08,0xb9,0x09,0x0a,0xbc,
- 0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x61,
- 0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
- 0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,
- 0x72,0x73,0x74,0x75 };
-
- switch(tr->translator_name)
- {
- case L('a','f'):
- // look for 'n and replace by a special character (unicode: schwa)
-
- utf8_in(&next2, &ptr[1]);
-
- if(!iswalpha(prev_in))
- {
- if((c == '\'') && (next_in == 'n') && IsSpace(next2))
- {
- // n preceded by either apostrophe or U2019 "right single quotation mark"
- ptr[0] = ' '; // delete the n
- return(0x0259); // replace ' by unicode schwa character
- }
- }
- break;
-
- case L('k','o'):
- if(((code = c - 0xac00) >= 0) && (c <= 0xd7af))
- {
- // break a syllable hangul into 2 or 3 individual jamo
- initial = (code/28)/21;
- medial = (code/28) % 21;
- final = code % 28;
-
- if(initial == 11)
- {
- // null initial
- c = medial + 0x1161;
- if(final > 0)
- *insert = final + 0x11a7;
- }
- else
- {
- // extact the initial and insert the remainder with a null initial
- c = initial + 0x1100;
- *insert = (11*28*21) + (medial*28) + final + 0xac00;
- }
- return(c);
- }
- else
- if(((code = c - 0x3130) >= 0) && (code < 0x34))
- {
- // Hangul compatibility jamo
- return(hangul_compatibility[code] + 0x1100);
- }
- break;
- }
- return(SubstituteChar(tr,c,next_in,insert));
-}
-
-
-void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *tone_out, char **voice_change)
-{//==========================================================================================================
- int ix;
- int c;
- int cc;
- unsigned int source_index=0;
- unsigned int prev_source_index=0;
- int prev_in;
- int prev_out=' ';
- int prev_out2;
- int prev_in2=0;
- int next_in;
- int char_inserted=0;
- int clause_pause;
- int pre_pause_add=0;
- int word_mark = 0;
- int all_upper_case=FLAG_ALL_UPPER;
- int finished;
- int single_quoted;
- int phoneme_mode = 0;
- int dict_flags = 0; // returned from dictionary lookup
- int word_flags; // set here
- int next_word_flags;
- int embedded_count = 0;
- int letter_count = 0;
- int space_inserted = 0;
- int syllable_marked = 0;
- int decimal_sep_count = 0;
- char *word;
- char *p;
- int j, k;
- int n_digits;
- int charix_top=0;
-
- short charix[N_TR_SOURCE+4];
- WORD_TAB words[N_CLAUSE_WORDS];
- int word_count=0; // index into words
-
- char sbuf[N_TR_SOURCE];
-
- int terminator;
- int tone;
- int tone2;
-
- p_textinput = (unsigned char *)vp_input;
- p_wchar_input = (wchar_t *)vp_input;
-
- embedded_ix = 0;
- embedded_read = 0;
- option_phoneme_input &= ~2; // clear bit 1 (temporary indication)
- pre_pause = 0;
-
- if((clause_start_char = count_characters) < 0)
- clause_start_char = 0;
- clause_start_word = count_words + 1;
-
- for(ix=0; ix<N_TR_SOURCE; ix++)
- charix[ix] = 0;
- terminator = ReadClause(tr, f_text, source, charix, &charix_top, N_TR_SOURCE, &tone2);
-
- charix[charix_top+1] = 0;
- charix[charix_top+2] = 0x7fff;
- charix[charix_top+3] = 0;
-
- clause_pause = (terminator & 0xfff) * 10; // mS
- tone = (terminator >> 12) & 0xf;
- if(tone2 != 0)
- {
- // override the tone type
- tone = tone2;
- }
-
- for(p=source; *p != 0; p++)
- {
- if(!isspace2(*p))
- {
- break;
- }
- }
- if(*p == 0)
- {
- // No characters except spaces. This is not a sentence.
- // Don't add this pause, just make up the previous pause to this value;
- clause_pause -= max_clause_pause;
- if(clause_pause < 0)
- clause_pause = 0;
-
- terminator &= ~CLAUSE_BIT_SENTENCE; // clear sentence bit
- max_clause_pause += clause_pause;
- }
- else
- {
- max_clause_pause = clause_pause;
- }
-
- if(new_sentence)
- {
- count_sentences++;
- if(skip_sentences > 0)
- {
- skip_sentences--;
- if(skip_sentences == 0)
- skipping_text = 0;
- }
- }
-
- memset(&ph_list2[0],0,sizeof(ph_list2[0]));
- ph_list2[0].phcode = phonPAUSE_SHORT;
-
- n_ph_list2 = 1;
- tr->prev_last_stress = 0;
- tr->prepause_timeout = 0;
- tr->expect_verb=0;
- tr->expect_noun=0;
- tr->expect_past=0;
- tr->expect_verb_s=0;
- tr->phonemes_repeat_count = 0;
- tr->end_stressed_vowel=0;
- tr->prev_dict_flags = 0;
-
- word_count = 0;
- single_quoted = 0;
- word_flags = 0;
- next_word_flags = 0;
-
- sbuf[0] = 0;
- sbuf[1] = ' ';
- sbuf[2] = ' ';
- ix = 3;
- prev_in = ' ';
-
- words[0].start = ix;
- words[0].flags = 0;
- finished = 0;
-
- for(j=0; charix[j]==0; j++);
- words[0].sourceix = charix[j];
- k = 0;
- while(charix[j] != 0)
- {
- // count the number of characters (excluding multibyte continuation bytes)
- if(charix[j++] != -1)
- k++;
- }
- words[0].length = k;
-
- while(!finished && (ix < (int)sizeof(sbuf))&& (n_ph_list2 < N_PHONEME_LIST-4))
- {
- prev_out2 = prev_out;
- utf8_in2(&prev_out,&sbuf[ix-1],1); // prev_out = sbuf[ix-1];
-
- if(tr->langopts.tone_numbers && IsDigit09(prev_out) && IsAlpha(prev_out2))
- {
- // tone numbers can be part of a word, consider them as alphabetic
- prev_out = 'a';
- }
-
- if(prev_in2 != 0)
- {
- prev_in = prev_in2;
- prev_in2 = 0;
- }
- else
- if(source_index > 0)
- {
- utf8_in2(&prev_in,&source[source_index-1],1); // prev_in = source[source_index-1];
- }
-
- prev_source_index = source_index;
-
- if(char_inserted)
- {
- c = char_inserted;
- char_inserted = 0;
- }
- else
- {
- source_index += utf8_in(&cc,&source[source_index]); // cc = source[source_index++];
- c = cc;
- }
- utf8_in(&next_in,&source[source_index]);
-
- if((c == CTRL_EMBEDDED) || (c == ctrl_embedded))
- {
- // start of embedded command in the text
- int srcix = source_index-1;
-
- if(prev_in != ' ')
- {
- c = ' ';
- prev_in2 = c;
- source_index--;
- }
- else
- {
- embedded_count += EmbeddedCommand(&source_index);
- prev_in2 = prev_in;
- // replace the embedded command by spaces
- memset(&source[srcix],' ',source_index-srcix);
- source_index = srcix;
- continue;
- }
- }
-
- if(option_sayas2 == SAYAS_KEY)
- {
- if(((c == '_') || (c == '-')) && IsAlpha(prev_in))
- {
- c = ' ';
- }
- c = towlower2(c);
- }
-
- if(phoneme_mode)
- {
- all_upper_case = FLAG_PHONEMES;
-
- if((c == ']') && (next_in == ']'))
- {
- phoneme_mode = 0;
- source_index++;
- c = ' ';
- }
- }
- else
- if((option_sayas2 & 0xf0) == SAYAS_DIGITS)
- {
- if(iswdigit(c))
- {
- count_sayas_digits++;
- if(count_sayas_digits > (option_sayas2 & 0xf))
- {
- // break after the specified number of digits
- c = ' ';
- space_inserted = 1;
- count_sayas_digits = 0;
- }
- }
- else
- {
- count_sayas_digits = 0;
- if(iswdigit(prev_out))
- {
- c = ' ';
- space_inserted = 1;
- }
- }
- }
- else
- if((option_sayas2 & 0x30) == 0)
- {
- // speak as words
-
-#ifdef deleted
-if((c == '/') && (tr->langopts.testing & 2) && IsDigit09(next_in) && IsAlpha(prev_out))
-{
- // TESTING, explicit indication of stressed syllable by /2 after the word
- word_mark = next_in-'0';
- source_index++;
- c = ' ';
-}
-#endif
- if((c == 0x92) || (c == 0xb4) || (c == 0x2019) || (c == 0x2032))
- c = '\''; // 'microsoft' quote or sexed closing single quote, or prime - possibly used as apostrophe
-
- if((c == '?') && IsAlpha(prev_out) && IsAlpha(next_in))
- {
- // ? between two letters may be a smart-quote replaced by ?
- c = '\'';
- }
-
- if(c == CHAR_EMPHASIS)
- {
- // this character is a marker that the previous word is the focus of the clause
- c = ' ';
- word_flags |= FLAG_FOCUS;
- }
-
- c = TranslateChar(tr, &source[source_index], prev_in,c, next_in, &char_inserted); // optional language specific function
- if(c == 8)
- continue; // ignore this character
-
- if(char_inserted)
- next_in = char_inserted;
-
- // allow certain punctuation within a word (usually only apostrophe)
- if(!IsAlpha(c) && !IsSpace(c) && (wcschr(tr->punct_within_word,c) == 0))
- {
- if(IsAlpha(prev_out))
- {
- if(tr->langopts.tone_numbers && IsDigit09(c) && !IsDigit09(next_in))
- {
- // allow a tone number as part of the word
- }
- else
- {
- c = ' '; // ensure we have an end-of-word terminator
- space_inserted = 1;
- }
- }
- }
-
- if(iswdigit(prev_out))
- {
- if(!iswdigit(c) && (c != '.') && (c != ','))
- {
- c = ' '; // terminate digit string with a space
- space_inserted = 1;
- }
- }
- else
- {
- if(prev_in != ',')
- {
- decimal_sep_count = 0;
- }
- }
-
- if((c == '[') && (next_in == '[') && option_phoneme_input)
- {
- phoneme_mode = FLAG_PHONEMES;
- source_index++;
- continue;
- }
-
- if(c == 0)
- {
- finished = 1;
- c = ' ';
- }
- else
- if(IsAlpha(c))
- {
- if(!IsAlpha(prev_out) || (tr->langopts.ideographs && ((c > 0x3040) || (prev_out > 0x3040))))
- {
- if(wcschr(tr->punct_within_word,prev_out) == 0)
- letter_count = 0; // don't reset count for an apostrophy within a word
-
- if((prev_out != ' ') && (wcschr(tr->punct_within_word,prev_out) == 0))
- {
- // start of word, insert space if not one there already
- c = ' ';
- space_inserted = 1;
- }
- else
- {
- if(iswupper(c))
- word_flags |= FLAG_FIRST_UPPER;
-
- if((prev_out == ' ') && iswdigit(sbuf[ix-2]) && !iswdigit(prev_in))
- {
- // word, following a number, but with a space between
- // Add an extra space, to distinguish "2 a" from "2a"
- sbuf[ix++] = ' ';
- words[word_count].start++;
- }
- }
- }
-
- letter_count++;
-
- if(iswupper(c))
- {
- c = towlower2(c);
-
- if((j = tr->langopts.param[LOPT_CAPS_IN_WORD]) > 0)
- {
- if((j == 2) && (syllable_marked == 0))
- {
- char_inserted = c;
- c = 0x2c8; // stress marker
- syllable_marked = 1;
- }
- }
- else
- {
- if(iswlower(prev_in))
- {
- c = ' '; // lower case followed by upper case, treat as new word
- space_inserted = 1;
- prev_in2 = c;
- }
- else
- if((c != ' ') && iswupper(prev_in) && iswlower(next_in) &&
- (memcmp(&source[source_index],"s ",2) != 0)) // ENGLISH specific plural
- {
- c = ' '; // change from upper to lower case, start new word at the last uppercase
- space_inserted = 1;
- prev_in2 = c;
- next_word_flags |= FLAG_NOSPACE;
- }
- }
- }
- else
- {
- if((all_upper_case) && (letter_count > 2))
- {
- if((c == 's') && (next_in==' '))
- {
- c = ' ';
- all_upper_case |= FLAG_HAS_PLURAL;
-
- if(sbuf[ix-1] == '\'')
- sbuf[ix-1] = ' ';
- }
- else
- all_upper_case = 0; // current word contains lower case letters, not "'s"
- }
- else
- all_upper_case = 0;
- }
- }
- else
- if(c=='-')
- {
- if(IsAlpha(prev_in) && IsAlpha(next_in))
- {
- // '-' between two letters is a hyphen, treat as a space
- word_flags |= FLAG_HYPHEN;
- words[word_count-1].flags |= FLAG_HYPHEN_AFTER;
- c = ' ';
- }
- else
- if((prev_in==' ') && (next_in==' '))
- {
- // ' - ' dash between two spaces, treat as pause
- c = ' ';
- pre_pause_add = 4;
- }
- else
- if(next_in=='-')
- {
- // double hyphen, treat as pause
- source_index++;
- c = ' ';
- pre_pause_add = 4;
- }
- else
- if((prev_out == ' ') && IsAlpha(sbuf[ix-2]) && !IsAlpha(prev_in))
- {
- // insert extra space between a word + space + hyphen, to distinguish 'a -2' from 'a-2'
- sbuf[ix++] = ' ';
- words[word_count].start++;
- }
- }
- else
- if(c == '\'')
- {
- if(iswalnum(prev_in) && IsAlpha(next_in))
- {
- // between two letters, consider apostrophe as part of the word
- single_quoted = 0;
- }
- else
- if((wcschr(tr->char_plus_apostrophe,prev_in) != 0) && (prev_out2 == ' '))
- {
- // consider single character plus apostrophe as a word
- single_quoted = 0;
- if(next_in == ' ')
- {
- source_index++; // skip following space
- }
- }
- else
- {
- if((prev_out == 's') && (single_quoted==0))
- {
- // looks like apostrophe after an 's'
- c = ' ';
- }
- else
- {
- if(IsSpace(prev_out))
- single_quoted = 1;
- else
- single_quoted = 0;
-
- pre_pause_add = 4; // single quote
- c = ' ';
- }
- }
- }
- else
-#ifdef deleted
-// Brackets are now recognised in TranslateRules()
- if(IsBracket(c))
- {
- pre_pause_add = 4;
- c = ' ';
- }
- else
-#endif
- if(lookupwchar(breaks,c) != 0)
- {
- c = ' '; // various characters to treat as space
- }
- else
- if(iswdigit(c))
- {
- if(tr->langopts.tone_numbers && IsAlpha(prev_out) && !IsDigit(next_in))
- {
- }
- else
- if((prev_out != ' ') && !iswdigit(prev_out))
- {
- if((prev_out != tr->langopts.decimal_sep) || ((decimal_sep_count > 0) && (tr->langopts.decimal_sep == ',')))
- {
- c = ' ';
- space_inserted = 1;
- }
- else
- {
- decimal_sep_count = 1;
- }
- }
- else
- if((prev_out == ' ') && IsAlpha(sbuf[ix-2]) && !IsAlpha(prev_in))
- {
- // insert extra space between a word and a number, to distinguish 'a 2' from 'a2'
- sbuf[ix++] = ' ';
- words[word_count].start++;
- }
- }
- }
-
- if(IsSpace(c))
- {
- if(prev_out == ' ')
- {
- continue; // multiple spaces
- }
-
- if(space_inserted)
- {
- words[word_count].length = source_index - words[word_count].sourceix;
- }
-
- // end of 'word'
- sbuf[ix++] = ' ';
-
- if((ix > words[word_count].start) && (word_count < N_CLAUSE_WORDS-1))
- {
- if(embedded_count > 0)
- {
- // there are embedded commands before this word
- embedded_list[embedded_ix-1] |= 0x80; // terminate list of commands for this word
- words[word_count].flags |= FLAG_EMBEDDED;
- embedded_count = 0;
- }
- words[word_count].pre_pause = pre_pause;
- words[word_count].flags |= (all_upper_case | word_flags | word_emphasis);
- words[word_count].wmark = word_mark;
-
- if(pre_pause > 0)
- {
- // insert an extra space before the word, to prevent influence from previous word across the pause
- for(j=ix; j>words[word_count].start; j--)
- {
- sbuf[j] = sbuf[j-1];
- }
- sbuf[j] = ' ';
- words[word_count].start++;
- ix++;
- }
-
- word_count++;
- words[word_count].start = ix;
- words[word_count].flags = 0;
-
- for(j=source_index; charix[j] <= 0; j++); // skip blanks
- words[word_count].sourceix = charix[j];
- k = 0;
- while(charix[j] != 0)
- {
- // count the number of characters (excluding multibyte continuation bytes)
- if(charix[j++] != -1)
- k++;
- }
- words[word_count].length = k;
-
- word_flags = next_word_flags;
- next_word_flags = 0;
- pre_pause = 0;
- word_mark = 0;
- all_upper_case = FLAG_ALL_UPPER;
- syllable_marked = 0;
- }
-
- if(space_inserted)
- {
- source_index = prev_source_index; // rewind to the previous character
- char_inserted = 0;
- space_inserted = 0;
- }
- }
- else
- {
- ix += utf8_out(c,&sbuf[ix]); // sbuf[ix++] = c;
- }
- if(pre_pause_add > pre_pause)
- pre_pause = pre_pause_add;
- pre_pause_add = 0;
- }
-
- if((word_count==0) && (embedded_count > 0))
- {
- // add a null 'word' to carry the embedded command flag
- embedded_list[embedded_ix-1] |= 0x80;
- words[word_count].flags |= FLAG_EMBEDDED;
- word_count = 1;
- }
-
- tr->clause_end = &sbuf[ix-1];
- sbuf[ix] = 0;
- words[0].pre_pause = 0; // don't add extra pause at beginning of clause
- words[word_count].pre_pause = 8;
- if(word_count > 0)
- words[word_count-1].flags |= FLAG_LAST_WORD;
- words[0].flags |= FLAG_FIRST_WORD;
-
- for(ix=0; ix<word_count; ix++)
- {
- int nx;
- int c_temp;
- char *pn;
- char *pw;
- static unsigned int break_numbers1 = 0x49249248;
- static unsigned int break_numbers2 = 0x24924aa8; // for languages which have numbers for 100,000 and 100,00,000, eg Hindi
- static unsigned int break_numbers3 = 0x49249268; // for languages which have numbers for 100,000 and 1,000,000
- unsigned int break_numbers;
- char number_buf[80];
-
- // start speaking at a specified word position in the text?
- count_words++;
- if(skip_words > 0)
- {
- skip_words--;
- if(skip_words == 0)
- skipping_text = 0;
- }
- if(skipping_text)
- continue;
-
-
- // digits should have been converted to Latin alphabet ('0' to '9')
- word = pw = &sbuf[words[ix].start];
-
- if(iswdigit(word[0]) && (tr->langopts.numbers2 & NUM2_100000))
- {
- // Languages with 100000 numbers. Remove thousands separators so that we can insert them again later
- pn = number_buf;
- while(pn < &number_buf[sizeof(number_buf)-3])
- {
- if(iswdigit(*pw))
- {
- *pn++ = *pw++;
- }
- else
- if((*pw == tr->langopts.thousands_sep) && (pw[1] == ' ') && iswdigit(pw[2]))
- {
- pw += 2;
- ix++; // skip "word"
- }
- else
- {
- nx = pw - word;
- memset(word,' ',nx);
- nx = pn - number_buf;
- memcpy(word,number_buf,nx);
- break;
- }
- }
- pw = word;
- }
-
- for(n_digits=0; iswdigit(word[n_digits]); n_digits++); // count consecutive digits
-
- if((n_digits > 4) && (word[0] != '0'))
- {
- // word is entirely digits, insert commas and break into 3 digit "words"
- number_buf[0] = ' ';
- pn = &number_buf[1];
- nx = n_digits;
-
- if((tr->langopts.numbers2 & NUM2_100000a) == NUM2_100000a)
- break_numbers = break_numbers3;
- else
- if(tr->langopts.numbers2 & NUM2_100000)
- break_numbers = break_numbers2;
- else
- break_numbers = break_numbers1;
-
- while(pn < &number_buf[sizeof(number_buf)-3])
- {
- if(!isdigit(c = *pw++) && (c != tr->langopts.decimal_sep))
- break;
-
- *pn++ = c;
- if((--nx > 0) && (break_numbers & (1 << nx)))
- {
- if(tr->langopts.thousands_sep != ' ')
- {
- *pn++ = tr->langopts.thousands_sep;
- }
- *pn++ = ' ';
- if(break_numbers & (1 << (nx-1)))
- {
- // the next group only has 1 digits (i.e. NUM2_10000), make it three
- *pn++ = '0';
- *pn++ = '0';
- }
- if(break_numbers & (1 << (nx-2)))
- {
- // the next group only has 2 digits (i.e. NUM2_10000), make it three
- *pn++ = '0';
- }
- }
- }
- word = pw;
-
- // include the next few characters, in case there are an ordinal indicator
- pn[0] = ' ';
- memcpy(pn+1, pw, 8);
- pn[8] = 0;
-
- for(pw = &number_buf[1]; pw < pn;)
- {
- dict_flags = TranslateWord2(tr, pw, &words[ix], words[ix].pre_pause,0 );
- while(*pw++ != ' ');
- words[ix].pre_pause = 0;
- words[ix].flags = 0;
- }
- }
- else
- {
- pre_pause = 0;
- dict_flags = TranslateWord2(tr, word, &words[ix], words[ix].pre_pause, words[ix+1].pre_pause);
-
- if(pre_pause > words[ix+1].pre_pause)
- {
- words[ix+1].pre_pause = pre_pause;
- pre_pause = 0;
- }
-
- if(dict_flags & FLAG_SPELLWORD)
- {
- // redo the word, speaking single letters
- for(pw = word; *pw != ' ';)
- {
- memset(number_buf,' ',9);
- nx = utf8_in(&c_temp, pw);
- memcpy(&number_buf[2],pw,nx);
- TranslateWord2(tr, &number_buf[2], &words[ix], 0, 0 );
- pw += nx;
- }
- }
-
- if((dict_flags & FLAG_DOT) && (ix == word_count-1) && (terminator == CLAUSE_PERIOD))
- {
- // probably an abbreviation such as Mr. or B. rather than end of sentence
- clause_pause = 10;
- tone = 4;
- }
- }
-
- if(dict_flags & FLAG_SKIPWORDS)
- {
- ix += dictionary_skipwords; // dictionary indicates skip next word(s)
- }
- }
-
- for(ix=0; ix<2; ix++)
- {
- // terminate the clause with 2 PAUSE phonemes
- PHONEME_LIST2 *p2;
- p2 = &ph_list2[n_ph_list2 + ix];
- p2->phcode = phonPAUSE;
- p2->stress = 0;
- p2->sourceix = source_index;
- p2->synthflags = 0;
- }
- n_ph_list2 += 2;
-
- if(count_words == 0)
- {
- clause_pause = 0;
- }
- if(Eof() && ((word_count == 0) || (option_endpause==0)))
- {
- clause_pause = 10;
- }
-
- MakePhonemeList(tr, clause_pause, new_sentence);
-
- if(embedded_count) // ???? is this needed
- {
- phoneme_list[n_phoneme_list-2].synthflags = SFLAG_EMBEDDED;
- embedded_list[embedded_ix-1] |= 0x80;
- }
-
-
- prev_clause_pause = clause_pause;
-
- *tone_out = tone;
-
- new_sentence = 0;
- if(terminator & CLAUSE_BIT_SENTENCE)
- {
- new_sentence = 1; // next clause is a new sentence
- }
-
-
- if(voice_change != NULL)
- {
- // return new voice name if an embedded voice change command terminated the clause
- if(terminator & CLAUSE_BIT_VOICE)
- *voice_change = &source[source_index];
- else
- *voice_change = NULL;
- }
-
- if(Eof() || (vp_input==NULL))
- return(NULL);
-
- if(option_multibyte == espeakCHARS_WCHAR)
- return((void *)p_wchar_input);
- else
- return((void *)p_textinput);
-} // end of TranslateClause
-
-
-
-
-
-void InitText(int control)
-{//=======================
- count_sentences = 0;
- count_words = 0;
- end_character_position = 0;
- skip_sentences = 0;
- skip_marker[0] = 0;
- skip_words = 0;
- skip_characters = 0;
- skipping_text = 0;
- new_sentence = 1;
-
- prev_clause_pause = 0;
-
- option_sayas = 0;
- option_sayas2 = 0;
- option_emphasis = 0;
- word_emphasis = 0;
- embedded_flag = 0;
-
- InitText2();
-
- if((control & espeakKEEP_NAMEDATA) == 0)
- {
- InitNamedata();
- }
-}
-
diff --git a/navit/support/espeak/translate.h b/navit/support/espeak/translate.h
deleted file mode 100755
index 0556bf280..000000000
--- a/navit/support/espeak/translate.h
+++ /dev/null
@@ -1,584 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2005 to 2007 by Jonathan Duddington *
- * email: jonsd@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, see: *
- * <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-
-#define L(c1,c2) (c1<<8)+c2 // combine two characters into an integer for translator name
-
-#define CTRL_EMBEDDED 0x01 // control character at the start of an embedded command
-#define REPLACED_E 'E' // 'e' replaced by silent e
-
-#define N_WORD_PHONEMES 160 // max phonemes in a word
-#define N_WORD_BYTES 160 // max bytes for the UTF8 characters in a word
-#define N_CLAUSE_WORDS 300 // max words in a clause
-#define N_RULE_GROUP2 120 // max num of two-letter rule chains
-#define N_HASH_DICT 1024
-#define N_CHARSETS 20
-#define N_LETTER_GROUPS 26
-
-
-/* dictionary flags, word 1 */
-// bits 0-3 stressed syllable, bit 6=unstressed
-#define FLAG_SKIPWORDS 0x80
-#define FLAG_PREPAUSE 0x100
-
-#define FLAG_ONLY 0x200
-#define FLAG_ONLY_S 0x400
-#define BITNUM_FLAG_ONLY 9 // bit 9 is set
-#define BITNUM_FLAG_ONLY_S 10 // bit 10 is set
-
-#define FLAG_STRESS_END 0x800 /* full stress if at end of clause */
-#define FLAG_STRESS_END2 0x1000 /* full stress if at end of clause, or only followed by unstressed */
-#define FLAG_UNSTRESS_END 0x2000 /* reduce stress at end of clause */
-#define FLAG_ATEND 0x4000 /* use this pronunciation if at end of clause */
-#define FLAG_SPELLWORD 0x8000 // re-translate the word as individual letters, separated by spaces
-
-#define FLAG_DOT 0x10000 /* ignore '.' after word (abbreviation) */
-#define FLAG_ABBREV 0x20000 // spell as letters, even with a vowel, OR use specified pronunciation rather than split into letters
-#define FLAG_STEM 0x40000 // must have a suffix
-
-#define FLAG_DOUBLING 0x80000 // doubles the following consonant
-#define FLAG_ALT_TRANS 0x100000 // language specific
-#define FLAG_ALT2_TRANS 0x200000 // language specific
-
-#define FLAG_MAX3 0x08000000 // limit to 3 repeats
-#define FLAG_PAUSE1 0x10000000 // shorter prepause
-#define FLAG_TEXTMODE 0x20000000 // word translates to replacement text, not phonemes
-#define BITNUM_FLAG_TEXTMODE 29
-
-#define FLAG_FOUND_ATTRIBUTES 0x40000000 // word was found in the dictionary list (has attributes)
-#define FLAG_FOUND 0x80000000 // pronunciation was found in the dictionary list
-
-// dictionary flags, word 2
-#define FLAG_VERBF 0x1 /* verb follows */
-#define FLAG_VERBSF 0x2 /* verb follows, may have -s suffix */
-#define FLAG_NOUNF 0x4 /* noun follows */
-#define FLAG_PASTF 0x8 /* past tense follows */
-#define FLAG_VERB 0x10 /* pronunciation for verb */
-#define FLAG_NOUN 0x20 /* pronunciation for noun */
-#define FLAG_PAST 0x40 /* pronunciation for past tense */
-#define FLAG_VERB_EXT 0x100 /* extend the 'verb follows' */
-#define FLAG_CAPITAL 0x200 /* pronunciation if initial letter is upper case */
-#define FLAG_ALLCAPS 0x400 // only if the word is all capitals
-#define BITNUM_FLAG_ALLCAPS 0x2a
-#define FLAG_ACCENT 0x800 // character name is base-character name + accent name
-#define FLAG_HYPHENATED 0x1000 // multiple-words, but needs hyphen between parts 1 and 2
-#define BITNUM_FLAG_HYPHENATED 0x2c
-
-
-// wordflags, flags in source word
-#define FLAG_ALL_UPPER 0x1 /* no lower case letters in the word */
-#define FLAG_FIRST_UPPER 0x2 /* first letter is upper case */
-#define FLAG_UPPERS 0x3 // FLAG_ALL_UPPER | FLAG_FIRST_UPPER
-#define FLAG_HAS_PLURAL 0x4 /* upper-case word with s or 's lower-case ending */
-#define FLAG_PHONEMES 0x8 /* word is phonemes */
-#define FLAG_LAST_WORD 0x10 /* last word in clause */
-#define FLAG_EMBEDDED 0x40 /* word is preceded by embedded commands */
-#define FLAG_HYPHEN 0x80
-#define FLAG_NOSPACE 0x100 // word is not seperated from previous word by a space
-#define FLAG_FIRST_WORD 0x200 // first word in clause
-#define FLAG_FOCUS 0x400 // the focus word of a clause
-#define FLAG_EMPHASIZED 0x800
-#define FLAG_EMPHASIZED2 0xc00 // FLAG_FOCUS | FLAG_EMPHASIZED
-#define FLAG_DONT_SWITCH_TRANSLATOR 0x1000
-#define FLAG_SUFFIX_REMOVED 0x2000
-#define FLAG_HYPHEN_AFTER 0x4000
-
-#define FLAG_NO_TRACE 0x10000 // passed to TranslateRules() to suppress dictionary lookup printout
-#define FLAG_NO_PREFIX 0x20000
-
-// prefix/suffix flags (bits 8 to 14, bits 16 to 22) don't use 0x8000, 0x800000
-#define SUFX_E 0x0100 // e may have been added
-#define SUFX_I 0x0200 // y may have been changed to i
-#define SUFX_P 0x0400 // prefix
-#define SUFX_V 0x0800 // suffix means use the verb form pronunciation
-#define SUFX_D 0x1000 // previous letter may have been doubles
-#define SUFX_F 0x2000 // verb follows
-#define SUFX_Q 0x4000 // don't retranslate
-#define SUFX_T 0x10000 // don't affect the stress position in the stem
-#define SUFX_B 0x20000 // break, this character breaks the word into stem and suffix (used with SUFX_P)
-
-#define FLAG_ALLOW_TEXTMODE 0x02 // allow dictionary to translate to text rather than phonemes
-#define FLAG_SUFX 0x04
-#define FLAG_SUFX_S 0x08
-#define FLAG_SUFX_E_ADDED 0x10
-
-
-// codes in dictionary rules
-#define RULE_PRE 1
-#define RULE_POST 2
-#define RULE_PHONEMES 3
-#define RULE_PH_COMMON 4 // At start of rule. Its phoneme string is used by subsequent rules
-#define RULE_CONDITION 5 // followed by condition number (byte)
-#define RULE_GROUP_START 6
-#define RULE_GROUP_END 7
-#define RULE_LINENUM 8 // next 2 bytes give a line number, for debugging purposes
-
-#define RULE_SPACE 32 // ascii space
-#define RULE_SYLLABLE 9
-#define RULE_STRESSED 10
-#define RULE_DOUBLE 11
-#define RULE_INC_SCORE 12
-#define RULE_DEL_FWD 13
-#define RULE_ENDING 14
-#define RULE_DIGIT 15 // D digit
-#define RULE_NONALPHA 16 // Z non-alpha
-#define RULE_LETTERGP 17 // A B C H F G Y letter group number
-#define RULE_LETTERGP2 18 // L + letter group number
-#define RULE_CAPITAL 19 // word starts with a capital letter
-#define RULE_REPLACEMENTS 20 // section for character replacements
-#define RULE_NO_SUFFIX 24 // N
-#define RULE_NOTVOWEL 25 // K
-#define RULE_IFVERB 26 // V
-#define RULE_ALT1 28 // T word has $alt attribute
-#define RULE_NOVOWELS 29 // X no vowels up to word boundary
-#define RULE_SPELLING 31 // W while spelling letter-by-letter
-#define RULE_LAST_RULE 31
-
-#define LETTERGP_A 0
-#define LETTERGP_B 1
-#define LETTERGP_C 2
-#define LETTERGP_H 3
-#define LETTERGP_F 4
-#define LETTERGP_G 5
-#define LETTERGP_Y 6
-#define LETTERGP_VOWEL2 7
-
-
-// Punctuation types returned by ReadClause()
-// bits 0-7 pause x 10mS, bits 12-14 intonation type,
-// bit 19=sentence, bit 18=clause, bits 17=voice change
-// bit 16 used to distinguish otherwise identical types
-// bit 20= punctuation character can be inside a word (Armenian)
-#define CLAUSE_BIT_SENTENCE 0x80000
-#define CLAUSE_BIT_VOICE 0x20000
-#define PUNCT_IN_WORD 0x100000
-
-#define CLAUSE_NONE 0 + 0x04000
-#define CLAUSE_PARAGRAPH 70 + 0x80000
-#define CLAUSE_EOF 35 + 0x90000
-#define CLAUSE_VOICE 0 + 0x24000
-#define CLAUSE_PERIOD 35 + 0x80000
-#define CLAUSE_COMMA 20 + 0x41000
-#define CLAUSE_SHORTCOMMA 4 + 0x41000
-#define CLAUSE_SHORTFALL 4 + 0x40000
-#define CLAUSE_QUESTION 35 + 0x82000
-#define CLAUSE_EXCLAMATION 40 + 0x83000
-#define CLAUSE_COLON 30 + 0x40000
-#ifdef PLATFORM_RISCOS
-#define CLAUSE_SEMICOLON 30 + 0x40000
-#else
-#define CLAUSE_SEMICOLON 30 + 0x41000
-#endif
-
-#define SAYAS_CHARS 0x12
-#define SAYAS_GLYPHS 0x13
-#define SAYAS_SINGLE_CHARS 0x14
-#define SAYAS_KEY 0x24
-#define SAYAS_DIGITS 0x40 // + number of digits
-#define SAYAS_DIGITS1 0xc1
-
-#define CHAR_EMPHASIS 0x0530 // this is an unused character code
-
-// Rule:
-// [4] [match] [1 pre] [2 post] [3 phonemes] 0
-// match 1 pre 2 post 0 - use common phoneme string
-// match 1 pre 2 post 3 0 - empty phoneme string
-
-typedef const char * constcharptr;
-
-typedef struct {
- int points;
- const char *phonemes;
- int end_type;
- char *del_fwd;
-} MatchRecord;
-
-
-// used to mark words with the source[] buffer
-typedef struct{
- unsigned short start;
- unsigned short sourceix;
- unsigned short flags;
- unsigned char pre_pause;
- unsigned char wmark;
- unsigned char length;
-} WORD_TAB;
-
-// a clause translated into phoneme codes (first stage)
-typedef struct {
- unsigned char phcode;
- unsigned char stress;
- unsigned char tone_number;
- unsigned char synthflags;
- unsigned short sourceix;
-} PHONEME_LIST2;
-
-
-typedef struct {
- int type;
- int parameter[N_SPEECH_PARAM];
-} PARAM_STACK;
-
-extern PARAM_STACK param_stack[];
-extern const int param_defaults[N_SPEECH_PARAM];
-
-
-
-#define N_LOPTS 16
-#define LOPT_DIERESES 1
- // 1=remove [:] from unstressed syllables, 2= remove from unstressed or non-penultimate syllables
- // bit 4=0, if stress < 4, bit 4=1, if not the highest stress in the word
-#define LOPT_IT_LENGTHEN 2
-
- // 1=german
-#define LOPT_PREFIXES 3
-
- // non-zero, change voiced/unoiced to match last consonant in a cluster
- // bit 1=LANG=ru, don't propagate over [v]
- // bit 2=don't propagate acress word boundaries
- // bit 3=LANG=pl, propagate over liquids and nasals
-#define LOPT_REGRESSIVE_VOICING 4
-
- // 0=default, 1=no check, other allow this character as an extra initial letter (default is 's')
-#define LOPT_UNPRONOUNCABLE 5
-
- // select length_mods tables, (length_mod_tab) + (length_mod_tab0 * 100)
-#define LOPT_LENGTH_MODS 6
-
- // increase this to prevent sonorants being shortened before shortened (eg. unstressed) vowels
-#define LOPT_SONORANT_MIN 7
-
- // don't break vowels at word boundary
-#define LOPT_WORD_MERGE 8
-
- // max. amplitude for vowel at the end of a clause
-#define LOPT_MAXAMP_EOC 9
-
- // bit 0=reduce even if phonemes are specified in the **_list file
- // bit 1=don't reduce the strongest vowel in a word which is marked 'unstressed'
-#define LOPT_REDUCE 10
-
- // LANG=cs,sk combine some prepositions with the following word, if the combination has N or fewer syllables
- // bits 0-3 N syllables
- // bit 4=only if the second word has $alt attribute
- // bit 5=not if the second word is end-of-sentence
-#define LOPT_COMBINE_WORDS 11
-
- // change [t] when followed by unstressed vowel
-#define LOPT_REDUCE_T 12
-
- // 1 = allow capitals inside a word
- // 2 = stressed syllable is indicated by capitals
-#define LOPT_CAPS_IN_WORD 13
-
- // bit 0=Italian "syntactic doubling" of consoants in the word after a word marked with $double attribute
- // bit 1=also after a word which ends with a stressed vowel
-#define LOPT_IT_DOUBLING 14
-
- // Call ApplySpecialAttributes() if $alt or $alt2 is set for a word
-#define LOPT_ALT 15
-
-
-typedef struct {
-// bits0-2 separate words with (1=pause_vshort, 2=pause_short, 3=pause, 4=pause_long 5=[?] phonemme)
-// bit 3=don't use linking phoneme
-// bit4=longer pause before STOP, VSTOP,FRIC
-// bit5=length of a final vowel doesn't depend on the next phoneme
- int word_gap;
- int vowel_pause;
- int stress_rule; // 1=first syllable, 2=penultimate, 3=last
-
-// bit0=don't stress monosyllables, except at end of clause
-// bit1=don't set diminished stress,
-// bit2=mark unstressed final syllables as diminished
-// bit4=don't allow secondary stress on last syllable
-// bit5-don't use automatic secondary stress
-// bit6=light syllable followed by heavy, move secondary stress to the heavy syllable. LANG=Finnish
-// bit8=stress last syllable if it doesn't end in a vowel
-// bit9=stress last syllable if it doesn't end in vowel or "s" or "n" LANG=Spanish
-// bit12= In a 2-syllable word, if one has primary stress then give the other secondary stress
-// bit13= If there is only one syllable before the primary stress, give it a secondary stress
-// bit15= Give stress to the first unstressed syllable
-// bit16= Don't diminish consecutive syllables within a word.
-// bit17= "priority" stress reduces other primary stress to "unstressed" not "secondary"
-// bit18= don't lengthen short vowels more than long vowels at end-of-clause
-// bit19=stress on final syllable if it has a long vowel, but previous syllable has a short vowel
-
- int stress_flags;
- int unstressed_wd1; // stress for $u word of 1 syllable
- int unstressed_wd2; // stress for $u word of >1 syllable
- int param[N_LOPTS];
- unsigned char *length_mods;
- unsigned char *length_mods0;
-
-#define NUM_ROMAN 0x20000
-#define NUM_ROMAN_UC 0x40000
-#define NUM_NOPAUSE 0x80000
-#define NUM_ROMAN_AFTER 0x200000
-#define NUM_VIGESIMAL 0x400000
-
- // bits0-1=which numbers routine to use.
- // bit2= thousands separator must be space
- // bit3= , decimal separator, not .
- // bit4=use three-and-twenty rather than twenty-three
- // bit5='and' between tens and units
- // bit6=add "and" after hundred or thousand
- // bit7=don't have "and" both after hundreds and also between tens and units
- // bit8=only one primary stress in tens+units
- // bit9=only one vowel betwen tens and units
- // bit10=omit "one" before "hundred"
- // bit11=say 19** as nineteen hundred
- // bit12=allow space as thousands separator (in addition to langopts.thousands_sep)
- // bits13-15 post-decimal-digits 0=single digits, 1=(LANG=it) 2=(LANG=pl) 3=(LANG=ro)
- // bit16=dot after number indicates ordinal
- // bit17=recognize roman numbers
- // bit18=Roman numbers only if upper case
- // bit19=don't add pause after a number
- // bit20='and' before hundreds
- // bit21= say "roman" after the number, not before
- // bit22= vigesimal number, if tens are not found
- int numbers;
-
-#define NUM2_100000 0x800 // numbers for 100,000 and 10,000,000
-#define NUM2_100000a 0xc00 // numbers for 100,000 and 1,000,000
- // bits 1-4 use variant form of numbers before thousands,millions,etc.
- // bit6=(LANG=pl) two forms of plural, M or MA
- // bit7=(LANG-ru) use MB for 1 thousand, million, etc
- // bit8=(LANG=cs,sk) two forms of plural, M or MA
- // bit9=(LANG=rw) say "thousand" and "million" before its number, not after
- // bit10=(LANG=sw) special word for 100,000 and 1,000,000
- // bit11=(LANG=hi) special word for 100,000 and 10,000,000
- int numbers2;
-
- int max_roman;
- int thousands_sep;
- int decimal_sep;
-
- // bit 0, accent name before the letter name, bit 1 "capital" after letter name
- int accents;
-
- int tone_language; // 1=tone language
- int intonation_group;
- int long_stop; // extra mS pause for a lengthened stop
- int phoneme_change; // TEST, change phonemes, after translation
- char max_initial_consonants;
- char spelling_stress; // 0=default, 1=stress first letter
- char tone_numbers;
- char ideographs; // treat as separate words
- char textmode; // the meaning of FLAG_TEXTMODE is reversed (to save data when *_list file is compiled)
- int testing; // testing options: bit 1= specify stressed syllable in the form: "outdoor/2"
- int listx; // compile *_listx after *list
- const unsigned int *replace_chars; // characters to be substitutes
- const char *ascii_language; // switch to this language for Latin characters
-} LANGUAGE_OPTIONS;
-
-
-// a parameter of ChangePhonemes()
-typedef struct {
- int flags;
- unsigned char stress; // stress level of this vowel
- unsigned char stress_highest; // the highest stress level of a vowel in this word
- unsigned char n_vowels; // number of vowels in the word
- unsigned char vowel_this; // syllable number of this vowel (counting from 1)
- unsigned char vowel_stressed; // syllable number of the highest stressed vowel
-} CHANGEPH;
-
-
-
-#define NUM_SEP_DOT 0x0008 // . , for thousands and decimal separator
-#define NUM_SEP_SPACE 0x1000 // allow space as thousands separator (in addition to langopts.thousands_sep)
-#define NUM_DEC_IT 0x2000 // (LANG=it) speak post-decimal-point digits as a combined number not as single digits
-
-typedef struct Translator
-{//=============
-
- LANGUAGE_OPTIONS langopts;
- int translator_name;
- int transpose_offset;
- int transpose_max;
- int transpose_min;
-
- char phon_out[300];
- char phonemes_repeat[20];
- int phonemes_repeat_count;
-
- unsigned char stress_amps[8];
- unsigned char stress_amps_r[8];
- short stress_lengths[8];
- int dict_condition; // conditional apply some pronunciation rules and dict.lookups
- const unsigned short *charset_a0; // unicodes for characters 0xa0 to oxff
- const wchar_t *char_plus_apostrophe; // single chars + apostrophe treated as words
- const wchar_t *punct_within_word; // allow these punctuation characters within words
-
-// holds properties of characters: vowel, consonant, etc for pronunciation rules
- unsigned char letter_bits[256];
- int letter_bits_offset;
- const wchar_t *letter_groups[8];
-
- /* index1=option, index2 by 0=. 1=, 2=?, 3=! 4=none */
-#define INTONATION_TYPES 8
-#define PUNCT_INTONATIONS 6
- unsigned char punct_to_tone[INTONATION_TYPES][PUNCT_INTONATIONS];
-
- char *data_dictrules; // language_1 translation rules file
- char *data_dictlist; // language_2 dictionary lookup file
- char *dict_hashtab[N_HASH_DICT]; // hash table to index dictionary lookup file
- char *letterGroups[N_LETTER_GROUPS];
-
- // groups1 and groups2 are indexes into data_dictrules, set up by InitGroups()
- // the two-letter rules for each letter must be consecutive in the language_rules source
-
- char *groups1[256]; // translation rule lists, index by single letter
- char *groups2[N_RULE_GROUP2]; // translation rule lists, indexed by two-letter pairs
- unsigned int groups2_name[N_RULE_GROUP2]; // the two letter pairs for groups2[]
- int n_groups2; // number of groups2[] entries used
-
- unsigned char groups2_count[256]; // number of 2 letter groups for this initial letter
- unsigned char groups2_start[256]; // index into groups2
-
-
- int expect_verb;
- int expect_past; // expect past tense
- int expect_verb_s;
- int expect_noun;
- int prev_last_stress;
- char *clause_end;
-
- int word_vowel_count; // number of vowels so far
- int word_stressed_count; // number of vowels so far which could be stressed
-
- int clause_upper_count; // number of upper case letters in the clause
- int clause_lower_count; // number of lower case letters in the clause
-
- int prepause_timeout;
- int end_stressed_vowel; // word ends with stressed vowel
- int prev_dict_flags; // dictionary flags from previous word
-} Translator; // end of class Translator
-
-
-extern int option_tone2;
-#define OPTION_EMPHASIZE_ALLCAPS 0x100
-#define OPTION_EMPHASIZE_PENULTIMATE 0x200
-extern int option_tone_flags;
-extern int option_waveout;
-extern int option_quiet;
-extern int option_phonemes;
-extern int option_phoneme_events;
-extern int option_linelength; // treat lines shorter than this as end-of-clause
-extern int option_multibyte;
-extern int option_capitals;
-extern int option_punctuation;
-extern int option_endpause;
-extern int option_ssml;
-extern int option_phoneme_input; // allow [[phonemes]] in input text
-extern int option_phoneme_variants;
-extern int option_sayas;
-extern int option_wordgap;
-
-extern int count_characters;
-extern int count_words;
-extern int count_sentences;
-extern int skip_characters;
-extern int skip_words;
-extern int skip_sentences;
-extern int skipping_text;
-extern int end_character_position;
-extern int clause_start_char;
-extern int clause_start_word;
-extern char *namedata;
-extern int pre_pause;
-
-
-
-#define N_MARKER_LENGTH 50 // max.length of a mark name
-extern char skip_marker[N_MARKER_LENGTH];
-
-#define N_PUNCTLIST 60
-extern wchar_t option_punctlist[N_PUNCTLIST]; // which punctuation characters to announce
-extern unsigned char punctuation_to_tone[INTONATION_TYPES][PUNCT_INTONATIONS];
-
-extern struct Translator *translator;
-extern struct Translator *translator2;
-extern const unsigned short *charsets[N_CHARSETS];
-extern char dictionary_name[40];
-extern char ctrl_embedded; // to allow an alternative CTRL for embedded commands
-extern unsigned char *p_textinput;
-extern wchar_t *p_wchar_input;
-extern int dictionary_skipwords;
-
-extern int (* uri_callback)(int, const char *, const char *);
-extern int (* phoneme_callback)(const char *);
-extern void SetLengthMods(struct Translator *tr, int value);
-
-void LoadConfig(void);
-int TransposeAlphabet(char *text, int offset, int min, int max);
-int utf8_in(int *c, const char *buf);
-int utf8_in2(int *c, const char *buf, int backwards);
-int utf8_out(unsigned int c, char *buf);
-int utf8_nbytes(const char *buf);
-int lookupwchar(const unsigned short *list,int c);
-int Eof(void);
-char *strchr_w(const char *s, int c);
-int IsBracket(int c);
-void InitNamedata(void);
-void InitText(int flags);
-void InitText2(void);
-int IsDigit(unsigned int c);
-int IsAlpha(unsigned int c);
-int isspace2(unsigned int c);
-int towlower2(unsigned int c);
-void GetTranslatedPhonemeString(char *phon_out, int n_phon_out);
-
-struct Translator *SelectTranslator(const char *name);
-int SetTranslator2(const char *name);
-void DeleteTranslator(struct Translator *tr);
-int Lookup(struct Translator *tr, const char *word, char *ph_out);
-
-int TranslateNumber(Translator *tr, char *word1, char *ph_out, unsigned int *flags, int wflags);
-int TranslateRoman(Translator *tr, char *word, char *ph_out);
-
-void ChangeWordStress(Translator *tr, char *word, int new_stress);
-void SetSpellingStress(Translator *tr, char *phonemes, int control, int n_chars);
-int TranslateLetter(Translator *tr, char *letter, char *phonemes, int control, int word_length);
-void LookupLetter(Translator *tr, unsigned int letter, int next_byte, char *ph_buf);
-void LookupAccentedLetter(Translator *tr, unsigned int letter, char *ph_buf);
-
-int LoadDictionary(Translator *tr, const char *name, int no_error);
-int LookupDictList(Translator *tr, char **wordptr, char *ph_out, unsigned int *flags, int end_flags, WORD_TAB *wtab);
-
-void MakePhonemeList(Translator *tr, int post_pause, int new_sentence);
-int ChangePhonemes_ru(Translator *tr, PHONEME_LIST2 *phlist, int n_ph, int index, PHONEME_TAB *ph, CHANGEPH *ch);
-void ApplySpecialAttribute(Translator *tr, char *phonemes, int dict_flags);
-void ApplySpecialAttribute2(Translator *tr, char *phonemes, int dict_flags);
-void AppendPhonemes(Translator *tr, char *string, int size, const char *ph);
-
-void CalcLengths(Translator *tr);
-void CalcPitches(Translator *tr, int clause_tone);
-
-int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy);
-int Unpronouncable(Translator *tr, char *word);
-void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags, int tonic, int prev_stress);
-int TranslateRules(Translator *tr, char *p, char *phonemes, int size, char *end_phonemes, int end_flags, unsigned int *dict_flags);
-int TranslateWord(Translator *tr, char *word1, int next_pause, WORD_TAB *wtab);
-void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *tone, char **voice_change);
-int ReadClause(Translator *tr, FILE *f_in, char *buf, short *charix, int *charix_top, int n_buf, int *tone_type);
-
-void SetVoiceStack(espeak_VOICE *v);
-
-extern FILE *f_trans; // for logging
diff --git a/navit/support/espeak/voice.h b/navit/support/espeak/voice.h
deleted file mode 100644
index ab69fa128..000000000
--- a/navit/support/espeak/voice.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2005 to 2007 by Jonathan Duddington *
- * email: jonsd@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write see: *
- * <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-
-
-typedef struct {
- char v_name[40];
-
- int phoneme_tab_ix; // phoneme table number
- int pitch_base; // Hz<<12
- int pitch_range; // standard = 0x1000
-
- int speedf1;
- int speedf2;
- int speedf3;
-
- int flutter;
- int roughness;
- int echo_delay;
- int echo_amp;
- int n_harmonic_peaks; // highest formant which is formed from adding harmonics
- int peak_shape; // alternative shape for formant peaks (0=standard 1=squarer)
- int voicing; // 100% = 64, level of formant-synthesized sound
- int formant_factor; // adjust nominal formant frequencies by this because of the voice's pitch (256ths)
- int consonant_amp; // amplitude of unvoiced consonants
- int consonant_ampv; // amplitude of the noise component of voiced consonants
- int klattv[8];
-
- // parameters used by Wavegen
- short freq[N_PEAKS]; // 100% = 256
- short height[N_PEAKS]; // 100% = 256
- short width[N_PEAKS]; // 100% = 256
- short freqadd[N_PEAKS]; // Hz
-
- // copies without temporary adjustments from embedded commands
- short freq2[N_PEAKS]; // 100% = 256
- short height2[N_PEAKS]; // 100% = 256
- short width2[N_PEAKS]; // 100% = 256
-
- int breath[N_PEAKS]; // amount of breath for each formant. breath[0] indicates whether any are set.
- int breathw[N_PEAKS]; // width of each breath formant
-
- // This table provides the opportunity for tone control.
- // Adjustment of harmonic amplitudes, steps of 8Hz
- // value of 128 means no change
- #define N_TONE_ADJUST 1000
- unsigned char tone_adjust[N_TONE_ADJUST]; // 8Hz steps * 1000 = 8kHz
-
-} voice_t;
-
-// percentages shown to user, ix=N_PEAKS means ALL peaks
-extern USHORT voice_pcnt[N_PEAKS+1][3];
-
-
-extern voice_t *voice;
-extern int tone_points[12];
-
-const char *SelectVoice(espeak_VOICE *voice_select, int *found);
-espeak_VOICE *SelectVoiceByName(espeak_VOICE **voices, const char *name);
-voice_t *LoadVoice(const char *voice_name, int control);
-voice_t *LoadVoiceVariant(const char *voice_name, int variant);
-void DoVoiceChange(voice_t *v);
-void WavegenSetVoice(voice_t *v);
-void ReadTonePoints(char *string, int *tone_pts);
-
diff --git a/navit/support/espeak/voices.c b/navit/support/espeak/voices.c
deleted file mode 100755
index a7bd3f5a0..000000000
--- a/navit/support/espeak/voices.c
+++ /dev/null
@@ -1,1746 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2005 to 2007 by Jonathan Duddington *
- * email: jonsd@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write see: *
- * <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-#include "StdAfx.h"
-
-#include "stdio.h"
-#include "ctype.h"
-#include "wctype.h"
-#include "string.h"
-#include "stdlib.h"
-#include "speech.h"
-
-#ifdef PLATFORM_WINDOWS
-#include "windows.h"
-#else
-#ifdef PLATFORM_RISCOS
-#include "kernel.h"
-#else
-#include "dirent.h"
-#endif
-#endif
-
-#include "speak_lib.h"
-#include "phoneme.h"
-#include "synthesize.h"
-#include "voice.h"
-#include "translate.h"
-
-#define int(x) ((int)(x))
-#define double(x) ((double)(x))
-#define __cdecl
-
-MNEM_TAB genders [] = {
- {"unknown", 0},
- {"male", 1},
- {"female", 2},
- {NULL, 0 }};
-
-int tone_points[12] = {600,170, 1200,135, 2000,110, 3000,110, -1,0};
-//int tone_points[12] = {250,200, 400,170, 600,170, 1200,135, 2000,110, -1,0};
-
-// limit the rate of change for each formant number
-//static int formant_rate_22050[9] = {50, 104, 165, 230, 220, 220, 220, 220, 220}; // values for 22kHz sample rate
-//static int formant_rate_22050[9] = {240, 180, 180, 180, 180, 180, 180, 180, 180}; // values for 22kHz sample rate
-static int formant_rate_22050[9] = {240, 170, 170, 170, 170, 170, 170, 170, 170}; // values for 22kHz sample rate
-int formant_rate[9]; // values adjusted for actual sample rate
-
-
-
-#define DEFAULT_LANGUAGE_PRIORITY 5
-#define N_VOICES_LIST 150
-static int n_voices_list = 0;
-static espeak_VOICE *voices_list[N_VOICES_LIST];
-static int len_path_voices;
-
-espeak_VOICE voice_selected;
-
-
-enum {
- V_NAME = 1,
- V_LANGUAGE,
- V_GENDER,
- V_TRANSLATOR,
- V_PHONEMES,
- V_DICTIONARY,
-
-// these affect voice quality, are independent of language
- V_FORMANT,
- V_PITCH,
- V_ECHO,
- V_FLUTTER,
- V_ROUGHNESS,
- V_CLARITY,
- V_TONE,
- V_VOICING,
- V_BREATH,
- V_BREATHW,
-
-// these override defaults set by the translator
- V_WORDGAP,
- V_INTONATION,
- V_STRESSLENGTH,
- V_STRESSAMP,
- V_STRESSADD,
- V_DICTRULES,
- V_STRESSRULE,
- V_CHARSET,
- V_NUMBERS,
- V_OPTION,
-
- V_MBROLA,
- V_KLATT,
- V_FAST,
-
-// these need a phoneme table to have been specified
- V_REPLACE,
- V_CONSONANTS
-};
-
-
-
-typedef struct {
- const char *mnem;
- int data;
-} keywtab_t;
-
-static keywtab_t keyword_tab[] = {
- {"name", V_NAME},
- {"language", V_LANGUAGE},
- {"gender", V_GENDER},
-
- {"formant", V_FORMANT},
- {"pitch", V_PITCH},
- {"phonemes", V_PHONEMES},
- {"translator", V_TRANSLATOR},
- {"dictionary", V_DICTIONARY},
- {"stressLength", V_STRESSLENGTH},
- {"stressAmp", V_STRESSAMP},
- {"stressAdd", V_STRESSADD},
- {"intonation", V_INTONATION},
- {"dictrules", V_DICTRULES},
- {"stressrule", V_STRESSRULE},
- {"charset", V_CHARSET},
- {"replace", V_REPLACE},
- {"words", V_WORDGAP},
- {"echo", V_ECHO},
- {"flutter", V_FLUTTER},
- {"roughness", V_ROUGHNESS},
- {"clarity", V_CLARITY},
- {"tone", V_TONE},
- {"voicing", V_VOICING},
- {"breath", V_BREATH},
- {"breathw", V_BREATHW},
- {"numbers", V_NUMBERS},
- {"option", V_OPTION},
- {"mbrola", V_MBROLA},
- {"consonants", V_CONSONANTS},
- {"klatt", V_KLATT},
- {"fast_test", V_FAST},
-
- // these just set a value in langopts.param[]
- {"l_dieresis", 0x100+LOPT_DIERESES},
-// {"l_lengthen", 0x100+LOPT_IT_LENGTHEN},
- {"l_prefix", 0x100+LOPT_PREFIXES},
- {"l_regressive_v", 0x100+LOPT_REGRESSIVE_VOICING},
- {"l_unpronouncable", 0x100+LOPT_UNPRONOUNCABLE},
- {"l_sonorant_min", 0x100+LOPT_SONORANT_MIN},
- {"l_length_mods", 0x100+LOPT_LENGTH_MODS},
- {NULL, 0} };
-
-#define N_VOICE_VARIANTS 12
-const char variants_either[N_VOICE_VARIANTS] = {1,2,12,3,13,4,14,5,11,0};
-const char variants_male[N_VOICE_VARIANTS] = {1,2,3,4,5,0};
-const char variants_female[N_VOICE_VARIANTS] = {11,12,13,14,0};
-const char *variant_lists[3] = {variants_either, variants_male, variants_female};
-
-static voice_t voicedata;
-voice_t *voice = &voicedata;
-
-
-static char *fgets_strip(char *buf, int size, FILE *f_in)
-{//======================================================
-// strip trailing spaces, and truncate lines at // comment
- int len;
- char *p;
-
- if(fgets(buf,size,f_in) == NULL)
- return(NULL);
-
- len = strlen(buf);
- while((--len > 0) && isspace(buf[len]))
- buf[len] = 0;
-
- if((p = strstr(buf,"//")) != NULL)
- *p = 0;
-
- return(buf);
-}
-
-
-static void SetToneAdjust(voice_t *voice, int *tone_pts)
-{//=====================================================
- int ix;
- int pt;
- int y;
- int freq1=0;
- int freq2;
- int height1 = tone_pts[1];
- int height2;
- double rate;
-
- for(pt=0; pt<12; pt+=2)
- {
- if(tone_pts[pt] == -1)
- {
- tone_pts[pt] = N_TONE_ADJUST*8;
- if(pt > 0)
- tone_pts[pt+1] = tone_pts[pt-1];
- }
- freq2 = tone_pts[pt] / 8; // 8Hz steps
- height2 = tone_pts[pt+1];
- if((freq2 - freq1) > 0)
- {
- rate = double(height2-height1)/(freq2-freq1);
-
- for(ix=freq1; ix<freq2; ix++)
- {
- y = height1 + int(rate * (ix-freq1));
- if(y > 255)
- y = 255;
- voice->tone_adjust[ix] = y;
- }
- }
- freq1 = freq2;
- height1 = height2;
- }
-}
-
-
-void ReadTonePoints(char *string, int *tone_pts)
-{//=============================================
-// tone_pts[] is int[12]
- int ix;
-
- for(ix=0; ix<12; ix++)
- tone_pts[ix] = -1;
-
- sscanf(string,"%d %d %d %d %d %d %d %d %d %d",
- &tone_pts[0],&tone_pts[1],&tone_pts[2],&tone_pts[3],
- &tone_pts[4],&tone_pts[5],&tone_pts[6],&tone_pts[7],
- &tone_pts[8],&tone_pts[9]);
-}
-
-
-
-
-static espeak_VOICE *ReadVoiceFile(FILE *f_in, const char *fname, const char*leafname)
-{//===================================================================================
-// Read a Voice file, allocate a VOICE_DATA and set data from the
-// file's language, gender, name lines
-
- char linebuf[120];
- char vname[80];
- char vgender[80];
- char vlanguage[80];
- char languages[300]; // allow space for several alternate language names and priorities
-
-
- unsigned int len;
- int langix = 0;
- int n_languages = 0;
- char *p;
- espeak_VOICE *voice_data;
- int priority;
- int age;
- int n_variants = 3; // default, number of variants of this voice before using another voice
- int gender;
-
-#ifdef PLATFORM_WINDOWS
- char fname_buf[sizeof(path_home)+15];
- if(memcmp(leafname,"mb-",3) == 0)
- {
- // check whether the mbrola speech data is present for this voice
- memcpy(vname,&leafname[3],3);
- vname[3] = 0;
- sprintf(fname_buf,"%s/mbrola/%s",path_home,vname);
-
- if(GetFileLength(fname_buf) <= 0)
- return(0);
- }
-#endif
-
- vname[0] = 0;
- vgender[0] = 0;
- age = 0;
-
- while(fgets_strip(linebuf,sizeof(linebuf),f_in) != NULL)
- {
- if(memcmp(linebuf,"name",4)==0)
- {
- p = &linebuf[4];
- while(isspace(*p)) p++;
- strncpy0(vname,p,sizeof(vname));
- }
- else
- if(memcmp(linebuf,"language",8)==0)
- {
- priority = DEFAULT_LANGUAGE_PRIORITY;
- vlanguage[0] = 0;
-
- sscanf(&linebuf[8],"%s %d",vlanguage,&priority);
- len = strlen(vlanguage) + 2;
- // check for space in languages[]
- if(len < (sizeof(languages)-langix-1))
- {
- languages[langix] = priority;
-
- strcpy(&languages[langix+1],vlanguage);
- langix += len;
- n_languages++;
- }
- }
- else
- if(memcmp(linebuf,"gender",6)==0)
- {
- sscanf(&linebuf[6],"%s %d",vgender,&age);
- }
- else
- if(memcmp(linebuf,"variants",8)==0)
- {
- sscanf(&linebuf[8],"%d",&n_variants);
- }
- }
- languages[langix++] = 0;
-
- gender = LookupMnem(genders,vgender);
-
- if(n_languages == 0)
- {
- return(NULL); // no language lines in the voice file
- }
-
- p = (char *)calloc(sizeof(espeak_VOICE) + langix + strlen(fname) + strlen(vname) + 3, 1);
- voice_data = (espeak_VOICE *)p;
- p = &p[sizeof(espeak_VOICE)];
-
- memcpy(p,languages,langix);
- voice_data->languages = p;
-
- strcpy(&p[langix],fname);
- voice_data->identifier = &p[langix];
- voice_data->name = &p[langix];
-
- if(vname[0] != 0)
- {
- langix += strlen(fname)+1;
- strcpy(&p[langix],vname);
- voice_data->name = &p[langix];
- }
-
- voice_data->age = age;
- voice_data->gender = gender;
- voice_data->variant = 0;
- voice_data->xx1 = n_variants;
- return(voice_data);
-} // end of ReadVoiceFile
-
-
-
-
-void VoiceReset(int tone_only)
-{//===========================
-// Set voice to the default values
-
- int pk;
- static unsigned char default_heights[N_PEAKS] = {128,128,120,120,110,110,128,128,128};
- static unsigned char default_widths[N_PEAKS] = {128,128,128,160,171,171,128,128,128};
-
- static int breath_widths[N_PEAKS] = {0,200,200,400,400,400,600,600,600};
-
- // default is: pitch 82,118
-// voice->pitch_base = 0x49000; // default, 73 << 12;
-// voice->pitch_range = 0x0f30; // default = 0x1000
- voice->pitch_base = 0x47000;
- voice->pitch_range = 3996;
-
- voice->formant_factor = 256;
-
- voice->echo_delay = 0;
- voice->echo_amp = 0;
- voice->flutter = 64;
- voice->n_harmonic_peaks = 5;
- voice->peak_shape = 0;
- voice->voicing = 64;
- voice->consonant_amp = 100;
- voice->consonant_ampv = 100;
- memset(voice->klattv,0,sizeof(voice->klattv));
- memset(speed.fast_settings,0,sizeof(speed.fast_settings));
-
-#ifdef PLATFORM_RISCOS
- voice->roughness = 1;
-#else
- voice->roughness = 2;
-#endif
-
- InitBreath();
- for(pk=0; pk<N_PEAKS; pk++)
- {
- voice->freq[pk] = 256;
- voice->height[pk] = default_heights[pk]*2;
- voice->width[pk] = default_widths[pk]*2;
- voice->breath[pk] = 0;
- voice->breathw[pk] = breath_widths[pk]; // default breath formant woidths
- voice->freqadd[pk] = 0;
-
- // adjust formant smoothing depending on sample rate
- formant_rate[pk] = (formant_rate_22050[pk] * 22050)/samplerate;
- }
- voice->height[2] = 240; // reduce F2 slightly
-
- // This table provides the opportunity for tone control.
- // Adjustment of harmonic amplitudes, steps of 8Hz
- // value of 128 means no change
-// memset(voice->tone_adjust,128,sizeof(voice->tone_adjust));
-SetToneAdjust(voice,tone_points);
-
- // default values of speed factors
- voice->speedf1 = 256;
- voice->speedf2 = 238;
- voice->speedf3 = 232;
-
- if(tone_only == 0)
- {
- n_replace_phonemes = 0;
- option_quiet = 0;
- LoadMbrolaTable(NULL,NULL,0);
- }
-} // end of VoiceReset
-
-
-static void VoiceFormant(char *p)
-{//==============================
- // Set parameters for a formant
- int ix;
- int formant;
- int freq = 100;
- int height = 100;
- int width = 100;
- int freqadd = 0;
-
- ix = sscanf(p,"%d %d %d %d %d",&formant,&freq,&height,&width,&freqadd);
- if(ix < 2)
- return;
-
- if((formant < 0) || (formant > 8))
- return;
-
- if(freq >= 0)
- voice->freq[formant] = int(freq * 2.56001);
- if(height >= 0)
- voice->height[formant] = int(height * 2.56001);
- if(width >= 0)
- voice->width[formant] = int(width * 2.56001);
- voice->freqadd[formant] = freqadd;
-}
-
-
-
-
-
-static void PhonemeReplacement(int type, char *p)
-{//==============================================
- int n;
- int phon;
- int flags = 0;
- char phon_string1[12];
- char phon_string2[12];
-
- strcpy(phon_string2,"NULL");
- n = sscanf(p,"%d %s %s",&flags,phon_string1,phon_string2);
- if((n < 2) || (n_replace_phonemes >= N_REPLACE_PHONEMES))
- return;
-
- if((phon = LookupPhonemeString(phon_string1)) == 0)
- return; // not recognised
-
- replace_phonemes[n_replace_phonemes].old_ph = phon;
- replace_phonemes[n_replace_phonemes].new_ph = LookupPhonemeString(phon_string2);
- replace_phonemes[n_replace_phonemes++].type = flags;
-} // end of PhonemeReplacement
-
-
-
-static int Read8Numbers(char *data_in,int *data)
-{//=============================================
-// Read 8 integer numbers
- return(sscanf(data_in,"%d %d %d %d %d %d %d %d",
- &data[0],&data[1],&data[2],&data[3],&data[4],&data[5],&data[6],&data[7]));
-}
-
-
-voice_t *LoadVoice(const char *vname, int control)
-{//===============================================
-// control, bit 0 1= no_default
-// bit 1 1 = change tone only, not language
-// bit 2 1 = don't report error on LoadDictionary
-// bit 4 1 = vname = full path
-
- FILE *f_voice = NULL;
- keywtab_t *k;
- char *p;
- int key;
- int ix;
- int n;
- int value;
- int error = 0;
- int langix = 0;
- int tone_only = control & 2;
- int language_set = 0;
- int phonemes_set = 0;
- int stress_amps_set = 0;
- int stress_lengths_set = 0;
- int stress_add_set = 0;
- int conditional_rules = 0;
- LANGUAGE_OPTIONS *langopts = NULL;
-
- Translator *new_translator = NULL;
-
- char voicename[40];
- char language_name[40];
- char translator_name[40];
- char new_dictionary[40];
- char phonemes_name[40];
- const char *language_type;
- char buf[200];
- char path_voices[sizeof(path_home)+12];
- char langname[4];
-
- int stress_amps[8];
- int stress_lengths[8];
- int stress_add[8];
-
- int pitch1;
- int pitch2;
-
- static char voice_identifier[40]; // file name for voice_selected
- static char voice_name[40]; // voice name for voice_selected
- static char voice_languages[100]; // list of languages and priorities for voice_selected
-
- strcpy(voicename,vname);
- if(voicename[0]==0)
- strcpy(voicename,"default");
-
- if(control & 0x10)
- {
- strcpy(buf,vname);
- if(GetFileLength(buf) <= 0)
- return(NULL);
- }
- else
- {
- sprintf(path_voices,"%s%cvoices%c",path_home,PATHSEP,PATHSEP);
- sprintf(buf,"%s%s",path_voices,voicename);
-
- if(GetFileLength(buf) <= 0)
- {
- // look for the voice in a sub-directory of the language name
- langname[0] = voicename[0];
- langname[1] = voicename[1];
- langname[2] = 0;
- sprintf(buf,"%s%s%c%s",path_voices,langname,PATHSEP,voicename);
-
- if(GetFileLength(buf) <= 0)
- {
- // look in "test" sub-directory
- sprintf(buf,"%stest%c%s",path_voices,PATHSEP,voicename);
- }
- }
- }
-
- f_voice = fopen(buf,"r");
-
- language_type = "en"; // default
- if(f_voice == NULL)
- {
- if(control & 3)
- return(NULL); // can't open file
-
- if(SelectPhonemeTableName(voicename) >= 0)
- language_type = voicename;
- }
-
- if(!tone_only && (translator != NULL))
- {
- DeleteTranslator(translator);
- translator = NULL;
- }
-
- strcpy(translator_name,language_type);
- strcpy(new_dictionary,language_type);
- strcpy(phonemes_name,language_type);
-
-
- if(!tone_only)
- {
- voice = &voicedata;
- strncpy0(voice_identifier,vname,sizeof(voice_identifier));
- voice_name[0] = 0;
- voice_languages[0] = 0;
-
- voice_selected.identifier = voice_identifier;
- voice_selected.name = voice_name;
- voice_selected.languages = voice_languages;
- }
- else
- {
- // append the variant file name to the voice identifier
- if((p = strchr(voice_identifier,'+')) != NULL)
- *p = 0; // remove previous variant name
- sprintf(buf,"+%s",&vname[3]); // omit !v/ from the variant filename
- strcat(voice_identifier,buf);
- langopts = &translator->langopts;
- }
- VoiceReset(tone_only);
-
- if(!tone_only)
- SelectPhonemeTableName(phonemes_name); // set up phoneme_tab
-
-
- while((f_voice != NULL) && (fgets_strip(buf,sizeof(buf),f_voice) != NULL))
- {
- // isolate the attribute name
- for(p=buf; (*p != 0) && !isspace(*p); p++);
- *p++ = 0;
-
- if(buf[0] == 0) continue;
-
- key = 0;
- for(k=keyword_tab; k->mnem != NULL; k++)
- {
- if(strcmp(buf,k->mnem)==0)
- {
- key = k->data;
- break;
- }
- }
-
- switch(key)
- {
- case V_LANGUAGE:
- {
- unsigned int len;
- int priority;
-
- if(tone_only)
- break;
-
- priority = DEFAULT_LANGUAGE_PRIORITY;
- language_name[0] = 0;
-
- sscanf(p,"%s %d",language_name,&priority);
- if(strcmp(language_name,"variant") == 0)
- break;
-
- len = strlen(language_name) + 2;
- // check for space in languages[]
- if(len < (sizeof(voice_languages)-langix-1))
- {
- voice_languages[langix] = priority;
-
- strcpy(&voice_languages[langix+1],language_name);
- langix += len;
- }
-
- // only act on the first language line
- if(language_set == 0)
- {
- language_type = strtok(language_name,"-");
- language_set = 1;
- strcpy(translator_name,language_type);
- strcpy(new_dictionary,language_type);
- strcpy(phonemes_name,language_type);
- SelectPhonemeTableName(phonemes_name);
-
- if(new_translator != NULL)
- DeleteTranslator(new_translator);
-
- new_translator = SelectTranslator(translator_name);
- langopts = &new_translator->langopts;
- }
- }
- break;
-
- case V_NAME:
- if(tone_only == 0)
- {
- while(isspace(*p)) p++;
- strncpy0(voice_name,p,sizeof(voice_name));
- }
- break;
-
- case V_GENDER:
- {
- int age;
- char vgender[80];
- sscanf(p,"%s %d",vgender,&age);
- voice_selected.gender = LookupMnem(genders,vgender);
- voice_selected.age = age;
- }
- break;
-
- case V_TRANSLATOR:
- if(tone_only) break;
-
- sscanf(p,"%s",translator_name);
-
- if(new_translator != NULL)
- DeleteTranslator(new_translator);
-
- new_translator = SelectTranslator(translator_name);
- langopts = &new_translator->langopts;
- break;
-
- case V_DICTIONARY: // dictionary
- sscanf(p,"%s",new_dictionary);
- break;
-
- case V_PHONEMES: // phoneme table
- sscanf(p,"%s",phonemes_name);
- break;
-
- case V_FORMANT:
- VoiceFormant(p);
- break;
-
- case V_PITCH:
- {
- double factor;
- // default is pitch 82 118
- n = sscanf(p,"%d %d",&pitch1,&pitch2);
- voice->pitch_base = (pitch1 - 9) << 12;
- voice->pitch_range = (pitch2 - pitch1) * 108;
- factor = double(pitch1 - 82)/82;
- voice->formant_factor = (int)((1+factor/4) * 256); // nominal formant shift for a different voice pitch
- }
- break;
-
- case V_STRESSLENGTH: // stressLength
- stress_lengths_set = Read8Numbers(p,stress_lengths);
- break;
-
- case V_STRESSAMP: // stressAmp
- stress_amps_set = Read8Numbers(p,stress_amps);
- break;
-
- case V_STRESSADD: // stressAdd
- stress_add_set = Read8Numbers(p,stress_add);
- break;
-
- case V_INTONATION: // intonation
- sscanf(p,"%d %d",&option_tone_flags,&option_tone2);
- if((option_tone_flags & 0xff) != 0)
- langopts->intonation_group = option_tone_flags & 0xff;
- break;
-
- case V_DICTRULES: // conditional dictionary rules and list entries
- while(*p != 0)
- {
- while(isspace(*p)) p++;
- n = -1;
- if(((n = atoi(p)) > 0) && (n < 32))
- {
- p++;
- conditional_rules |= (1 << n);
- }
- while(isalnum(*p)) p++;
- }
- break;
-
- case V_REPLACE:
- if(phonemes_set == 0)
- {
- // must set up a phoneme table before we can lookup phoneme mnemonics
- SelectPhonemeTableName(phonemes_name);
- phonemes_set = 1;
- }
- PhonemeReplacement(key,p);
- break;
-
- case V_WORDGAP: // words
- sscanf(p,"%d %d",&langopts->word_gap, &langopts->vowel_pause);
- break;
-
- case V_STRESSRULE:
- sscanf(p,"%d %d %d %d",&langopts->stress_rule,
- &langopts->stress_flags,
- &langopts->unstressed_wd1,
- &langopts->unstressed_wd2);
- break;
-
- case V_CHARSET:
- if((sscanf(p,"%d",&value)==1) && (value < N_CHARSETS))
- new_translator->charset_a0 = charsets[value];
- break;
-
- case V_NUMBERS:
- sscanf(p,"%d %d",&langopts->numbers,&langopts->numbers2);
- break;
-
- case V_OPTION:
- if(sscanf(p,"%d %d",&ix,&value) == 2)
- {
- if((ix >= 0) && (ix < N_LOPTS))
- langopts->param[ix] = value;
- }
- break;
-
- case V_ECHO:
- // echo. suggest: 135mS 11%
- value = 0;
- voice->echo_amp = 0;
- sscanf(p,"%d %d",&voice->echo_delay,&voice->echo_amp);
- break;
-
- case V_FLUTTER: // flutter
- if(sscanf(p,"%d",&value)==1)
- voice->flutter = value * 32;
- break;
-
- case V_ROUGHNESS: // roughness
- if(sscanf(p,"%d",&value)==1)
- voice->roughness = value;
- break;
-
- case V_CLARITY: // formantshape
- if(sscanf(p,"%d",&value)==1)
- {
- if(value > 4)
- {
- voice->peak_shape = 1; // squarer formant peaks
- value = 4;
- }
- voice->n_harmonic_peaks = 1+value;
- }
- break;
-
- case V_TONE:
- {
- int tone_data[12];
- ReadTonePoints(p,tone_data);
- SetToneAdjust(voice,tone_data);
- }
- break;
-
- case V_VOICING:
- if(sscanf(p,"%d",&value)==1)
- voice->voicing = (value * 64)/100;
- break;
-
- case V_BREATH:
- voice->breath[0] = Read8Numbers(p,&voice->breath[1]);
- for(ix=1; ix<8; ix++)
- {
- if(ix % 2)
- voice->breath[ix] = -voice->breath[ix];
- }
- break;
-
- case V_BREATHW:
- voice->breathw[0] = Read8Numbers(p,&voice->breathw[1]);
- break;
-
- case V_CONSONANTS:
- value = sscanf(p,"%d %d",&voice->consonant_amp, &voice->consonant_ampv);
- break;
-
- case V_MBROLA:
- {
- int srate = 16000;
- char name[40];
- char phtrans[40];
-
- phtrans[0] = 0;
- sscanf(p,"%s %s %d",name,phtrans,&srate);
- LoadMbrolaTable(name,phtrans,srate);
- }
- break;
-
- case V_KLATT:
- voice->klattv[0] = 1; // default source: IMPULSIVE
- Read8Numbers(p,voice->klattv);
- voice->klattv[KLATT_Kopen] -= 40;
- break;
-
- case V_FAST:
- Read8Numbers(p,speed.fast_settings);
- SetSpeed(2);
- break;
-
- default:
- if((key & 0xff00) == 0x100)
- {
- sscanf(p,"%d",&langopts->param[key &0xff]);
- }
- else
- {
- fprintf(stderr,"Bad voice attribute: %s\n",buf);
- }
- break;
- }
- }
- if(f_voice != NULL)
- fclose(f_voice);
-
- if((new_translator == NULL) && (!tone_only))
- {
- // not set by language attribute
- new_translator = SelectTranslator(translator_name);
- }
-
- for(ix=0; ix<N_PEAKS; ix++)
- {
- voice->freq2[ix] = voice->freq[ix];
- voice->height2[ix] = voice->height[ix];
- voice->width2[ix] = voice->width[ix];
- }
-
- if(tone_only)
- {
- new_translator = translator;
- }
- else
- {
- if((ix = SelectPhonemeTableName(phonemes_name)) < 0)
- {
- fprintf(stderr,"Unknown phoneme table: '%s'\n",phonemes_name);
- }
- voice->phoneme_tab_ix = ix;
- error = LoadDictionary(new_translator, new_dictionary, control & 4);
- if(dictionary_name[0]==0)
- return(NULL); // no dictionary loaded
-
- new_translator->dict_condition = conditional_rules;
-
- voice_languages[langix] = 0;
- }
-
- langopts = &new_translator->langopts;
-
-
- if((value = langopts->param[LOPT_LENGTH_MODS]) != 0)
- {
- SetLengthMods(new_translator,value);
- }
-
- voice->width[0] = (voice->width[0] * 105)/100;
-
- if(!tone_only)
- {
- translator = new_translator;
- }
-
- // relative lengths of different stress syllables
- for(ix=0; ix<stress_lengths_set; ix++)
- {
- translator->stress_lengths[ix] = stress_lengths[ix];
- }
- for(ix=0; ix<stress_add_set; ix++)
- {
- translator->stress_lengths[ix] += stress_add[ix];
- }
- for(ix=0; ix<stress_amps_set; ix++)
- {
- translator->stress_amps[ix] = stress_amps[ix];
- translator->stress_amps_r[ix] = stress_amps[ix] -1;
- }
-
- return(voice);
-} // end of LoadVoice
-
-
-static char *ExtractVoiceVariantName(char *vname, int variant_num)
-{//===============================================================
-// Remove any voice variant suffix (name or number) from a voice name
-// Returns the voice variant name
-
- char *p;
- static char variant_name[20];
- char variant_prefix[5];
-
- variant_name[0] = 0;
- sprintf(variant_prefix,"!v%c",PATHSEP);
-
- if(vname != NULL)
- {
- if((p = strchr(vname,'+')) != NULL)
- {
- // The voice name has a +variant suffix
- *p++ = 0; // delete the suffix from the voice name
- if(isdigit(*p))
- {
- variant_num = atoi(p); // variant number
- }
- else
- {
- // voice variant name, not number
- strcpy(variant_name,variant_prefix);
- strncpy0(&variant_name[3],p,sizeof(variant_name)-3);
- }
- }
- }
-
- if(variant_num > 0)
- {
- if(variant_num < 10)
- sprintf(variant_name,"%sm%d",variant_prefix, variant_num); // male
- else
- sprintf(variant_name,"%sf%d",variant_prefix, variant_num-10); // female
- }
-
- return(variant_name);
-} // end of ExtractVoiceVariantName
-
-
-
-voice_t *LoadVoiceVariant(const char *vname, int variant_num)
-{//==========================================================
-// Load a voice file.
-// Also apply a voice variant if specified by "variant", or by "+number" or "+name" in the "vname"
-
- voice_t *v;
- char *variant_name;
- char buf[60];
-
- strncpy0(buf,vname,sizeof(buf));
- variant_name = ExtractVoiceVariantName(buf,variant_num);
-
- if((v = LoadVoice(buf,0)) == NULL)
- return(NULL);
-
- if(variant_name[0] != 0)
- {
- v = LoadVoice(variant_name,2);
- }
- return(v);
-}
-
-
-
-static int __cdecl VoiceNameSorter(const void *p1, const void *p2)
-{//=======================================================
- int ix;
- espeak_VOICE *v1 = *(espeak_VOICE **)p1;
- espeak_VOICE *v2 = *(espeak_VOICE **)p2;
-
-
- if((ix = strcmp(&v1->languages[1],&v2->languages[1])) != 0) // primary language name
- return(ix);
- if((ix = v1->languages[0] - v2->languages[0]) != 0) // priority number
- return(ix);
- return(strcmp(v1->name,v2->name));
-}
-
-
-static int __cdecl VoiceScoreSorter(const void *p1, const void *p2)
-{//========================================================
- int ix;
- espeak_VOICE *v1 = *(espeak_VOICE **)p1;
- espeak_VOICE *v2 = *(espeak_VOICE **)p2;
-
- if((ix = v2->score - v1->score) != 0)
- return(ix);
- return(strcmp(v1->name,v2->name));
-}
-
-
-static int ScoreVoice(espeak_VOICE *voice_spec, const char *spec_language, int spec_n_parts, int spec_lang_len, espeak_VOICE *voice)
-{//=========================================================================================================================
- int ix;
- const char *p;
- int c1, c2;
- int language_priority;
- int n_parts;
- int matching;
- int matching_parts;
- int score = 0;
- int x;
- int ratio;
- int required_age;
- int diff;
-
- p = voice->languages; // list of languages+dialects for which this voice is suitable
-
- if(strcmp(spec_language,"mbrola")==0)
- {
- // only list mbrola voices
- if(memcmp(voice->identifier,"mb/",3) == 0)
- return(100);
- return(0);
- }
-
- if(spec_n_parts == 0)
- {
- score = 100;
- }
- else
- {
- if((*p == 0) && (strcmp(spec_language,"variants")==0))
- {
- // match on a voice with no languages if the required language is "variants"
- score = 100;
- }
-
- // compare the required language with each of the languages of this voice
- while(*p != 0)
- {
- language_priority = *p++;
-
- matching = 1;
- matching_parts = 0;
- n_parts = 1;
-
- for(ix=0; ; ix++)
- {
- if((ix >= spec_lang_len) || ((c1 = spec_language[ix]) == '-'))
- c1 = 0;
- if((c2 = p[ix]) == '-')
- c2 = 0;
-
- if(c1 != c2)
- {
- matching = 0;
- }
-
- if(p[ix] == '-')
- {
- n_parts++;
- if(matching)
- matching_parts++;
- }
- if(p[ix] == 0)
- break;
- }
- p += (ix+1);
- matching_parts += matching; // number of parts which match
-
- if(matching_parts == 0)
- continue; // no matching parts for this language
-
- x = 5;
- // reduce the score if not all parts of the required language match
- if((diff = (spec_n_parts - matching_parts)) > 0)
- x -= diff;
-
- // reduce score if the language is more specific than required
- if((diff = (n_parts - matching_parts)) > 0)
- x -= diff;
-
- x = x*100 - (language_priority * 2);
-
- if(x > score)
- score = x;
- }
- }
- if(score == 0)
- return(0);
-
- if(voice_spec->name != NULL)
- {
- if(strcmp(voice_spec->name,voice->name)==0)
- {
- // match on voice name
- score += 500;
- }
- else
- if(strcmp(voice_spec->name,voice->identifier)==0)
- {
- score += 400;
- }
- }
-
- if(((voice_spec->gender == 1) || (voice_spec->gender == 2)) &&
- ((voice->gender == 1) || (voice->gender == 2)))
- {
- if(voice_spec->gender == voice->gender)
- score += 50;
- else
- score -= 50;
- }
-
- if((voice_spec->age <= 12) && (voice->gender == 2) && (voice->age > 12))
- {
- score += 5; // give some preference for non-child female voice if a child is requested
- }
-
- if(voice->age != 0)
- {
- if(voice_spec->age == 0)
- required_age = 30;
- else
- required_age = voice_spec->age;
-
- ratio = (required_age*100)/voice->age;
- if(ratio < 100)
- ratio = 10000/ratio;
- ratio = (ratio - 100)/10; // 0=exact match, 10=out by factor of 2
- x = 5 - ratio;
- if(x > 0) x = 0;
-
- score = score + x;
-
- if(voice_spec->age > 0)
- score += 10; // required age specified, favour voices with a specified age (near it)
- }
- if(score < 1)
- score = 1;
- return(score);
-} // end of ScoreVoice
-
-
-static int SetVoiceScores(espeak_VOICE *voice_select, espeak_VOICE **voices, int control)
-{//======================================================================================
-// control: bit0=1 include mbrola voices
- int ix;
- int score;
- int nv; // number of candidates
- int n_parts=0;
- int lang_len=0;
- espeak_VOICE *vp;
- char language[80];
-
- // count number of parts in the specified language
- if((voice_select->languages != NULL) && (voice_select->languages[0] != 0))
- {
- n_parts = 1;
- lang_len = strlen(voice_select->languages);
- for(ix=0; (ix<=lang_len) && ((unsigned)ix < sizeof(language)); ix++)
- {
- if((language[ix] = tolower(voice_select->languages[ix])) == '-')
- n_parts++;
- }
- }
- // select those voices which match the specified language
- nv = 0;
- for(ix=0; ix<n_voices_list; ix++)
- {
- vp = voices_list[ix];
-
- if(((control & 1) == 0) && (memcmp(vp->identifier,"mb/",3) == 0))
- continue;
-
- if((score = ScoreVoice(voice_select, language, n_parts, lang_len, voices_list[ix])) > 0)
- {
- voices[nv++] = vp;
- vp->score = score;
- }
- }
- voices[nv] = NULL; // list terminator
-
- if(nv==0)
- return(0);
-
- // sort the selected voices by their score
- qsort(voices,nv,sizeof(espeak_VOICE *),VoiceScoreSorter);
-
- return(nv);
-} // end of SetVoiceScores
-
-
-
-
-espeak_VOICE *SelectVoiceByName(espeak_VOICE **voices, const char *name)
-{//=====================================================================
- int ix;
- int match_fname = -1;
- int match_fname2 = -1;
- int match_name = -1;
- const char *id;
- int last_part_len;
- char last_part[41];
-
- if(voices == NULL)
- {
- if(n_voices_list == 0)
- espeak_ListVoices(NULL); // create the voices list
- voices = voices_list;
- }
-
- sprintf(last_part,"%c%s",PATHSEP,name);
- last_part_len = strlen(last_part);
-
- for(ix=0; voices[ix] != NULL; ix++)
- {
- if(strcmp(name,voices[ix]->name)==0)
- {
- match_name = ix; // found matching voice name
- break;
- }
- else
- if(strcmp(name,id = voices[ix]->identifier)==0)
- {
- match_fname = ix; // matching identifier, use this if no matching name
- }
- else
- if(strcmp(last_part,&id[strlen(id)-last_part_len])==0)
- {
- match_fname2 = ix;
- }
- }
-
- if(match_name < 0)
- {
- match_name = match_fname; // no matching name, try matching filename
- if(match_name < 0)
- match_name = match_fname2; // try matching just the last part of the filename
- }
-
- if(match_name < 0)
- return(NULL);
-
- return(voices[match_name]);
-} // end of SelectVoiceByName
-
-
-
-
-char const *SelectVoice(espeak_VOICE *voice_select, int *found)
-{//============================================================
-// Returns a path within espeak-voices, with a possible +variant suffix
-// variant is an output-only parameter
- int nv; // number of candidates
- int ix, ix2;
- int j;
- int n_variants;
- int variant_number;
- int gender;
- int skip;
- int aged=1;
- char *variant_name;
- const char *p, *p_start;
- espeak_VOICE *vp = NULL;
- espeak_VOICE *vp2;
- espeak_VOICE voice_select2;
- espeak_VOICE *voices[N_VOICES_LIST]; // list of candidates
- espeak_VOICE *voices2[N_VOICES_LIST+N_VOICE_VARIANTS];
- static espeak_VOICE voice_variants[N_VOICE_VARIANTS];
- static char voice_id[50];
-
- *found = 1;
- memcpy(&voice_select2,voice_select,sizeof(voice_select2));
-
- if(n_voices_list == 0)
- espeak_ListVoices(NULL); // create the voices list
-
- if((voice_select2.languages == NULL) || (voice_select2.languages[0] == 0))
- {
- // no language is specified. Get language from the named voice
- static char buf[60];
-
- if(voice_select2.name == NULL)
- {
- if((voice_select2.name = voice_select2.identifier) == NULL)
- voice_select2.name = "default";
- }
-
- strncpy0(buf,voice_select2.name,sizeof(buf));
- variant_name = ExtractVoiceVariantName(buf,0);
-
- vp = SelectVoiceByName(voices_list,buf);
- if(vp != NULL)
- {
- voice_select2.languages = &(vp->languages[1]);
-
- if((voice_select2.gender==0) && (voice_select2.age==0) && (voice_select2.variant==0))
- {
- if(variant_name[0] != 0)
- {
- sprintf(voice_id,"%s+%s",vp->identifier,&variant_name[3]); // omit the !v/ from variant_name
- return(voice_id);
- }
-
- return(vp->identifier);
- }
- }
- }
-
- // select and sort voices for the required language
- nv = SetVoiceScores(&voice_select2,voices,0);
-
- if(nv == 0)
- {
- // no matching voice, choose the default
- *found = 0;
- if((voices[0] = SelectVoiceByName(voices_list,"default")) != NULL)
- nv = 1;
- }
-
- gender = 0;
- if((voice_select2.gender == 2) || ((voice_select2.age > 0) && (voice_select2.age < 13)))
- gender = 2;
- else
- if(voice_select2.gender == 1)
- gender = 1;
-
-#define AGE_OLD 60
- if(voice_select2.age < AGE_OLD)
- aged = 0;
-
- p = p_start = variant_lists[gender];
- if(aged == 0)
- p++; // the first voice in the variants list is older
-
- // add variants for the top voices
- n_variants = 0;
- for(ix=0, ix2=0; ix<nv; ix++)
- {
- vp = voices[ix];
- // is the main voice the required gender?
- skip=0;
- if((gender != 0) && (vp->gender != gender))
- {
- skip=1;
- }
- if((ix2==0) && aged && (vp->age < AGE_OLD))
- {
- skip=1;
- }
- if(skip==0)
- {
- voices2[ix2++] = vp;
- }
-
- for(j=0; (j < vp->xx1) && (n_variants < N_VOICE_VARIANTS);)
- {
- if((variant_number = *p) == 0)
- {
- p = p_start;
- continue;
- }
-
- vp2 = &voice_variants[n_variants++]; // allocate space for voice variant
- memcpy(vp2,vp,sizeof(espeak_VOICE)); // copy from the original voice
- vp2->variant = variant_number;
- voices2[ix2++] = vp2;
- p++;
- j++;
- }
- }
- // add any more variants to the end of the list
- while((vp != NULL) && ((variant_number = *p++) != 0) && (n_variants < N_VOICE_VARIANTS))
- {
- vp2 = &voice_variants[n_variants++]; // allocate space for voice variant
- memcpy(vp2,vp,sizeof(espeak_VOICE)); // copy from the original voice
- vp2->variant = variant_number;
- voices2[ix2++] = vp2;
- }
-
- // index the sorted list by the required variant number
- vp = voices2[voice_select2.variant % ix2];
-
- if(vp->variant != 0)
- {
- variant_name = ExtractVoiceVariantName(NULL,vp->variant);
- sprintf(voice_id,"%s+%s",vp->identifier,&variant_name[3]);
- return(voice_id);
- }
-
- return(vp->identifier);
-} // end of SelectVoice
-
-
-
-static void GetVoices(const char *path)
-{//====================================
- FILE *f_voice;
- espeak_VOICE *voice_data;
- int ftype;
- char fname[sizeof(path_home)+100];
-
-#ifdef PLATFORM_RISCOS
- int len;
- int *type;
- char *p;
- _kernel_swi_regs regs;
- _kernel_oserror *error;
- char buf[80];
- char directory2[sizeof(path_home)+100];
-
- regs.r[0] = 10;
- regs.r[1] = (int)path;
- regs.r[2] = (int)buf;
- regs.r[3] = 1;
- regs.r[4] = 0;
- regs.r[5] = sizeof(buf);
- regs.r[6] = 0;
-
- while(regs.r[3] > 0)
- {
- error = _kernel_swi(0x0c+0x20000,&regs,&regs); /* OS_GBPB 10, read directory entries */
- if((error != NULL) || (regs.r[3] == 0))
- {
- break;
- }
- type = (int *)(&buf[16]);
- len = strlen(&buf[20]);
- sprintf(fname,"%s.%s",path,&buf[20]);
-
- if(*type == 2)
- {
- // a sub-directory
- GetVoices(fname);
- }
- else
- {
- // a regular line, add it to the voices list
- if((f_voice = fopen(fname,"r")) == NULL)
- continue;
-
- // pass voice file name within the voices directory
- voice_data = ReadVoiceFile(f_voice, fname+len_path_voices, &buf[20]);
- fclose(f_voice);
-
- if(voice_data != NULL)
- {
- voices_list[n_voices_list++] = voice_data;
- }
- }
- }
-#else
-#ifdef PLATFORM_WINDOWS
- WIN32_FIND_DATAA FindFileData;
- HANDLE hFind = INVALID_HANDLE_VALUE;
-
-#undef UNICODE // we need FindFirstFileA() which takes an 8-bit c-string
- sprintf(fname,"%s\\*",path);
- hFind = FindFirstFileA(fname, &FindFileData);
- if(hFind == INVALID_HANDLE_VALUE)
- return;
-
- do {
- sprintf(fname,"%s%c%s",path,PATHSEP,FindFileData.cFileName);
-
- ftype = GetFileLength(fname);
-
- if((ftype == -2) && (FindFileData.cFileName[0] != '.'))
- {
- // a sub-sirectory
- GetVoices(fname);
- }
- else
- if(ftype > 0)
- {
- // a regular line, add it to the voices list
- if((f_voice = fopen(fname,"r")) == NULL)
- continue;
-
- // pass voice file name within the voices directory
- voice_data = ReadVoiceFile(f_voice, fname+len_path_voices, FindFileData.cFileName);
- fclose(f_voice);
-
- if(voice_data != NULL)
- {
- voices_list[n_voices_list++] = voice_data;
- }
- }
- } while(FindNextFileA(hFind, &FindFileData) != 0);
- FindClose(hFind);
-
-#else
- DIR *dir;
- struct dirent *ent;
-
- if((dir = opendir((char *)path)) == NULL) // note: (char *) is needed for WINCE
- return;
-
- while((ent = readdir(dir)) != NULL)
- {
- if(n_voices_list >= (N_VOICES_LIST-2))
- break; // voices list is full
-
- sprintf(fname,"%s%c%s",path,PATHSEP,ent->d_name);
-
- ftype = GetFileLength(fname);
-
- if((ftype == -2) && (ent->d_name[0] != '.'))
- {
- // a sub-sirectory
- GetVoices(fname);
- }
- else
- if(ftype > 0)
- {
- // a regular line, add it to the voices list
- if((f_voice = fopen(fname,"r")) == NULL)
- continue;
-
- // pass voice file name within the voices directory
- voice_data = ReadVoiceFile(f_voice, fname+len_path_voices, ent->d_name);
- fclose(f_voice);
-
- if(voice_data != NULL)
- {
- voices_list[n_voices_list++] = voice_data;
- }
- }
- }
- closedir(dir);
-#endif
-#endif
-} // end of GetVoices
-
-
-
-espeak_ERROR SetVoiceByName(const char *name)
-{//=========================================
- espeak_VOICE *v;
- espeak_VOICE voice_selector;
- char *variant_name;
- static char buf[60];
-
- strncpy0(buf,name,sizeof(buf));
- variant_name = ExtractVoiceVariantName(buf,0);
-
- memset(&voice_selector,0,sizeof(voice_selector));
-// voice_selector.name = buf;
- voice_selector.name = (char *)name; // include variant name in voice stack ??
-
- // first check for a voice with this filename
- // This may avoid the need to call espeak_ListVoices().
-
- if(LoadVoice(buf,1) != NULL)
- {
- if(variant_name[0] != 0)
- {
- LoadVoice(variant_name,2);
- }
-
- DoVoiceChange(voice);
- SetVoiceStack(&voice_selector);
- return(EE_OK);
- }
-
- if(n_voices_list == 0)
- espeak_ListVoices(NULL); // create the voices list
-
- if((v = SelectVoiceByName(voices_list,buf)) != NULL)
- {
- if(LoadVoice(v->identifier,0) != NULL)
- {
- if(variant_name[0] != 0)
- {
- LoadVoice(variant_name,2);
- }
- DoVoiceChange(voice);
- SetVoiceStack(&voice_selector);
- return(EE_OK);
- }
- }
- return(EE_INTERNAL_ERROR); // voice name not found
-} // end of SetVoiceByName
-
-
-
-espeak_ERROR SetVoiceByProperties(espeak_VOICE *voice_selector)
-{//============================================================
- const char *voice_id;
- int voice_found;
-
- voice_id = SelectVoice(voice_selector, &voice_found);
-
- if(voice_found == 0)
- return(EE_NOT_FOUND);
-
- LoadVoiceVariant(voice_id,0);
- DoVoiceChange(voice);
- SetVoiceStack(voice_selector);
-
- return(EE_OK);
-} // end of SetVoiceByProperties
-
-
-
-
-//=======================================================================
-// Library Interface Functions
-//=======================================================================
-#pragma GCC visibility push(default)
-
-
-const espeak_VOICE **espeak_ListVoices(espeak_VOICE *voice_spec)
-{//========================================================================
-#ifndef PLATFORM_RISCOS
- int ix;
- int j;
- espeak_VOICE *v;
- static espeak_VOICE *voices[N_VOICES_LIST];
- char path_voices[sizeof(path_home)+12];
-
- // free previous voice list data
-
- for(ix=0; ix<n_voices_list; ix++)
- {
- if(voices_list[ix] != NULL)
- free(voices_list[ix]);
- }
- n_voices_list = 0;
-
- sprintf(path_voices,"%s%cvoices",path_home,PATHSEP);
- len_path_voices = strlen(path_voices)+1;
-
- GetVoices(path_voices);
- voices_list[n_voices_list] = NULL; // voices list terminator
-
- // sort the voices list
- qsort(voices_list,n_voices_list,sizeof(espeak_VOICE *),VoiceNameSorter);
-
-
- if(voice_spec)
- {
- // select the voices which match the voice_spec, and sort them by preference
- SetVoiceScores(voice_spec,voices,1);
- }
- else
- {
- // list all: omit variant voices and mbrola voices
- j = 0;
- for(ix=0; (v = voices_list[ix]) != NULL; ix++)
- {
- if((v->languages[0] != 0) && (strcmp(&v->languages[1],"variant") != 0) && (memcmp(v->identifier,"mb/",3) != 0))
- {
- voices[j++] = v;
- }
- }
- voices[j] = NULL;
- }
- return((const espeak_VOICE **)voices);
-#endif
- return((const espeak_VOICE **)voices_list);
-} // end of espeak_ListVoices
-
-
-
-espeak_VOICE *espeak_GetCurrentVoice(void)
-{//==================================================
- return(&voice_selected);
-}
-
-#pragma GCC visibility pop
-
-
diff --git a/navit/support/espeak/wave.c b/navit/support/espeak/wave.c
deleted file mode 100755
index 364dcf577..000000000
--- a/navit/support/espeak/wave.c
+++ /dev/null
@@ -1,1112 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2007, Gilles Casse <gcasse@oralux.org> *
- * based on AudioIO.cc (Audacity-1.2.4b) and wavegen.cpp *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-#include "speech.h"
-
-#ifdef USE_ASYNC
-// This source file is only used for asynchronious modes
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <math.h>
-#include <assert.h>
-#include <sys/time.h>
-#include <time.h>
-
-#include "portaudio.h"
-#ifndef PLATFORM_WINDOWS
-#include <unistd.h>
-#endif
-#include "wave.h"
-#include "debug.h"
-
-//<Definitions
-
-enum {ONE_BILLION=1000000000};
-
-#ifdef USE_PORTAUDIO
-
-#undef USE_PORTAUDIO
-// determine portaudio version by looking for a #define which is not in V18
-#ifdef paNeverDropInput
-#define USE_PORTAUDIO 19
-#else
-#define USE_PORTAUDIO 18
-#endif
-
-
-static t_wave_callback* my_callback_is_output_enabled=NULL;
-
-#define N_WAV_BUF 10
-#define SAMPLE_RATE 22050
-#define FRAMES_PER_BUFFER 512
-#define BUFFER_LENGTH (SAMPLE_RATE*2*sizeof(uint16_t))
-#define THRESHOLD (BUFFER_LENGTH/5)
-static char myBuffer[BUFFER_LENGTH];
-static char* myRead=NULL;
-static char* myWrite=NULL;
-static int out_channels=1;
-static int my_stream_could_start=0;
-
-static int mInCallbackFinishedState = false;
-#if (USE_PORTAUDIO == 18)
-static PortAudioStream *pa_stream=NULL;
-#endif
-#if (USE_PORTAUDIO == 19)
-static struct PaStreamParameters myOutputParameters;
-static PaStream *pa_stream=NULL;
-#endif
-
-static int userdata[4];
-static PaError pa_init_err=0;
-
-// time measurement
-// The read and write position audio stream in the audio stream are measured in ms.
-//
-// * When the stream is opened, myReadPosition and myWritePosition are cleared.
-// * myWritePosition is updated in wave_write.
-// * myReadPosition is updated in pa_callback (+ sample delay).
-
-static uint32_t myReadPosition = 0; // in ms
-static uint32_t myWritePosition = 0;
-
-//>
-//<init_buffer, get_used_mem
-
-static void init_buffer()
-{
- myWrite = myBuffer;
- myRead = myBuffer;
- memset(myBuffer,0,BUFFER_LENGTH);
- myReadPosition = myWritePosition = 0;
- SHOW("init_buffer > myRead=0x%x, myWrite=0x%x, BUFFER_LENGTH=0x%x, myReadPosition = myWritePosition = 0\n", (int)myRead, (int)myWrite, BUFFER_LENGTH);
-}
-
-static unsigned int get_used_mem()
-{
- char* aRead = myRead;
- char* aWrite = myWrite;
- unsigned int used = 0;
-
- assert ((aRead >= myBuffer)
- && (aRead <= myBuffer + BUFFER_LENGTH)
- && (aWrite >= myBuffer)
- && (aWrite <= myBuffer + BUFFER_LENGTH));
-
- if (aRead < aWrite)
- {
- used = aWrite - aRead;
- }
- else
- {
- used = aWrite + BUFFER_LENGTH - aRead;
- }
- SHOW("get_used_mem > %d\n", used);
-
- return used;
-}
-
-//>
-//<start stream
-
-static void start_stream()
-{
- PaError err;
- SHOW_TIME("start_stream");
-
- my_stream_could_start=0;
- mInCallbackFinishedState = false;
-
- err = Pa_StartStream(pa_stream);
- SHOW("start_stream > Pa_StartStream=%d (%s)\n", err, Pa_GetErrorText(err));
-
-#if USE_PORTAUDIO == 19
- if(err == paStreamIsNotStopped)
- {
- SHOW_TIME("start_stream > restart stream (begin)");
- // not sure why we need this, but PA v19 seems to need it
- err = Pa_StopStream(pa_stream);
- SHOW("start_stream > Pa_StopStream=%d (%s)\n", err, Pa_GetErrorText(err));
- err = Pa_StartStream(pa_stream);
- SHOW("start_stream > Pa_StartStream=%d (%s)\n", err, Pa_GetErrorText(err));
- SHOW_TIME("start_stream > restart stream (end)");
- }
-#endif
-}
-
-//>
-//<pa_callback
-
-/* This routine will be called by the PortAudio engine when audio is needed.
-** It may called at interrupt level on some machines so don't do anything
-** that could mess up the system like calling malloc() or free().
-*/
-#if USE_PORTAUDIO == 18
-static int pa_callback(void *inputBuffer, void *outputBuffer,
- unsigned long framesPerBuffer, PaTimestamp outTime, void *userData )
-#else
- static int pa_callback(const void *inputBuffer, void *outputBuffer,
- long unsigned int framesPerBuffer, const PaStreamCallbackTimeInfo *outTime,
- PaStreamCallbackFlags flags, void *userData )
-#endif
-{
- int aResult=0; // paContinue
- char* aWrite = myWrite;
- size_t n = out_channels*sizeof(uint16_t)*framesPerBuffer;
-
- myReadPosition += framesPerBuffer;
- SHOW("pa_callback > myReadPosition=%u, framesPerBuffer=%lu (n=0x%x) \n",(int)myReadPosition, framesPerBuffer, n);
-
- if (aWrite >= myRead)
- {
- if((size_t)(aWrite - myRead) >= n)
- {
- memcpy(outputBuffer, myRead, n);
- myRead += n;
- }
- else
- {
- SHOW_TIME("pa_callback > underflow");
- aResult=1; // paComplete;
- mInCallbackFinishedState = true;
- size_t aUsedMem=0;
- aUsedMem = (size_t)(aWrite - myRead);
- if (aUsedMem)
- {
- memcpy(outputBuffer, myRead, aUsedMem);
- }
- char* p = (char*)outputBuffer + aUsedMem;
- memset(p, 0, n - aUsedMem);
- // myReadPosition += aUsedMem/(out_channels*sizeof(uint16_t));
- myRead = aWrite;
- }
- }
- else // myRead > aWrite
- {
- if ((size_t)(myBuffer + BUFFER_LENGTH - myRead) >= n)
- {
- memcpy(outputBuffer, myRead, n);
- myRead += n;
- }
- else if ((size_t)(aWrite + BUFFER_LENGTH - myRead) >= n)
- {
- int aTopMem = myBuffer + BUFFER_LENGTH - myRead;
- if (aTopMem)
- {
- SHOW("pa_callback > myRead=0x%x, aTopMem=0x%x\n",(int)myRead, (int)aTopMem);
- memcpy(outputBuffer, myRead, aTopMem);
- }
- int aRest = n - aTopMem;
- if (aRest)
- {
- SHOW("pa_callback > myRead=0x%x, aRest=0x%x\n",(int)myRead, (int)aRest);
- char* p = (char*)outputBuffer + aTopMem;
- memcpy(p, myBuffer, aRest);
- }
- myRead = myBuffer + aRest;
- }
- else
- {
- SHOW_TIME("pa_callback > underflow");
- aResult=1; // paComplete;
-
- int aTopMem = myBuffer + BUFFER_LENGTH - myRead;
- if (aTopMem)
- {
- SHOW("pa_callback > myRead=0x%x, aTopMem=0x%x\n",(int)myRead, (int)aTopMem);
- memcpy(outputBuffer, myRead, aTopMem);
- }
- int aRest = aWrite - myBuffer;
- if (aRest)
- {
- SHOW("pa_callback > myRead=0x%x, aRest=0x%x\n",(int)myRead, (int)aRest);
- char* p = (char*)outputBuffer + aTopMem;
- memcpy(p, myBuffer, aRest);
- }
-
- size_t aUsedMem = aTopMem + aRest;
- char* p = (char*)outputBuffer + aUsedMem;
- memset(p, 0, n - aUsedMem);
- // myReadPosition += aUsedMem/(out_channels*sizeof(uint16_t));
- myRead = aWrite;
- }
- }
-
- SHOW("pa_callback > myRead=%x\n",(int)myRead);
-
-
- // #if USE_PORTAUDIO == 18
- // if(aBufferEmpty)
- // {
- // static int end_timer = 0;
- // if(end_timer == 0)
- // end_timer = 4;
- // if(end_timer > 0)
- // {
- // end_timer--;
- // if(end_timer == 0)
- // return(1);
- // }
- // }
- // return(0);
- // #else
-
-#ifdef ARCH_BIG
- {
- // BIG-ENDIAN, swap the order of bytes in each sound sample in the portaudio buffer
- int c;
- unsigned char *out_ptr;
- unsigned char *out_end;
- out_ptr = (unsigned char *)outputBuffer;
- out_end = out_ptr + framesPerBuffer*2 * out_channels;
- while(out_ptr < out_end)
- {
- c = out_ptr[0];
- out_ptr[0] = out_ptr[1];
- out_ptr[1] = c;
- out_ptr += 2;
- }
- }
-#endif
-
-
- return(aResult);
- //#endif
-
-} // end of WaveCallBack
-
-//>
-
-
-void wave_flush(void* theHandler)
-{
- ENTER("wave_flush");
-
- if (my_stream_could_start)
- {
-// #define buf 1024
-// static char a_buffer[buf*2];
-// memset(a_buffer,0,buf*2);
-// wave_write(theHandler, a_buffer, buf*2);
- start_stream();
- }
-}
-
-//<wave_open_sound
-
-static int wave_open_sound()
-{
- ENTER("wave_open_sound");
-
- PaError err=paNoError;
- PaError active;
-
-#if USE_PORTAUDIO == 18
- active = Pa_StreamActive(pa_stream);
-#else
- active = Pa_IsStreamActive(pa_stream);
-#endif
-
- if(active == 1)
- {
- SHOW_TIME("wave_open_sound > already active");
- return(0);
- }
- if(active < 0)
- {
- out_channels = 1;
-
-#if USE_PORTAUDIO == 18
- // err = Pa_OpenDefaultStream(&pa_stream,0,1,paInt16,SAMPLE_RATE,FRAMES_PER_BUFFER,N_WAV_BUF,pa_callback,(void *)userdata);
-
- PaDeviceID playbackDevice = Pa_GetDefaultOutputDeviceID();
-
- PaError err = Pa_OpenStream( &pa_stream,
- /* capture parameters */
- paNoDevice,
- 0,
- paInt16,
- NULL,
- /* playback parameters */
- playbackDevice,
- out_channels,
- paInt16,
- NULL,
- /* general parameters */
- SAMPLE_RATE, FRAMES_PER_BUFFER, 0,
- //paClipOff | paDitherOff,
- paNoFlag,
- pa_callback, (void *)userdata);
-
- SHOW("wave_open_sound > Pa_OpenDefaultStream(1): err=%d (%s)\n",err, Pa_GetErrorText(err));
-
- if(err == paInvalidChannelCount)
- {
- SHOW_TIME("wave_open_sound > try stereo");
- // failed to open with mono, try stereo
- out_channels = 2;
- // myOutputParameters.channelCount = out_channels;
- PaError err = Pa_OpenStream( &pa_stream,
- /* capture parameters */
- paNoDevice,
- 0,
- paInt16,
- NULL,
- /* playback parameters */
- playbackDevice,
- out_channels,
- paInt16,
- NULL,
- /* general parameters */
- SAMPLE_RATE, FRAMES_PER_BUFFER, 0,
- //paClipOff | paDitherOff,
- paNoFlag,
- pa_callback, (void *)userdata);
-// err = Pa_OpenDefaultStream(&pa_stream,0,2,paInt16,
-// SAMPLE_RATE,
-// FRAMES_PER_BUFFER,
-// N_WAV_BUF,pa_callback,(void *)userdata);
- SHOW("wave_open_sound > Pa_OpenDefaultStream(2): err=%d (%s)\n",err, Pa_GetErrorText(err));
- err=0; // avoid warning
- }
- mInCallbackFinishedState = false; // v18 only
-#else
- myOutputParameters.channelCount = out_channels;
- unsigned long framesPerBuffer = paFramesPerBufferUnspecified;
- err = Pa_OpenStream(
- &pa_stream,
- NULL, /* no input */
- &myOutputParameters,
- SAMPLE_RATE,
- framesPerBuffer,
- paNoFlag,
- // paClipOff | paDitherOff,
- pa_callback,
- (void *)userdata);
- if ((err!=paNoError)
- && (err!=paInvalidChannelCount)) //err==paUnanticipatedHostError
- {
- fprintf(stderr, "wave_open_sound > Pa_OpenStream : err=%d (%s)\n",err,Pa_GetErrorText(err));
- framesPerBuffer = FRAMES_PER_BUFFER;
- err = Pa_OpenStream(
- &pa_stream,
- NULL, /* no input */
- &myOutputParameters,
- SAMPLE_RATE,
- framesPerBuffer,
- paNoFlag,
- // paClipOff | paDitherOff,
- pa_callback,
- (void *)userdata);
- }
- if(err == paInvalidChannelCount)
- {
- SHOW_TIME("wave_open_sound > try stereo");
- // failed to open with mono, try stereo
- out_channels = 2;
- myOutputParameters.channelCount = out_channels;
- err = Pa_OpenStream(
- &pa_stream,
- NULL, /* no input */
- &myOutputParameters,
- SAMPLE_RATE,
- framesPerBuffer,
- paNoFlag,
- // paClipOff | paDitherOff,
- pa_callback,
- (void *)userdata);
-
- // err = Pa_OpenDefaultStream(&pa_stream,0,2,paInt16,(double)SAMPLE_RATE,FRAMES_PER_BUFFER,pa_callback,(void *)userdata);
- }
- mInCallbackFinishedState = false;
-#endif
- }
-
- SHOW("wave_open_sound > %s\n","LEAVE");
-
- return (err != paNoError);
-}
-
-//>
-//<select_device
-
-#if (USE_PORTAUDIO == 19)
-static void update_output_parameters(int selectedDevice, const PaDeviceInfo *deviceInfo)
-{
- // const PaDeviceInfo *pdi = Pa_GetDeviceInfo(i);
- myOutputParameters.device = selectedDevice;
- // myOutputParameters.channelCount = pdi->maxOutputChannels;
- myOutputParameters.channelCount = 1;
- myOutputParameters.sampleFormat = paInt16;
-
- // Latency greater than 100ms for avoiding glitches
- // (e.g. when moving a window in a graphical desktop)
- // deviceInfo = Pa_GetDeviceInfo(selectedDevice);
- if (deviceInfo)
- {
- double aLatency = deviceInfo->defaultLowOutputLatency;
- double aCoeff = round(0.100 / aLatency);
-// myOutputParameters.suggestedLatency = aCoeff * aLatency; // to avoid glitches ?
- myOutputParameters.suggestedLatency = aLatency; // for faster response ?
- SHOW("Device=%d, myOutputParameters.suggestedLatency=%f, aCoeff=%f\n",
- selectedDevice,
- myOutputParameters.suggestedLatency,
- aCoeff);
- }
- else
- {
- myOutputParameters.suggestedLatency = (double)0.1; // 100ms
- SHOW("Device=%d, myOutputParameters.suggestedLatency=%f (default)\n",
- selectedDevice,
- myOutputParameters.suggestedLatency);
- }
- //pdi->defaultLowOutputLatency;
-
- myOutputParameters.hostApiSpecificStreamInfo = NULL;
-}
-#endif
-
-static void select_device(const char* the_api)
-{
- ENTER("select_device");
-
-#if (USE_PORTAUDIO == 19)
- int numDevices = Pa_GetDeviceCount();
- if( numDevices < 0 )
- {
- SHOW( "ERROR: Pa_CountDevices returned 0x%x\n", numDevices );
- assert(0);
- }
-
- PaDeviceIndex i=0, selectedIndex=0, defaultAlsaIndex=numDevices;
- const PaDeviceInfo *deviceInfo=NULL;
- const PaDeviceInfo *selectedDeviceInfo=NULL;
-
- if(option_device_number >= 0)
- {
- selectedIndex = option_device_number;
- selectedDeviceInfo = Pa_GetDeviceInfo(selectedIndex);
- }
-
- if(selectedDeviceInfo == NULL)
- {
- for( i=0; i<numDevices; i++ )
- {
- deviceInfo = Pa_GetDeviceInfo( i );
-
- if (deviceInfo == NULL)
- {
- break;
- }
- const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo( deviceInfo->hostApi );
-
- if (hostInfo && hostInfo->type == paALSA)
- {
- // Check (once) the default output device
- if (defaultAlsaIndex == numDevices)
- {
- defaultAlsaIndex = hostInfo->defaultOutputDevice;
- const PaDeviceInfo *deviceInfo = Pa_GetDeviceInfo( defaultAlsaIndex );
- update_output_parameters(defaultAlsaIndex, deviceInfo);
- if (Pa_IsFormatSupported(NULL, &myOutputParameters, SAMPLE_RATE) == 0)
- {
- SHOW( "select_device > ALSA (default), name=%s (#%d)\n", deviceInfo->name, defaultAlsaIndex);
- selectedIndex = defaultAlsaIndex;
- selectedDeviceInfo = deviceInfo;
- break;
- }
- }
-
- // if the default output device does not match,
- // look for the device with the highest number of output channels
- SHOW( "select_device > ALSA, i=%d (numDevices=%d)\n", i, numDevices);
-
- update_output_parameters(i, deviceInfo);
-
- if (Pa_IsFormatSupported(NULL, &myOutputParameters, SAMPLE_RATE) == 0)
- {
- SHOW( "select_device > ALSA, name=%s (#%d)\n", deviceInfo->name, i);
-
- if (!selectedDeviceInfo
- || (selectedDeviceInfo->maxOutputChannels < deviceInfo->maxOutputChannels))
- {
- selectedIndex = i;
- selectedDeviceInfo = deviceInfo;
- }
- }
- }
- }
- }
-
- if (selectedDeviceInfo)
- {
- update_output_parameters(selectedIndex, selectedDeviceInfo);
- }
- else
- {
- i = Pa_GetDefaultOutputDevice();
- deviceInfo = Pa_GetDeviceInfo( i );
- update_output_parameters(i, deviceInfo);
- }
-
-#endif
-}
-
-//>
-
-
-// int wave_Close(void* theHandler)
-// {
-// SHOW_TIME("WaveCloseSound");
-
-// // PaError active;
-
-// // check whether speaking has finished, and close the stream
-// if(pa_stream != NULL)
-// {
-// Pa_CloseStream(pa_stream);
-// pa_stream = NULL;
-// init_buffer();
-
-// // #if USE_PORTAUDIO == 18
-// // active = Pa_StreamActive(pa_stream);
-// // #else
-// // active = Pa_IsStreamActive(pa_stream);
-// // #endif
-// // if(active == 0)
-// // {
-// // SHOW_TIME("WaveCloseSound > ok, not active");
-// // Pa_CloseStream(pa_stream);
-// // pa_stream = NULL;
-// // return(1);
-// // }
-// }
-// return(0);
-// }
-
-//<wave_set_callback_is_output_enabled
-
-void wave_set_callback_is_output_enabled(t_wave_callback* cb)
-{
- my_callback_is_output_enabled = cb;
-}
-
-//>
-//<wave_init
-
-// TBD: the arg could be "alsa", "oss",...
-void wave_init()
-{
- ENTER("wave_init");
- PaError err;
-
- pa_stream = NULL;
- mInCallbackFinishedState = false;
- init_buffer();
-
- // PortAudio sound output library
- err = Pa_Initialize();
- pa_init_err = err;
- if(err != paNoError)
- {
- SHOW_TIME("wave_init > Failed to initialise the PortAudio sound");
- }
-}
-
-//>
-//<wave_open
-
-void* wave_open(const char* the_api)
-{
- ENTER("wave_open");
- static int once=0;
-
- // TBD: the_api (e.g. "alsa") is not used at the moment
- // select_device is called once
- if (!once)
- {
- select_device("alsa");
- once=1;
- }
- return((void*)1);
-}
-
-//>
-//<copyBuffer
-
-
-static size_t copyBuffer(char* dest, char* src, const size_t theSizeInBytes)
-{
- size_t bytes_written = 0;
- unsigned int i = 0;
- uint16_t* a_dest = NULL;
- uint16_t* a_src = NULL;
-
- if ((src != NULL) && dest != NULL)
- {
- // copy for one channel (mono)?
- if(out_channels==1)
- {
- SHOW("copyBuffer > 1 channel > memcpy %x (%d bytes)\n", (int)myWrite, theSizeInBytes);
- memcpy(dest, src, theSizeInBytes);
- bytes_written = theSizeInBytes;
- }
- else // copy for 2 channels (stereo)
- {
- SHOW("copyBuffer > 2 channels > memcpy %x (%d bytes)\n", (int)myWrite, theSizeInBytes);
- i = 0;
- a_dest = (uint16_t* )dest;
- a_src = (uint16_t* )src;
-
- for(i=0; i<theSizeInBytes/2; i++)
- {
- a_dest[2*i] = a_src[i];
- a_dest[2*i+1] = a_src[i];
- }
- bytes_written = 2*theSizeInBytes;
- } // end if(out_channels==1)
- } // end if ((src != NULL) && dest != NULL)
-
- return bytes_written;
-}
-
-//>
-//<wave_write
-
-size_t wave_write(void* theHandler, char* theMono16BitsWaveBuffer, size_t theSize)
-{
- ENTER("wave_write");
- size_t bytes_written = 0;
- // space in ringbuffer for the sample needed: 1x mono channel but 2x for 1 stereo channel
- size_t bytes_to_write = (out_channels==1) ? theSize : theSize*2;
- my_stream_could_start = 0;
-
- if(pa_stream == NULL)
- {
- SHOW_TIME("wave_write > wave_open_sound\n");
- if (0 != wave_open_sound())
- {
- SHOW_TIME("wave_write > wave_open_sound fails!");
- return 0;
- }
- my_stream_could_start=1;
- }
- else if (!wave_is_busy(NULL))
- {
- my_stream_could_start = 1;
- }
- assert(BUFFER_LENGTH >= bytes_to_write);
-
- if (myWrite >= myBuffer + BUFFER_LENGTH)
- {
- myWrite = myBuffer;
- } // end if (myWrite >= myBuffer + BUFFER_LENGTH)
-
- size_t aTotalFreeMem=0;
- char* aRead = myRead;
- SHOW("wave_write > aRead=%x, myWrite=%x\n", (int)aRead, (int)myWrite);
-
- while (1)
- {
- if (my_callback_is_output_enabled && (0==my_callback_is_output_enabled()))
- {
- SHOW_TIME("wave_write > my_callback_is_output_enabled: no!");
- return 0;
- }
-
- aRead = myRead;
-
- // write pointer is before read pointer?
- if (myWrite >= aRead)
- {
- aTotalFreeMem = aRead + BUFFER_LENGTH - myWrite;
- }
- else // read pointer is before write pointer!
- {
- aTotalFreeMem = aRead - myWrite;
- } // end if (myWrite >= aRead)
-
- if (aTotalFreeMem>1)
- {
- // -1 because myWrite must be different of aRead
- // otherwise buffer would be considered as empty
- aTotalFreeMem -= 1;
- } // end if (aTotalFreeMem>1)
-
- if (aTotalFreeMem >= bytes_to_write)
- {
- break;
- } // end if (aTotalFreeMem >= bytes_to_write)
-
- //SHOW_TIME("wave_write > wait");
- SHOW("wave_write > wait: aTotalFreeMem=%d\n", aTotalFreeMem);
- SHOW("wave_write > aRead=%x, myWrite=%x\n", (int)aRead, (int)myWrite);
- usleep(10000);
- } // end while (1)
-
- aRead = myRead;
-
- // write pointer is ahead the read pointer?
- if (myWrite >= aRead)
- {
- SHOW_TIME("wave_write > myWrite >= aRead");
- // determine remaining free memory to the end of the ringbuffer
- size_t aFreeMem = myBuffer + BUFFER_LENGTH - myWrite;
- // is enough linear space available (regardless 1 or 2 channels)?
- if (aFreeMem >= bytes_to_write)
- {
- // copy direct - no wrap around at end of ringbuffer needed
- myWrite += copyBuffer(myWrite, theMono16BitsWaveBuffer, theSize);
- }
- else // not enough linear space available
- {
- // 2 channels (stereo)?
- if (out_channels == 2)
- {
- // copy with wrap around at the end of ringbuffer
- copyBuffer(myWrite, theMono16BitsWaveBuffer, aFreeMem/2);
- myWrite = myBuffer;
- myWrite += copyBuffer(myWrite, theMono16BitsWaveBuffer+aFreeMem/2, theSize - aFreeMem/2);
- }
- else // 1 channel (mono)
- {
- // copy with wrap around at the end of ringbuffer
- copyBuffer(myWrite, theMono16BitsWaveBuffer, aFreeMem);
- myWrite = myBuffer;
- myWrite += copyBuffer(myWrite, theMono16BitsWaveBuffer+aFreeMem, theSize - aFreeMem);
- } // end if (out_channels == 2)
- } // end if (aFreeMem >= bytes_to_write)
- } // if (myWrite >= aRead)
- else // read pointer is ahead the write pointer
- {
- SHOW_TIME("wave_write > myWrite <= aRead");
- myWrite += copyBuffer(myWrite, theMono16BitsWaveBuffer, theSize);
- } // end if (myWrite >= aRead)
-
- bytes_written = bytes_to_write;
- myWritePosition += theSize/sizeof(uint16_t); // add number of samples
-
- if (my_stream_could_start && (get_used_mem() >= out_channels * sizeof(uint16_t) * FRAMES_PER_BUFFER))
- {
- start_stream();
- } // end if (my_stream_could_start && (get_used_mem() >= out_channels * sizeof(uint16_t) * FRAMES_PER_BUFFER))
-
- SHOW_TIME("wave_write > LEAVE");
-
- return bytes_written;
-}
-
-//>
-//<wave_close
-
-int wave_close(void* theHandler)
-{
- SHOW_TIME("wave_close > ENTER");
-
- static int aStopStreamCount = 0;
-
-#if (USE_PORTAUDIO == 19)
- if( pa_stream == NULL )
- {
- SHOW_TIME("wave_close > LEAVE (NULL stream)");
- return 0;
- }
-
- if( Pa_IsStreamStopped( pa_stream ) )
- {
- SHOW_TIME("wave_close > LEAVE (stopped)");
- return 0;
- }
-#else
- if( pa_stream == NULL )
- {
- SHOW_TIME("wave_close > LEAVE (NULL stream)");
- return 0;
- }
-
- if( Pa_StreamActive( pa_stream ) == false && mInCallbackFinishedState == false )
- {
- SHOW_TIME("wave_close > LEAVE (not active)");
- return 0;
- }
-#endif
-
- // Avoid race condition by making sure this function only
- // gets called once at a time
- aStopStreamCount++;
- if (aStopStreamCount != 1)
- {
- SHOW_TIME("wave_close > LEAVE (stopStreamCount)");
- return 0;
- }
-
- // Comment from Audacity-1.2.4b adapted to the eSpeak context.
- //
- // We got here in one of two ways:
- //
- // 1. The calling program calls the espeak_Cancel function and we
- // therefore want to stop as quickly as possible.
- // So we use AbortStream(). If this is
- // the case the portaudio stream is still in the Running state
- // (see PortAudio state machine docs).
- //
- // 2. The callback told PortAudio to stop the stream since it had
- // reached the end of the selection.
- // The event polling thread discovered this by noticing that
- // wave_is_busy() returned false.
- // wave_is_busy() (which calls Pa_GetStreamActive()) will not return
- // false until all buffers have finished playing, so we can call
- // AbortStream without losing any samples. If this is the case
- // we are in the "callback finished state" (see PortAudio state
- // machine docs).
- //
- // The moral of the story: We can call AbortStream safely, without
- // losing samples.
- //
- // DMM: This doesn't seem to be true; it seems to be necessary to
- // call StopStream if the callback brought us here, and AbortStream
- // if the user brought us here.
- //
-
-#if (USE_PORTAUDIO == 19)
- if (pa_stream)
- {
- Pa_AbortStream( pa_stream );
- SHOW_TIME("wave_close > Pa_AbortStream (end)");
-
- Pa_CloseStream( pa_stream );
- SHOW_TIME("wave_close > Pa_CloseStream (end)");
- pa_stream = NULL;
- mInCallbackFinishedState = false;
- }
-#else
- if (pa_stream)
- {
- if (mInCallbackFinishedState)
- {
- Pa_StopStream( pa_stream );
- SHOW_TIME("wave_close > Pa_StopStream (end)");
- }
- else
- {
- Pa_AbortStream( pa_stream );
- SHOW_TIME("wave_close > Pa_AbortStream (end)");
- }
- Pa_CloseStream( pa_stream );
- SHOW_TIME("wave_close > Pa_CloseStream (end)");
-
- pa_stream = NULL;
- mInCallbackFinishedState = false;
- }
-#endif
- init_buffer();
-
- aStopStreamCount = 0; // last action
- SHOW_TIME("wave_close > LEAVE");
- return 0;
-}
-
-// int wave_close(void* theHandler)
-// {
-// ENTER("wave_close");
-
-// if(pa_stream != NULL)
-// {
-// PaError err = Pa_AbortStream(pa_stream);
-// SHOW_TIME("wave_close > Pa_AbortStream (end)");
-// SHOW("wave_close Pa_AbortStream > err=%d\n",err);
-// while(1)
-// {
-// PaError active;
-// #if USE_PORTAUDIO == 18
-// active = Pa_StreamActive(pa_stream);
-// #else
-// active = Pa_IsStreamActive(pa_stream);
-// #endif
-// if (active != 1)
-// {
-// break;
-// }
-// SHOW("wave_close > active=%d\n",err);
-// usleep(10000); /* sleep until playback has finished */
-// }
-// err = Pa_CloseStream( pa_stream );
-// SHOW_TIME("wave_close > Pa_CloseStream (end)");
-// SHOW("wave_close Pa_CloseStream > err=%d\n",err);
-// pa_stream = NULL;
-// init_buffer();
-// }
-// return 0;
-// }
-
-//>
-//<wave_is_busy
-
-int wave_is_busy(void* theHandler)
-{
- PaError active=0;
-
- SHOW_TIME("wave_is_busy");
-
- if (pa_stream)
- {
-#if USE_PORTAUDIO == 18
- active = Pa_StreamActive(pa_stream)
- && (mInCallbackFinishedState == false);
-#else
- active = Pa_IsStreamActive(pa_stream)
- && (mInCallbackFinishedState == false);
-#endif
- }
-
- SHOW("wave_is_busy: %d\n",active);
-
-
- return (active==1);
-}
-
-//>
-//<wave_terminate
-
-void wave_terminate()
-{
- ENTER("wave_terminate");
-
- Pa_Terminate();
-
-}
-
-//>
-//<wave_get_read_position, wave_get_write_position, wave_get_remaining_time
-
-uint32_t wave_get_read_position(void* theHandler)
-{
- SHOW("wave_get_read_position > myReadPosition=%u\n", myReadPosition);
- return myReadPosition;
-}
-
-uint32_t wave_get_write_position(void* theHandler)
-{
- SHOW("wave_get_write_position > myWritePosition=%u\n", myWritePosition);
- return myWritePosition;
-}
-
-int wave_get_remaining_time(uint32_t sample, uint32_t* time)
-{
- double a_time=0;
-
- if (!time || !pa_stream)
- {
- SHOW("event get_remaining_time> %s\n","audio device not available");
- return -1;
- }
-
- if (sample > myReadPosition)
- {
- // TBD: take in account time suplied by portaudio V18 API
- a_time = sample - myReadPosition;
- a_time = 0.5 + (a_time * 1000.0) / SAMPLE_RATE;
- }
- else
- {
- a_time = 0;
- }
-
- SHOW("wave_get_remaining_time > sample=%d, time=%d\n", sample, (uint32_t)a_time);
-
- *time = (uint32_t)a_time;
-
- return 0;
-}
-
-//>
-//<wave_test_get_write_buffer
-
-void *wave_test_get_write_buffer()
-{
- return myWrite;
-}
-
-
-#else
-// notdef USE_PORTAUDIO
-
-
-void wave_init() {}
-void* wave_open(const char* the_api) {return (void *)1;}
-size_t wave_write(void* theHandler, char* theMono16BitsWaveBuffer, size_t theSize) {return theSize;}
-int wave_close(void* theHandler) {return 0;}
-int wave_is_busy(void* theHandler) {return 0;}
-void wave_terminate() {}
-uint32_t wave_get_read_position(void* theHandler) {return 0;}
-uint32_t wave_get_write_position(void* theHandler) {return 0;}
-void wave_flush(void* theHandler) {}
-typedef int (t_wave_callback)(void);
-void wave_set_callback_is_output_enabled(t_wave_callback* cb) {}
-extern void* wave_test_get_write_buffer() {return NULL;}
-
-int wave_get_remaining_time(uint32_t sample, uint32_t* time)
-{
- if (!time) return(-1);
- *time = (uint32_t)0;
- return 0;
-}
-
-#endif // of USE_PORTAUDIO
-
-//>
-//<clock_gettime2, add_time_in_ms
-
-void clock_gettime2(struct timespec *ts)
-{
- struct timeval tv;
-
- if (!ts)
- {
- return;
- }
-
- assert (gettimeofday(&tv, NULL) != -1);
- ts->tv_sec = tv.tv_sec;
- ts->tv_nsec = tv.tv_usec*1000;
-}
-
-void add_time_in_ms(struct timespec *ts, int time_in_ms)
-{
- if (!ts)
- {
- return;
- }
-
- uint64_t t_ns = (uint64_t)ts->tv_nsec + 1000000 * (uint64_t)time_in_ms;
- while(t_ns >= ONE_BILLION)
- {
- SHOW("event > add_time_in_ms ns: %d sec %Lu nsec \n", ts->tv_sec, t_ns);
- ts->tv_sec += 1;
- t_ns -= ONE_BILLION;
- }
- ts->tv_nsec = (long int)t_ns;
-}
-
-
-#endif // USE_ASYNC
-
-//>
diff --git a/navit/support/espeak/wave.h b/navit/support/espeak/wave.h
deleted file mode 100644
index de8bf1ef8..000000000
--- a/navit/support/espeak/wave.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef WAVE_H
-#define WAVE_H
-
-#ifdef _MSC_VER
-
-typedef __int32 int32_t;
-typedef unsigned __int32 uint32_t;
-typedef __int64 int64_t;
-typedef unsigned __int32 uint64_t;
-
-#else
-#ifndef PLATFORM_DOS
-#include "stdint.h"
-#endif
-#endif
-
-extern int option_device_number;
-
-extern void wave_init();
-// TBD: the arg could be "alsa", "oss",...
-extern void* wave_open(const char* the_api);
-
-extern size_t wave_write(void* theHandler, char* theMono16BitsWaveBuffer, size_t theSize);
-extern int wave_close(void* theHandler);
-extern void wave_flush(void* theHandler);
-extern int wave_is_busy(void* theHandler);
-extern void wave_terminate();
-extern uint32_t wave_get_read_position(void* theHandler);
-extern uint32_t wave_get_write_position(void* theHandler);
-
-// Supply the remaining time in ms before the sample is played
-// (or 0 if the event has been already played).
-// sample: sample identifier
-// time: supplied value in ms
-//
-// return 0 if ok or -1 otherwise (stream not opened).
-extern int wave_get_remaining_time(uint32_t sample, uint32_t* time);
-
-// set the callback which informs if the output is still enabled.
-// Helpful if a new sample is waiting for free space whereas sound must be stopped.
-typedef int (t_wave_callback)(void);
-extern void wave_set_callback_is_output_enabled(t_wave_callback* cb);
-
-
-// general functions
-extern void clock_gettime2(struct timespec *ts);
-extern void add_time_in_ms(struct timespec *ts, int time_in_ms);
-
-// for tests
-extern void *wave_test_get_write_buffer();
-
-#endif
diff --git a/navit/support/espeak/wave_pulse.c b/navit/support/espeak/wave_pulse.c
deleted file mode 100755
index d5fbc8c1e..000000000
--- a/navit/support/espeak/wave_pulse.c
+++ /dev/null
@@ -1,935 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2007, Gilles Casse <gcasse@oralux.org> *
- * eSpeak driver for PulseAudio *
- * based on the XMMS PulseAudio Plugin *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-// TBD:
-// * ARCH_BIG
-// * uint64? a_timing_info.read_index
-// * prebuf,... size?
-// * 0.9.6: pb pulse_free using tlength=8820 (max size never returned -> tlength=10000 ok, but higher drain).
-//
-#include "speech.h"
-
-#ifdef USE_ASYNC
-// This source file is only used for asynchronious modes
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <math.h>
-#include <assert.h>
-#include <sys/time.h>
-#include <time.h>
-#include <pulse/pulseaudio.h>
-#include <pthread.h>
-
-#ifndef PLATFORM_WINDOWS
-#include <unistd.h>
-#endif
-#include "wave.h"
-#include "debug.h"
-
-//<Definitions
-
-enum {ONE_BILLION=1000000000};
-
-enum {
-// /* 100ms.
-// If a greater value is set (several seconds),
-// please update _pulse_timeout_start accordingly */
-// PULSE_TIMEOUT_IN_USEC = 100000,
-
- /* return value */
- PULSE_OK = 0,
- PULSE_ERROR = -1,
- PULSE_NO_CONNECTION = -2
-};
-
-#ifdef USE_PULSEAUDIO
-
-static t_wave_callback* my_callback_is_output_enabled=NULL;
-
-#define SAMPLE_RATE 22050
-#define ESPEAK_FORMAT PA_SAMPLE_S16LE
-#define ESPEAK_CHANNEL 1
-
-#define MAXLENGTH 132300
-#define TLENGTH 4410
-#define PREBUF 2200
-#define MINREQ 880
-#define FRAGSIZE 0
-
-static pthread_mutex_t pulse_mutex;
-
-static pa_context *context = NULL;
-static pa_stream *stream = NULL;
-static pa_threaded_mainloop *mainloop = NULL;
-
-static pa_cvolume volume;
-static int volume_valid = 0;
-
-static int do_trigger = 0;
-static uint64_t written = 0;
-static int time_offset_msec = 0;
-static int just_flushed = 0;
-
-static int connected = 0;
-
-#define CHECK_DEAD_GOTO(label, warn) do { \
-if (!mainloop || \
- !context || pa_context_get_state(context) != PA_CONTEXT_READY || \
- !stream || pa_stream_get_state(stream) != PA_STREAM_READY) { \
- if (warn) \
- SHOW("Connection died: %s\n", context ? pa_strerror(pa_context_errno(context)) : "NULL"); \
- goto label; \
- } \
-} while(0);
-
-#define CHECK_CONNECTED(retval) \
-do { \
- if (!connected) return retval; \
-} while (0);
-
-#define CHECK_CONNECTED_NO_RETVAL(id) \
- do { \
- if (!connected){ SHOW("CHECK_CONNECTED_NO_RETVAL: !pulse_connected\n", ""); return; } \
- } while (0);
-
-//>
-
-
-// static void display_timing_info(const pa_timing_info* the_time)
-// {
-// const struct timeval *tv=&(the_time->timestamp);
-
-// SHOW_TIME("ti>");
-// SHOW("ti> timestamp=%03d.%03dms\n",(int)(tv->tv_sec%1000), (int)(tv->tv_usec/1000));
-// SHOW("ti> synchronized_clocks=%d\n",the_time->synchronized_clocks);
-// SHOW("ti> sink_usec=%ld\n",the_time->sink_usec);
-// SHOW("ti> source_usec=%ld\n",the_time->source_usec);
-// SHOW("ti> transport=%ld\n",the_time->transport_usec);
-// SHOW("ti> playing=%d\n",the_time->playing);
-// SHOW("ti> write_index_corrupt=%d\n",the_time->write_index_corrupt);
-// SHOW("ti> write_index=0x%lx\n",the_time->write_index);
-// SHOW("ti> read_index_corrupt=%d\n",the_time->read_index_corrupt);
-// SHOW("ti> read_index=0x%lx\n",the_time->read_index);
-// }
-
-
-static void info_cb(struct pa_context *c, const struct pa_sink_input_info *i, int is_last, void *userdata) {
- ENTER(__FUNCTION__);
- assert(c);
-
- if (!i)
- return;
-
- volume = i->volume;
- volume_valid = 1;
-}
-
-static void subscribe_cb(struct pa_context *c, enum pa_subscription_event_type t, uint32_t index, void *userdata) {
- pa_operation *o;
- ENTER(__FUNCTION__);
-
- assert(c);
-
- if (!stream ||
- index != pa_stream_get_index(stream) ||
- (t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE) &&
- t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW)))
- return;
-
- if (!(o = pa_context_get_sink_input_info(c, index, info_cb, NULL))) {
- SHOW("pa_context_get_sink_input_info() failed: %s\n", pa_strerror(pa_context_errno(c)));
- return;
- }
-
- pa_operation_unref(o);
-}
-
-static void context_state_cb(pa_context *c, void *userdata) {
- ENTER(__FUNCTION__);
- assert(c);
-
- switch (pa_context_get_state(c)) {
- case PA_CONTEXT_READY:
- case PA_CONTEXT_TERMINATED:
- case PA_CONTEXT_FAILED:
- pa_threaded_mainloop_signal(mainloop, 0);
- break;
-
- case PA_CONTEXT_UNCONNECTED:
- case PA_CONTEXT_CONNECTING:
- case PA_CONTEXT_AUTHORIZING:
- case PA_CONTEXT_SETTING_NAME:
- break;
- }
-}
-
-static void stream_state_cb(pa_stream *s, void * userdata) {
- ENTER(__FUNCTION__);
- assert(s);
-
- switch (pa_stream_get_state(s)) {
-
- case PA_STREAM_READY:
- case PA_STREAM_FAILED:
- case PA_STREAM_TERMINATED:
- pa_threaded_mainloop_signal(mainloop, 0);
- break;
-
- case PA_STREAM_UNCONNECTED:
- case PA_STREAM_CREATING:
- break;
- }
-}
-
-static void stream_success_cb(pa_stream *s, int success, void *userdata) {
- ENTER(__FUNCTION__);
- assert(s);
-
- if (userdata)
- *(int*) userdata = success;
-
- pa_threaded_mainloop_signal(mainloop, 0);
-}
-
-static void context_success_cb(pa_context *c, int success, void *userdata) {
- ENTER(__FUNCTION__);
- assert(c);
-
- if (userdata)
- *(int*) userdata = success;
-
- pa_threaded_mainloop_signal(mainloop, 0);
-}
-
-static void stream_request_cb(pa_stream *s, size_t length, void *userdata) {
- ENTER(__FUNCTION__);
- assert(s);
-
- pa_threaded_mainloop_signal(mainloop, 0);
-}
-
-static void stream_latency_update_cb(pa_stream *s, void *userdata) {
- // ENTER(__FUNCTION__);
- assert(s);
-
- pa_threaded_mainloop_signal(mainloop, 0);
-}
-
-static int pulse_free(void) {
- ENTER(__FUNCTION__);
- size_t l = 0;
- pa_operation *o = NULL;
-
- CHECK_CONNECTED(0);
-
- SHOW("pulse_free: %s (call)\n", "pa_threaded_main_loop_lock");
- pa_threaded_mainloop_lock(mainloop);
- CHECK_DEAD_GOTO(fail, 1);
-
- if ((l = pa_stream_writable_size(stream)) == (size_t) -1) {
- SHOW("pa_stream_writable_size() failed: %s", pa_strerror(pa_context_errno(context)));
- l = 0;
- goto fail;
- }
-
- SHOW("pulse_free: %s (ret=%d)\n", "pa_stream_writable_size", l);
-
- /* If this function is called twice with no pulse_write() call in
- * between this means we should trigger the playback */
- if (do_trigger) {
- int success = 0;
-
- SHOW("pulse_free: %s (call)\n", "pa_stream_trigger");
- if (!(o = pa_stream_trigger(stream, stream_success_cb, &success))) {
- SHOW("pa_stream_trigger() failed: %s", pa_strerror(pa_context_errno(context)));
- goto fail;
- }
-
- SHOW("pulse_free: %s (call)\n", "pa_threaded_main_loop");
- while (pa_operation_get_state(o) != PA_OPERATION_DONE) {
- CHECK_DEAD_GOTO(fail, 1);
- pa_threaded_mainloop_wait(mainloop);
- }
- SHOW("pulse_free: %s (ret)\n", "pa_threaded_main_loop");
-
- if (!success)
- SHOW("pa_stream_trigger() failed: %s", pa_strerror(pa_context_errno(context)));
- }
-
-fail:
- SHOW("pulse_free: %s (call)\n", "pa_operation_unref");
- if (o)
- pa_operation_unref(o);
-
- SHOW("pulse_free: %s (call)\n", "pa_threaded_main_loop_unlock");
- pa_threaded_mainloop_unlock(mainloop);
-
- do_trigger = !!l;
- SHOW("pulse_free: %d (ret)\n", (int)l);
- return (int) l;
-}
-
-static int pulse_playing(const pa_timing_info *the_timing_info) {
- ENTER(__FUNCTION__);
- int r = 0;
- const pa_timing_info *i;
-
- assert(the_timing_info);
-
- CHECK_CONNECTED(0);
-
- pa_threaded_mainloop_lock(mainloop);
-
- for (;;) {
- CHECK_DEAD_GOTO(fail, 1);
-
- if ((i = pa_stream_get_timing_info(stream)))
- {
- break;
- }
- if (pa_context_errno(context) != PA_ERR_NODATA) {
- SHOW("pa_stream_get_timing_info() failed: %s", pa_strerror(pa_context_errno(context)));
- goto fail;
- }
-
- pa_threaded_mainloop_wait(mainloop);
- }
-
- r = i->playing;
- memcpy((void*)the_timing_info, (void*)i, sizeof(pa_timing_info));
-
- // display_timing_info(i);
-
-fail:
- pa_threaded_mainloop_unlock(mainloop);
-
- return r;
-}
-
-
-// static void pulse_flush(int time) {
-// ENTER(__FUNCTION__);
-// pa_operation *o = NULL;
-// int success = 0;
-
-// CHECK_CONNECTED();
-
-// pa_threaded_mainloop_lock(mainloop);
-// CHECK_DEAD_GOTO(fail, 1);
-
-// if (!(o = pa_stream_flush(stream, stream_success_cb, &success))) {
-// SHOW("pa_stream_flush() failed: %s", pa_strerror(pa_context_errno(context)));
-// goto fail;
-// }
-
-// while (pa_operation_get_state(o) != PA_OPERATION_DONE) {
-// CHECK_DEAD_GOTO(fail, 1);
-// pa_threaded_mainloop_wait(mainloop);
-// }
-
-// if (!success)
-// SHOW("pa_stream_flush() failed: %s", pa_strerror(pa_context_errno(context)));
-
-// written = (uint64_t) (((double) time * pa_bytes_per_second(pa_stream_get_sample_spec(stream))) / 1000);
-// just_flushed = 1;
-// time_offset_msec = time;
-
-// fail:
-// if (o)
-// pa_operation_unref(o);
-
-// pa_threaded_mainloop_unlock(mainloop);
-// }
-
-
-static void pulse_write(void* ptr, int length) {
- ENTER(__FUNCTION__);
-
-
- SHOW("pulse_write > length=%d\n", length);
-
- CHECK_CONNECTED();
-
- pa_threaded_mainloop_lock(mainloop);
- CHECK_DEAD_GOTO(fail, 1);
-
- if (pa_stream_write(stream, ptr, length, NULL, PA_SEEK_RELATIVE, (pa_seek_mode_t)0) < 0) {
- SHOW("pa_stream_write() failed: %s", pa_strerror(pa_context_errno(context)));
- goto fail;
- }
-
- do_trigger = 0;
- written += length;
-
-fail:
-
- pa_threaded_mainloop_unlock(mainloop);
-}
-
-static int drain(void) {
- pa_operation *o = NULL;
- int success = 0;
- int ret = PULSE_ERROR;
-
- ENTER(__FUNCTION__);
-
- CHECK_CONNECTED(ret);
-
- pa_threaded_mainloop_lock(mainloop);
- CHECK_DEAD_GOTO(fail, 0);
-
- SHOW_TIME("pa_stream_drain (call)");
- if (!(o = pa_stream_drain(stream, stream_success_cb, &success))) {
- SHOW("pa_stream_drain() failed: %s\n", pa_strerror(pa_context_errno(context)));
- goto fail;
- }
-
- SHOW_TIME("pa_threaded_mainloop_wait (call)");
- while (pa_operation_get_state(o) != PA_OPERATION_DONE) {
- CHECK_DEAD_GOTO(fail, 1);
- pa_threaded_mainloop_wait(mainloop);
- }
- SHOW_TIME("pa_threaded_mainloop_wait (ret)");
-
- if (!success) {
- SHOW("pa_stream_drain() failed: %s\n", pa_strerror(pa_context_errno(context)));
- }
- else {
- ret = PULSE_OK;
- }
-
-fail:
- SHOW_TIME("pa_operation_unref (call)");
- if (o)
- pa_operation_unref(o);
-
- pa_threaded_mainloop_unlock(mainloop);
- SHOW_TIME("drain (ret)");
-
- return ret;
-}
-
-
-static void pulse_close(void) {
-
- ENTER(__FUNCTION__);
-
- drain();
-
- connected = 0;
-
- if (mainloop)
- pa_threaded_mainloop_stop(mainloop);
-
- connected = 0;
-
- if (context) {
- SHOW_TIME("pa_context_disconnect (call)");
- pa_context_disconnect(context);
- pa_context_unref(context);
- context = NULL;
- }
-
- if (mainloop) {
- SHOW_TIME("pa_threaded_mainloop_free (call)");
- pa_threaded_mainloop_free(mainloop);
- mainloop = NULL;
- }
- SHOW_TIME("pulse_close (ret)");
-
-}
-
-
-static int pulse_open()
-{
- ENTER(__FUNCTION__);
- pa_sample_spec ss;
- pa_operation *o = NULL;
- int success;
- int ret = PULSE_ERROR;
-
- assert(!mainloop);
- assert(!context);
- assert(!stream);
- assert(!connected);
-
- pthread_mutex_init( &pulse_mutex, (const pthread_mutexattr_t *)NULL);
-
- ss.format = ESPEAK_FORMAT;
- ss.rate = SAMPLE_RATE;
- ss.channels = ESPEAK_CHANNEL;
-
- if (!pa_sample_spec_valid(&ss))
- return false;
-
-/* if (!volume_valid) { */
- pa_cvolume_reset(&volume, ss.channels);
- volume_valid = 1;
-/* } else if (volume.channels != ss.channels) */
-/* pa_cvolume_set(&volume, ss.channels, pa_cvolume_avg(&volume)); */
-
- SHOW_TIME("pa_threaded_mainloop_new (call)");
- if (!(mainloop = pa_threaded_mainloop_new())) {
- SHOW("Failed to allocate main loop\n","");
- goto fail;
- }
-
- pa_threaded_mainloop_lock(mainloop);
-
- SHOW_TIME("pa_context_new (call)");
- if (!(context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), "eSpeak"))) {
- SHOW("Failed to allocate context\n","");
- goto unlock_and_fail;
- }
-
- pa_context_set_state_callback(context, context_state_cb, NULL);
- pa_context_set_subscribe_callback(context, subscribe_cb, NULL);
-
- SHOW_TIME("pa_context_connect (call)");
- if (pa_context_connect(context, NULL, (pa_context_flags_t)0, NULL) < 0) {
- SHOW("Failed to connect to server: %s", pa_strerror(pa_context_errno(context)));
- ret = PULSE_NO_CONNECTION;
- goto unlock_and_fail;
- }
-
- SHOW_TIME("pa_threaded_mainloop_start (call)");
- if (pa_threaded_mainloop_start(mainloop) < 0) {
- SHOW("Failed to start main loop","");
- goto unlock_and_fail;
- }
-
- /* Wait until the context is ready */
- SHOW_TIME("pa_threaded_mainloop_wait");
- pa_threaded_mainloop_wait(mainloop);
-
- if (pa_context_get_state(context) != PA_CONTEXT_READY) {
- SHOW("Failed to connect to server: %s", pa_strerror(pa_context_errno(context)));
- ret = PULSE_NO_CONNECTION;
- if (mainloop)
- pa_threaded_mainloop_stop(mainloop);
- goto unlock_and_fail;
- }
-
- SHOW_TIME("pa_stream_new");
- if (!(stream = pa_stream_new(context, "unknown", &ss, NULL))) {
- SHOW("Failed to create stream: %s", pa_strerror(pa_context_errno(context)));
- goto unlock_and_fail;
- }
-
- pa_stream_set_state_callback(stream, stream_state_cb, NULL);
- pa_stream_set_write_callback(stream, stream_request_cb, NULL);
- pa_stream_set_latency_update_callback(stream, stream_latency_update_cb, NULL);
-
-
-
- pa_buffer_attr a_attr;
-
- a_attr.maxlength = MAXLENGTH;
- a_attr.tlength = TLENGTH;
- a_attr.prebuf = PREBUF;
- a_attr.minreq = MINREQ;
- a_attr.fragsize = 0;
-
- SHOW_TIME("pa_connect_playback");
- if (pa_stream_connect_playback(stream, NULL, &a_attr, (pa_stream_flags_t)(PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE), &volume, NULL) < 0) {
- SHOW("Failed to connect stream: %s", pa_strerror(pa_context_errno(context)));
- goto unlock_and_fail;
- }
-
- /* Wait until the stream is ready */
- SHOW_TIME("pa_threaded_mainloop_wait");
- pa_threaded_mainloop_wait(mainloop);
-
- if (pa_stream_get_state(stream) != PA_STREAM_READY) {
- SHOW("Failed to connect stream: %s", pa_strerror(pa_context_errno(context)));
- goto unlock_and_fail;
- }
-
- /* Now subscribe to events */
- SHOW_TIME("pa_context_subscribe");
- if (!(o = pa_context_subscribe(context, PA_SUBSCRIPTION_MASK_SINK_INPUT, context_success_cb, &success))) {
- SHOW("pa_context_subscribe() failed: %s", pa_strerror(pa_context_errno(context)));
- goto unlock_and_fail;
- }
-
- success = 0;
- SHOW_TIME("pa_threaded_mainloop_wait");
- while (pa_operation_get_state(o) != PA_OPERATION_DONE) {
- CHECK_DEAD_GOTO(fail, 1);
- pa_threaded_mainloop_wait(mainloop);
- }
-
- if (!success) {
- SHOW("pa_context_subscribe() failed: %s", pa_strerror(pa_context_errno(context)));
- goto unlock_and_fail;
- }
-
- pa_operation_unref(o);
-
- /* Now request the initial stream info */
- if (!(o = pa_context_get_sink_input_info(context, pa_stream_get_index(stream), info_cb, NULL))) {
- SHOW("pa_context_get_sink_input_info() failed: %s", pa_strerror(pa_context_errno(context)));
- goto unlock_and_fail;
- }
-
- SHOW_TIME("pa_threaded_mainloop_wait 2");
- while (pa_operation_get_state(o) != PA_OPERATION_DONE) {
- CHECK_DEAD_GOTO(fail, 1);
- pa_threaded_mainloop_wait(mainloop);
- }
-
-/* if (!volume_valid) { */
-/* SHOW("pa_context_get_sink_input_info() failed: %s", pa_strerror(pa_context_errno(context))); */
-/* goto unlock_and_fail; */
-/* } */
-
- do_trigger = 0;
- written = 0;
- time_offset_msec = 0;
- just_flushed = 0;
- connected = 1;
- // volume_time_event = NULL;
-
- pa_threaded_mainloop_unlock(mainloop);
- SHOW_TIME("pulse_open (ret true)");
-
- // return true;
- return PULSE_OK;
-
-
-unlock_and_fail:
-
- if (o)
- pa_operation_unref(o);
-
- pa_threaded_mainloop_unlock(mainloop);
-
-fail:
-
- // pulse_close();
-
- if (ret == PULSE_NO_CONNECTION) {
- if (context) {
- SHOW_TIME("pa_context_disconnect (call)");
- pa_context_disconnect(context);
- pa_context_unref(context);
- context = NULL;
- }
-
- if (mainloop) {
- SHOW_TIME("pa_threaded_mainloop_free (call)");
- pa_threaded_mainloop_free(mainloop);
- mainloop = NULL;
- }
- }
- else {
- pulse_close();
- }
-
- SHOW_TIME("pulse_open (ret false)");
-
- return ret;
-
-}
-
-void wave_flush(void* theHandler)
-{
- ENTER("wave_flush");
-
-// if (my_stream_could_start)
-// {
-// // #define buf 1024
-// // static char a_buffer[buf*2];
-// // memset(a_buffer,0,buf*2);
-// // wave_write(theHandler, a_buffer, buf*2);
-// start_stream();
-// }
-}
-
-
-
-//<wave_set_callback_is_output_enabled
-
-void wave_set_callback_is_output_enabled(t_wave_callback* cb)
-{
- my_callback_is_output_enabled = cb;
-}
-
-//>
-//<wave_init
-
-void wave_init()
-{
- ENTER("wave_init");
-
- stream = NULL;
-
- pulse_open();
-}
-
-//>
-//<wave_open
-
-void* wave_open(const char* the_api)
-{
- ENTER("wave_open");
- return((void*)1);
-}
-
-//>
-//<wave_write
-
-size_t wave_write(void* theHandler, char* theMono16BitsWaveBuffer, size_t theSize)
-{
- ENTER("wave_write");
- size_t bytes_to_write = theSize;
- char* aBuffer=theMono16BitsWaveBuffer;
-
- assert(stream);
-
- size_t aTotalFreeMem=0;
-
- pthread_mutex_lock(&pulse_mutex);
-
- while (1)
- {
- if (my_callback_is_output_enabled
- && (0==my_callback_is_output_enabled()))
- {
- SHOW_TIME("wave_write > my_callback_is_output_enabled: no!");
- theSize=0;
- goto terminate;
- }
-
- aTotalFreeMem = pulse_free();
- if (aTotalFreeMem >= bytes_to_write)
- {
- SHOW("wave_write > aTotalFreeMem(%d) >= bytes_to_write(%d)\n", aTotalFreeMem, bytes_to_write);
- break;
- }
-
- // TBD: check if really helpful
- if (aTotalFreeMem >= MAXLENGTH*2)
- {
- aTotalFreeMem = MAXLENGTH*2;
- }
-
- SHOW("wave_write > wait: aTotalFreeMem(%d) < bytes_to_write(%d)\n", aTotalFreeMem, bytes_to_write);
-
- // 500: threshold for avoiding too many calls to pulse_write
- if (aTotalFreeMem>500)
- {
- pulse_write(aBuffer, aTotalFreeMem);
- bytes_to_write -= aTotalFreeMem;
- aBuffer += aTotalFreeMem;
- }
-
- usleep(10000);
- }
-
- pulse_write(aBuffer, bytes_to_write);
-
- terminate:
- pthread_mutex_unlock(&pulse_mutex);
- SHOW("wave_write: theSize=%d", theSize);
- SHOW_TIME("wave_write > LEAVE");
- return theSize;
-}
-
-//>
-//<wave_close
-
-int wave_close(void* theHandler)
-{
- SHOW_TIME("wave_close > ENTER");
-
- int a_status = pthread_mutex_lock(&pulse_mutex);
- if (a_status) {
- SHOW("Error: pulse_mutex lock=%d (%s)\n", a_status, __FUNCTION__);
- return PULSE_ERROR;
- }
-
- drain();
-
- pthread_mutex_unlock(&pulse_mutex);
- SHOW_TIME("wave_close (ret)");
-
- return PULSE_OK;
-}
-
-//>
-//<wave_is_busy
-
-int wave_is_busy(void* theHandler)
-{
- SHOW_TIME("wave_is_busy");
-
- pa_timing_info a_timing_info;
- int active = pulse_playing(&a_timing_info);
- SHOW("wave_is_busy: %d\n",active);
- return active;
-}
-
-//>
-//<wave_terminate
-
-void wave_terminate()
-{
- ENTER("wave_terminate");
-
-// Pa_Terminate();
-
- int a_status;
- pthread_mutex_t* a_mutex = NULL;
- a_mutex = &pulse_mutex;
- a_status = pthread_mutex_lock(a_mutex);
-
- pulse_close();
-
- SHOW_TIME("unlock mutex");
- a_status = pthread_mutex_unlock(a_mutex);
- pthread_mutex_destroy(a_mutex);
-}
-
-//>
-//<wave_get_read_position, wave_get_write_position, wave_get_remaining_time
-
-uint32_t wave_get_read_position(void* theHandler)
-{
- pa_timing_info a_timing_info;
- pulse_playing(&a_timing_info);
- SHOW("wave_get_read_position > %lx\n", a_timing_info.read_index);
- return a_timing_info.read_index;
-}
-
-uint32_t wave_get_write_position(void* theHandler)
-{
- pa_timing_info a_timing_info;
- pulse_playing(&a_timing_info);
- SHOW("wave_get_read_position > %lx\n", a_timing_info.write_index);
- return a_timing_info.write_index;
-}
-
-int wave_get_remaining_time(uint32_t sample, uint32_t* time)
-{
- double a_time=0;
-
- if (!time || !stream)
- {
- SHOW("event get_remaining_time> %s\n","audio device not available");
- return -1;
- }
-
- pa_timing_info a_timing_info;
- pulse_playing(&a_timing_info);
-
- if (sample > a_timing_info.read_index)
- {
- // TBD: take in account time suplied by portaudio V18 API
- a_time = sample - a_timing_info.read_index;
- a_time = 0.5 + (a_time * 1000.0) / SAMPLE_RATE;
- }
- else
- {
- a_time = 0;
- }
-
- SHOW("wave_get_remaining_time > sample=%d, time=%d\n", sample, (uint32_t)a_time);
-
- *time = (uint32_t)a_time;
-
- return 0;
-}
-
-//>
-//<wave_test_get_write_buffer
-
-void *wave_test_get_write_buffer()
-{
- return NULL;
-}
-
-
-#else
-// notdef USE_PULSEAUDIO
-
-
-void wave_init() {}
-void* wave_open(const char* the_api) {return (void *)1;}
-size_t wave_write(void* theHandler, char* theMono16BitsWaveBuffer, size_t theSize) {return theSize;}
-int wave_close(void* theHandler) {return 0;}
-int wave_is_busy(void* theHandler) {return 0;}
-void wave_terminate() {}
-uint32_t wave_get_read_position(void* theHandler) {return 0;}
-uint32_t wave_get_write_position(void* theHandler) {return 0;}
-void wave_flush(void* theHandler) {}
-typedef int (t_wave_callback)(void);
-void wave_set_callback_is_output_enabled(t_wave_callback* cb) {}
-extern void* wave_test_get_write_buffer() {return NULL;}
-
-int wave_get_remaining_time(uint32_t sample, uint32_t* time)
-{
- if (!time) return(-1);
- *time = (uint32_t)0;
- return 0;
-}
-
-#endif // of USE_PORTAUDIO
-
-//>
-//<clock_gettime2, add_time_in_ms
-
-void clock_gettime2(struct timespec *ts)
-{
- struct timeval tv;
-
- if (!ts)
- {
- return;
- }
-
- assert (gettimeofday(&tv, NULL) != -1);
- ts->tv_sec = tv.tv_sec;
- ts->tv_nsec = tv.tv_usec*1000;
-}
-
-void add_time_in_ms(struct timespec *ts, int time_in_ms)
-{
- if (!ts)
- {
- return;
- }
-
- uint64_t t_ns = (uint64_t)ts->tv_nsec + 1000000 * (uint64_t)time_in_ms;
- while(t_ns >= ONE_BILLION)
- {
- SHOW("event > add_time_in_ms ns: %d sec %Lu nsec \n", ts->tv_sec, t_ns);
- ts->tv_sec += 1;
- t_ns -= ONE_BILLION;
- }
- ts->tv_nsec = (long int)t_ns;
-}
-
-
-#endif // USE_ASYNC
-
-//>
diff --git a/navit/support/espeak/wave_sada.c b/navit/support/espeak/wave_sada.c
deleted file mode 100755
index c69a4dc99..000000000
--- a/navit/support/espeak/wave_sada.c
+++ /dev/null
@@ -1,588 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2008, Sun Microsystems, Inc. *
- * eSpeak driver for Solaris Audio Device Architecture (SADA) *
- * Written by Willie Walker, based on the eSpeak PulseAudio driver *
- * from Gilles Casse *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-#include "speech.h"
-
-#ifdef USE_ASYNC
-// This source file is only used for asynchronious modes
-
-#include <errno.h>
-#include <string.h>
-#include <stropts.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/audioio.h>
-
-#include "wave.h"
-#include "debug.h"
-
-enum {ONE_BILLION=1000000000};
-#define SAMPLE_RATE 22050
-#define SAMPLE_SIZE 16
-
-#ifdef USE_SADA
-
-static t_wave_callback* my_callback_is_output_enabled=NULL;
-
-static const char *sun_audio_device = "/dev/audio";
-static int sun_audio_fd = -1;
-
-// The total number of 16-bit samples sent to be played via the
-// wave_write method.
-//
-static uint32_t total_samples_sent;
-
-// The total number of samples sent to be played via the wave_write
-// method, but which were never played because of a call to
-// wave_close.
-//
-static uint32_t total_samples_skipped;
-
-// The last known playing index after a call to wave_close.
-//
-static uint32_t last_play_position=0;
-
-//>
-// wave_init
-//
-// DESCRIPTION:
-//
-// initializes the audio subsytem.
-//
-// GLOBALS USED/MODIFIED:
-//
-// sun_audio_fd: modified to hold the file descriptor of the opened
-// audio device.
-//
-//<wave_init
-
-void wave_init() {
- ENTER("wave_init");
-
- audio_info_t ainfo;
- char *audio_device = NULL;
-
- audio_device = getenv("AUDIODEV");
- if (audio_device != NULL) {
- if ((sun_audio_fd = open(audio_device, O_WRONLY)) < 0) {
- SHOW("wave_init() could not open: %s (%d)\n",
- audio_device, sun_audio_fd);
- }
- }
-
- if (sun_audio_fd < 0) {
- if ((sun_audio_fd = open(sun_audio_device, O_WRONLY)) < 0) {
- SHOW("wave_init() could not open: %s (%d)\n",
- sun_audio_device, sun_audio_fd);
- }
- }
-
- SHOW("wave_init() sun_audio_fd: %d\n", sun_audio_fd);
-
- if (sun_audio_fd < 0) {
- return;
- }
-
- ioctl(sun_audio_fd, AUDIO_GETINFO, &ainfo);
- SHOW("wave_init() play buffer size: %d\n", ainfo.play.buffer_size);
- ainfo.play.encoding = AUDIO_ENCODING_LINEAR;
- ainfo.play.channels = 1;
- ainfo.play.sample_rate = SAMPLE_RATE;
- ainfo.play.precision = SAMPLE_SIZE;
-
- if (ioctl(sun_audio_fd, AUDIO_SETINFO, &ainfo) == -1) {
- SHOW("wave_init() failed to set audio params: %s\n", strerror(errno));
- close(sun_audio_fd);
- return;
- }
-}
-
-//>
-// wave_open
-//
-// DESCRIPTION:
-//
-// opens the audio subsystem given a specific API (e.g., "alsa",
-// "oss", ...). We ignore the_api and just return the sun_audio_fd we
-// opened in wave_init. This return value will be passed in as the
-// theHandler parameter in all other methods.
-//
-// PARAMETERS:
-//
-// the_api: "alsa", "oss" (ignored)
-//
-// GLOBALS USED/MODIFIED:
-//
-// sun_audio_fd: used as return value
-//
-// RETURNS:
-//
-// sun_audio_fd opened in wave_init, which is passed in as theHandler
-// parameter in all other methods
-//
-//<wave_open
-
-void* wave_open(const char* the_api)
-{
- ENTER("wave_open");
- return((void*) sun_audio_fd);
-}
-
-//>
-// wave_write
-//
-// DESCRIPTION:
-//
-// Meant to be asynchronous, it supplies the wave sample to the lower
-// audio layer and returns. The sample is played later on. [[[WDW -
-// we purposely do not open the audio device as non-blocking because
-// managing that would be a pain. So, we rely a lot upon fifo.cpp and
-// event.cpp to not overload us, allowing us to get away with a
-// blocking write. event.cpp:polling_thread in particular appears to
-// use get_remaining_time to prevent flooding.]]]
-//
-// PARAMETERS:
-//
-// theHandler: the audio device file descriptor
-// theMono16BitsWaveBuffer: the audio data
-// theSize: the number of bytes (not 16-bit samples)
-//
-// GLOBALS USED/MODIFIED:
-//
-// total_samples_sent: modified based upon 16-bit samples sent
-//
-// RETURNS:
-//
-// the number of bytes (not 16-bit samples) sent
-//
-//<wave_write
-
-size_t wave_write(void* theHandler,
- char* theMono16BitsWaveBuffer,
- size_t theSize)
-{
- size_t num;
- ENTER("wave_write");
- if (my_callback_is_output_enabled && (0==my_callback_is_output_enabled())) {
- SHOW_TIME("wave_write > my_callback_is_output_enabled: no!");
- return 0;
- }
-
-#if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN
- {
- // BIG-ENDIAN, swap the order of bytes in each sound sample
- int c;
- char *out_ptr;
- char *out_end;
- out_ptr = (char *)theMono16BitsWaveBuffer;
- out_end = out_ptr + theSize;
- while(out_ptr < out_end)
- {
- c = out_ptr[0];
- out_ptr[0] = out_ptr[1];
- out_ptr[1] = c;
- out_ptr += 2;
- }
- }
-#endif
-
- num = write((int) theHandler, theMono16BitsWaveBuffer, theSize);
-
- // Keep track of the total number of samples sent -- we use this in
- // wave_get_read_position and also use it to help calculate the
- // total_samples_skipped in wave_close.
- //
- total_samples_sent += num / 2;
-
- if (num < theSize) {
- SHOW("ERROR: wave_write only wrote %d of %d bytes\n", num, theSize);
- } else {
- SHOW("wave_write wrote %d bytes\n", theSize);
- }
-
- SHOW_TIME("wave_write > LEAVE");
- return num;
-}
-
-//>
-// wave_close
-//
-// DESCRIPTION:
-//
-// Does what SADA normally would call a flush, which means to cease
-// all audio production in progress and throw any remaining audio
-// away. [[[WDW - see comment in wave_flush.]]]
-//
-// PARAMETERS:
-//
-// theHandler: the audio device file descriptor
-//
-// GLOBALS USED/MODIFIED:
-//
-// last_play_position: modified to reflect play position the last time
-// this method was called
-// total_samples_sent: used to help calculate total_samples_skipped
-// total_samples_skipped: modified to hold the total number of 16-bit
-// samples sent to wave_write, but which were
-// never played
-// sun_audio_fd: used because some calls to wave_close seem to
-// pass a NULL for theHandler for some odd reason
-//
-// RETURNS:
-//
-// The result of the ioctl call (non-0 means failure)
-//
-//<wave_close
-
-int wave_close(void* theHandler)
-{
- int ret;
- audio_info_t ainfo;
- int audio_fd = (int) theHandler;
- if (!audio_fd) {
- audio_fd = sun_audio_fd;
- }
- ENTER("wave_close");
- // [[[WDW: maybe do a pause/resume ioctl???]]]
- ret = ioctl(audio_fd, I_FLUSH, FLUSHRW);
- ioctl(audio_fd, AUDIO_GETINFO, &ainfo);
-
- // Calculate the number of samples that won't get
- // played. We also keep track of the last_play_position
- // because wave_close can be called multiple times
- // before another call to wave_write.
- //
- if (last_play_position != ainfo.play.samples) {
- last_play_position = ainfo.play.samples;
- total_samples_skipped = total_samples_sent - last_play_position;
- }
- SHOW_TIME("wave_close > LEAVE");
- return ret;
-}
-
-//>
-// wave_is_busy
-//
-// DESCRIPTION:
-//
-// Returns a non-0 value if audio is being played.
-//
-// PARAMETERS:
-//
-// theHandler: the audio device file descriptor
-//
-// GLOBALS USED/MODIFIED:
-//
-// sun_audio_fd: used because some calls to wave_is_busy seem to
-// pass a NULL for theHandler for some odd reason
-//
-// RETURNS:
-//
-// A non-0 value if audio is being played
-//
-//<wave_is_busy
-
-int wave_is_busy(void* theHandler)
-{
- uint32_t time;
- wave_get_remaining_time(total_samples_sent - 1, &time);
- return time != 0;
-}
-
-//>
-// wave_terminate
-//
-// DESCRIPTION:
-//
-// Used to end our session with eSpeak.
-//
-// GLOBALS USED/MODIFIED:
-//
-// sun_audio_fd: modified - closed and set to -1
-//
-//<wave_terminate
-
-void wave_terminate()
-{
- ENTER("wave_terminate");
- close(sun_audio_fd);
- sun_audio_fd = -1;
- SHOW_TIME("wave_terminate > LEAVE");
-}
-
-//>
-// wave_flush
-//
-// DESCRIPTION:
-//
-// Appears to want to tell the audio subsystem to make sure it plays
-// the audio. In our case, the system is already doing this, so this
-// is basically a no-op. [[[WDW - if you do a drain, you block, so
-// don't do that. In addition the typical SADA notion of flush is
-// currently handled by wave_close. I think this is most likely just
-// terminology conflict between eSpeak and SADA.]]]
-//
-// PARAMETERS:
-//
-// theHandler: the audio device file descriptor
-//
-//<wave_flush
-
-void wave_flush(void* theHandler)
-{
- ENTER("wave_flush");
- //ioctl((int) theHandler, AUDIO_DRAIN, 0);
- SHOW_TIME("wave_flush > LEAVE");
-}
-
-//>
-// wave_set_callback_is_output_enabled
-//
-// DESCRIPTION:
-//
-// Sets the callback to call from wave_write before it sends data to
-// be played. It helps wave_write determine if the data should be
-// thrown away or not.
-//
-// PARAMETERS:
-//
-// cb: the callback to call from wave_write
-//
-//<wave_set_callback_is_output_enabled
-
-void wave_set_callback_is_output_enabled(t_wave_callback* cb)
-{
- my_callback_is_output_enabled = cb;
-}
-
-//>
-// wave_test_get_write_buffer
-//
-// DESCRIPTION:
-//
-// Unnecessary and is used for debug output from
-// speak_lib.cpp:dispatch_audio.
-//
-// RETURNS:
-//
-// NULL
-//
-//<wave_test_get_write_buffer
-
-void *wave_test_get_write_buffer()
-{
- return NULL;
-}
-
-//>
-// wave_get_read_position
-//
-// DESCRIPTION:
-//
-// Concerns the sample which is currently played by the audio layer,
-// where 'sample' is a small buffer of synthesized wave data,
-// identified so that the user callback could be called when the
-// 'sample' is really played. The identifier is returned by
-// wave_get_write_position. This method is unused.
-//
-// PARAMETERS:
-//
-// theHandler: the audio device file descriptor
-//
-// RETURNS:
-//
-// The total number of 16-bit samples played by the audio system
-// so far.
-//
-//<wave_get_read_position
-
-uint32_t wave_get_read_position(void* theHandler)
-{
- audio_info_t ainfo;
- ENTER("wave_get_read_position");
- ioctl((int) theHandler, AUDIO_GETINFO, &ainfo);
- SHOW("wave_get_read_position: %d\n", ainfo.play.samples);
- SHOW_TIME("wave_get_read_position > LEAVE");
- return ainfo.play.samples;
-}
-
-//>
-// wave_get_write_position
-//
-// DESCRIPTION:
-//
-// Returns an identifier for a new sample, where 'sample' is a small
-// buffer of synthesized wave data, identified so that the user
-// callback could be called when the 'sample' is really played. This
-// implementation views the audio as one long continuous stream of
-// 16-bit samples.
-//
-// PARAMETERS:
-//
-// theHandler: the audio device file descriptor
-//
-// GLOBALS USED/MODIFIED:
-//
-// total_samples_sent: used as the return value
-//
-// RETURNS:
-//
-// total_samples_sent, which is the index for the end of this long
-// continuous stream. [[[WDW: with a unit32_t managing 16-bit
-// samples at 22050Hz, we have about 54 hours of play time before
-// the index wraps back to 0. We don't handle that wrapping, so
-// the behavior after 54 hours of play time is undefined.]]]
-//
-//<wave_get_write_position
-
-uint32_t wave_get_write_position(void* theHandler)
-{
- ENTER("wave_get_write_position");
- SHOW("wave_get_write_position: %d\n", total_samples_sent);
- SHOW_TIME("wave_get_write_position > LEAVE");
- return total_samples_sent;
-}
-
-//>
-// wave_get_remaining_time
-//
-// DESCRIPTION:
-//
-// Returns the remaining time (in ms) before the sample is played.
-// The sample in this case is a return value from a previous call to
-// wave_get_write_position.
-//
-// PARAMETERS:
-//
-// sample: an index returned from wave_get_write_position representing
-// an index into the long continuous stream of 16-bit samples
-// time: a return value representing the delay in milliseconds until
-// sample is played. A value of 0 means the sample is either
-// currently being played or it has already been played.
-//
-// GLOBALS USED/MODIFIED:
-//
-// sun_audio_fd: used to determine total number of samples played by
-// the audio system
-// total_samples_skipped: used in remaining time calculation
-//
-// RETURNS:
-//
-// Time in milliseconds before the sample is played or 0 if the sample
-// is currently playing or has already been played.
-//
-//<wave_get_remaining_time
-
-int wave_get_remaining_time(uint32_t sample, uint32_t* time)
-{
- uint32_t a_time=0;
- uint32_t actual_index;
-
- audio_info_t ainfo;
- ENTER("wave_get_remaining_time");
- if (!time) {
- return(-1);
- SHOW_TIME("wave_get_remaining_time > LEAVE");
- }
-
- ioctl(sun_audio_fd, AUDIO_GETINFO, &ainfo);
-
- // See if this sample has already been played or is currently
- // playing.
- //
- actual_index = sample - total_samples_skipped;
- if ((sample < total_samples_skipped) ||
- (actual_index <= ainfo.play.samples)) {
- *time = 0;
- } else {
- a_time = ((actual_index - ainfo.play.samples) * 1000) / SAMPLE_RATE;
- *time = (uint32_t) a_time;
- }
- SHOW("wave_get_remaining_time for %d: %d\n", sample, *time);
- SHOW_TIME("wave_get_remaining_time > LEAVE");
- return 0;
-}
-
-#else
-// notdef USE_SADA
-
-void wave_init() {}
-void* wave_open(const char* the_api) {return (void *)1;}
-size_t wave_write(void* theHandler, char* theMono16BitsWaveBuffer, size_t theSize) {return theSize;}
-int wave_close(void* theHandler) {return 0;}
-int wave_is_busy(void* theHandler) {return 0;}
-void wave_terminate() {}
-uint32_t wave_get_read_position(void* theHandler) {return 0;}
-uint32_t wave_get_write_position(void* theHandler) {return 0;}
-void wave_flush(void* theHandler) {}
-typedef int (t_wave_callback)(void);
-void wave_set_callback_is_output_enabled(t_wave_callback* cb) {}
-extern void* wave_test_get_write_buffer() {return NULL;}
-
-int wave_get_remaining_time(uint32_t sample, uint32_t* time)
-{
- if (!time) return(-1);
- *time = (uint32_t)0;
- return 0;
-}
-
-#endif // of USE_PORTAUDIO
-
-//>
-//<clock_gettime2, add_time_in_ms
-
-void clock_gettime2(struct timespec *ts)
-{
- struct timeval tv;
-
- if (!ts)
- {
- return;
- }
-
- assert (gettimeofday(&tv, NULL) != -1);
- ts->tv_sec = tv.tv_sec;
- ts->tv_nsec = tv.tv_usec*1000;
-}
-
-void add_time_in_ms(struct timespec *ts, int time_in_ms)
-{
- if (!ts)
- {
- return;
- }
-
- uint64_t t_ns = (uint64_t)ts->tv_nsec + 1000000 * (uint64_t)time_in_ms;
- while(t_ns >= ONE_BILLION)
- {
- SHOW("event > add_time_in_ms ns: %d sec %Lu nsec \n", ts->tv_sec, t_ns);
- ts->tv_sec += 1;
- t_ns -= ONE_BILLION;
- }
- ts->tv_nsec = (long int)t_ns;
-}
-
-#endif // USE_ASYNC
-
-//>
diff --git a/navit/support/espeak/wavegen.c b/navit/support/espeak/wavegen.c
deleted file mode 100755
index a5467ca1e..000000000
--- a/navit/support/espeak/wavegen.c
+++ /dev/null
@@ -1,1941 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2005 to 2007 by Jonathan Duddington *
- * email: jonsd@users.sourceforge.net *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, see: *
- * <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-#include "StdAfx.h"
-
-// this version keeps wavemult window as a constant fraction
-// of the cycle length - but that spreads out the HF peaks too much
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <math.h>
-
-
-#include "speak_lib.h"
-#include "speech.h"
-#include "phoneme.h"
-#include "synthesize.h"
-#include "voice.h"
-
-//#undef INCLUDE_KLATT
-
-#ifdef USE_PORTAUDIO
-#include "portaudio.h"
-#undef USE_PORTAUDIO
-// determine portaudio version by looking for a #define which is not in V18
-#ifdef paNeverDropInput
-#define USE_PORTAUDIO 19
-#else
-#define USE_PORTAUDIO 18
-#endif
-#endif
-
-#define N_SINTAB 2048
-#include "sintab.h"
-
-
-#define PI 3.1415927
-#define PI2 6.283185307
-#define N_WAV_BUF 10
-
-voice_t *wvoice;
-
-FILE *f_log = NULL;
-int option_waveout = 0;
-static int option_harmonic1 = 10; // 10
-int option_log_frames = 0;
-static int flutter_amp = 64;
-
-static int general_amplitude = 60;
-static int consonant_amp = 26; // 24
-
-int embedded_value[N_EMBEDDED_VALUES];
-
-static int PHASE_INC_FACTOR;
-int samplerate = 0; // this is set by Wavegeninit()
-int samplerate_native=0;
-extern int option_device_number;
-extern int option_quiet;
-
-static wavegen_peaks_t peaks[N_PEAKS];
-static int peak_harmonic[N_PEAKS];
-static int peak_height[N_PEAKS];
-
-#define N_ECHO_BUF 5500 // max of 250mS at 22050 Hz
-static int echo_head;
-static int echo_tail;
-static int echo_length = 0; // period (in sample\) to ensure completion of echo at the end of speech, set in WavegenSetEcho()
-static int echo_amp = 0;
-static short echo_buf[N_ECHO_BUF];
-
-static int voicing;
-static RESONATOR rbreath[N_PEAKS];
-
-static int harm_sqrt_n = 0;
-
-
-#define N_LOWHARM 30
-static int harm_inc[N_LOWHARM]; // only for these harmonics do we interpolate amplitude between steps
-static int *harmspect;
-static int hswitch=0;
-static int hspect[2][MAX_HARMONIC]; // 2 copies, we interpolate between then
-static int max_hval=0;
-
-static int nsamples=0; // number to do
-static int modulation_type = 0;
-static int glottal_flag = 0;
-static int glottal_reduce = 0;
-
-
-WGEN_DATA wdata;
-
-static int amp_ix;
-static int amp_inc;
-static unsigned char *amplitude_env = NULL;
-
-static int samplecount=0; // number done
-static int samplecount_start=0; // count at start of this segment
-static int end_wave=0; // continue to end of wave cycle
-static int wavephase;
-static int phaseinc;
-static int cycle_samples; // number of samples in a cycle at current pitch
-static int cbytes;
-static int hf_factor;
-
-static double minus_pi_t;
-static double two_pi_t;
-
-
-unsigned char *out_ptr;
-unsigned char *out_start;
-unsigned char *out_end;
-int outbuf_size = 0;
-
-// the queue of operations passed to wavegen from sythesize
-long wcmdq[N_WCMDQ][4];
-int wcmdq_head=0;
-int wcmdq_tail=0;
-
-// pitch,speed,
-int embedded_default[N_EMBEDDED_VALUES] = {0,50,170,100,50, 0,0, 0,170,0,0,0,0,0};
-static int embedded_max[N_EMBEDDED_VALUES] = {0,0x7fff,600,300,99,99,99, 0,600,0,0,0,0,4};
-
-#define N_CALLBACK_IX N_WAV_BUF-2 // adjust this delay to match display with the currently spoken word
-int current_source_index=0;
-
-extern FILE *f_wave;
-
-#if (USE_PORTAUDIO == 18)
-static PortAudioStream *pa_stream=NULL;
-#endif
-#if (USE_PORTAUDIO == 19)
-static PaStream *pa_stream=NULL;
-#endif
-
-/* default pitch envelope, a steady fall */
-#define ENV_LEN 128
-
-#define int(x) (int)(x)
-/*
-unsigned char Pitch_env0[ENV_LEN] = {
- 255,253,251,249,247,245,243,241,239,237,235,233,231,229,227,225,
- 223,221,219,217,215,213,211,209,207,205,203,201,199,197,195,193,
- 191,189,187,185,183,181,179,177,175,173,171,169,167,165,163,161,
- 159,157,155,153,151,149,147,145,143,141,139,137,135,133,131,129,
- 127,125,123,121,119,117,115,113,111,109,107,105,103,101, 99, 97,
- 95, 93, 91, 89, 87, 85, 83, 81, 79, 77, 75, 73, 71, 69, 67, 65,
- 63, 61, 59, 57, 55, 53, 51, 49, 47, 45, 43, 41, 39, 37, 35, 33,
- 31, 29, 27, 25, 23, 21, 19, 17, 15, 13, 11, 9, 7, 5, 3, 1
-};
-*/
-
-/*
-unsigned char Pitch_long[ENV_LEN] = {
- 254,249,250,251,252,253,254,254, 255,255,255,255,254,254,253,252,
- 251,250,249,247,244,242,238,234, 230,225,221,217,213,209,206,203,
- 199,195,191,187,183,179,175,172, 168,165,162,159,156,153,150,148,
- 145,143,140,138,136,134,132,130, 128,126,123,120,117,114,111,107,
- 104,100,96,91, 86,82,77,73, 70,66,63,60, 58,55,53,51,
- 49,47,46,45, 43,42,40,38, 36,34,31,28, 26,24,22,20,
- 18,16,14,12, 11,10,9,8, 8,8,8,8, 9,8,8,8,
- 8,8,7,7, 6,6,6,5, 4,4,3,3, 2,1,1,0
-};
-*/
-
-// 1st index=roughness
-// 2nd index=modulation_type
-// value: bits 0-3 amplitude (16ths), bits 4-7 every n cycles
-#define N_ROUGHNESS 8
-static unsigned char modulation_tab[N_ROUGHNESS][8] = {
- {0, 0x00, 0x00, 0x00, 0, 0x46, 0xf2, 0x29},
- {0, 0x2f, 0x00, 0x2f, 0, 0x45, 0xf2, 0x29},
- {0, 0x2f, 0x00, 0x2e, 0, 0x45, 0xf2, 0x28},
- {0, 0x2e, 0x00, 0x2d, 0, 0x34, 0xf2, 0x28},
- {0, 0x2d, 0x2d, 0x2c, 0, 0x34, 0xf2, 0x28},
- {0, 0x2b, 0x2b, 0x2b, 0, 0x34, 0xf2, 0x28},
- {0, 0x2a, 0x2a, 0x2a, 0, 0x34, 0xf2, 0x28},
- {0, 0x29, 0x29, 0x29, 0, 0x34, 0xf2, 0x28},
-};
-
-// Flutter table, to add natural variations to the pitch
-#define N_FLUTTER 0x170
-static int Flutter_inc;
-static const unsigned char Flutter_tab[N_FLUTTER] = {
- 0x80, 0x9b, 0xb5, 0xcb, 0xdc, 0xe8, 0xed, 0xec,
- 0xe6, 0xdc, 0xce, 0xbf, 0xb0, 0xa3, 0x98, 0x90,
- 0x8c, 0x8b, 0x8c, 0x8f, 0x92, 0x94, 0x95, 0x92,
- 0x8c, 0x83, 0x78, 0x69, 0x59, 0x49, 0x3c, 0x31,
- 0x2a, 0x29, 0x2d, 0x36, 0x44, 0x56, 0x69, 0x7d,
- 0x8f, 0x9f, 0xaa, 0xb1, 0xb2, 0xad, 0xa4, 0x96,
- 0x87, 0x78, 0x69, 0x5c, 0x53, 0x4f, 0x4f, 0x55,
- 0x5e, 0x6b, 0x7a, 0x88, 0x96, 0xa2, 0xab, 0xb0,
-
- 0xb1, 0xae, 0xa8, 0xa0, 0x98, 0x91, 0x8b, 0x88,
- 0x89, 0x8d, 0x94, 0x9d, 0xa8, 0xb2, 0xbb, 0xc0,
- 0xc1, 0xbd, 0xb4, 0xa5, 0x92, 0x7c, 0x63, 0x4a,
- 0x32, 0x1e, 0x0e, 0x05, 0x02, 0x05, 0x0f, 0x1e,
- 0x30, 0x44, 0x59, 0x6d, 0x7f, 0x8c, 0x96, 0x9c,
- 0x9f, 0x9f, 0x9d, 0x9b, 0x99, 0x99, 0x9c, 0xa1,
- 0xa9, 0xb3, 0xbf, 0xca, 0xd5, 0xdc, 0xe0, 0xde,
- 0xd8, 0xcc, 0xbb, 0xa6, 0x8f, 0x77, 0x60, 0x4b,
-
- 0x3a, 0x2e, 0x28, 0x29, 0x2f, 0x3a, 0x48, 0x59,
- 0x6a, 0x7a, 0x86, 0x90, 0x94, 0x95, 0x91, 0x89,
- 0x80, 0x75, 0x6b, 0x62, 0x5c, 0x5a, 0x5c, 0x61,
- 0x69, 0x74, 0x80, 0x8a, 0x94, 0x9a, 0x9e, 0x9d,
- 0x98, 0x90, 0x86, 0x7c, 0x71, 0x68, 0x62, 0x60,
- 0x63, 0x6b, 0x78, 0x88, 0x9b, 0xaf, 0xc2, 0xd2,
- 0xdf, 0xe6, 0xe7, 0xe2, 0xd7, 0xc6, 0xb2, 0x9c,
- 0x84, 0x6f, 0x5b, 0x4b, 0x40, 0x39, 0x37, 0x38,
-
- 0x3d, 0x43, 0x4a, 0x50, 0x54, 0x56, 0x55, 0x52,
- 0x4d, 0x48, 0x42, 0x3f, 0x3e, 0x41, 0x49, 0x56,
- 0x67, 0x7c, 0x93, 0xab, 0xc3, 0xd9, 0xea, 0xf6,
- 0xfc, 0xfb, 0xf4, 0xe7, 0xd5, 0xc0, 0xaa, 0x94,
- 0x80, 0x71, 0x64, 0x5d, 0x5a, 0x5c, 0x61, 0x68,
- 0x70, 0x77, 0x7d, 0x7f, 0x7f, 0x7b, 0x74, 0x6b,
- 0x61, 0x57, 0x4e, 0x48, 0x46, 0x48, 0x4e, 0x59,
- 0x66, 0x75, 0x84, 0x93, 0x9f, 0xa7, 0xab, 0xaa,
-
- 0xa4, 0x99, 0x8b, 0x7b, 0x6a, 0x5b, 0x4e, 0x46,
- 0x43, 0x45, 0x4d, 0x5a, 0x6b, 0x7f, 0x92, 0xa6,
- 0xb8, 0xc5, 0xcf, 0xd3, 0xd2, 0xcd, 0xc4, 0xb9,
- 0xad, 0xa1, 0x96, 0x8e, 0x89, 0x87, 0x87, 0x8a,
- 0x8d, 0x91, 0x92, 0x91, 0x8c, 0x84, 0x78, 0x68,
- 0x55, 0x41, 0x2e, 0x1c, 0x0e, 0x05, 0x01, 0x05,
- 0x0f, 0x1f, 0x34, 0x4d, 0x68, 0x81, 0x9a, 0xb0,
- 0xc1, 0xcd, 0xd3, 0xd3, 0xd0, 0xc8, 0xbf, 0xb5,
-
- 0xab, 0xa4, 0x9f, 0x9c, 0x9d, 0xa0, 0xa5, 0xaa,
- 0xae, 0xb1, 0xb0, 0xab, 0xa3, 0x96, 0x87, 0x76,
- 0x63, 0x51, 0x42, 0x36, 0x2f, 0x2d, 0x31, 0x3a,
- 0x48, 0x59, 0x6b, 0x7e, 0x8e, 0x9c, 0xa6, 0xaa,
- 0xa9, 0xa3, 0x98, 0x8a, 0x7b, 0x6c, 0x5d, 0x52,
- 0x4a, 0x48, 0x4a, 0x50, 0x5a, 0x67, 0x75, 0x82
-};
-
-// waveform shape table for HF peaks, formants 6,7,8
-#define N_WAVEMULT 128
-static int wavemult_offset=0;
-static int wavemult_max=0;
-
-// the presets are for 22050 Hz sample rate.
-// A different rate will need to recalculate the presets in WavegenInit()
-static unsigned char wavemult[N_WAVEMULT] = {
- 0, 0, 0, 2, 3, 5, 8, 11, 14, 18, 22, 27, 32, 37, 43, 49,
- 55, 62, 69, 76, 83, 90, 98,105,113,121,128,136,144,152,159,166,
- 174,181,188,194,201,207,213,218,224,228,233,237,240,244,246,249,
- 251,252,253,253,253,253,252,251,249,246,244,240,237,233,228,224,
- 218,213,207,201,194,188,181,174,166,159,152,144,136,128,121,113,
- 105, 98, 90, 83, 76, 69, 62, 55, 49, 43, 37, 32, 27, 22, 18, 14,
- 11, 8, 5, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
-
-// set from y = pow(2,x) * 128, x=-1 to 1
-unsigned char pitch_adjust_tab[MAX_PITCH_VALUE+1] = {
- 64, 65, 66, 67, 68, 69, 70, 71,
- 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 86, 87, 88,
- 89, 91, 92, 93, 94, 96, 97, 98,
- 100,101,103,104,105,107,108,110,
- 111,113,115,116,118,119,121,123,
- 124,126,128,130,132,133,135,137,
- 139,141,143,145,147,149,151,153,
- 155,158,160,162,164,167,169,171,
- 174,176,179,181,184,186,189,191,
- 194,197,199,202,205,208,211,214,
- 217,220,223,226,229,232,236,239,
- 242,246,249,252, 254,255 };
-
-int WavegenFill(int fill_zeros);
-
-
-#ifdef LOG_FRAMES
-static void LogMarker(int type, int value)
-{//=======================================
- if(option_log_frames == 0)
- return;
-
- if((type == espeakEVENT_PHONEME) || (type == espeakEVENT_SENTENCE))
- {
- f_log=fopen("log-espeakedit","a");
- if(f_log)
- {
- if(type == espeakEVENT_PHONEME)
- fprintf(f_log,"Phoneme [%s]\n",WordToString(value));
- else
- fprintf(f_log,"\n");
- fclose(f_log);
- f_log = NULL;
- }
- }
-}
-#endif
-
-void WcmdqStop()
-{//=============
- wcmdq_head = 0;
- wcmdq_tail = 0;
-#ifdef USE_PORTAUDIO
- Pa_AbortStream(pa_stream);
-#endif
-}
-
-
-int WcmdqFree()
-{//============
- int i;
- i = wcmdq_head - wcmdq_tail;
- if(i <= 0) i += N_WCMDQ;
- return(i);
-}
-
-int WcmdqUsed()
-{//============
- return(N_WCMDQ - WcmdqFree());
-}
-
-
-void WcmdqInc()
-{//============
- wcmdq_tail++;
- if(wcmdq_tail >= N_WCMDQ) wcmdq_tail=0;
-}
-
-static void WcmdqIncHead()
-{//=======================
- wcmdq_head++;
- if(wcmdq_head >= N_WCMDQ) wcmdq_head=0;
-}
-
-
-
-// data points from which to make the presets for pk_shape1 and pk_shape2
-#define PEAKSHAPEW 256
-static const float pk_shape_x[2][8] = {
- {0,-0.6f, 0.0f, 0.6f, 1.4f, 2.5f, 4.5f, 5.5f},
- {0,-0.6f, 0.0f, 0.6f, 1.4f, 2.0f, 4.5f, 5.5f }};
-static const float pk_shape_y[2][8] = {
- {0, 67, 81, 67, 31, 14, 0, -6} ,
- {0, 77, 81, 77, 31, 7, 0, -6 }};
-
-unsigned char pk_shape1[PEAKSHAPEW+1] = {
- 255,254,254,254,254,254,253,253,252,251,251,250,249,248,247,246,
- 245,244,242,241,239,238,236,234,233,231,229,227,225,223,220,218,
- 216,213,211,209,207,205,203,201,199,197,195,193,191,189,187,185,
- 183,180,178,176,173,171,169,166,164,161,159,156,154,151,148,146,
- 143,140,138,135,132,129,126,123,120,118,115,112,108,105,102, 99,
- 96, 95, 93, 91, 90, 88, 86, 85, 83, 82, 80, 79, 77, 76, 74, 73,
- 72, 70, 69, 68, 67, 66, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55,
- 55, 54, 53, 52, 52, 51, 50, 50, 49, 48, 48, 47, 47, 46, 46, 46,
- 45, 45, 45, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 44, 43,
- 42, 42, 41, 40, 40, 39, 38, 38, 37, 36, 36, 35, 35, 34, 33, 33,
- 32, 32, 31, 30, 30, 29, 29, 28, 28, 27, 26, 26, 25, 25, 24, 24,
- 23, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 18, 17, 17, 16,
- 16, 15, 15, 15, 14, 14, 13, 13, 13, 12, 12, 11, 11, 11, 10, 10,
- 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 5, 5,
- 5, 5, 4, 4, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2,
- 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 };
-
-static unsigned char pk_shape2[PEAKSHAPEW+1] = {
- 255,254,254,254,254,254,254,254,254,254,253,253,253,253,252,252,
- 252,251,251,251,250,250,249,249,248,248,247,247,246,245,245,244,
- 243,243,242,241,239,237,235,233,231,229,227,225,223,221,218,216,
- 213,211,208,205,203,200,197,194,191,187,184,181,178,174,171,167,
- 163,160,156,152,148,144,140,136,132,127,123,119,114,110,105,100,
- 96, 94, 91, 88, 86, 83, 81, 78, 76, 74, 71, 69, 66, 64, 62, 60,
- 57, 55, 53, 51, 49, 47, 44, 42, 40, 38, 36, 34, 32, 30, 29, 27,
- 25, 23, 21, 19, 18, 16, 14, 12, 11, 9, 7, 6, 4, 3, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 };
-
-static unsigned char *pk_shape;
-
-
-static void WavegenInitPkData(int which)
-{//=====================================
-// this is only needed to set up the presets for pk_shape1 and pk_shape2
-// These have already been pre-calculated and preset
-#ifdef deleted
- int ix;
- int p;
- float x;
- float y[PEAKSHAPEW];
- float maxy=0;
-
- if(which==0)
- pk_shape = pk_shape1;
- else
- pk_shape = pk_shape2;
-
- p = 0;
- for(ix=0;ix<PEAKSHAPEW;ix++)
- {
- x = (4.5*ix)/PEAKSHAPEW;
- if(x >= pk_shape_x[which][p+3]) p++;
- y[ix] = polint(&pk_shape_x[which][p],&pk_shape_y[which][p],3,x);
- if(y[ix] > maxy) maxy = y[ix];
- }
- for(ix=0;ix<PEAKSHAPEW;ix++)
- {
- p = (int)(y[ix]*255/maxy);
- pk_shape[ix] = (p >= 0) ? p : 0;
- }
- pk_shape[PEAKSHAPEW]=0;
-#endif
-} // end of WavegenInitPkData
-
-
-
-#ifdef USE_PORTAUDIO
-// PortAudio interface
-
-static int userdata[4];
-static PaError pa_init_err=0;
-static int out_channels=1;
-
-#if USE_PORTAUDIO == 18
-static int WaveCallback(void *inputBuffer, void *outputBuffer,
- unsigned long framesPerBuffer, PaTimestamp outTime, void *userData )
-#else
-static int WaveCallback(const void *inputBuffer, void *outputBuffer,
- long unsigned int framesPerBuffer, const PaStreamCallbackTimeInfo *outTime,
- PaStreamCallbackFlags flags, void *userData )
-#endif
-{
- int ix;
- int result;
- unsigned char *p;
-
- out_ptr = out_start = (unsigned char *)outputBuffer;
- out_end = out_ptr + framesPerBuffer*2;
-
-#ifdef LIBRARY
- event_list_ix = 0;
-#endif
-
- result = WavegenFill(1);
-
-#ifdef LIBRARY
- count_samples += framesPerBuffer;
- if(synth_callback)
- {
- // synchronous-playback mode, allow the calling process to abort the speech
- event_list[event_list_ix].type = espeakEVENT_LIST_TERMINATED; // indicates end of event list
- event_list[event_list_ix].user_data = 0;
-
- if(synth_callback(NULL,0,event_list) == 1)
- {
- SpeakNextClause(NULL,NULL,2); // stop speaking
- result = 1;
- }
- }
-#endif
-
-#ifdef ARCH_BIG
- {
- // swap the order of bytes in each sound sample in the portaudio buffer
- int c;
- out_ptr = (unsigned char *)outputBuffer;
- out_end = out_ptr + framesPerBuffer*2;
- while(out_ptr < out_end)
- {
- c = out_ptr[0];
- out_ptr[0] = out_ptr[1];
- out_ptr[1] = c;
- out_ptr += 2;
- }
- }
-#endif
-
- if(out_channels == 2)
- {
- // sound output can only do stereo, not mono. Duplicate each sound sample to
- // produce 2 channels.
- out_ptr = (unsigned char *)outputBuffer;
- for(ix=framesPerBuffer-1; ix>=0; ix--)
- {
- p = &out_ptr[ix*4];
- p[3] = p[1] = out_ptr[ix*2 + 1];
- p[2] = p[0] = out_ptr[ix*2];
- }
- }
-
-#if USE_PORTAUDIO == 18
-#ifdef PLATFORM_WINDOWS
- return(result);
-#endif
- if(result != 0)
- {
- static int end_timer = 0;
- if(end_timer == 0)
- end_timer = 4;
- if(end_timer > 0)
- {
- end_timer--;
- if(end_timer == 0)
- return(1);
- }
- }
- return(0);
-#else
- return(result);
-#endif
-
-} // end of WaveCallBack
-
-
-#if USE_PORTAUDIO == 19
-/* This is a fixed version of Pa_OpenDefaultStream() for use if the version in portaudio V19
- is broken */
-
-static PaError Pa_OpenDefaultStream2( PaStream** stream,
- int inputChannelCount,
- int outputChannelCount,
- PaSampleFormat sampleFormat,
- double sampleRate,
- unsigned long framesPerBuffer,
- PaStreamCallback *streamCallback,
- void *userData )
-{
- PaError result;
- PaStreamParameters hostApiOutputParameters;
-
- if(option_device_number >= 0)
- hostApiOutputParameters.device = option_device_number;
- else
- hostApiOutputParameters.device = Pa_GetDefaultOutputDevice();
-
- if( hostApiOutputParameters.device == paNoDevice )
- return paDeviceUnavailable;
-
- hostApiOutputParameters.channelCount = outputChannelCount;
- hostApiOutputParameters.sampleFormat = sampleFormat;
- /* defaultHighOutputLatency is used below instead of
- defaultLowOutputLatency because it is more important for the default
- stream to work reliably than it is for it to work with the lowest
- latency.
- */
- hostApiOutputParameters.suggestedLatency =
- Pa_GetDeviceInfo( hostApiOutputParameters.device )->defaultHighOutputLatency;
- hostApiOutputParameters.hostApiSpecificStreamInfo = NULL;
-
- result = Pa_OpenStream(
- stream, NULL, &hostApiOutputParameters, sampleRate, framesPerBuffer, paNoFlag, streamCallback, userData );
-
- return(result);
-}
-#endif
-
-
-int WavegenOpenSound()
-{//===================
- PaError err, err2;
- PaError active;
-
- if(option_waveout || option_quiet)
- {
- // writing to WAV file, not to portaudio
- return(0);
- }
-
-#if USE_PORTAUDIO == 18
- active = Pa_StreamActive(pa_stream);
-#else
- active = Pa_IsStreamActive(pa_stream);
-#endif
-
- if(active == 1)
- return(0);
- if(active < 0)
- {
- out_channels = 1;
-
-#if USE_PORTAUDIO == 18
- err2 = Pa_OpenDefaultStream(&pa_stream,0,1,paInt16,samplerate,512,N_WAV_BUF,WaveCallback,(void *)userdata);
-
- if(err2 == paInvalidChannelCount)
- {
- // failed to open with mono, try stereo
- out_channels=2;
- err2 = Pa_OpenDefaultStream(&pa_stream,0,2,paInt16,samplerate,512,N_WAV_BUF,WaveCallback,(void *)userdata);
- }
-#else
- err2 = Pa_OpenDefaultStream2(&pa_stream,0,1,paInt16,(double)samplerate,512,WaveCallback,(void *)userdata);
-
- if(err2 == paInvalidChannelCount)
- {
- // failed to open with mono, try stereo
- out_channels=2;
- err2 = Pa_OpenDefaultStream(&pa_stream,0,2,paInt16,(double)samplerate,512,WaveCallback,(void *)userdata);
- }
-#endif
- }
- err = Pa_StartStream(pa_stream);
-
-#if USE_PORTAUDIO == 19
- if(err == paStreamIsNotStopped)
- {
- // not sure why we need this, but PA v19 seems to need it
- err = Pa_StopStream(pa_stream);
- err = Pa_StartStream(pa_stream);
- }
-#endif
-
- if(err != paNoError)
- {
- // exit speak if we can't open the sound device - this is OK if speak is being run for each utterance
- exit(2);
- }
-
- return(0);
-}
-
-
-
-int WavegenCloseSound()
-{//====================
- PaError active;
-
- // check whether speaking has finished, and close the stream
- if(pa_stream != NULL)
- {
-#if USE_PORTAUDIO == 18
- active = Pa_StreamActive(pa_stream);
-#else
- active = Pa_IsStreamActive(pa_stream);
-#endif
- if(WcmdqUsed() == 0) // also check that the queue is empty
- {
- if(active == 0)
- {
- Pa_CloseStream(pa_stream);
- pa_stream = NULL;
- return(1);
- }
- }
- else
- {
- WavegenOpenSound(); // still items in the queue, shouldn't be closed
- }
- }
- return(0);
-}
-
-
-int WavegenInitSound()
-{//===================
- PaError err;
-
- if(option_quiet)
- return(0);
-
- // PortAudio sound output library
- err = Pa_Initialize();
- pa_init_err = err;
- if(err != paNoError)
- {
- fprintf(stderr,"Failed to initialise the PortAudio sound\n");
- return(1);
- }
- return(0);
-}
-#else
-int WavegenOpenSound()
-{//===================
- return(0);
-}
-int WavegenCloseSound()
-{//====================
- return(0);
-}
-int WavegenInitSound()
-{//===================
- return(0);
-}
-#endif
-
-
-void WavegenInit(int rate, int wavemult_fact)
-{//==========================================
- int ix;
- double x;
-
- if(wavemult_fact == 0)
- wavemult_fact=60; // default
-
- wvoice = NULL;
- samplerate = samplerate_native = rate;
- PHASE_INC_FACTOR = 0x8000000 / samplerate; // assumes pitch is Hz*32
- Flutter_inc = (64 * samplerate)/rate;
- samplecount = 0;
- nsamples = 0;
- wavephase = 0x7fffffff;
- max_hval = 0;
-
- wdata.amplitude = 32;
- wdata.prev_was_synth = 0;
-
- for(ix=0; ix<N_EMBEDDED_VALUES; ix++)
- embedded_value[ix] = embedded_default[ix];
-
-
- // set up window to generate a spread of harmonics from a
- // single peak for HF peaks
- wavemult_max = (samplerate * wavemult_fact)/(256 * 50);
- if(wavemult_max > N_WAVEMULT) wavemult_max = N_WAVEMULT;
-
- wavemult_offset = wavemult_max/2;
-
- if(samplerate != 22050)
- {
- // wavemult table has preset values for 22050 Hz, we only need to
- // recalculate them if we have a different sample rate
- for(ix=0; ix<wavemult_max; ix++)
- {
- x = 127*(1.0 - cos(PI2*ix/wavemult_max));
- wavemult[ix] = (int)x;
- }
- }
-
- WavegenInitPkData(1);
- WavegenInitPkData(0);
- pk_shape = pk_shape2; // pk_shape2
-
-#ifdef INCLUDE_KLATT
- KlattInit();
-#endif
-
-#ifdef LOG_FRAMES
-remove("log-espeakedit");
-#endif
-} // end of WavegenInit
-
-
-int GetAmplitude(void)
-{//===================
- int amp;
-
- // normal, none, reduced, moderate, strong
- static const unsigned char amp_emphasis[5] = {16, 16, 10, 16, 22};
-
- amp = (embedded_value[EMBED_A])*55/100;
- general_amplitude = amp * amp_emphasis[embedded_value[EMBED_F]] / 16;
- return(general_amplitude);
-}
-
-
-static void WavegenSetEcho(void)
-{//=============================
- int delay;
- int amp;
-
- voicing = wvoice->voicing;
- delay = wvoice->echo_delay;
- amp = wvoice->echo_amp;
-
- if(delay >= N_ECHO_BUF)
- delay = N_ECHO_BUF-1;
- if(amp > 100)
- amp = 100;
-
- memset(echo_buf,0,sizeof(echo_buf));
- echo_tail = 0;
-
- if(embedded_value[EMBED_H] > 0)
- {
- // set echo from an embedded command in the text
- amp = embedded_value[EMBED_H];
- delay = 130;
- }
- if(embedded_value[EMBED_T] > 0)
- {
- // announcing punctuation
- amp = embedded_value[EMBED_T] * 8;
- delay = 60;
- }
-
- if(delay == 0)
- amp = 0;
-
- echo_head = (delay * samplerate)/1000;
- echo_length = echo_head; // ensure completion of echo at the end of speech. Use 1 delay period?
- if(amp == 0)
- echo_length = 0;
- if(amp > 20)
- echo_length = echo_head * 2; // perhaps allow 2 echo periods if the echo is loud.
-
- // echo_amp units are 1/256ths of the amplitude of the original sound.
- echo_amp = amp;
- // compensate (partially) for increase in amplitude due to echo
- general_amplitude = GetAmplitude();
- general_amplitude = ((general_amplitude * (500-amp))/500);
-} // end of WavegenSetEcho
-
-
-
-int PeaksToHarmspect(wavegen_peaks_t *peaks, int pitch, int *htab, int control)
-{//============================================================================
-// Calculate the amplitude of each harmonics from the formants
-// Only for formants 0 to 5
-
-// control 0=initial call, 1=every 64 cycles
-
- // pitch and freqs are Hz<<16
-
- int f;
- wavegen_peaks_t *p;
- int fp; // centre freq of peak
- int fhi; // high freq of peak
- int h; // harmonic number
- int pk;
- int hmax;
- int hmax_samplerate; // highest harmonic allowed for the samplerate
- int x;
- int ix;
- int h1;
-
-#ifdef SPECT_EDITOR
- if(harm_sqrt_n > 0)
- return(HarmToHarmspect(pitch,htab));
-#endif
-
- // initialise as much of *out as we will need
- if(wvoice == NULL)
- return(1);
- hmax = (peaks[wvoice->n_harmonic_peaks].freq + peaks[wvoice->n_harmonic_peaks].right)/pitch;
- if(hmax >= MAX_HARMONIC)
- hmax = MAX_HARMONIC-1;
-
- // restrict highest harmonic to half the samplerate
- hmax_samplerate = (((samplerate * 19)/40) << 16)/pitch; // only 95% of Nyquist freq
-// hmax_samplerate = (samplerate << 16)/(pitch*2);
-
- if(hmax > hmax_samplerate)
- hmax = hmax_samplerate;
-
- for(h=0;h<=hmax;h++)
- htab[h]=0;
-
- h=0;
- for(pk=0; pk<=wvoice->n_harmonic_peaks; pk++)
- {
- p = &peaks[pk];
- if((p->height == 0) || (fp = p->freq)==0)
- continue;
-
- fhi = p->freq + p->right;
- h = ((p->freq - p->left) / pitch) + 1;
- if(h <= 0) h = 1;
-
- for(f=pitch*h; f < fp; f+=pitch)
- {
- htab[h++] += pk_shape[(fp-f)/(p->left>>8)] * p->height;
- }
- for(; f < fhi; f+=pitch)
- {
- htab[h++] += pk_shape[(f-fp)/(p->right>>8)] * p->height;
- }
- }
-
-{
-int y;
-int h2;
- // increase bass
- y = peaks[1].height * 10; // addition as a multiple of 1/256s
- h2 = (1000<<16)/pitch; // decrease until 1000Hz
- if(h2 > 0)
- {
- x = y/h2;
- h = 1;
- while(y > 0)
- {
- htab[h++] += y;
- y -= x;
- }
- }
-}
-
- // find the nearest harmonic for HF peaks where we don't use shape
- for(; pk<N_PEAKS; pk++)
- {
- x = peaks[pk].height >> 14;
- peak_height[pk] = (x * x * 5)/2;
-
- // find the nearest harmonic for HF peaks where we don't use shape
- if(control == 0)
- {
- // set this initially, but make changes only at the quiet point
- peak_harmonic[pk] = peaks[pk].freq / pitch;
- }
- // only use harmonics up to half the samplerate
- if(peak_harmonic[pk] >= hmax_samplerate)
- peak_height[pk] = 0;
- }
-
- // convert from the square-rooted values
- f = 0;
- for(h=0; h<=hmax; h++, f+=pitch)
- {
- x = htab[h] >> 15;
- htab[h] = (x * x) >> 8;
-
- if((ix = (f >> 19)) < N_TONE_ADJUST)
- {
- htab[h] = (htab[h] * wvoice->tone_adjust[ix]) >> 13; // index tone_adjust with Hz/8
- }
- }
-
- // adjust the amplitude of the first harmonic, affects tonal quality
- h1 = htab[1] * option_harmonic1;
- htab[1] = h1/8;
-
-
- // calc intermediate increments of LF harmonics
- if(control & 1)
- {
- for(h=1; h<N_LOWHARM; h++)
- {
- harm_inc[h] = (htab[h] - harmspect[h]) >> 3;
- }
- }
-
- return(hmax); // highest harmonic number
-} // end of PeaksToHarmspect
-
-
-
-static void AdvanceParameters()
-{//============================
-// Called every 64 samples to increment the formant freq, height, and widths
-
- int x;
- int ix;
- static int Flutter_ix = 0;
-
- // advance the pitch
- wdata.pitch_ix += wdata.pitch_inc;
- if((ix = wdata.pitch_ix>>8) > 127) ix = 127;
- x = wdata.pitch_env[ix] * wdata.pitch_range;
- wdata.pitch = (x>>8) + wdata.pitch_base;
-
- amp_ix += amp_inc;
-
- /* add pitch flutter */
- if(Flutter_ix >= (N_FLUTTER*64))
- Flutter_ix = 0;
- x = ((int)(Flutter_tab[Flutter_ix >> 6])-0x80) * flutter_amp;
- Flutter_ix += Flutter_inc;
- wdata.pitch += x;
- if(wdata.pitch < 102400)
- wdata.pitch = 102400; // min pitch, 25 Hz (25 << 12)
-
- if(samplecount == samplecount_start)
- return;
-
- for(ix=0; ix <= wvoice->n_harmonic_peaks; ix++)
- {
- peaks[ix].freq1 += peaks[ix].freq_inc;
- peaks[ix].freq = (int)(peaks[ix].freq1);
- peaks[ix].height1 += peaks[ix].height_inc;
- if((peaks[ix].height = (int)(peaks[ix].height1)) < 0)
- peaks[ix].height = 0;
- peaks[ix].left1 += peaks[ix].left_inc;
- peaks[ix].left = (int)(peaks[ix].left1);
- if(ix < 3)
- {
- peaks[ix].right1 += peaks[ix].right_inc;
- peaks[ix].right = (int)(peaks[ix].right1);
- }
- else
- {
- peaks[ix].right = peaks[ix].left;
- }
- }
- for(;ix < 8; ix++)
- {
- // formants 6,7,8 don't have a width parameter
- if(ix < 7)
- {
- peaks[ix].freq1 += peaks[ix].freq_inc;
- peaks[ix].freq = (int)(peaks[ix].freq1);
- }
- peaks[ix].height1 += peaks[ix].height_inc;
- if((peaks[ix].height = (int)(peaks[ix].height1)) < 0)
- peaks[ix].height = 0;
- }
-
-#ifdef SPECT_EDITOR
- if(harm_sqrt_n != 0)
- {
- // We are generating from a harmonic spectrum at a given pitch, not from formant peaks
- for(ix=0; ix<harm_sqrt_n; ix++)
- harm_sqrt[ix] += harm_sqrt_inc[ix];
- }
-#endif
-} // end of AdvanceParameters
-
-
-#ifndef PLATFORM_RISCOS
-static double resonator(RESONATOR *r, double input)
-{//================================================
- double x;
-
- x = r->a * input + r->b * r->x1 + r->c * r->x2;
- r->x2 = r->x1;
- r->x1 = x;
-
- return x;
-}
-
-
-
-static void setresonator(RESONATOR *rp, int freq, int bwidth, int init)
-{//====================================================================
-// freq Frequency of resonator in Hz
-// bwidth Bandwidth of resonator in Hz
-// init Initialize internal data
-
- double x;
- double arg;
-
- if(init)
- {
- rp->x1 = 0;
- rp->x2 = 0;
- }
-
- // x = exp(-pi * bwidth * t)
- arg = minus_pi_t * bwidth;
- x = exp(arg);
-
- // c = -(x*x)
- rp->c = -(x * x);
-
- // b = x * 2*cos(2 pi * freq * t)
-
- arg = two_pi_t * freq;
- rp->b = x * cos(arg) * 2.0;
-
- // a = 1.0 - b - c
- rp->a = 1.0 - rp->b - rp->c;
-} // end if setresonator
-#endif
-
-
-void InitBreath(void)
-{//==================
-#ifndef PLATFORM_RISCOS
- int ix;
-
- minus_pi_t = -PI / samplerate;
- two_pi_t = -2.0 * minus_pi_t;
-
- for(ix=0; ix<N_PEAKS; ix++)
- {
- setresonator(&rbreath[ix],2000,200,1);
- }
-#endif
-} // end of InitBreath
-
-
-
-static void SetBreath()
-{//====================
-#ifndef PLATFORM_RISCOS
- int pk;
-
- if(wvoice->breath[0] == 0)
- return;
-
- for(pk=1; pk<N_PEAKS; pk++)
- {
- if(wvoice->breath[pk] != 0)
- {
- // breath[0] indicates that some breath formants are needed
- // set the freq from the current ynthesis formant and the width from the voice data
- setresonator(&rbreath[pk], peaks[pk].freq >> 16, wvoice->breathw[pk],0);
- }
- }
-#endif
-} // end of SetBreath
-
-
-static int ApplyBreath(void)
-{//=========================
- int value = 0;
-#ifndef PLATFORM_RISCOS
- int noise;
- int ix;
- int amp;
-
- // use two random numbers, for alternate formants
- noise = (rand() & 0x3fff) - 0x2000;
-
- for(ix=1; ix < N_PEAKS; ix++)
- {
- if((amp = wvoice->breath[ix]) != 0)
- {
- amp *= (peaks[ix].height >> 14);
- value += (int)(resonator(&rbreath[ix],noise) * amp);
- }
- }
-#endif
- return (value);
-}
-
-
-
-int Wavegen()
-{//==========
- unsigned short waveph;
- unsigned short theta;
- int total;
- int h;
- int ix;
- int z, z1, z2;
- int echo;
- int ov;
- static int maxh, maxh2;
- int pk;
- signed char c;
- int sample;
- int amp;
- int modn_amp, modn_period;
- static int agc = 256;
- static int h_switch_sign = 0;
- static int cycle_count = 0;
- static int amplitude2 = 0; // adjusted for pitch
-
- // continue until the output buffer is full, or
- // the required number of samples have been produced
-
- for(;;)
- {
- if((end_wave==0) && (samplecount==nsamples))
- return(0);
-
- if((samplecount & 0x3f) == 0)
- {
- // every 64 samples, adjust the parameters
- if(samplecount == 0)
- {
- hswitch = 0;
- harmspect = hspect[0];
- maxh2 = PeaksToHarmspect(peaks, wdata.pitch<<4, hspect[0], 0);
-
- // adjust amplitude to compensate for fewer harmonics at higher pitch
- amplitude2 = (wdata.amplitude * wdata.pitch)/(100 << 11);
-
- // switch sign of harmonics above about 900Hz, to reduce max peak amplitude
- h_switch_sign = 890 / (wdata.pitch >> 12);
- }
- else
- AdvanceParameters();
-
- // pitch is Hz<<12
- phaseinc = (wdata.pitch>>7) * PHASE_INC_FACTOR;
- cycle_samples = samplerate/(wdata.pitch >> 12); // sr/(pitch*2)
- hf_factor = wdata.pitch >> 11;
-
- maxh = maxh2;
- harmspect = hspect[hswitch];
- hswitch ^= 1;
- maxh2 = PeaksToHarmspect(peaks, wdata.pitch<<4, hspect[hswitch], 1);
-
- SetBreath();
- }
- else
- if((samplecount & 0x07) == 0)
- {
- for(h=1; h<N_LOWHARM && h<=maxh2 && h<=maxh; h++)
- {
- harmspect[h] += harm_inc[h];
- }
-
- // bring automctic gain control back towards unity
- if(agc < 256) agc++;
- }
-
- samplecount++;
-
- if(wavephase > 0)
- {
- wavephase += phaseinc;
- if(wavephase < 0)
- {
- // sign has changed, reached a quiet point in the waveform
- cbytes = wavemult_offset - (cycle_samples)/2;
- if(samplecount > nsamples)
- return(0);
-
- cycle_count++;
-
- for(pk=wvoice->n_harmonic_peaks+1; pk<N_PEAKS; pk++)
- {
- // find the nearest harmonic for HF peaks where we don't use shape
- peak_harmonic[pk] = peaks[pk].freq / (wdata.pitch*16);
- }
-
- // adjust amplitude to compensate for fewer harmonics at higher pitch
- amplitude2 = (wdata.amplitude * wdata.pitch)/(100 << 11);
-
- if(glottal_flag > 0)
- {
- if(glottal_flag == 3)
- {
- if((nsamples-samplecount) < (cycle_samples*2))
- {
- // Vowel before glottal-stop.
- // This is the start of the penultimate cycle, reduce its amplitude
- glottal_flag = 2;
- amplitude2 = (amplitude2 * glottal_reduce)/256;
- }
- }
- else
- if(glottal_flag == 4)
- {
- // Vowel following a glottal-stop.
- // This is the start of the second cycle, reduce its amplitude
- glottal_flag = 2;
- amplitude2 = (amplitude2 * glottal_reduce)/256;
- }
- else
- {
- glottal_flag--;
- }
- }
-
- if(amplitude_env != NULL)
- {
- // amplitude envelope is only used for creaky voice effect on certain vowels/tones
- if((ix = amp_ix>>8) > 127) ix = 127;
- amp = amplitude_env[ix];
- amplitude2 = (amplitude2 * amp)/128;
-// if(amp < 255)
-// modulation_type = 7;
- }
-
- // introduce roughness into the sound by reducing the amplitude of
- modn_period = 0;
- if(voice->roughness < N_ROUGHNESS)
- {
- modn_period = modulation_tab[voice->roughness][modulation_type];
- modn_amp = modn_period & 0xf;
- modn_period = modn_period >> 4;
- }
-
- if(modn_period != 0)
- {
- if(modn_period==0xf)
- {
- // just once */
- amplitude2 = (amplitude2 * modn_amp)/16;
- modulation_type = 0;
- }
- else
- {
- // reduce amplitude every [modn_period} cycles
- if((cycle_count % modn_period)==0)
- amplitude2 = (amplitude2 * modn_amp)/16;
- }
- }
- }
- }
- else
- {
- wavephase += phaseinc;
- }
- waveph = (unsigned short)(wavephase >> 16);
- total = 0;
-
- // apply HF peaks, formants 6,7,8
- // add a single harmonic and then spread this my multiplying by a
- // window. This is to reduce the processing power needed to add the
- // higher frequence harmonics.
- cbytes++;
- if(cbytes >=0 && cbytes<wavemult_max)
- {
- for(pk=wvoice->n_harmonic_peaks+1; pk<N_PEAKS; pk++)
- {
- theta = peak_harmonic[pk] * waveph;
- total += (long)sin_tab[theta >> 5] * peak_height[pk];
- }
-
- // spread the peaks by multiplying by a window
- total = (long)(total / hf_factor) * wavemult[cbytes];
- }
-
- // apply main peaks, formants 0 to 5
-#ifdef USE_ASSEMBLER_1
- // use an optimised routine for this loop, if available
- total += AddSineWaves(waveph, h_switch_sign, maxh, harmspect); // call an assembler code routine
-#else
- theta = waveph;
-
- for(h=1; h<=h_switch_sign; h++)
- {
- total += ((int)(sin_tab[theta >> 5]) * harmspect[h]);
- theta += waveph;
- }
- while(h<=maxh)
- {
- total -= ((int)(sin_tab[theta >> 5]) * harmspect[h]);
- theta += waveph;
- h++;
- }
-#endif
-
- if(voicing != 64)
- {
- total = (total >> 6) * voicing;
- }
-
-#ifndef PLATFORM_RISCOS
- if(wvoice->breath[0])
- {
- total += ApplyBreath();
- }
-#endif
-
- // mix with sampled wave if required
- z2 = 0;
- if(wdata.mix_wavefile_ix < wdata.n_mix_wavefile)
- {
- if(wdata.mix_wave_scale == 0)
- {
- // a 16 bit sample
- c = wdata.mix_wavefile[wdata.mix_wavefile_ix+1];
- sample = wdata.mix_wavefile[wdata.mix_wavefile_ix] + (c * 256);
- wdata.mix_wavefile_ix += 2;
- }
- else
- {
- // a 8 bit sample, scaled
- sample = (signed char)wdata.mix_wavefile[wdata.mix_wavefile_ix++] * wdata.mix_wave_scale;
- }
- z2 = (sample * wdata.amplitude_v) >> 10;
- z2 = (z2 * wdata.mix_wave_amp)/32;
- }
-
- z1 = z2 + (((total>>8) * amplitude2) >> 13);
-
- echo = (echo_buf[echo_tail++] * echo_amp);
- z1 += echo >> 8;
- if(echo_tail >= N_ECHO_BUF)
- echo_tail=0;
-
- z = (z1 * agc) >> 8;
-
- // check for overflow, 16bit signed samples
- if(z >= 32768)
- {
- ov = 8388608/z1 - 1; // 8388608 is 2^23, i.e. max value * 256
- if(ov < agc) agc = ov; // set agc to number of 1/256ths to multiply the sample by
- z = (z1 * agc) >> 8; // reduce sample by agc value to prevent overflow
- }
- else
- if(z <= -32768)
- {
- ov = -8388608/z1 - 1;
- if(ov < agc) agc = ov;
- z = (z1 * agc) >> 8;
- }
- *out_ptr++ = z;
- *out_ptr++ = z >> 8;
-
- echo_buf[echo_head++] = z;
- if(echo_head >= N_ECHO_BUF)
- echo_head = 0;
-
- if(out_ptr >= out_end)
- return(1);
- }
- return(0);
-} // end of Wavegen
-
-
-static int PlaySilence(int length, int resume)
-{//===========================================
- static int n_samples;
- int value=0;
-
- if(length == 0)
- return(0);
-
- nsamples = 0;
- samplecount = 0;
-
- if(resume==0)
- n_samples = length;
-
- while(n_samples-- > 0)
- {
- value = (echo_buf[echo_tail++] * echo_amp) >> 8;
-
- if(echo_tail >= N_ECHO_BUF)
- echo_tail = 0;
-
- *out_ptr++ = value;
- *out_ptr++ = value >> 8;
-
- echo_buf[echo_head++] = value;
- if(echo_head >= N_ECHO_BUF)
- echo_head = 0;
-
- if(out_ptr >= out_end)
- return(1);
- }
- return(0);
-} // end of PlaySilence
-
-
-
-static int PlayWave(int length, int resume, unsigned char *data, int scale, int amp)
-{//=================================================================================
- static int n_samples;
- static int ix=0;
- int value;
- signed char c;
-
- if(resume==0)
- {
- n_samples = length;
- ix = 0;
- }
-
- nsamples = 0;
- samplecount = 0;
-
- while(n_samples-- > 0)
- {
- if(scale == 0)
- {
- // 16 bits data
- c = data[ix+1];
- value = data[ix] + (c * 256);
- ix+=2;
- }
- else
- {
- // 8 bit data, shift by the specified scale factor
- value = (signed char)data[ix++] * scale;
- }
- value *= (consonant_amp * general_amplitude); // reduce strength of consonant
- value = value >> 10;
- value = (value * amp)/32;
-
- value += ((echo_buf[echo_tail++] * echo_amp) >> 8);
-
- if(value > 32767)
- value = 32768;
- else
- if(value < -32768)
- value = -32768;
-
- if(echo_tail >= N_ECHO_BUF)
- echo_tail = 0;
-
- out_ptr[0] = value;
- out_ptr[1] = value >> 8;
- out_ptr+=2;
-
- echo_buf[echo_head++] = (value*3)/4;
- if(echo_head >= N_ECHO_BUF)
- echo_head = 0;
-
- if(out_ptr >= out_end)
- return(1);
- }
- return(0);
-}
-
-
-static int SetWithRange0(int value, int max)
-{//=========================================
- if(value < 0)
- return(0);
- if(value > max)
- return(max);
- return(value);
-}
-
-
-void SetEmbedded(int control, int value)
-{//=====================================
- // there was an embedded command in the text at this point
- int sign=0;
- int command;
- int ix;
- int factor;
- int pitch_value;
-
- command = control & 0x1f;
- if((control & 0x60) == 0x60)
- sign = -1;
- else
- if((control & 0x60) == 0x40)
- sign = 1;
-
- if(command < N_EMBEDDED_VALUES)
- {
- if(sign == 0)
- embedded_value[command] = value;
- else
- embedded_value[command] += (value * sign);
- embedded_value[command] = SetWithRange0(embedded_value[command],embedded_max[command]);
- }
-
- switch(command)
- {
- case EMBED_T:
- WavegenSetEcho(); // and drop through to case P
- case EMBED_P:
- // adjust formants to give better results for a different voice pitch
- if((pitch_value = embedded_value[EMBED_P]) > MAX_PITCH_VALUE)
- pitch_value = MAX_PITCH_VALUE;
-
- factor = 256 + (25 * (pitch_value - 50))/50;
- for(ix=0; ix<=5; ix++)
- {
- wvoice->freq[ix] = (wvoice->freq2[ix] * factor)/256;
- }
- factor = embedded_value[EMBED_T]*3;
- wvoice->height[0] = (wvoice->height2[0] * (256 - factor*2))/256;
- wvoice->height[1] = (wvoice->height2[1] * (256 - factor))/256;
- break;
-
- case EMBED_A: // amplitude
- general_amplitude = GetAmplitude();
- break;
-
- case EMBED_F: // emphasiis
- general_amplitude = GetAmplitude();
- break;
-
- case EMBED_H:
- WavegenSetEcho();
- break;
- }
-}
-
-
-void WavegenSetVoice(voice_t *v)
-{//=============================
- static voice_t v2;
-
- memcpy(&v2,v,sizeof(v2));
- wvoice = &v2;
-
- if(v->peak_shape==0)
- pk_shape = pk_shape1;
- else
- pk_shape = pk_shape2;
-
- consonant_amp = (v->consonant_amp * 26) /100;
- if(samplerate <= 11000)
- {
- consonant_amp = consonant_amp*2; // emphasize consonants at low sample rates
- option_harmonic1 = 6;
- }
- WavegenSetEcho();
-}
-
-
-static void SetAmplitude(int length, unsigned char *amp_env, int value)
-{//====================================================================
- amp_ix = 0;
- if(length==0)
- amp_inc = 0;
- else
- amp_inc = (256 * ENV_LEN * STEPSIZE)/length;
-
- wdata.amplitude = (value * general_amplitude)/16;
- wdata.amplitude_v = (wdata.amplitude * wvoice->consonant_ampv * 15)/100; // for wave mixed with voiced sounds
-
- amplitude_env = amp_env;
-}
-
-
-void SetPitch2(voice_t *voice, int pitch1, int pitch2, int *pitch_base, int *pitch_range)
-{//======================================================================================
- int x;
- int base;
- int range;
- int pitch_value;
-
- if(pitch1 > pitch2)
- {
- x = pitch1; // swap values
- pitch1 = pitch2;
- pitch2 = x;
- }
-
- if((pitch_value = embedded_value[EMBED_P]) > MAX_PITCH_VALUE)
- pitch_value = MAX_PITCH_VALUE;
- pitch_value -= embedded_value[EMBED_T]; // adjust tone for announcing punctuation
- if(pitch_value < 0)
- pitch_value = 0;
-
- base = (voice->pitch_base * pitch_adjust_tab[pitch_value])/128;
- range = (voice->pitch_range * embedded_value[EMBED_R])/50;
-
- // compensate for change in pitch when the range is narrowed or widened
- base -= (range - voice->pitch_range)*18;
-
- *pitch_base = base + (pitch1 * range);
- *pitch_range = base + (pitch2 * range) - *pitch_base;
-}
-
-
-void SetPitch(int length, unsigned char *env, int pitch1, int pitch2)
-{//==================================================================
-// length in samples
-
-#ifdef LOG_FRAMES
-if(option_log_frames)
-{
- f_log=fopen("log-espeakedit","a");
- if(f_log != NULL)
- {
- fprintf(f_log," pitch %3d %3d %3dmS\n",pitch1,pitch2,(length*1000)/samplerate);
- fclose(f_log);
- f_log=NULL;
- }
-}
-#endif
- if((wdata.pitch_env = env)==NULL)
- wdata.pitch_env = env_fall; // default
-
- wdata.pitch_ix = 0;
- if(length==0)
- wdata.pitch_inc = 0;
- else
- wdata.pitch_inc = (256 * ENV_LEN * STEPSIZE)/length;
-
- SetPitch2(wvoice, pitch1, pitch2, &wdata.pitch_base, &wdata.pitch_range);
- // set initial pitch
- wdata.pitch = ((wdata.pitch_env[0] * wdata.pitch_range) >>8) + wdata.pitch_base; // Hz << 12
-
- flutter_amp = wvoice->flutter;
-
-} // end of SetPitch
-
-
-
-
-
-void SetSynth(int length, int modn, frame_t *fr1, frame_t *fr2, voice_t *v)
-{//========================================================================
- int ix;
- DOUBLEX next;
- int length2;
- int length4;
- int qix;
- int cmd;
- static int glottal_reduce_tab1[4] = {0x30, 0x30, 0x40, 0x50}; // vowel before [?], amp * 1/256
-// static int glottal_reduce_tab1[4] = {0x30, 0x40, 0x50, 0x60}; // vowel before [?], amp * 1/256
- static int glottal_reduce_tab2[4] = {0x90, 0xa0, 0xb0, 0xc0}; // vowel after [?], amp * 1/256
-
-#ifdef LOG_FRAMES
-if(option_log_frames)
-{
- f_log=fopen("log-espeakedit","a");
- if(f_log != NULL)
- {
- fprintf(f_log,"%3dmS %3d %3d %4d %4d (%3d %3d %3d %3d) to %3d %3d %4d %4d (%3d %3d %3d %3d)\n",length*1000/samplerate,
- fr1->ffreq[0],fr1->ffreq[1],fr1->ffreq[2],fr1->ffreq[3], fr1->fheight[0],fr1->fheight[1],fr1->fheight[2],fr1->fheight[3],
- fr2->ffreq[0],fr2->ffreq[1],fr2->ffreq[2],fr2->ffreq[3], fr2->fheight[0],fr2->fheight[1],fr2->fheight[2],fr2->fheight[3] );
-
- fclose(f_log);
- f_log=NULL;
- }
-}
-#endif
-
- harm_sqrt_n = 0;
- end_wave = 1;
-
- // any additional information in the param1 ?
- modulation_type = modn & 0xff;
-
- glottal_flag = 0;
- if(modn & 0x400)
- {
- glottal_flag = 3; // before a glottal stop
- glottal_reduce = glottal_reduce_tab1[(modn >> 8) & 3];
- }
- if(modn & 0x800)
- {
- glottal_flag = 4; // after a glottal stop
- glottal_reduce = glottal_reduce_tab2[(modn >> 8) & 3];
- }
-
- for(qix=wcmdq_head+1;;qix++)
- {
- if(qix >= N_WCMDQ) qix = 0;
- if(qix == wcmdq_tail) break;
-
- cmd = wcmdq[qix][0];
- if(cmd==WCMD_SPECT)
- {
- end_wave = 0; // next wave generation is from another spectrum
- break;
- }
- if((cmd==WCMD_WAVE) || (cmd==WCMD_PAUSE))
- break; // next is not from spectrum, so continue until end of wave cycle
- }
-
- // round the length to a multiple of the stepsize
- length2 = (length + STEPSIZE/2) & ~0x3f;
- if(length2 == 0)
- length2 = STEPSIZE;
-
- // add this length to any left over from the previous synth
- samplecount_start = samplecount;
- nsamples += length2;
-
- length4 = length2/4;
-
- peaks[7].freq = (7800 * v->freq[7] + v->freqadd[7]*256) << 8;
- peaks[8].freq = (9000 * v->freq[8] + v->freqadd[8]*256) << 8;
-
- for(ix=0; ix < 8; ix++)
- {
- if(ix < 7)
- {
- peaks[ix].freq1 = (fr1->ffreq[ix] * v->freq[ix] + v->freqadd[ix]*256) << 8;
- peaks[ix].freq = (int)(peaks[ix].freq1);
- next = (fr2->ffreq[ix] * v->freq[ix] + v->freqadd[ix]*256) << 8;
- peaks[ix].freq_inc = ((next - peaks[ix].freq1) * (STEPSIZE/4)) / length4; // lower headroom for fixed point math
- }
-
- peaks[ix].height1 = (fr1->fheight[ix] * v->height[ix]) << 6;
- peaks[ix].height = (int)(peaks[ix].height1);
- next = (fr2->fheight[ix] * v->height[ix]) << 6;
- peaks[ix].height_inc = ((next - peaks[ix].height1) * STEPSIZE) / length2;
-
- if(ix <= wvoice->n_harmonic_peaks)
- {
- peaks[ix].left1 = (fr1->fwidth[ix] * v->width[ix]) << 10;
- peaks[ix].left = int(peaks[ix].left1);
- next = (fr2->fwidth[ix] * v->width[ix]) << 10;
- peaks[ix].left_inc = ((next - peaks[ix].left1) * STEPSIZE) / length2;
-
- if(ix < 3)
- {
- peaks[ix].right1 = (fr1->fright[ix] * v->width[ix]) << 10;
- peaks[ix].right = int(peaks[ix].right1);
- next = (fr2->fright[ix] * v->width[ix]) << 10;
- peaks[ix].right_inc = ((next - peaks[ix].right1) * STEPSIZE) / length2;
- }
- else
- {
- peaks[ix].right = peaks[ix].left;
- }
- }
- }
-} // end of SetSynth
-
-
-static int Wavegen2(int length, int modulation, int resume, frame_t *fr1, frame_t *fr2)
-{//====================================================================================
- if(resume==0)
- SetSynth(length, modulation, fr1, fr2, wvoice);
-
- return(Wavegen());
-}
-
-void Write4Bytes(FILE *f, int value)
-{//=================================
-// Write 4 bytes to a file, least significant first
- int ix;
-
- for(ix=0; ix<4; ix++)
- {
- fputc(value & 0xff,f);
- value = value >> 8;
- }
-}
-
-
-
-
-int WavegenFill(int fill_zeros)
-{//============================
-// Pick up next wavegen commands from the queue
-// return: 0 output buffer has been filled
-// return: 1 input command queue is now empty
-
- long *q;
- int length;
- int result;
- static int resume=0;
- static int echo_complete=0;
-
-#ifdef TEST_MBROLA
- if(mbrola_name[0] != 0)
- return(MbrolaFill(fill_zeros));
-#endif
-
- while(out_ptr < out_end)
- {
- if(WcmdqUsed() <= 0)
- {
- if(echo_complete > 0)
- {
- // continue to play silence until echo is completed
- resume = PlaySilence(echo_complete,resume);
- if(resume == 1)
- return(0); // not yet finished
- }
-
- if(fill_zeros)
- {
- while(out_ptr < out_end)
- *out_ptr++ = 0;
- }
- return(1); // queue empty, close sound channel
- }
-
- result = 0;
- q = wcmdq[wcmdq_head];
- length = q[1];
-
- switch(q[0])
- {
- case WCMD_PITCH:
- SetPitch(length,(unsigned char *)q[2],q[3] >> 16,q[3] & 0xffff);
- break;
-
- case WCMD_PAUSE:
- if(resume==0)
- {
- echo_complete -= length;
- }
- wdata.n_mix_wavefile = 0;
- wdata.prev_was_synth = 0;
- result = PlaySilence(length,resume);
- break;
-
- case WCMD_WAVE:
- echo_complete = echo_length;
- wdata.n_mix_wavefile = 0;
- wdata.prev_was_synth = 0;
- result = PlayWave(length,resume,(unsigned char*)q[2], q[3] & 0xff, q[3] >> 8);
- break;
-
- case WCMD_WAVE2:
- // wave file to be played at the same time as synthesis
- wdata.mix_wave_amp = q[3] >> 8;
- wdata.mix_wave_scale = q[3] & 0xff;
- if(wdata.mix_wave_scale == 0)
- wdata.n_mix_wavefile = length*2;
- else
- wdata.n_mix_wavefile = length;
- wdata.mix_wavefile_ix = 0;
- wdata.mix_wavefile = (unsigned char *)q[2];
- break;
-
- case WCMD_SPECT2: // as WCMD_SPECT but stop any concurrent wave file
- wdata.n_mix_wavefile = 0; // ... and drop through to WCMD_SPECT case
- case WCMD_SPECT:
- echo_complete = echo_length;
- result = Wavegen2(length & 0xffff,q[1] >> 16,resume,(frame_t *)q[2],(frame_t *)q[3]);
- break;
-
-#ifdef INCLUDE_KLATT
- case WCMD_KLATT2: // as WCMD_SPECT but stop any concurrent wave file
- wdata.n_mix_wavefile = 0; // ... and drop through to WCMD_SPECT case
- case WCMD_KLATT:
- echo_complete = echo_length;
- result = Wavegen_Klatt2(length & 0xffff,q[1] >> 16,resume,(frame_t *)q[2],(frame_t *)q[3]);
- break;
-#endif
-
- case WCMD_MARKER:
- MarkerEvent(q[1],q[2],q[3],out_ptr);
-#ifdef LOG_FRAMES
- LogMarker(q[1],q[3]);
-#endif
- if(q[1] == 1)
- {
- current_source_index = q[2] & 0xffffff;
- }
- break;
-
- case WCMD_AMPLITUDE:
- SetAmplitude(length,(unsigned char *)q[2],q[3]);
- break;
-
- case WCMD_VOICE:
- WavegenSetVoice((voice_t *)q[1]);
- free((voice_t *)q[1]);
- break;
-
- case WCMD_EMBEDDED:
- SetEmbedded(q[1],q[2]);
- break;
- }
-
- if(result==0)
- {
- WcmdqIncHead();
- resume=0;
- }
- else
- {
- resume=1;
- }
- }
-
- return(0);
-} // end of WavegenFill
-
-