diff --git a/dictsource/hi_list b/dictsource/hi_list index 52330a0a..ab3e5b47 100755 --- a/dictsource/hi_list +++ b/dictsource/hi_list @@ -156,7 +156,7 @@ _dpt _d@s@ml'o:_ // ?? what is Hi for "." ? ऱ r@ व v@ श S@ -ष S@ // should be retroflex [S] +ष s.@ // should be retroflex [S] स s@ ह H@ क़ q@ diff --git a/dictsource/hi_rules b/dictsource/hi_rules index 81ec0dec..7c916eb7 100755 --- a/dictsource/hi_rules +++ b/dictsource/hi_rules @@ -347,9 +347,9 @@ ?1 श (_ S .group ष - ष SV //?? or retroflex [S] - ष (B S //?? -?1 ष (_ S //?? + ष s.V //?? or retroflex [S] + ष (B s. //?? +?1 ष (_ s. //?? .group स स sV diff --git a/dictsource/ru_list b/dictsource/ru_list index 00391980..8e7d8a83 100644 --- a/dictsource/ru_list +++ b/dictsource/ru_list @@ -18,7 +18,7 @@ _2 dv'A _3 t;r'i _4 ts;It'yr;I _5 p;'jat; -_6 S'Es;t; +_6 s.'Es;t; _7 s;'em _8 v'os;E2m _9 d;'ev;It; @@ -28,7 +28,7 @@ _12 dv;In'AttsVt; _13 tr;In'AttsVt; _14 ts;It'y@-*nVttsVt; _15 p;Itn'AttsVt; -_16 SE#stn'AttsVt; +_16 s.E#stn'AttsVt; _17 s;Imn'AttsVt; _18 vOs;Imn'AttsVt; _19 d;E2v;Itn'AttsVt; @@ -36,7 +36,7 @@ _2X dv'AttsVt; _3X tr;'ittsVt; _4X s'o@-*Ok _5X p;Id;d;Is;'jat -_6X SE2z;d;d;Is;'jat +_6X s.E2z;d;d;Is;'jat _7X s;'emd;E2s;It _8X v'os;E2md;E2s;It _9X d;E2v;In'ostO @@ -45,7 +45,7 @@ _2C dv;'es;t;I _3C tr;'ista _4C ts;It'yr;E2sta _5C p;,It;s'ot -_6C S,E#s;t;s'ot +_6C s.,E#s;t;s'ot _7C s;,Ims'ot _8C vOs;Ims'ot _9C d;E2v;It;s'ot @@ -82,7 +82,7 @@ _dpt2 _d;Is;'atYx // end of decimal fraction // questions -что Sto $u $pause // what, that +что s.to $u $pause // what, that // misc. diff --git a/dictsource/ru_rules b/dictsource/ru_rules index 62ce34b2..1fb01063 100755 --- a/dictsource/ru_rules +++ b/dictsource/ru_rules @@ -177,25 +177,25 @@ .group ж - _) ж (_ ZE - ж (кY S - ж (кь S - ж (пY S - ж (пь S - ж (сь S - ж (сY S - ж (ть S - ж (тY S - ж (фь S - ж (фY S - ж (ффь S - ж (ффY S - ж (хь S - ж (хY S - ж (хкY S - ж (хкь S + _) ж (_ z.E + ж (кY s. + ж (кь s. + ж (пY s. + ж (пь s. + ж (сь s. + ж (сY s. + ж (ть s. + ж (тY s. + ж (фь s. + ж (фY s. + ж (ффь s. + ж (ффY s. + ж (хь s. + ж (хY s. + ж (хкY s. + ж (хкь s. - ж Z + ж z. .group з _) з (_ zE @@ -243,8 +243,8 @@ з (сь s; з (сY s; - з (ж Z - з (ш S + з (ж z. + з (ш s. з (щ s;s; з (ч s;s; з z @@ -329,6 +329,10 @@ .group о о o + о (B oj + о (Cь oj + о (FY oj + .group п _) п (_ pE @@ -396,10 +400,10 @@ с (дY z; с (дB z; - с (ж Z - с (ш S - с (щ s;s; - с (ч s;s; + с (ж z. + с (ш s. + с (щ s; + с (ч s; с s @@ -430,7 +434,7 @@ т (ж d - т t + т t .group у _) у (_ u @@ -546,27 +550,27 @@ .group ш - _) ш (_ SA - ш (б Z - ш (бь Z - ш (бY Z - ш (бмь Z - ш (бмY Z - ш (бвь Z - ш (бвY Z - ш (г Z - ш (гь Z - ш (гY Z - ш (д Z - ш (дь Z - ш (дY Z - ш (дB Z - ш (ж Z - ш (з Z - ш (зь Z - ш (зY Z + _) ш (_ s.A + ш (б z. + ш (бь z. + ш (бY z. + ш (бмь z. + ш (бмY z. + ш (бвь z. + ш (бвY z. + ш (г z. + ш (гь z. + ш (гY z. + ш (д z. + ш (дь z. + ш (дY z. + ш (дB z. + ш (ж z. + ш (з z. + ш (зь z. + ш (зY z. - ш S + ш s. .group щ _) щ (_ S;ja diff --git a/dictsource/sv_rules b/dictsource/sv_rules index dcd3ffa3..bf9a6c8c 100755 --- a/dictsource/sv_rules +++ b/dictsource/sv_rules @@ -243,11 +243,11 @@ espeak _^_EN .group r r r r) r - rs S + rs s. rsi (o rsx' - rsk Sk + rsk s.k rsk (i rsx - rss S + rss s. rg (_ rj radera rad'e:ra diff --git a/dictsource/vi_rules b/dictsource/vi_rules index 503d5755..9fdbda1c 100644 --- a/dictsource/vi_rules +++ b/dictsource/vi_rules @@ -1,4 +1,4 @@ - + .group a a a: ai a:I @@ -387,7 +387,7 @@ qu kw .group r - r D + r z; .group s s s diff --git a/phsource/compile_report b/phsource/compile_report index 63f9ad28..d9e64da9 100644 --- a/phsource/compile_report +++ b/phsource/compile_report @@ -1,38 +1,38 @@ 33 phoneme tables new total - base 89 89 - en 52 136 - en_n 29 136 - en_us 36 136 - en_sc 39 138 - en_rp 34 136 - en_wm 30 136 - af 37 120 - cy 30 115 - de 28 112 - eo 15 101 - fi 40 120 - fr 32 113 - fr_ca 11 113 - hi 50 125 - hu 24 106 - nl 25 109 - pl 17 100 - sk 22 115 - cs 6 116 - hr 15 119 - ru 35 116 - it 28 109 - es 7 109 - pt 25 124 - pt_pt 17 124 - ro 36 133 - el 7 109 - sv 25 111 - no 29 115 - vi 41 126 - zh_yue 32 117 - sw 14 98 + base 91 91 + en 52 138 + en_n 29 138 + en_us 36 138 + en_sc 39 140 + en_rp 34 138 + en_wm 30 138 + af 37 122 + cy 30 117 + de 28 114 + eo 15 103 + fi 40 122 + fr 32 115 + fr_ca 11 115 + hi 50 127 + hu 24 108 + nl 25 111 + pl 17 102 + sk 22 117 + cs 6 118 + hr 15 121 + ru 36 119 + it 28 111 + es 7 111 + pt 25 126 + pt_pt 17 126 + ro 36 135 + el 7 111 + sv 25 113 + no 29 117 + vi 41 128 + zh_yue 32 119 + sw 14 100 3 b/b base hi ro 2 b/b_ base hi @@ -216,7 +216,9 @@ 1 ufric/sh_ base 2 ufric/sh_pzd base ro 3 ufric/sh_pzd_ base - 5 ufric/s_pzd base ro + 2 ufric/sh_rfx base + 3 ufric/s_pzd base ro + 2 ufric/s_pzd_ base 1 ufric/sx_sv sv 1 ufric/th base 1 ufric/th_ base @@ -343,8 +345,8 @@ 1 vdiph/y#y fi 2 vdiph/y#y_2 af zh_yue 1 vdiph/y#y_3 nl - 2 vnasal/aa_n en fr - 1 vnasal/aa_n3 af + 1 vnasal/aa_n en + 2 vnasal/aa_n3 af fr 2 vnasal/ee_n en fr_ca 3 vnasal/ee_n2 hi pl pt_pt 2 vnasal/e_n af pt @@ -356,7 +358,8 @@ 1 vnasal/oi_n pt 2 vnasal/o_n hi pt 1 vnasal/o_n2 af - 2 vnasal/oo_n en fr + 1 vnasal/o_n3 fr + 1 vnasal/oo_n en 2 vnasal/oo_n2 hi pl 1 vnasal/&u_n pt 1 vnasal/u_n pt @@ -375,18 +378,18 @@ 1 vocw/Q2 nl 6 vocw/v base ro 4 vocw/zh base ro - 1 vocw/zh_rfx cs + 3 vocw/zh_rfx base cs 3 voc/z base fr ro 3 voc/z_ base fr ro - 2 voc/zh base ro - 2 voc/zh_ base ro + 3 voc/zh base ro + 3 voc/zh_ base ro 1 voc/zh_2 cs 2 voc/z_pzd base 2 voc/z_pzd_ base 14 vowel/@ base en en_us en_rp cy hi hr 1 vowel/@- base 4 vowel/& en_rp fi hi sv - 5 vowel/0 en fr hi it pt + 4 vowel/0 en hi it pt 4 vowel/0_2 en_n en_wm pt_pt sw 5 vowel/0_3 en_us en_sc en_rp hu 1 vowel/@_2 fr @@ -402,7 +405,7 @@ 5 vowel/a_2 eo it pt_pt ro vi 3 vowel/a#_2 hr sv sw 5 vowel/a_3 en_sc cs - 11 vowel/a#_3 en en_n en_us en_wm de hi pt_pt vi zh_yue + 12 vowel/a#_3 en en_n en_us en_wm de hi ru pt_pt vi zh_yue 4 vowel/a_4 en_wm el vi 2 vowel/a_5 sv sw 7 vowel/aa en_us fi fr_ca no zh_yue @@ -445,13 +448,13 @@ 2 vowel/ii_4 en_rp 6 vowel/ii_en en en_n 5 vowel/@_low hi ro no - 9 vowel/o en en_wm de fr hi it pt_pt sv + 8 vowel/o en en_wm de hi it pt_pt sv 4 vowel/o_2 cy hi hu no 2 vowel/o-_2 en_n en_wm 2 vowel/o_3 en_sc 1 vowel/o-_3 en_rp - 1 vowel/o_4 en_n - 1 vowel/o_6 nl + 2 vowel/o_4 en_n fr + 2 vowel/o_6 fr nl 4 vowel/oe en af de fr 1 vowel/oe_2 no 1 vowel/oe_4 sv diff --git a/phsource/ph_french b/phsource/ph_french index 01b0c75a..d3c3405d 100644 --- a/phsource/ph_french +++ b/phsource/ph_french @@ -50,14 +50,14 @@ endphoneme phoneme o vowel starttype (o) endtype (o) length 166 - formants vowel/o + formants vowel/o_4 endphoneme phoneme O vowel starttype (o) endtype (o) length 190 - formants vowel/0 + formants vowel/o_6 endphoneme @@ -102,7 +102,7 @@ endphoneme phoneme A~ vowel starttype (a) endtype (a) length 222 - formants vnasal/aa_n + formants vnasal/aa_n3 endphoneme @@ -116,7 +116,7 @@ endphoneme phoneme O~ vowel starttype (o) endtype (o) length 222 - formants vnasal/oo_n + formants vnasal/o_n3 endphoneme @@ -188,7 +188,6 @@ phoneme R length 100 lengthmod 7 beforenotvowel r/ - trill formants vwl_fr/@R+r3/rx%80 endphoneme @@ -240,7 +239,7 @@ endphoneme phoneme z2 // silent unless followed by vowel beforenotvowel NULL vcd alv frc sibilant - vowelout f1=0 f2=1700 -300 300 f3=-100 60 len=50 + vowelout f1=0 f2=1700 -300 300 f3=-100 60 len=50 formants voc/z+ufric/s_ before _ voc/z_+ufric/s_ lengthmod 6 @@ -277,3 +276,4 @@ endphoneme + diff --git a/phsource/ph_russian b/phsource/ph_russian index 4d3c1679..4a68780c 100755 --- a/phsource/ph_russian +++ b/phsource/ph_russian @@ -278,4 +278,10 @@ phoneme a length 100 endphoneme +phoneme a# + vowel starttype (a) endtype (a) + formants vowel/a#_3 + length 100 +endphoneme + diff --git a/phsource/phonemes b/phsource/phonemes index 99e0262c..75341000 100644 --- a/phsource/phonemes +++ b/phsource/phonemes @@ -774,12 +774,23 @@ phoneme Z endphoneme +phoneme z. + vcd pla frc sibilant + vowelin f1=0 f2=1800 -100 300 f3=-300 80 + vowelout f1=2 f2=1800 -100 300 f3=-300 80 brk + formants voc/zh+vocw/zh_rfx + before _ voc/zh_+vocw/zh_rfx + lengthmod 6 + switchvoicing s. +endphoneme + + phoneme z; vcd pal frc sibilant palatal vowelin f1=2 f2=2700 400 600 f3=300 80 rate len=70 vowelout f1=2 f2=2300 250 300 f3=-300 80 brk - formants voc/z_pzd+ufric/s_pzd%40 - before _ voc/z_pzd_+ufric/s_pzd%40 + formants voc/z_pzd+ufric/s_pzd%80 + before _ voc/z_pzd_+ufric/s_pzd_%80 lengthmod 6 switchvoicing s; endphoneme @@ -994,12 +1005,24 @@ phoneme s; vowelout f1=1 f2=2700 400 600 f3=200 70 rate len=70 length 100 lengthmod 3 - wave ufric/s_pzd%50 - before _ ufric/s_pzd%50 + wave ufric/s_pzd + before _ ufric/s_pzd_ switchvoicing z; endphoneme +phoneme s. + vls pla frc sibilant + vowelin f1=0 f2=1800 -100 300 f3=-300 80 + vowelout f1=0 f2=1800 -100 300 f3=-300 80 + length 100 + lengthmod 3 + wave ufric/sh_rfx%80 + before _ ufric/sh_rfx%60 + switchvoicing z. +endphoneme + + phoneme S; vls pal frc sibilant palatal vowelin f1=1 f2=2700 400 600 f3=200 70 rate len=70 diff --git a/phsource/ufric/s_pzd.wav b/phsource/ufric/s_pzd.wav index 775aa16c..6be18370 100644 Binary files a/phsource/ufric/s_pzd.wav and b/phsource/ufric/s_pzd.wav differ diff --git a/phsource/ufric/s_pzd_.wav b/phsource/ufric/s_pzd_.wav new file mode 100644 index 00000000..2ca263d7 Binary files /dev/null and b/phsource/ufric/s_pzd_.wav differ diff --git a/phsource/ufric/sh_rfx.wav b/phsource/ufric/sh_rfx.wav new file mode 100644 index 00000000..85c70f6a Binary files /dev/null and b/phsource/ufric/sh_rfx.wav differ diff --git a/phsource/vnasal/o_n3 b/phsource/vnasal/o_n3 index 96c431e5..84446101 100644 Binary files a/phsource/vnasal/o_n3 and b/phsource/vnasal/o_n3 differ diff --git a/phsource/vnasal/oo_n b/phsource/vnasal/oo_n index e94b5b37..3b2ddc9c 100644 Binary files a/phsource/vnasal/oo_n and b/phsource/vnasal/oo_n differ diff --git a/phsource/vnasal/vowelchart.png b/phsource/vnasal/vowelchart.png index 84f36af1..9f4bb568 100644 Binary files a/phsource/vnasal/vowelchart.png and b/phsource/vnasal/vowelchart.png differ diff --git a/phsource/vowel/V b/phsource/vowel/V index de4b2e20..f902e9fc 100644 Binary files a/phsource/vowel/V and b/phsource/vowel/V differ diff --git a/phsource/vowel/V_2 b/phsource/vowel/V_2 index d637987d..e754fc83 100644 Binary files a/phsource/vowel/V_2 and b/phsource/vowel/V_2 differ diff --git a/phsource/vwl_fr/@R b/phsource/vwl_fr/@R index 02d86667..5bf76ffb 100644 Binary files a/phsource/vwl_fr/@R and b/phsource/vwl_fr/@R differ diff --git a/src/dictionary.cpp b/src/dictionary.cpp index 4263d3ce..69316c35 100755 --- a/src/dictionary.cpp +++ b/src/dictionary.cpp @@ -1098,9 +1098,9 @@ void Translator::SetWordStress(char *output, unsigned int dictionary_flags, int if((langopts.stress_flags & 0x1000) && (vowel_stress[1] == 0)) { - if((vowel_count == 3) && (vowel_stress[2] >= 4)) + // If there is only one syllable before the primary stress, give it a secondary stress + if((vowel_count > 2) && (vowel_stress[2] >= 4)) { - // 2-syllable word, put a secondary stress on the initial syllable vowel_stress[1] = 3; } } diff --git a/src/intonation.cpp b/src/intonation.cpp index d9b8d511..e0526418 100755 --- a/src/intonation.cpp +++ b/src/intonation.cpp @@ -267,7 +267,7 @@ static TONE_TABLE tone_table[N_TONE_TABLE] = { {PITCHfrise, 38,10, PITCHfrise2, 36,10, // comma, or question 20, 25, 34, 20, drops_0, 3, 3, 15, 25, 0}, - {PITCHdrop, 40, 2, PITCHdrop, 42,25, // exclamation + {PITCHdrop, 38, 1, PITCHdrop, 42,25, // exclamation 20, 25, 34, 22, drops_0, 3, 3, 12, 8, 0}, diff --git a/src/readclause.cpp b/src/readclause.cpp index ce9343d1..32010b97 100644 --- a/src/readclause.cpp +++ b/src/readclause.cpp @@ -1841,8 +1841,11 @@ void InitText2(void) ssml_sp->voice_variant = 0; ssml_sp->voice_gender = 0; ssml_sp->voice_age = 0; - strncpy0(ssml_sp->voice_name,pvoice->name,sizeof(ssml_sp->voice_name)); - strncpy0(ssml_sp->language,&pvoice->languages[1],sizeof(ssml_sp->language)); + if(pvoice != NULL) + { + strncpy0(ssml_sp->voice_name,pvoice->name,sizeof(ssml_sp->voice_name)); + strncpy0(ssml_sp->language,&pvoice->languages[1],sizeof(ssml_sp->language)); + } current_voice_id[0] = 0; n_param_stack = 1; diff --git a/src/speak_lib.cpp b/src/speak_lib.cpp index 173c822a..8b8f83d7 100644 --- a/src/speak_lib.cpp +++ b/src/speak_lib.cpp @@ -646,11 +646,13 @@ ESPEAK_API int espeak_Initialize(espeak_AUDIO_OUTPUT output_type, int buf_length buf_length = 200; outbuf_size = (buf_length * samplerate)/500; outbuf = (unsigned char*)realloc(outbuf,outbuf_size); - out_start = outbuf; + if((out_start = outbuf) == NULL) + return(EE_INTERNAL_ERROR); // allocate space for event list. Allow 500 events per minute n_event_list = (buf_length*500)/1000; - event_list = (espeak_EVENT *)realloc(event_list,sizeof(espeak_EVENT) * n_event_list); + if((event_list = (espeak_EVENT *)realloc(event_list,sizeof(espeak_EVENT) * n_event_list)) == NULL) + return(EE_INTERNAL_ERROR); option_phonemes = 0; @@ -1050,7 +1052,9 @@ ESPEAK_API espeak_ERROR espeak_Terminate(void) #endif Free(event_list); + event_list = NULL; Free(outbuf); + outbuf = NULL; FreePhData(); return EE_OK; diff --git a/src/speak_lib.h b/src/speak_lib.h index 1c20a706..c85008bd 100644 --- a/src/speak_lib.h +++ b/src/speak_lib.h @@ -145,7 +145,7 @@ int espeak_Initialize(espeak_AUDIO_OUTPUT output, int buflength, const char *pat path: The directory which contains the espeak-data directory, or NULL for the default location. - Returns: sample rate in Hz + Returns: sample rate in Hz, or -1 (EE_INTERNAL_ERROR). */ typedef int (t_espeak_callback)(short*, int, espeak_EVENT*); diff --git a/src/speak_riscos.cpp b/src/speak_riscos.cpp new file mode 100644 index 00000000..507fe513 --- /dev/null +++ b/src/speak_riscos.cpp @@ -0,0 +1,1234 @@ + +/************************************************************************** +* Copyright (C) 2005,2006 by Jonathan Duddington * +* 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 2 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. * +***************************************************************************/ + +#define USE_MODULE + +#include +#include +#include +#include +#include +#include "kernel.h" + +#include "speech.h" +#include "speak_lib.h" +#include "voice.h" +#include "phoneme.h" +#include "synthesize.h" +#include "translate.h" + +#define os_X 0x20000 + +// interface to the assembler section +extern "C" { +extern void DMA_Handler(void); + + +// used from the cmhgfile +extern _kernel_oserror *user_init(char *cmd_fail, int podule_base, void *pw); +extern _kernel_oserror *swi_handler(int swi_no, int *r, void *pw); +extern _kernel_oserror *command_handler(char *arg_string, int argc, int cmd_no, void *pw); +extern int callback_handler(_kernel_swi_regs *r, void *pw); +extern int callback_entry(_kernel_swi_regs *r, void *pw); +extern int sound_handler(_kernel_swi_regs *r, void *pw); +extern int sound_entry(_kernel_swi_regs *r, void *pw); + +} + +extern int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume); +extern void RiscosOpenSound(); +extern int WcmdqUsed(); +extern void FreePhData(); +extern void FreeDictionary(); + +extern int wcmdq_head; +extern int wcmdq_tail; +extern int current_source_index; + +FILE *f_text; +int (* uri_callback)(int, const char *, const char *) = NULL; + +int amp = 8; // default + +char path_home[80] = ""; +char wavefile[120]; +char textbuffile[L_tmpnam]; +int sample_rate_index; // current value +int current_voice_num=0; +int n_voice_files = 0; + +// output sound buffer, 2 bytes per sample +static unsigned short SoundBuf[4096]; +static void *module_data; +static int callback_inhibit = 0; +static int more_text=0; + +#define N_VOICE_NAMES 40 +static char *voice_names[40]; + +#define N_STATIC_BUF 8000 +static char static_buf[N_STATIC_BUF]; +static _kernel_oserror errblk; + + + +USHORT voice_pcnt[N_PEAKS+1][3]; +voice_t voice_data; +voice_t *voice; + +static const char *help_text = +"\nspeak [options] [\"\"]\n\n" +"-f Text file to speak\n" +"--stdin Read text input from stdin instead of a file\n\n" +"If neither -f nor --stdin, are spoken, or if none then text is\n" +"spoken from stdin, each line separately.\n\n" +"-a \n" +"\t Amplitude, 0 to 200, default is 100\n" +"-l \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 \n" +"\t Pitch adjustment, 0 to 99, default is 50\n" +"-s \n" +"\t Speed in words per minute 80 to 370, default is 170\n" +"-v \n" +"\t Use voice file of this name from espeak-data/voices\n" +"-w \n" +"\t Write output to this WAV file, rather than speaking it directly\n" +"-b\t Input text is 8-bit encoding\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" +"--stdout Write speech output to stdout\n" +"--compile=\n" +"\t Compile the pronunciation rules and dictionary in the current\n" +"\t directory. = is optional and specifies which language\n" +"--punct=\"\"\n" +"\t Speak the names of punctuation characters during speaking. If\n" +"\t = is omitted, all punctuation is spoken.\n" +"--voices=\n" +"\t List the available voices for the specified language.\n" +"\t If is omitted, then list all voices.\n"; + + +// 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 > 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 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); +} + +const int wcslen(const wchar_t *str) +{ + int ix=0; + + while(*str != 0) + { + ix++; + } + return(ix); +} + + +int GetFileLength(const char *filename) +{//==================================== + int length=0; + int type; + _kernel_swi_regs regs; + _kernel_oserror *error; + + regs.r[0] = 5; + regs.r[1] = (int)filename; + regs.r[2] = 0; + regs.r[3] = 0; + regs.r[4] = 0; + regs.r[5] = 0; + + error = _kernel_swi(0x20008,®s,®s); + if(error) + return(0); + + type = regs.r[0]; + length = regs.r[4]; + + if(type==2) + return(-2); // a directory + if((type!=1) && (type!=3)) + return(0); /* not a file */ + + return(length); +} /* end of GetFileLength */ + + + +void ReadVoiceNames2(char *directory) +{//================================== + int len; + int *type; + char *p; + _kernel_swi_regs regs; + _kernel_oserror *error; + char buf[80]; + char directory2[80]; + + regs.r[0] = 10; + regs.r[1] = (int)directory; + 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+os_X,®s,®s); /* OS_GBPB 10, read directory entries */ + if((error != NULL) || (regs.r[3] == 0)) + { + break; + } + type = (int *)(&buf[16]); + len = strlen(&buf[20]); + + if(*type == 2) + { + // a sub-directory + sprintf(directory2,"%s.%s",directory,&buf[20]); + ReadVoiceNames2(directory2); + } + else + { + p = Alloc(len+1); + strcpy(p,&buf[20]); + voice_names[n_voice_files++] = p; + if(n_voice_files >= (N_VOICE_NAMES-1)) + break; + } + } +} + + +void ReadVoiceNames() +{//=================== + char directory[80]; + + for(n_voice_files=0; n_voice_files sizeof(SoundBuf)) + size = sizeof(SoundBuf); + + out_ptr = (unsigned char *)(&SoundBuf[0]); + out_end = (unsigned char *)(&SoundBuf[size]); + WavegenFill(1); +} + + + +int initialise(void) +{//================= + sprintf(path_home,"%s.espeak-data",""); + if(GetFileLength(path_home) != -2) + { + // not found, try the 10 character version of the directory name + sprintf(path_home,"%s.espeak-dat",""); + } + if(GetFileLength(path_home) != -2) + { + // still can't find data directory + sprintf(errblk.errmess,"Speak: Can't find data directory: '%s'\n",path_home); + return(-1); + } + + WavegenInit(22050,0); + LoadPhData(); + SynthesizeInit(); + return(0); +} + + + +void speak_text_string(char *data, int terminator, int len, int wait, int voice_num) +/**********************************************************************************/ +/* 'wait' indictes wait until speaking is finished before returning */ +{ + int c; + int ix; + static static_length=0; + static int user_token=0; /* increment for each call of translate() */ + _kernel_swi_regs regs; + + regs.r[0] = (int)callback_entry; + regs.r[1] = (int)module_data; + _kernel_swi(0x5f, ®s, ®s); + + + if((voice_num >= 0) && (voice_num != current_voice_num) && (voice_num < N_VOICE_NAMES)) + { + SetVoiceByName(voice_names[voice_num]); + WavegenSetVoice(voice); + } + current_voice_num = voice_num; + + /* don't count CR as terminator if length is specified */ + if(len > 0) terminator = 0; + + ix = 0; + if(more_text == 0) + static_length = 0; + else + { + strcat(&static_buf[static_length]," : "); + static_length+=3; + } + + if(terminator == 0) + { + while(((c = data[ix++]) != 0) && (static_length < N_STATIC_BUF-4)) + { + static_buf[static_length++] = c; + if(ix == len) + break; + } + } + else + { + while(((c = data[ix++]) != '\r') && (c != '\n') && (c != 0) && (static_length < N_STATIC_BUF-3)) + { + static_buf[static_length++] = c; + if(ix == len) + break; + } + } + static_buf[static_length] = 0; + + if(option_waveout==0) + { + if(more_text == 0) + { + InitText(0); + RiscosOpenSound(); + more_text = SpeakNextClause(NULL,(void *)static_buf,0); + } + + while(wait) + { + if((more_text==0) && (wcmdq_head == wcmdq_tail)) + break; + + //we need to block to allow the callback handler to run + regs.r[0] = 129; // wait for key press + regs.r[1] = 10; + regs.r[2] = 0; + _kernel_swi(0x06, ®s, ®s); // OS_Byte + } + } + else + { + more_text = 0; + SpeakNextClause(NULL,(void *)static_buf,0); + + for(;;) + { + if(WavegenFile() != 0) + break; // finished, wavegen command queue is empty + + if(Generate(phoneme_list,&n_phoneme_list,1)==0) + SpeakNextClause(NULL,NULL,1); + } + + CloseWaveFile(samplerate); + } + +} /* end of speak_text_string */ + + + + +void speak_file(char *fname) +{//========================= + FILE *f_in; + char buf[120]; + + f_in = fopen(fname,"r"); + if(f_in == NULL) + { + fprintf(stderr,"Can't read file: '%s'",fname); + return; + } + more_text = 1; + + if(option_waveout == 0) + { + RiscosOpenSound(); + SpeakNextClause(f_in,NULL,0); + } + else + { + more_text = 0; + SpeakNextClause(f_in,NULL,0); + + for(;;) + { + if(WavegenFile() != 0) + break; // finished, wavegen command queue is empty + + if(Generate(phoneme_list,&n_phoneme_list,1)==0) + SpeakNextClause(NULL,NULL,1); + } + + CloseWaveFile(samplerate); + } +} + + + +void set_say_options(int reg2, int reg3) +/**************************************/ +/* Sets options from information in 'say' SWI */ +/* R3 bits 0-7 stress indicator character + bit 8 inhibit unpronouncable check */ +{ + option_linelength = 0; + option_phonemes = 0; + option_waveout = 0; + option_harmonic1 = 8; + option_multibyte = 0; // auto + option_capitals = 0; + option_punctuation = 0; + option_punctlist[0] = 0; +} /* end of set_say_options */ + + + +void jsd_swi_functions(int *r) +/****************************/ +{ + switch(r[0]) + { + case 0: /* major version */ + r[0] = 3; + break; + + case 1: /* register user */ + break; + + case 2: /* deregister user */ + break; + + case 3: +// r[0] = (int)speech_to_phonemes((char *)r[1]); + break; + + case 4: +// r[0] = reload_word_dict(NULL); + break; + + case 5: /* get table of voice names */ + r[0] = (int)voice_names; + break; + + case 6: /* update voice data, r1 = voice_number */ + if(r[1] < N_VOICE_NAMES) + { + SetVoiceByName(voice_names[r[1]]); + current_voice_num = r[1]; + WavegenSetVoice(voice); + } + break; + + case 7: /* load voice data */ +// init_voice((char *)r[1]); + break; + + default: + r[0] = 0; + r[1] = 0; + break; + } +} /* end of jsd_swi_functions */ + + + + +_kernel_oserror *swi_handler(int swi_no, int *r, void *pw) +/*********************************************************/ +{ + int value; + int q_length; + int speed; + int amp; + value = r[0]; + + switch(swi_no) + { + + case 0: // ready ? + // returns the index into the source text of the currently speaking word + if(current_source_index > 0) + r[1] = current_source_index-1; + else + r[1] = current_source_index; /* source index */ + r[2] = 0; /* source tag */ + r[3] = 0; /* for future expansion */ + r[4] = 0; + r[5] = 0; + + if(wcmdq_head == wcmdq_tail) + { + r[0] = -1; /* ready, or nearly */ + } + else + r[0] = 0; + break; + + case 1: /* restore old sound channel. DO NOTHING */ + break; + + case 2: /* miscellaneous functions */ + jsd_swi_functions(r); + break; + + case 3: /* speak text */ +// _kernel_irqs_on(); + set_say_options(r[2],r[3]); + speak_text_string((char *)r[0],'\r',r[1],0,r[2]); + break; + + case 4: /* speak text and wait */ +// _kernel_irqs_on(); /* enable interrupts */ + set_say_options(r[2],r[3]); + speak_text_string((char *)r[0],'\r',r[1],1,r[2]); + break; + + case 5: /* stop speaking */ + SpeakNextClause(NULL,NULL,2); + more_text = 0; + break; + + case 7: /* pitch */ + // not implemented + break; + + case 8: /* speed */ + speed = (value * 160)/140; + SetParameter(espeakRATE,speed,0); + break; + + case 9: /* word_gap */ + // not implemented + break; + + case 10: /* pitch_range */ + // not implemented + break; + + case 12: /* reset */ + // not implemented + break; + + case 13: /* volume */ + amp = (value*45)/100; + SetParameter(espeakVOLUME,amp,0); + WavegenSetVoice(voice); + break; + } + return(NULL); +} /* end of swi_handler */ + + + +void PitchAdjust(int pitch_adjustment) +{//=================================== + int ix, factor; + voice_t *voice = &voice_data; + extern unsigned char pitch_adjust_tab[100]; + + voice->pitch_base = (voice->pitch_base * pitch_adjust_tab[pitch_adjustment])/128; + + // adjust formants to give better results for a different voice pitch + factor = 256 + (25 * (pitch_adjustment - 50))/50; + for(ix=0; ix<=5; ix++) + { + voice->freq[ix] = (voice->freq2[ix] * factor)/256; + } +} // end of PitchAdjustment + + + +char *param_string(char **argp) +{//============================ + char *p; + int ix=0; + static char buf[80]; + + p = *argp; + while(*p == ' ') p++; + while(!isspace(*p)) + buf[ix++] = *p++; + buf[ix]=0; + + *argp = p; + return(buf); +} + +int param_number(char **argp) +{//========================== + int value; + char *p; + + p = *argp; + while(*p == ' ') p++; + + value = atoi(p); + while(!isspace(*p)) p++; + *argp = p; + return(value); +} + +void command_line(char *arg_string, int wait) +{//========================================== + + int option_index = 0; + int c; + int value; + int speed; + int amp; + int speaking = 0; + int flag_stdin = 0; + int flag_compile = 0; + int error; + int pitch_adjustment = 50; + char filename[80]; + char voicename[40]; + char command[80]; + char *p; + int ix; + + voicename[0] = 0; + wavefile[0] = 0; + filename[0] = 0; + option_linelength = 0; + option_phonemes = 0; + option_waveout = 0; + option_quiet = 0; + option_harmonic1 = 8; + option_multibyte = 0; // auto + option_capitals = 0; + option_punctuation = 0; + option_punctlist[0] = 0; + + f_trans = stdout; + + p = arg_string; + + for(;;) + { + while(*p==' ') p++; // skip spaces + if(*p == '\r') break; // end of line + + if(*p == '-') + { + // a command line argument + p++; + switch(*p++) + { + case 'h': + printf("\nspeak text-to-speech: %s\n%s",version_string,help_text); + return; + + case 'b': + option_multibyte = espeakCHARS_8BIT; + break; + + case 'a': + amp = param_number(&p); + SetParameter(espeakVOLUME,amp,0); + break; + + case 'f': + strncpy0(filename,param_string(&p),sizeof(filename)); + break; + + case 'k': + option_capitals = param_number(&p); + SetParameter(espeakCAPITALS,option_capitals,0); + break; + + case 'l': + option_linelength = param_number(&p); + break; + + case 'p': + pitch_adjustment = param_number(&p); + break; + + case 'q': + option_quiet = 1; + break; + + case 's': + speed = param_number(&p); + SetParameter(espeakRATE,speed,0); + break; + + case 'v': + strncpy0(voicename,param_string(&p),sizeof(voicename)); + break; + + case 'w': + option_waveout=1; + strncpy0(wavefile,param_string(&p),sizeof(wavefile)); + break; + + case 'x': + option_phonemes = 1; + break; + + case 'X': + option_phonemes = 2; + break; + + case '-': + strncpy0(command,param_string(&p),sizeof(command)); + if(memcmp(command,"compile=",8)==0) + { + CompileDictionary(NULL,&command[8],NULL,NULL); + return; + } + else + if(strcmp(command,"help")==0) + { + printf("\nspeak text-to-speech: %s\n%s",version,help_text); + return; + } + else + if(memcmp(command,"punct",5)==0) + { + option_punctuation = 1; + if((command[5]=='=') && (command[6]=='"')) + { + ix = 0; + while((ix < N_PUNCTLIST) && ((option_punctlist[ix] = command[ix+7]) != 0)) ix++; + option_punctlist[N_PUNCTLIST-1] = 0; + option_punctuation = 2; + } + SetParameter(espeakPUNCTUATION,option_punctuation,0); + } + else + { + printf("Command not recognised\n"); + } + break; + + default: + printf("Command not recognised\n"); + break; + } + + } + else + { + break; + } + } + + SetVoiceByName(voicename); + + if((filename[0]==0) && (p[0]=='\r')) + { + // nothing to speak + if(option_quiet) + { + SpeakNextClause(NULL,NULL,2); // stop speaking + more_text = 0; + } + } + + if(option_waveout || option_quiet) + { + // write speech to a WAV file + if(option_quiet) + { + OpenWaveFile(NULL,samplerate); + option_waveout = 2; + } + else + { + if(OpenWaveFile(wavefile,samplerate) != 0) + { + fprintf(stderr,"Can't write to output file '%s'\n'",wavefile); + return; + } + } + } + + if(pitch_adjustment != 50) + { + PitchAdjust(pitch_adjustment); + } + WavegenSetVoice(voice); + + if(filename[0]==0) + speak_text_string(p,'\r',0,wait,-1); + else + speak_file(filename); +} + + + +_kernel_oserror *command_handler(char *arg_string, int argc, int cmd_no, void *pw) +/********************************************************************************/ +{ + switch(cmd_no) + { + case 0: /* Say */ + command_line(arg_string,0); // for compatibility with speak V2 + break; + + case 1: /* Sayw ] */ + command_line(arg_string,0); + break; + + } + return(NULL); +} /* end of cmd_handler */ + + +// sound handler data +int current_sound_handler=0; +int prev_sound_handler=0; +int prev_sound_data=0; +int prev_sound_rate=13; +int sound_handler_changed=0; + + +void RiscosCloseSound() +{//==================== +_kernel_swi_regs regs; + if((sound_handler_changed) && (prev_sound_handler != (int)DMA_Handler)) + { + // check whether current handler is ours + regs.r[0]=0; + _kernel_swi(0x40145,®s,®s); + if(regs.r[1] == (int)DMA_Handler) + { + regs.r[0]=1; + regs.r[1]=prev_sound_handler; + regs.r[2]=prev_sound_data; + _kernel_swi(0x40145,®s,®s); // Sound LinearHandler 1 + + // reset to the previous sample rate + regs.r[0]=3; + regs.r[1]=prev_sound_rate; + _kernel_swi(0x40146,®s,®s); // Sound_SampleRate 3 + + current_sound_handler = prev_sound_handler; + sound_handler_changed = 0; + } + } +} // end of RiscosCloseSound + + + +void RiscosOpenSound() +{//=================== + _kernel_swi_regs regs; + + if(current_sound_handler != (int)DMA_Handler) + { + // register the sound handler + regs.r[0]=1; + regs.r[1]=(int)DMA_Handler; + regs.r[2]=(int)module_data; + _kernel_swi(0x40145,®s,®s); // Sound_LinearHandler 1 + prev_sound_handler = regs.r[1]; + prev_sound_data = regs.r[2]; + + // set the sample rate + regs.r[0]=3; + regs.r[1]=sample_rate_index; + regs.r[2]=0; + _kernel_swi(0x40146,®s,®s); // Sound_SampleRate + prev_sound_rate = regs.r[1]; + + current_sound_handler = (int)DMA_Handler; + sound_handler_changed = 1; + } +} // end of RiscosOpenSound + + + + + +int callback_handler(_kernel_swi_regs *r, void *pw) +/*************************************************/ +{ + if(Generate(phoneme_list,&n_phoneme_list,1)==0) + { + more_text = SpeakNextClause(NULL,NULL,1); + } + + if((WcmdqUsed() == 0) && (more_text == 0)) + { + RiscosCloseSound(); + } + callback_inhibit = 0; + + return(1); +} /* end of callback_handler */ + + + +int sound_handler(_kernel_swi_regs *r, void *pw) +/**********************************************/ +{ + int n_queue; + int size; + int *dma_buf; + int x; + int ix; + + module_data = (int *)pw; + dma_buf = (int *)r->r[1]; + size = (r->r[2] - r->r[1])/4; + FillSoundBuf(size); + + for(ix=0; ixr[0] = 0; + if(callback_inhibit == 0) + { + // set a callback either: + // - queue is low and there is more text to be processed + // - queue is empty and no more text, so callback handler will remove the sound handler + if(((n_queue < 20) && (more_text != 0)) || + ((n_queue==0) && (more_text == 0))) + { + callback_inhibit = 1; + r->r[0] = 1; + r->r[1] = (int)pw; + } + } + return(1); +} + + + + +int InitSound16(int sample_rate) +/******************************/ +/* Find sample rate index */ +{ + int current_rate_index; // current value + + int sound_mode; + int sound_config; + int srate; + int n_srix; + int ix; + _kernel_swi_regs regs; + _kernel_oserror *error; + + sound_mode = 0; + regs.r[0] = 0; + error = _kernel_swi(0x40144+os_X,®s,®s); + sound_mode = regs.r[0]; + sound_config = regs.r[1]; + + if((error == NULL) && (sound_mode == 1)) + { + /* 16 bit sound, find sample rate index */ + regs.r[0] = 0; + regs.r[1] = 0; + _kernel_swi(0x40146,®s,®s); + n_srix = regs.r[1]; + + regs.r[0] = 1; + regs.r[1] = 0; + _kernel_swi(0x40146,®s,®s); + current_rate_index = regs.r[1]; // current sample rate index + srate = regs.r[2]; + for(ix=1; ix<=n_srix; ix++) + { + regs.r[0] = 2; + regs.r[1] = ix; + _kernel_swi(0x40146,®s,®s); + srate = regs.r[2]; + if(srate >= (sample_rate*1024)) + { + return(ix); + } + } + } + return(14); // this was the index for 22050 +} // end of InitSound16 + + + +void RemoveCallback() +/*******************/ +{ + _kernel_swi_regs regs; + + regs.r[0] = (int)callback_entry; + regs.r[1] = (int)module_data; + _kernel_swi(0x5f, ®s, ®s); +} + + +void terminate_module(void) +/*************************/ +{ + RiscosCloseSound(); + RemoveCallback(); + delete translator; + FreePhData(); +} /* end of terminate_module */ + + +void kill_module(void) +/********************/ +{ + _kernel_swi_regs regs; + regs.r[0]=4; + regs.r[1]=(int)"Speak"; + _kernel_swi(0x1e,®s,®s); /* RMKill */ +} + + +_kernel_oserror *user_init(char *cmd_fail, int podule_base, void *pw) +/*******************************************************************/ +{ + _kernel_swi_regs regs; + _kernel_oserror *error; + 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. + + static char *locale = "ISO8859-1"; + setlocale(LC_CTYPE,locale); + + module_data = pw; + + sample_rate_index = InitSound16(22050); + + if(initialise() < 0) + { + // exit module, errblk.errmess is set by initialise() + errblk.errnum = 0x101; + return(&errblk); + } + + ReadVoiceNames(); + SetVoiceByName("default"); + + for(param=0; paramlangopts.stress_rule = 3; // stress on final syllable - tr->langopts.stress_flags = 0x20; // don't use secondary stress + 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; diff --git a/src/translate.h b/src/translate.h index c49114e2..0ceca9be 100755 --- a/src/translate.h +++ b/src/translate.h @@ -254,7 +254,7 @@ typedef struct { // 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 2-syllable words, give the first syllable a secondary stress +// bit12= If there is only one syllable before the primary stress, give it a secondary stress int stress_flags; int unstressed_wd1; // stress for $u word of 1 syllable diff --git a/src/voices.cpp b/src/voices.cpp index 82afd18f..aaf413eb 100755 --- a/src/voices.cpp +++ b/src/voices.cpp @@ -47,6 +47,9 @@ MNEM_TAB genders [] = { {"female", 2}, {NULL, 0 }}; +//int tone_points[10] = {250,140, 1200,110, -1,0, -1,0, -1,0}; +int tone_points[10] = {600,180, 1200,140, 2000,110, 3000,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] = {50, 100, 165, 200, 200, 200, 200, 200, 200}; // values for 22kHz sample rate @@ -155,7 +158,6 @@ const char variants_female[N_VOICE_VARIANTS] = {11,12,13,14,0}; const char *variant_lists[3] = {variants_either, variants_male, variants_female}; -int tone_points[10] = {250,140, 1200,110, -1,0, -1,0, -1,0}; void SetToneAdjust(voice_t *voice, int *tone_pts) {//============================================== @@ -544,11 +546,6 @@ voice_t *LoadVoice(char *vname, int control) } f_voice = fopen(buf,"r"); - if(first_voice == NULL) - { - first_voice = ReadVoiceFile(f_voice,buf+len_path_voices,voicename); - rewind(f_voice); - } language_type = "en"; // default if(f_voice == NULL) @@ -560,6 +557,13 @@ voice_t *LoadVoice(char *vname, int control) language_type = voicename; } + if(first_voice == NULL) + { + first_voice = ReadVoiceFile(f_voice,buf+strlen(path_voices),voicename); + rewind(f_voice); + } + + if(!tone_only && (translator != NULL)) { delete translator;