Browse Source

[1.27.04] tr_languages: replace_char substitution can do 2->1 and 1->2 characters.

espeakedit: set and save path for master phonemes file.
espeakedit: added delete_phoneme and import_phoneme actions in phoneme files.
espeakedit: improve data in log_espeakedit, include phoneme names.
espeakedit: only write to log_espeakedit for speak from text window, not when playing vowel files.


git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@59 d46cf337-b52f-0410-862d-fd96e6ae7743
master
jonsd 18 years ago
parent
commit
1a28202d00

+ 10
- 12
dictsource/dict_phonemes View File



- : ; b c d dZ f - : ; b c d dZ f
g h j k l m n N g h j k l m n N
p r r- s S t tS v
w x2 z Z
p r r- s S t tS ts
v w x2 z Z




Dictionary cs_dict Dictionary cs_dict


* : b d f g h j * : b d f g h j
k l m n N p r s k l m n N p r s
S s2 t v Z
S s2 t ts v Z




Dictionary fr_dict Dictionary fr_dict
: ; b c d dZ f g : ; b c d dZ f g
h j k l L m n N h j k l L m n N
n^ p R s S t t2 tS n^ p R s S t t2 tS
v w z Z z2
ts v w z Z z2




Dictionary hi_dict Dictionary hi_dict
Dictionary hr_dict Dictionary hr_dict


& @ @- @2 a A a: aI & @ @- @2 a A a: aI
aU E e e: E~ i I i:
l- o o: oU r- u U u:
y
aU E e e: i I i: l-
o o: oU r- u U u: y


* b d dZ dZ; f g h * b d dZ dZ; f g h
j k l l^ m n N n^ j k l l^ m n N n^
* : ; b C d f g * : ; b C d f g
h j k l m n N n^ h j k l m n N n^
p Q r s S s; t tS p Q r s S s; t tS
v v2 w x z
ts v v2 w x z




Dictionary no_dict Dictionary no_dict
f g h j J k l l# f g h j J k l l#
m m# n N n# N# n^ n^# m m# n N n# N# n^ n^#
p Q r R r# R2 s S p Q r R r# R2 s S
t T tl# v x z
t T tl# ts v x z




Dictionary la_dict Dictionary la_dict
Dictionary sr_dict Dictionary sr_dict


& @ @- @2 a A a: aI & @ @- @2 a A a: aI
aU E e e: E~ i I i:
l- o o: oU r- u U u:
y
aU E e e: i I i: l-
o o: oU r- u U u: y


* b d dZ dZ; f g h * b d dZ dZ; f g h
j k l l^ m n N n^ j k l l^ m n N n^

+ 4
- 1
dictsource/en_rules View File

// * GNU General Public License for more details. * // * GNU General Public License for more details. *
// * * // * *
// * You should have received a copy of the GNU General Public License * // * You should have received a copy of the GNU General Public License *
// * along with this program; if not, write see: *
// * along with this program; if not, see: *
// * <http://www.gnu.org/licenses/>. * // * <http://www.gnu.org/licenses/>. *
// ***************************************************************************/ // ***************************************************************************/


.group a .group a
_) a (_ a2 _) a (_ a2
_) a (- 'eI _) a (- 'eI
_) a (-half a2
_) a (_D ,eI _) a (_D ,eI
_) a's (_ eIz _) a's (_ eIz
D_) a (_ eI D_) a (_ eI
&b) a (_ =@ &b) a (_ =@
grandC) a (_ A: grandC) a (_ A:
aa A: aa A:
aa (a a:
aa) aa a:
aar 'A@ aar 'A@
a (Bo_ 'A: a (Bo_ 'A:
_C) a (ble eI _C) a (ble eI

+ 7
- 0
dictsource/hu_list View File

volna $u // would volna $u // would
részén $u //on ... part of részén $u //on ... part of


nélkül $u // without
folytán $u // because of
úgy $u // like that
így $u // like this
egyaránt $u // alike
minden $u // all
részben $u // partly




// word pairs // word pairs

+ 2
- 1
dictsource/hu_rules View File



.group a .group a
a A a A

_) a (_ %A _) a (_ %A


!_n) ato a:to: // NATO

.group á .group á
á a: á a:



+ 3
- 3
dictsource/ru_list View File

_7C s;,Ims'ot _7C s;,Ims'ot
_8C vOs;Ims'ot _8C vOs;Ims'ot
_9C dev;Vn'ostO _9C dev;Vn'ostO
_1M1 t'ys;Its;V // no '1' before thousand
_1MA1 t'ys;Its;V // no '1' before thousand
_0MA1 t'ys;Its;i _0MA1 t'ys;Its;i
_0M1 t'ys;Vts; _0M1 t'ys;Vts;
_1M2 m;,IlI;'on
_1MA2 m;,IlI;'on
_0MA2 m;,IlI;'ona _0MA2 m;,IlI;'ona
_0M2 m;,IlI;'onof _0M2 m;,IlI;'onof
_1M3 m;,IlI;'art
_1MA3 m;,IlI;'art
_0MA3 m;,IlI;'arda _0MA3 m;,IlI;'arda
_0M3 m;,IlI;'artof _0M3 m;,IlI;'artof
_dpt _:'i_: // start of decimal fraction _dpt _:'i_: // start of decimal fraction

+ 3
- 4
dictsource/ru_rules View File



.group р .group р
_) р (_ E* _) р (_ E*
р (_ r;
р (Y r;
р (B r;
р @-*
р (Y R;
р (B R;
р R


.group с .group с
_) с (_ Es _) с (_ Es

+ 24
- 24
phsource/compile_report View File

38 phoneme tables 38 phoneme tables
new total new total
base 96 96
base 97 97
base2 23 114 base2 23 114
en 53 144
en_n 29 144
en_us 37 144
en_sc 39 146
en_rp 34 144
en_wm 30 144
af 38 128
cy 29 122
de 32 123
eo 13 108
fi 40 127
fr 33 118
fr_ca 11 118
hi 49 131
en 54 145
en_n 29 145
en_us 37 145
en_sc 39 147
en_rp 34 145
en_wm 30 145
af 38 129
cy 29 123
de 31 123
eo 12 108
fi 40 128
fr 33 119
fr_ca 11 119
hi 49 132
hu 22 112 hu 22 112
nl 26 117
nl 26 118
pl 15 107 pl 15 107
sk 29 125 sk 29 125
cs 5 125 cs 5 125
sr 2 129 sr 2 129
ru 36 124 ru 36 124
it 17 117 it 17 117
la 21 114
la 21 115
es 6 114 es 6 114
pt 28 131 pt 28 131
pt_pt 20 131 pt_pt 20 131
ro 36 138 ro 36 138
el 8 114 el 8 114
sv 25 118
no 28 122
is 32 121
vi 41 133
zhy 32 124
sw 14 105
sv 25 119
no 28 123
is 32 122
vi 41 134
zhy 32 125
sw 14 106


3 b/b base hi ro 3 b/b base hi ro
2 b/b_ base hi 2 b/b_ base hi
2 ustop/t_hi hi 2 ustop/t_hi hi
4 ustop/t_pzd pl ru 4 ustop/t_pzd pl ru
7 ustop/tr base en hi ru 7 ustop/tr base en hi ru
8 ustop/ts base2 de eo hu pl ru ro zhy
7 ustop/ts base base2 hu pl ru ro zhy
2 ustop/tsh base zhy 2 ustop/tsh base zhy
2 ustop/tsh_ base zhy 2 ustop/tsh_ base zhy
3 ustop/t_short hi sk el 3 ustop/t_short hi sk el

+ 1
- 0
phsource/ph_macedonian View File

// Initially empty

+ 5
- 5
phsource/ph_russian View File



phoneme i phoneme i
vowel starttype (i) endtype (i) vowel starttype (i) endtype (i)
length 130
length 100
formants vwl_ru/i formants vwl_ru/i
endphoneme endphoneme




phoneme y phoneme y
vowel starttype (i) endtype (i) vowel starttype (i) endtype (i)
length 130
length 100
formants vwl_ru/i# formants vwl_ru/i#
endphoneme endphoneme




phoneme A phoneme A
vowel starttype (a) endtype (a) vowel starttype (a) endtype (a)
length 150
length 100
formants vwl_ru/a formants vwl_ru/a
endphoneme endphoneme




phoneme u phoneme u
vowel starttype (u) endtype (u) vowel starttype (u) endtype (u)
length 150
length 80
formants vwl_ru/u formants vwl_ru/u
endphoneme endphoneme




phoneme e phoneme e
vowel starttype (e) endtype (e) vowel starttype (e) endtype (e)
length 190
length 100
formants vwl_ru/ee formants vwl_ru/ee
endphoneme endphoneme



BIN
phsource/voc/v View File


+ 66
- 9
src/compiledata.cpp View File

* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write see: *
* along with this program; if not, see: *
* <http://www.gnu.org/licenses/>. * * <http://www.gnu.org/licenses/>. *
***************************************************************************/ ***************************************************************************/


#define tSWITCHVOICING 21 #define tSWITCHVOICING 21
#define tVOWELIN 22 #define tVOWELIN 22
#define tVOWELOUT 23 #define tVOWELOUT 23
#define tAPPENDPH 24
#define tAPPENDPH 24 // always insert another phoneme (linkout) after this one
#define tIMPORTPH 25


#define tPHONEMENUMBER 29 #define tPHONEMENUMBER 29
#define tPHONEMETABLE 30 #define tPHONEMETABLE 30
void AddSpectList(int *list, int control); void AddSpectList(int *list, int control);
void AddEnvelope(int *list); void AddEnvelope(int *list);
void VowelTransition(int which, unsigned int *trans); void VowelTransition(int which, unsigned int *trans);
void ImportPhoneme(void);




FILE *f_in; FILE *f_in;
{"fricative", 0x1000000+phFRICATIVE}, {"fricative", 0x1000000+phFRICATIVE},
{"vstop", 0x1000000+phVSTOP}, {"vstop", 0x1000000+phVSTOP},
{"vfricative",0x1000000+phVFRICATIVE}, {"vfricative",0x1000000+phVFRICATIVE},
{"delete_phoneme", 0x1000000+phDELETED},


// type of consonant // type of consonant
{"stop", 0x1000000+phSTOP}, {"stop", 0x1000000+phSTOP},
{"vowelin",22}, {"vowelin",22},
{"vowelout",23}, {"vowelout",23},
{"appendph",24}, {"appendph",24},
{"import_phoneme",25},


// flags // flags
{"wavef", 0x2000000+phWAVE}, {"wavef", 0x2000000+phWAVE},
} // end of VowelTransition } // end of VowelTransition




void Compile::ImportPhoneme(void)
{//==============================
int ix;
unsigned int mnem;
unsigned int ph_mnem;
unsigned int ph_code;
PHONEME_TAB_LIST *phtab = NULL;

NextItem(tSTRING);
mnem = StringToWord(item_string);

NextItem(tSTRING);
for(ix=0; ix<n_phoneme_tabs; ix++)
{
if(strcmp(phoneme_tab_list2[ix].name,item_string) == 0)
{
phtab = &phoneme_tab_list2[ix];
break;
}
}
if(phtab == NULL)
{
Error("Unknown phoneme table",item_string);
return; // phoneme table not found
}

for(ix=1; ix<256; ix++)
{
if(mnem == phtab->phoneme_tab_ptr[ix].mnemonic)
{
ph_mnem = ph->mnemonic;
ph_code = ph->code;
memcpy(ph,&phtab->phoneme_tab_ptr[ix],sizeof(PHONEME_TAB));
ph->mnemonic = ph_mnem;
ph->code = ph_code;
break;
}
}
if(ix == 256)
{
Error("Import phoneme not found",WordToString(mnem));
}
}


int Compile::CPhoneme() int Compile::CPhoneme()
{//==================== {//====================
VowelTransition(2,vowel_out); VowelTransition(2,vowel_out);
break; break;


case tIMPORTPH:
ImportPhoneme();
break;

default: default:
Error("Syntax error",item_string); Error("Syntax error",item_string);
break; break;


ph->std_length |= 0x8000; // 'locally declared' indicator ph->std_length |= 0x8000; // 'locally declared' indicator


if(ph->type == phDELETED)
{
ph->mnemonic = 0x01; // will not be recognised
}

return(phindex); return(phindex);
} // end of Compile::CPhoneme } // end of Compile::CPhoneme


f_errors = stderr; f_errors = stderr;


strncpy0(current_fname,source,sizeof(current_fname)); strncpy0(current_fname,source,sizeof(current_fname));
sprintf(fname,"%s%s",path_source,source);

strncpy0(fname,path_phfile.mb_str(wxConvLocal),sizeof(fname));
f_in = fopen_log(f_errors,fname,"rb"); f_in = fopen_log(f_errors,fname,"rb");
if(f_in == NULL) if(f_in == NULL)
{ {
if(gui_flag) if(gui_flag)
{ {
wxString dir = wxDirSelector(_T("Directory for 'phonemes' file"),path_phsource);
if(!dir.IsEmpty())
wxString phfile = wxFileSelector(_T("Master phonemes file"),path_phsource,
_T(""),_T(""),_T("*"),wxOPEN);

if(!phfile.IsEmpty())
{ {
path_phsource = dir;
strncpy0(path_source,path_phsource.mb_str(wxConvLocal),sizeof(path_source)-1);
strcat(path_source,"/");
path_phfile = phfile;
} }
} }


sprintf(fname,"%s%s",path_source,source);
strncpy0(fname,path_phfile.mb_str(wxConvLocal),sizeof(fname));
f_in = fopen_log(f_errors,fname,"rb"); f_in = fopen_log(f_errors,fname,"rb");
if(f_in == NULL) if(f_in == NULL)
{ {

+ 12
- 2
src/espeakedit.cpp View File

* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write see: *
* along with this program; if not, see: *
* <http://www.gnu.org/licenses/>. * * <http://www.gnu.org/licenses/>. *
***************************************************************************/ ***************************************************************************/


EVT_MENU(MENU_SPECTRUM2, MyFrame::OnNewWindow) EVT_MENU(MENU_SPECTRUM2, MyFrame::OnNewWindow)
EVT_MENU(MENU_PROSODY, MyFrame::OnProsody) EVT_MENU(MENU_PROSODY, MyFrame::OnProsody)
EVT_MENU(MENU_PARAMS, MyFrame::OnOptions) EVT_MENU(MENU_PARAMS, MyFrame::OnOptions)
EVT_MENU(MENU_PATH0, MyFrame::OnOptions)
EVT_MENU(MENU_PATH1, MyFrame::OnOptions) EVT_MENU(MENU_PATH1, MyFrame::OnOptions)
EVT_MENU(MENU_PATH2, MyFrame::OnOptions) EVT_MENU(MENU_PATH2, MyFrame::OnOptions)
EVT_MENU(MENU_PATH3, MyFrame::OnOptions) EVT_MENU(MENU_PATH3, MyFrame::OnOptions)
} }
break; break;


case MENU_PATH0:
string = wxFileSelector(_T("Master phonemes file"),wxFileName(path_phfile).GetPath(),
_T(""),_T(""),_T("*"),wxOPEN);
if(!string.IsEmpty())
{
path_phfile = string;
}
break;

case MENU_PATH1: case MENU_PATH1:
string = wxDirSelector(_T("Phoneme source directory"),path_phsource); string = wxDirSelector(_T("Phoneme source directory"),path_phsource);
if(!string.IsEmpty()) if(!string.IsEmpty())


case MENU_PATH4: case MENU_PATH4:
string = wxFileSelector(_T("Voice file to modify formant peaks"),wxFileName(path_speech).GetPath(), string = wxFileSelector(_T("Voice file to modify formant peaks"),wxFileName(path_speech).GetPath(),
_T(""),_T("WAV"),_T("*"),wxSAVE);
_T(""),_T(""),_T("*"),wxOPEN);
if(!string.IsEmpty()) if(!string.IsEmpty())
{ {
path_modifiervoice = string; path_modifiervoice = string;

+ 1
- 0
src/main.h View File

MENU_OPTIONS, MENU_OPTIONS,
MENU_PARAMS, MENU_PARAMS,
MENU_PATHS, MENU_PATHS,
MENU_PATH0,
MENU_PATH1, MENU_PATH1,
MENU_PATH2, MENU_PATH2,
MENU_PATH3, MENU_PATH3,

+ 3
- 2
src/menus.cpp View File

* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write see: *
* along with this program; if not, see: *
* <http://www.gnu.org/licenses/>. * * <http://www.gnu.org/licenses/>. *
***************************************************************************/ ***************************************************************************/


// OPTIONS MENU // OPTIONS MENU
paths_menu = new wxMenu; paths_menu = new wxMenu;
paths_menu->Append(MENU_PATH0, _("Master phonemes file"));
paths_menu->Append(MENU_PATH1, _("Phoneme data source")); paths_menu->Append(MENU_PATH1, _("Phoneme data source"));
paths_menu->Append(MENU_PATH2, _("Dictionary data source")); paths_menu->Append(MENU_PATH2, _("Dictionary data source"));
paths_menu->Append(MENU_PATH3, _("Synthesized sound WAV file")); paths_menu->Append(MENU_PATH3, _("Synthesized sound WAV file"));
speak_menu->AppendSeparator();
paths_menu->AppendSeparator();
paths_menu->Append(MENU_PATH4, _("Voice file to modify formant peaks")); paths_menu->Append(MENU_PATH4, _("Voice file to modify formant peaks"));


option_menu = new wxMenu; option_menu = new wxMenu;

+ 18
- 9
src/numbers.cpp View File

* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write see: *
* along with this program; if not, see: *
* <http://www.gnu.org/licenses/>. * * <http://www.gnu.org/licenses/>. *
***************************************************************************/ ***************************************************************************/


{//============================== {//==============================
// returns M, or perhaps MA for some cases // returns M, or perhaps MA for some cases
// for Polish language - two forms of plural!
if ((translator->langopts.numbers & 0x80000) &&
((value % 10)>=2) &&
((value % 10)<=4) &&
((value % 100)>20 || (value % 100)<10))
if(((value % 100)>20) || ((value % 100)<10)) // but not teens, 10 to 19
{ {
return("MA");
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("M"); return("M");
} }
Lookup("_0of",ph_of); Lookup("_0of",ph_of);
} }


sprintf(string,"_0%s%d",M_Variant(value),thousandplex);
sprintf(string,"_%s%d",M_Variant(value),thousandplex);


if(Lookup(string,ph_thousands) == 0) if(Lookup(string,ph_thousands) == 0)
{ {
else else
if((thousandplex > 1) && prev_thousands && (prev_value > 0)) if((thousandplex > 1) && prev_thousands && (prev_value > 0))
{ {
sprintf(string,"_0%s%d",M_Variant(value),thousandplex+1);
sprintf(string,"_%s%d",M_Variant(value),thousandplex+1);
if(Lookup(string,buf1)==0) if(Lookup(string,buf1)==0)
{ {
// speak this thousandplex if there was no word for the previous thousandplex // speak this thousandplex if there was no word for the previous thousandplex

+ 4
- 1
src/options.cpp View File

* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write see: *
* along with this program; if not, see: *
* <http://www.gnu.org/licenses/>. * * <http://www.gnu.org/licenses/>. *
***************************************************************************/ ***************************************************************************/


wxString path_pitches; wxString path_pitches;
wxString path_wave; wxString path_wave;
wxString path_speech; wxString path_speech;
wxString path_phfile;
wxString path_phsource; wxString path_phsource;
wxString path_dictsource; wxString path_dictsource;
wxString path_speaktext; wxString path_speaktext;
pConfig->Read(_T("/voicename"),&string,wxEmptyString); pConfig->Read(_T("/voicename"),&string,wxEmptyString);
strcpy(voice_name,string.mb_str(wxConvLocal)); strcpy(voice_name,string.mb_str(wxConvLocal));
pConfig->Read(_T("/phsource"),&path_phsource,basedir+_T("/phsource")); pConfig->Read(_T("/phsource"),&path_phsource,basedir+_T("/phsource"));
pConfig->Read(_T("/phfile"),&path_phfile,path_phsource+_T("/phonemes"));
pConfig->Read(_T("/dictsource"),&path_dictsource,basedir+_T("/dictsource")); pConfig->Read(_T("/dictsource"),&path_dictsource,basedir+_T("/dictsource"));
pConfig->Read(_T("/speaktext"),&path_speaktext,wxEmptyString); pConfig->Read(_T("/speaktext"),&path_speaktext,wxEmptyString);
pConfig->Read(_T("/modifiervoice"),&path_modifiervoice,basedir); pConfig->Read(_T("/modifiervoice"),&path_modifiervoice,basedir);
pConfig->Write(_T("/speechpath"),path_speech); pConfig->Write(_T("/speechpath"),path_speech);
pConfig->Write(_T("/voicename"),wxString(voice_name,wxConvLocal)); pConfig->Write(_T("/voicename"),wxString(voice_name,wxConvLocal));
pConfig->Write(_T("/phsource"),path_phsource); pConfig->Write(_T("/phsource"),path_phsource);
pConfig->Write(_T("/phfile"),path_phfile);
pConfig->Write(_T("/dictsource"),path_dictsource); pConfig->Write(_T("/dictsource"),path_dictsource);
pConfig->Write(_T("/speaktext"),path_speaktext); pConfig->Write(_T("/speaktext"),path_speaktext);
pConfig->Write(_T("/speed"),option_speed); pConfig->Write(_T("/speed"),option_speed);

+ 2
- 1
src/options.h View File

* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write see: *
* along with this program; if not, see: *
* <http://www.gnu.org/licenses/>. * * <http://www.gnu.org/licenses/>. *
***************************************************************************/ ***************************************************************************/


extern wxString path_spectload; extern wxString path_spectload;
extern wxString path_spectload2; extern wxString path_spectload2;
extern wxString path_pitches; extern wxString path_pitches;
extern wxString path_phfile;
extern wxString path_phsource; extern wxString path_phsource;
extern wxString path_dictsource; extern wxString path_dictsource;
extern wxString path_modifiervoice; extern wxString path_modifiervoice;

+ 2
- 1
src/phoneme.h View File

* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write see: *
* along with this program; if not, see: *
* <http://www.gnu.org/licenses/>. * * <http://www.gnu.org/licenses/>. *
***************************************************************************/ ***************************************************************************/


#define phVFRICATIVE 7 #define phVFRICATIVE 7
#define phNASAL 8 #define phNASAL 8
#define phVIRTUAL 9 #define phVIRTUAL 9
#define phDELETED 14
#define phINVALID 15 #define phINVALID 15





+ 8
- 1
src/phonemelist.cpp View File

* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write see: *
* along with this program; if not, see: *
* <http://www.gnu.org/licenses/>. * * <http://www.gnu.org/licenses/>. *
***************************************************************************/ ***************************************************************************/




if(alternative > 1) if(alternative > 1)
{ {
PHONEME_TAB *ph2;
ph2 = ph;
ph = phoneme_tab[alternative]; ph = phoneme_tab[alternative];

if(ph->type == phVOWEL) if(ph->type == phVOWEL)
{
plist2->synthflags |= SFLAG_SYLLABLE; plist2->synthflags |= SFLAG_SYLLABLE;
if(ph2->type != phVOWEL)
plist2->stress = 0; // change from non-vowel to vowel, make sure it's unstressed
}
else else
plist2->synthflags &= ~SFLAG_SYLLABLE; plist2->synthflags &= ~SFLAG_SYLLABLE;
} }

+ 1
- 1
src/speak_lib.h View File

* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write see: *
* along with this program; if not, see: *
* <http://www.gnu.org/licenses/>. * * <http://www.gnu.org/licenses/>. *
***************************************************************************/ ***************************************************************************/



+ 2
- 2
src/synthdata.cpp View File

* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write see: *
* along with this program; if not, see: *
* <http://www.gnu.org/licenses/>. * * <http://www.gnu.org/licenses/>. *
***************************************************************************/ ***************************************************************************/


#include "translate.h" #include "translate.h"
#include "wave.h" #include "wave.h"


const char *version_string = "1.27.03 03.Jul.07";
const char *version_string = "1.27.04 04.Jul.07";
const int version_phdata = 0x012701; const int version_phdata = 0x012701;


int option_device_number = -1; int option_device_number = -1;

+ 1
- 1
src/synthesize.cpp View File

* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write see: *
* along with this program; if not, see: *
* <http://www.gnu.org/licenses/>. * * <http://www.gnu.org/licenses/>. *
***************************************************************************/ ***************************************************************************/



+ 1
- 0
src/synthesize.h View File

extern int event_list_ix; extern int event_list_ix;
extern espeak_EVENT *event_list; extern espeak_EVENT *event_list;
extern t_espeak_callback* synth_callback; extern t_espeak_callback* synth_callback;
extern int option_log_frames;


#define N_SOUNDICON_TAB 100 #define N_SOUNDICON_TAB 100
extern int n_soundicon_tab; extern int n_soundicon_tab;

+ 37
- 31
src/tr_languages.cpp View File

* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write see: *
* along with this program; if not, see: *
* <http://www.gnu.org/licenses/>. * * <http://www.gnu.org/licenses/>. *
***************************************************************************/ ***************************************************************************/


#define OFFSET_CYRILLIC 0x420 #define OFFSET_CYRILLIC 0x420
#define OFFSET_DEVANAGARI 0x900 #define OFFSET_DEVANAGARI 0x900



static const unsigned int replace_cyrillic[] =
{0x430,0x431,0x446,0x45b,0x447,0x45f,0x455,0x434,0x452,
0x435,0x444,0x433,0x445,0x438,0x458,0x43a,0x459,
0x43b,0x43c,0x45a,0x43d,0x43e,0x43f,0x440,0x441,
0x448,0x442,0x443,0x432,0x437,0x436,
0x453,0x45c,0}; // ѓ ѕ ќ

static const unsigned int replace_cyrillic_latin[] =
{'a','b','c',0x107,0x10d,'d'+(0x17e<<16),'d'+('z'<<16),'d',0x111,
'e','f','g','h','i','j','k','l'+('j'<<16),
'l','m','n'+('j'<<16),'n','o','p','r','s',
0x161,'t','u','v','z',0x17e,
0x111,0x107,0};


void SetupTranslator(Translator *tr, int *lengths, int *amps) void SetupTranslator(Translator *tr, int *lengths, int *amps)
{//========================================================== {//==========================================================
if(lengths != NULL) if(lengths != NULL)
case L('h','i'): case L('h','i'):
{ {
static const char dev_consonants2[] = {0x02,0x03,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f}; static const char dev_consonants2[] = {0x02,0x03,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f};
static const wchar_t replace_chars_hi[11] = {0x966,0x967,0x968,0x969,0x96a,0x96b,0x96c,0x96d,0x96e,0x96f,0}; // digits 0-9
static const unsigned int replace_chars_hi[11] = {0x966,0x967,0x968,0x969,0x96a,0x96b,0x96c,0x96d,0x96e,0x96f,0}; // digits 0-9
static const unsigned int replacement_chars_hi[11] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0}; static const unsigned int replacement_chars_hi[11] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0};
static int stress_lengths_hi[8] = {190, 190, 210, 210, 0, 0, 230, 250}; static int stress_lengths_hi[8] = {190, 190, 210, 210, 0, 0, 230, 250};
static int stress_amps_hi[8] = {17,14, 20,19, 20,24, 24,22 }; static int stress_amps_hi[8] = {17,14, 20,19, 20,24, 24,22 };
case L('h','r'): // Croatian case L('h','r'): // Croatian
case L('s','r'): // Serbian case L('s','r'): // Serbian
{ {
static const wchar_t replace_chars_hr[] =
{0x430,0x431,0x446,0x45b,0x447,0x434,0x452,0x45f,
0x435,0x444,0x433,0x445,0x438,0x458,0x43a,0x43b,
0x459,0x43c,0x43d,0x45a,0x43e,0x43f,0x440,0x441,
0x448,0x442,0x443,0x432,0x437,0x436,
0x453,0x455,0x45c,0}; // ѓ ѕ ќ

static const unsigned int replacement_chars_hr[] =
{'a','b','c',0x107,0x10d,'d',0x111,'d'+(0x17e<<16),
'e','f','g','h','i','j','k','l',
'l'+('j'<<16),'m','n','n'+('j'<<16),'o','p','r','s',
0x161,'t','u','v','z',0x17e,
0x111,'d'+('z'<<16),0x107,0};

static int stress_amps_hr[8] = {16,16, 20,20, 20,24, 24,22 }; static int stress_amps_hr[8] = {16,16, 20,20, 20,24, 24,22 };
static int stress_lengths_hr[8] = {180,160, 200,200, 0,0, 220,230}; static int stress_lengths_hr[8] = {180,160, 200,200, 0,0, 220,230};


tr->langopts.max_initial_consonants = 5; tr->langopts.max_initial_consonants = 5;
tr->langopts.spelling_stress = 1; tr->langopts.spelling_stress = 1;


tr->langopts.numbers = 0x1c0d + 0x84000;
tr->langopts.numbers2 = 0xa; // variant numbers before thousands,milliards
tr->langopts.replace_chars = replace_chars_hr;
tr->langopts.replacement_chars = replacement_chars_hr;
tr->langopts.numbers = 0x1c0d + 0x4000;
tr->langopts.numbers2 = 0x4a; // variant numbers before thousands,milliards
tr->langopts.replace_chars = replace_cyrillic;
tr->langopts.replacement_chars = replace_cyrillic_latin;


SetLetterVowel(tr,'y'); SetLetterVowel(tr,'y');
SetLetterVowel(tr,'r'); SetLetterVowel(tr,'r');
static int stress_amps_hu[8] = {17,17, 19,19, 20,24, 24,22 }; static int stress_amps_hu[8] = {17,17, 19,19, 20,24, 24,22 };
static int stress_lengths_hu[8] = {185,190, 190,190, 0,0, 210,220}; static int stress_lengths_hu[8] = {185,190, 190,190, 0,0, 210,220};
// static int stress_lengths_hu[8] = {180,180, 200,190, 0,0, 210,225}; // static int stress_lengths_hu[8] = {180,180, 200,190, 0,0, 210,225};
static const wchar_t replace_chars_hu[] = {0xd4,0xf4,0xdb,0xfb,0};
static const unsigned int replace_chars_hu[] = {0xd4,0xf4,0xdb,0xfb,0};
static const unsigned int replacement_chars_hu[] = {0x150,0x151,0x170,0x171,0}; // allow o,u-circumflex for o,u-double-acute static const unsigned int replacement_chars_hu[] = {0x150,0x151,0x170,0x171,0}; // allow o,u-circumflex for o,u-double-acute


tr = new Translator(); tr = new Translator();
tr->letter_groups[0] = vowels_cyrillic; tr->letter_groups[0] = vowels_cyrillic;


tr->langopts.stress_rule = 4; // antipenultimate tr->langopts.stress_rule = 4; // antipenultimate
tr->langopts.numbers = 0x0c29 + 0x84000;
tr->langopts.numbers2 = 0xa; // variant numbers before thousands,milliards
tr->langopts.numbers = 0x0c29 + 0x4000;
tr->langopts.numbers2 = 0x8a; // variant numbers before thousands,milliards

tr->langopts.replace_chars = replace_cyrillic_latin;
tr->langopts.replacement_chars = replace_cyrillic;
} }
break; break;


tr->langopts.stress_flags = 0x6; // mark unstressed final syllables as diminished tr->langopts.stress_flags = 0x6; // mark unstressed final syllables as diminished
tr->langopts.param[LOPT_REGRESSIVE_VOICING] = 0x8; tr->langopts.param[LOPT_REGRESSIVE_VOICING] = 0x8;
tr->langopts.max_initial_consonants = 7; // for example: wchrzczony :) tr->langopts.max_initial_consonants = 7; // for example: wchrzczony :)
tr->langopts.numbers=0x81809 + 0x4000;
tr->langopts.numbers=0x1809 + 0x4000;
tr->langopts.numbers2=0x40;
tr->langopts.param[LOPT_COMBINE_WORDS] = 2 + 0x100; // combine 'nie' (marked with $alt2) with some 1-syllable words (marked with $alt) tr->langopts.param[LOPT_COMBINE_WORDS] = 2 + 0x100; // combine 'nie' (marked with $alt2) with some 1-syllable words (marked with $alt)
SetLetterVowel(tr,'y'); SetLetterVowel(tr,'y');
} }
{ {
static int stress_lengths_ro[8] = {170, 170, 180, 180, 0, 0, 240, 260}; static int stress_lengths_ro[8] = {170, 170, 180, 180, 0, 0, 240, 260};
static int stress_amps_ro[8] = {15,13, 18,18, 20,22, 22,22 }; static int stress_amps_ro[8] = {15,13, 18,18, 20,22, 22,22 };
static const wchar_t replace_chars_ro[5] = {0x218,0x219,0x21a,0x21b,0};
static const unsigned int replace_chars_ro[5] = {0x218,0x219,0x21a,0x21b,0};
static const unsigned int replacement_chars_ro[5] = {0x15e,0x15f,0x162,0x163,0}; // replace s-comma, t-comma by s-cedilla, t-cedilla static const unsigned int replacement_chars_ro[5] = {0x15e,0x15f,0x162,0x163,0}; // replace s-comma, t-comma by s-cedilla, t-cedilla


tr = new Translator(); tr = new Translator();
tr->langopts.spelling_stress = 1; tr->langopts.spelling_stress = 1;
tr->langopts.param[LOPT_COMBINE_WORDS] = 4; // combine some prepositions with the following word tr->langopts.param[LOPT_COMBINE_WORDS] = 4; // combine some prepositions with the following word


// tr->langopts.numbers = 0x1c0d + 0x84000;
tr->langopts.numbers = 0x1c01 + 0x84000;
tr->langopts.numbers = 0x1c01 + 0x4000;
tr->langopts.numbers2 = 0x40;
tr->langopts.thousands_sep = 0; //no thousands separator tr->langopts.thousands_sep = 0; //no thousands separator
tr->langopts.decimal_sep = ','; tr->langopts.decimal_sep = ',';


langopts.stress_rule = 5; langopts.stress_rule = 5;
langopts.stress_flags = 0x0020; // waas 0x1010 langopts.stress_flags = 0x0020; // waas 0x1010


langopts.numbers = 0x80409;
langopts.numbers2 = 0x2; // variant numbers before thousands
langopts.numbers = 0x0409;
langopts.numbers2 = 0xc2; // variant numbers before thousands
langopts.phoneme_change = 1; langopts.phoneme_change = 1;
langopts.testing = 2; langopts.testing = 2;


} }




int Translator_Afrikaans::TranslateChar(char *ptr, int prev_in, int c, int next_in, int *insert)
{//=============================================================================================
int Translator_Afrikaans::TranslateChar(char *ptr, int prev_in, unsigned int c, unsigned int next_in, int *insert)
{//===============================================================================================================
// look for 'n and replace by a special character (unicode: schwa) // look for 'n and replace by a special character (unicode: schwa)


if(!iswalpha(prev_in)) if(!iswalpha(prev_in))

+ 1
- 1
src/tr_languages.h View File

public: public:
Translator_Afrikaans(); Translator_Afrikaans();
private: private:
int TranslateChar(char *ptr, int prev_in, int c, int next_in, int *insert);
int TranslateChar(char *ptr, int prev_in, unsigned int c, unsigned int next_in, int *insert);


}; // end of class Translator_Afrikaans }; // end of class Translator_Afrikaans



+ 55
- 29
src/translate.cpp View File

* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write see: *
* along with this program; if not, see: *
* <http://www.gnu.org/licenses/>. * * <http://www.gnu.org/licenses/>. *
***************************************************************************/ ***************************************************************************/








int Translator::TranslateChar(char *ptr, int prev_in, int c, int next_in, int *insert)
{//===================================================================================
int Translator::TranslateChar(char *ptr, int prev_in, unsigned int c, unsigned int next_in, int *insert)
{//=====================================================================================================
// To allow language specific examination and replacement of characters // To allow language specific examination and replacement of characters


const wchar_t *p;
int ix;
unsigned int word;
unsigned int new_c, c2; unsigned int new_c, c2;
int upper_case = 0; int upper_case = 0;
static int ignore_next = 0;


if(ignore_next)
{
ignore_next = 0;
return(8);
}
if(c == 0) return(0); if(c == 0) return(0);


if(langopts.replace_chars != NULL)
{
// there is a list of character codes to be substituted with alternative codes
if(langopts.replace_chars == NULL)
return(c);


if((p = wcschr(langopts.replace_chars,c)) == NULL)
{
// Try converting to lower case
if((p = wcschr(langopts.replace_chars,towlower(c))) != NULL)
upper_case =1;
}
// there is a list of character codes to be substituted with alternative codes


if(p != NULL)
if(iswupper(c))
{
c = towlower(c);
upper_case = 1;
}

new_c = 0;
for(ix=0; (word = langopts.replace_chars[ix]) != 0; ix++)
{
if(c == (word & 0xffff))
{ {
new_c = langopts.replacement_chars[p - langopts.replace_chars];
if(new_c & 0xffe00000)
if((word >> 16) == 0)
{ {
// 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;
new_c = langopts.replacement_chars[ix];
break;
}
if((word >> 16) == tolower(next_in))
{
new_c = langopts.replacement_chars[ix];
ignore_next = 1;
break;
} }
#ifndef PLATFORM_RISCOS
if(upper_case)
new_c = towupper(new_c);
#endif
return(new_c);
} }
} }
return(c);

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;
}
#ifndef PLATFORM_RISCOS
if(upper_case)
new_c = towupper(new_c);
#endif
return(new_c);
} }




} }


c = TranslateChar(&source[source_index], prev_in,c, next_in, &char_inserted); // optional language specific function c = TranslateChar(&source[source_index], prev_in,c, next_in, &char_inserted); // optional language specific function
if(c == 8)
continue; // ignore this character

if(char_inserted) if(char_inserted)
next_in = char_inserted; next_in = char_inserted;



+ 5
- 4
src/translate.h View File

* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write see: *
* along with this program; if not, see: *
* <http://www.gnu.org/licenses/>. * * <http://www.gnu.org/licenses/>. *
***************************************************************************/ ***************************************************************************/


// bits13-15 post-decimal-digits 0=single digits, 1=(LANG=it) 2=(LANG=pl) 3=(LANG=ro) // bits13-15 post-decimal-digits 0=single digits, 1=(LANG=it) 2=(LANG=pl) 3=(LANG=ro)
// bit16=dot after number indicates ordinal // bit16=dot after number indicates ordinal
// bit18=special word for 100,000s LANG=sw // bit18=special word for 100,000s LANG=sw
// bit19=(LANG=pl) two forms of plural, M or MA


int numbers; int numbers;


// bits 1-4 use variant form of numbers before thousands,millions,etc. // 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
int numbers2; int numbers2;


int thousands_sep; int thousands_sep;
char tone_numbers; char tone_numbers;
char ideographs; // treat as separate words char ideographs; // treat as separate words
int testing; // testing options: bit 1= specify stressed syllable in the form: "outdoor/2" int testing; // testing options: bit 1= specify stressed syllable in the form: "outdoor/2"
const wchar_t *replace_chars; // characters to be substitutes
const unsigned int *replace_chars; // characters to be substitutes
const unsigned int *replacement_chars; // substitutes for replace_chars const unsigned int *replacement_chars; // substitutes for replace_chars
} LANGUAGE_OPTIONS; } LANGUAGE_OPTIONS;


virtual int Unpronouncable(char *word); virtual int Unpronouncable(char *word);
virtual void SetWordStress(char *output, unsigned int dictionary_flags, int tonic, int prev_stress); virtual void SetWordStress(char *output, unsigned int dictionary_flags, int tonic, int prev_stress);
virtual int RemoveEnding(char *word, int end_type, char *word_copy); virtual int RemoveEnding(char *word, int end_type, char *word_copy);
virtual int TranslateChar(char *ptr, int prev_in, int c, int next_in, int *insert);
virtual int TranslateChar(char *ptr, int prev_in, unsigned int c, unsigned int next_in, int *insert);
virtual int TranslateNumber(char *word1, char *ph_out, unsigned int *flags, int wflags); virtual int TranslateNumber(char *word1, char *ph_out, unsigned int *flags, int wflags);
virtual int ChangePhonemes(PHONEME_LIST2 *phlist, int n_ph, int index, PHONEME_TAB *ph, CHANGEPH *ch); virtual int ChangePhonemes(PHONEME_LIST2 *phlist, int n_ph, int index, PHONEME_TAB *ph, CHANGEPH *ch);



+ 4
- 1
src/transldlg.cpp View File

* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write see: *
* along with this program; if not, see: *
* <http://www.gnu.org/licenses/>. * * <http://www.gnu.org/licenses/>. *
***************************************************************************/ ***************************************************************************/


{ {
myframe->OnProsody(event); myframe->OnProsody(event);
} }
option_phoneme_events = 1;
option_log_frames = 1;
MakeWave2(ph_list,n_ph_list); MakeWave2(ph_list,n_ph_list);
option_log_frames = 0;
break; break;
} }
} // end of TranslDlg::OnCommand } // end of TranslDlg::OnCommand

+ 46
- 14
src/wavegen.cpp View File

* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write see: *
* along with this program; if not, see: *
* <http://www.gnu.org/licenses/>. * * <http://www.gnu.org/licenses/>. *
***************************************************************************/ ***************************************************************************/


FILE *f_log = NULL; FILE *f_log = NULL;
int option_waveout = 0; int option_waveout = 0;
int option_harmonic1 = 11; // 10 int option_harmonic1 = 11; // 10
int option_log_frames = 0;
static int flutter_amp = 64; static int flutter_amp = 64;


static int general_amplitude = 60; static int general_amplitude = 60;
int pitch_value; int pitch_value;


#ifdef LOG_FRAMES #ifdef LOG_FRAMES
f_log=fopen("log-espeakedit","a");
if(f_log != NULL)
if(option_log_frames)
{ {
fprintf(f_log," %3d %3d\n",pitch1,pitch2);
fclose(f_log);
f_log=NULL;
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 #endif
if((pitch_env = env)==NULL) if((pitch_env = env)==NULL)
static int glottal_reduce_tab2[4] = {0x90, 0xa0, 0xb0, 0xc0}; // vowel after [?], amp * 1/256 static int glottal_reduce_tab2[4] = {0x90, 0xa0, 0xb0, 0xc0}; // vowel after [?], amp * 1/256


#ifdef LOG_FRAMES #ifdef LOG_FRAMES
f_log=fopen("log-espeakedit","a");
if(f_log != NULL)
if(option_log_frames)
{ {
fprintf(f_log,"%3dmS %4d/%3d %4d/%3d %4d/%3d %4d/%3d %4d/%3d %4d/%3d %4d/%3d %4d/%3d\n",length*1000/samplerate,
fr1->ffreq[0],fr1->fheight[0],fr1->ffreq[1],fr1->fheight[1], fr1->ffreq[2],fr1->fheight[2], fr1->ffreq[3],fr1->fheight[3],
fr2->ffreq[0],fr2->fheight[0],fr2->ffreq[1],fr2->fheight[1], fr2->ffreq[2],fr2->fheight[2], fr2->ffreq[3],fr2->fheight[3] );
fclose(f_log);
f_log=NULL;
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 #endif


} // end of SetSynth } // end of SetSynth




#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

static int Wavegen2(int length, int modulation, int resume, frame_t *fr1, frame_t *fr2) static int Wavegen2(int length, int modulation, int resume, frame_t *fr1, frame_t *fr2)
{//==================================================================================== {//====================================================================================
if(resume==0) if(resume==0)


case WCMD_MARKER: case WCMD_MARKER:
MarkerEvent(q[1],q[2],q[3],out_ptr); MarkerEvent(q[1],q[2],q[3],out_ptr);

#ifdef LOG_FRAMES
LogMarker(q[1],q[3]);
#endif
if(q[1] == 1) if(q[1] == 1)
{ {
current_source_index = q[2] & 0xffffff; current_source_index = q[2] & 0xffffff;

Loading…
Cancel
Save