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

make_espeak.iss 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. ; This is the script for "Inno Setup 5" to create the setup_espeak.exe installer for Windows
  2. [Setup]
  3. AppName=eSpeak
  4. AppVerName=eSpeak version 1.29.03
  5. DefaultDirName={pf}\eSpeak
  6. DefaultGroupName=eSpeak
  7. OutputBaseFilename=setup_espeak
  8. Compression=lzma
  9. SolidCompression=yes
  10. ShowLanguageDialog=auto
  11. [InstallDelete]
  12. Type: files; Name: "{app}\espeak.dll"
  13. [Dirs]
  14. Name: "{app}\espeak-data\soundicons"
  15. Name: "{app}\espeak-data\mbrola"
  16. [Files]
  17. Source: "espeak_sapi.dll"; DestDir: "{app}"; Flags: regserver promptifolder replacesameversion
  18. Source: "TTSApp.exe"; DestDir:"{app}"
  19. Source: "espeak-data\*"; DestDir: "{app}\espeak-data"; Flags: recursesubdirs
  20. Source: "dictsource2\*"; DestDir: "{app}\dictsource"
  21. Source: "docs\*"; DestDir: "{app}\docs"; Flags: recursesubdirs
  22. Source: "command_line\*"; DestDir: "{app}\command_line"
  23. Source: "Readme.txt"; DestDir: "{app}"; Flags: isreadme
  24. Source: "License.txt"; DestDir: "{app}";
  25. [Registry]
  26. Root: HKLM; Subkey: "Software\Microsoft\Speech\Voices\Tokens\eSpeak"; Flags: deletekey uninsdeletekey
  27. Root: HKLM; Subkey: "Software\Microsoft\Speech\Voices\Tokens\eSpeak_1"; Flags: deletekey uninsdeletekey
  28. Root: HKLM; Subkey: "Software\Microsoft\Speech\Voices\Tokens\eSpeak_2"; Flags: deletekey uninsdeletekey
  29. Root: HKLM; Subkey: "Software\Microsoft\Speech\Voices\Tokens\eSpeak_3"; Flags: deletekey uninsdeletekey
  30. Root: HKLM; Subkey: "Software\Microsoft\Speech\Voices\Tokens\eSpeak_4"; Flags: deletekey uninsdeletekey
  31. Root: HKLM; Subkey: "Software\Microsoft\Speech\Voices\Tokens\eSpeak_5"; Flags: deletekey uninsdeletekey
  32. Root: HKLM; Subkey: "Software\Microsoft\Speech\PhoneConverters\Tokens\eSpeak"; Flags: deletekey uninsdeletekey
  33. [Languages]
  34. Name: "en"; MessagesFile: "compiler:Default.isl"
  35. Name: "af"; MessagesFile: "compiler:Languages\Afrikaans.isl"
  36. Name: "bs"; MessagesFile: "compiler:Languages\Bosnian.isl"
  37. Name: "cs"; MessagesFile: "compiler:Languages\Czech.isl"
  38. Name: "de"; MessagesFile: "compiler:Languages\German.isl"
  39. Name: "el"; MessagesFile: "compiler:Languages\Greek.isl"
  40. Name: "es"; MessagesFile: "compiler:Languages\Spanish.isl"
  41. Name: "fi"; MessagesFile: "compiler:Languages\Finnish.isl"
  42. Name: "fr"; MessagesFile: "compiler:Languages\French.isl"
  43. Name: "hr"; MessagesFile: "compiler:Languages\Croatian.isl"
  44. Name: "hu"; MessagesFile: "compiler:Languages\Hungarian.isl"
  45. Name: "it"; MessagesFile: "compiler:Languages\Italian.isl"
  46. Name: "nl"; MessagesFile: "compiler:Languages\Dutch.isl"
  47. Name: "pl"; MessagesFile: "compiler:Languages\Polish.isl"
  48. Name: "pt"; MessagesFile: "compiler:Languages\Portuguese.isl"
  49. Name: "ro"; MessagesFile: "compiler:Languages\Romanian.isl"
  50. Name: "ru"; MessagesFile: "compiler:Languages\Russian.isl"
  51. Name: "sk"; MessagesFile: "compiler:Languages\Slovak.isl"
  52. Name: "sr"; MessagesFile: "compiler:Languages\Serbian.isl"
  53. [CustomMessages]
  54. v1=Select which voices to install
  55. v2=or press Enter to accept defaults
  56. v3=Enter voice names, eg: (for Portuguese) pt, or with a variant, eg: pt+f3
  57. bs.v1=Odaberite jezik kojeg želite instalirati
  58. bs.v2=ili pritisnite Enter za prihvat zadanih.
  59. bs.v3=Upišite, npr. bs (za Bosanski) ili s varjantom: bs+f3
  60. hr.v1=Odaberite jezik kojeg želite instalirati
  61. hr.v2=ili pritisnite Enter za prihvat zadanih.
  62. hr.v3=Upišite, npr. hr (za Hrvatski) ili s varjantom: hr+f3
  63. pt.v1=Seleccione as vozes que pretende instalar
  64. pt.v2=ou precione enter para aceitar as predefinidas.
  65. pt.v3=Introduza os nomes das vozes, ex: (Brazil) pt (ou Portugal) pt-pt, ou com outras caracter?sticas, ex: pt+f3
  66. sr.v1=Molimo vas da odaberete glasove, koje želite da instalirate
  67. sr.v2=ili pritisnite Enter za instalaciju podrazumevanih glasova.
  68. sr.v3=Da odaberete glas, unesite ime glasa kojeg želite instalirati, na primer sr, ili sr+f3
  69. [Code]
  70. var
  71. UILanguage: Integer;
  72. UIVoice: String;
  73. Page: TInputQueryWizardPage;
  74. const
  75. sEspeak = 'eSpeak-';
  76. RegVoice1 = 'Software\Microsoft\Speech\Voices\Tokens\eSpeak';
  77. RegPhConv = 'Software\Microsoft\Speech\PhoneConverters\Tokens';
  78. function VoiceFromLanguage(language: Integer): String;
  79. var
  80. lang_main: Integer;
  81. begin
  82. lang_main := language and $3ff;
  83. Result := 'af';
  84. // translation from microsoft codes to language codes
  85. case lang_main of
  86. $05: Result := 'cs';
  87. $07: Result := 'de';
  88. $08: Result := 'el';
  89. $0a: Result := 'es';
  90. $0b: Result := 'fi';
  91. $0c: Result := 'fr';
  92. $0e: Result := 'hu';
  93. $0f: Result := 'is';
  94. $10: Result := 'it';
  95. $13: Result := 'nl';
  96. $14: Result := 'no';
  97. $15: Result := 'pl';
  98. $16: Result := 'pt';
  99. $18: Result := 'ro';
  100. $19: Result := 'ru';
  101. $1a: Result := 'hr';
  102. $1b: Result := 'sk';
  103. $1d: Result := 'sv';
  104. $2a: Result := 'vi';
  105. $2f: Result := 'mk';
  106. $36: Result := 'af';
  107. $39: Result := 'hi';
  108. $41: Result := 'sw';
  109. $52: Result := 'cy';
  110. end;
  111. // is there a match on the full language code?
  112. case language of
  113. $816: Result := 'pt-pt';
  114. $41a: Result := 'hr';
  115. $81a: Result := 'sr';
  116. $c1a: Result := 'sr';
  117. $141a: Result := 'bs';
  118. end;
  119. end;
  120. function LanguageFromVoice(voice: String): String;
  121. var
  122. value: Integer;
  123. lang1: String;
  124. len: Integer;
  125. begin
  126. value := $409; // default en-us
  127. lang1 := Copy(voice,0,2);
  128. if lang1 = 'mb' then
  129. begin
  130. lang1 := Copy(voice,3,3);
  131. len := Length(voice);
  132. if len > 8 then
  133. lang1 := Copy(voice,8,6); // eg. mb-de4-en, return 'en'
  134. end;
  135. case lang1 of
  136. 'af': value := $436;
  137. 'bs': value := $41a; // should be $141a but Jaws crashes on startup
  138. 'cs': value := $405;
  139. 'cy': value := $452;
  140. 'de': value := $407;
  141. 'el': value := $408;
  142. 'en': value := $409;
  143. 'es': value := $40a;
  144. 'fi': value := $40b;
  145. 'fr': value := $40c;
  146. 'hi': value := $439;
  147. 'hr': value := $41a;
  148. 'hu': value := $40e;
  149. 'is': value := $40f;
  150. 'it': value := $410;
  151. 'mk': value := $42f;
  152. 'nl': value := $413;
  153. 'no': value := $414;
  154. 'pl': value := $415;
  155. 'pt': value := $416;
  156. 'ro': value := $418;
  157. 'ru': value := $419;
  158. 'sk': value := $41b;
  159. 'sr': value := $81a;
  160. 'sv': value := $41d;
  161. 'sw': value := $441;
  162. 'vi': value := $42a;
  163. // mbrola voices
  164. '-af': value := $436;
  165. '-br': value := $416;
  166. '-ca': value := $c0c;
  167. '-cr': value := $41a;
  168. '-cz': value := $405;
  169. '-de': value := $407;
  170. '-en': value := $809;
  171. '-es': value := $40a;
  172. '-fr': value := $40c;
  173. '-gr': value := $408;
  174. '-hu': value := $40e;
  175. '-ic': value := $40f;
  176. '-in': value := $439;
  177. '-it': value := $410;
  178. '-mx': value := $80a;
  179. '-nl': value := $413;
  180. '-pl': value := $415;
  181. '-pt': value := $816;
  182. '-ro': value := $418;
  183. '-sw': value := $41d;
  184. '-us': value := $409;
  185. '-vz': value := $200a;
  186. end;
  187. // check for specific voices
  188. case voice of
  189. 'pt-pt': value := $816;
  190. end;
  191. Result := Format('%X',[value]);
  192. end;
  193. // is the language number already in a PhoneConvertor ?
  194. function CheckPhoneConvertors(Lcode: String): Integer;
  195. var
  196. Convertors: TArrayOfString;
  197. ix: Integer;
  198. len: Integer;
  199. s1: String;
  200. s2: String;
  201. sLangs: String;
  202. begin
  203. Result := 0;
  204. len := Length(Lcode);
  205. if RegGetSubkeyNames(HKEY_LOCAL_MACHINE, RegPhConv, Convertors) then
  206. begin
  207. for ix := 0 to GetArrayLength(Convertors) - 1 do
  208. begin
  209. s1 := RegPhConv + '\' + Convertors[ix] + '\Attributes';
  210. if RegQueryStringValue(HKEY_LOCAL_MACHINE, s1, 'Language', sLangs) then
  211. begin
  212. s2 := Copy(sLangs, 1, len);
  213. if s2 = Lcode then
  214. Result := 1;
  215. if sLangs = Lcode then
  216. Result := 1;
  217. if Pos(';' + Lcode, sLangs) > 0 then
  218. Result := 1;
  219. end;
  220. end;
  221. end;
  222. end;
  223. // ensure the language number is included in a PhoneConvertor
  224. procedure SetPhoneConvertor(Lcode: String);
  225. var
  226. done: Boolean;
  227. s1: String;
  228. sLangs: String;
  229. begin
  230. if CheckPhoneConvertors(Lcode) = 0 then
  231. begin
  232. done := False;
  233. s1 := RegPhConv + '\Universal\Attributes';
  234. if RegQueryStringValue(HKEY_LOCAL_MACHINE, s1, 'Language', sLangs) then
  235. begin
  236. done := RegWriteStringValue(HKEY_LOCAL_MACHINE, s1, 'Language', Lcode + ';' + sLangs);
  237. end;
  238. if done = False then
  239. begin
  240. s1 := RegPhConv + '\eSpeak\Attributes';
  241. if RegQueryStringValue(HKEY_LOCAL_MACHINE, s1, 'Language', sLangs) = False then
  242. begin
  243. // add 'eSpeak' dummy PhoneConvertor
  244. RegWriteStringValue(HKEY_LOCAL_MACHINE, RegPhConv + '\eSpeak', 'CLSID','{9185F743-1143-4C28-86B5-BFF14F20E5C8}');
  245. RegWriteStringValue(HKEY_LOCAL_MACHINE, RegPhConv + '\eSpeak', 'PhoneMap','- 0001');
  246. RegWriteStringValue(HKEY_LOCAL_MACHINE, s1, 'Language','');
  247. end;
  248. if RegQueryStringValue(HKEY_LOCAL_MACHINE, s1, 'Language', sLangs) then
  249. begin
  250. done := RegWriteStringValue(HKEY_LOCAL_MACHINE, s1, 'Language', Lcode + ';' + sLangs);
  251. end;
  252. end;
  253. end;
  254. end;
  255. procedure SetupVoice(Voice, Lcode: String; Index: Integer);
  256. var
  257. RegVoice2: String;
  258. RegVoice2a: String;
  259. VoiceUC: String;
  260. begin
  261. if Index = 0 then
  262. RegVoice2 := RegVoice1
  263. else
  264. RegVoice2 := RegVoice1 + Format('_%d',[Index]);
  265. RegVoice2a := RegVoice2 + '\Attributes';
  266. if Voice = 'default' then
  267. VoiceUC := 'default'
  268. else
  269. VoiceUC := Uppercase(Voice);
  270. RegWriteStringValue(HKEY_LOCAL_MACHINE,RegVoice2,'',sEspeak+VoiceUC);
  271. RegWriteStringValue(HKEY_LOCAL_MACHINE,RegVoice2,'CLSID','{BE985C8D-BE32-4A22-AA93-55C16A6D1D91}');
  272. RegWriteStringValue(HKEY_LOCAL_MACHINE,RegVoice2,'Path',ExpandConstant('{app}'));
  273. RegWriteStringValue(HKEY_LOCAL_MACHINE,RegVoice2,'VoiceName',Voice);
  274. RegWriteStringValue(HKEY_LOCAL_MACHINE,RegVoice2a,'Name',sEspeak+Voice);
  275. RegWriteStringValue(HKEY_LOCAL_MACHINE,RegVoice2a,'Gender','Male');
  276. RegWriteStringValue(HKEY_LOCAL_MACHINE,RegVoice2a,'Age','Adult');
  277. RegWriteStringValue(HKEY_LOCAL_MACHINE,RegVoice2a,'Language',Lcode);
  278. RegWriteStringValue(HKEY_LOCAL_MACHINE,RegVoice2a,'Vendor','Jonathan Duddington');
  279. SetPhoneConvertor(Lcode);
  280. end;
  281. procedure CurStepChanged(CurStep: TSetupStep);
  282. var
  283. ix: Integer;
  284. begin
  285. if CurStep = ssPostInstall then
  286. begin
  287. for ix := 0 to 5 do begin
  288. if Page.Values[ix] <> '' then
  289. SetUpVoice(Page.Values[ix],LanguageFromVoice(Page.Values[ix]),ix);
  290. end;
  291. end;
  292. end;
  293. procedure InitializeWizard;
  294. var
  295. lang: String;
  296. begin
  297. // Create the language selection page
  298. lang := ActiveLanguage;
  299. Page := CreateInputQueryPage(wpSelectDir,CustomMessage('v1'),CustomMessage('v2'),CustomMessage('v3'));
  300. // Add items (False means it's not a password edit)
  301. Page.Add('', False);
  302. Page.Add('', False);
  303. Page.Add('', False);
  304. Page.Add('', False);
  305. Page.Add('', False);
  306. Page.Add('', False);
  307. UILanguage := GetUILanguage;
  308. UIVoice := VoiceFromLanguage(UILanguage);
  309. // Set initial values (optional)
  310. Page.Values[0] := 'en';
  311. Page.Values[1] := UIVoice;
  312. Page.Values[2] := 'en-r';
  313. end;