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.

espeakedit.cpp 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  1. /***************************************************************************
  2. * Copyright (C) 2005 to 2007 by Jonathan Duddington *
  3. * email: [email protected] *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; either version 3 of the License, or *
  8. * (at your option) any later version. *
  9. * *
  10. * This program is distributed in the hope that it will be useful, *
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  13. * GNU General Public License for more details. *
  14. * *
  15. * You should have received a copy of the GNU General Public License *
  16. * along with this program; if not, see: *
  17. * <http://www.gnu.org/licenses/>. *
  18. ***************************************************************************/
  19. #include "wx/wx.h"
  20. #include "wx/wfstream.h"
  21. #include "wx/notebook.h"
  22. #include "wx/image.h"
  23. #include "wx/filename.h"
  24. #include "wx/numdlg.h"
  25. #include "wx/mdi.h"
  26. #include "wx/laywin.h"
  27. #include "wx/sashwin.h"
  28. #include <locale.h>
  29. #include "speak_lib.h"
  30. #include "main.h"
  31. #include "speech.h"
  32. #include "options.h"
  33. #include "phoneme.h"
  34. #include "synthesize.h"
  35. #include "voice.h"
  36. #include "spect.h"
  37. #include "translate.h"
  38. #include "prosodydisplay.h"
  39. static char *about_string = "espeakedit: %s\nAuthor: Jonathan Duddington (c) 2007\n\n"
  40. "Licensed under GNU General Public License version 3\n"
  41. "http://espeak.sourceforge.net/";
  42. const char *path_data = "/home/jsd1/speechdata/phsource";
  43. extern void TestTest(int control);
  44. extern void CompareLexicon(int);
  45. extern void ConvertToUtf8();
  46. extern void init_z();
  47. extern void CompileInit(void);
  48. extern void CompileMbrola();
  49. extern void InitSpectrumDisplay();
  50. extern void InitProsodyDisplay();
  51. extern void InitWaveDisplay();
  52. extern void VowelChart(int control, char *fname);
  53. extern void MakeVowelLists(void);
  54. extern void MakeWordFreqList();
  55. extern const char *dict_name;
  56. MyFrame *myframe = NULL;
  57. SpectDisplay *currentcanvas = NULL;
  58. ChildFrProsody *prosodyframe = NULL;
  59. ProsodyDisplay *prosodycanvas = NULL;
  60. wxNotebook *notebook = NULL;
  61. wxProgressDialog *progress;
  62. int progress_max;
  63. int gui_flag = 0;
  64. wxList my_children;
  65. wxFont FONT_SMALL(8,wxSWISS,wxNORMAL,wxNORMAL);
  66. wxFont FONT_MEDIUM(9,wxSWISS,wxNORMAL,wxNORMAL);
  67. wxFont FONT_NORMAL(10,wxSWISS,wxNORMAL,wxNORMAL);
  68. IMPLEMENT_APP(MyApp)
  69. wxString AppName = _T("espeakedit");
  70. int MyApp::OnExit()
  71. {//================
  72. ConfigSave(1);
  73. return(0);
  74. }
  75. static const char *help_text =
  76. "\n\nespeakedit\n"
  77. "\tRun with GUI\n"
  78. "espeakedit --compile\n"
  79. "\tCompile phoneme data in espeak-data/phsource\n"
  80. "\tand dictionary data in espeak-data/dictsource\n";
  81. // Initialise this in OnInit, not statically
  82. bool MyApp::OnInit(void)
  83. {//=====================
  84. int j;
  85. wxChar *p;
  86. char param[80];
  87. if(argc > 1)
  88. {
  89. extern void VoiceReset(int control);
  90. p = argv[1];
  91. j = 0;
  92. while((param[j] = p[j]) != 0) j++;
  93. if((strcmp(param,"--help")==0) || (strcmp(param,"-h")==0))
  94. {
  95. printf(about_string,espeak_Info(NULL));
  96. printf(help_text);
  97. exit(0);
  98. }
  99. ConfigInit();
  100. VoiceReset(0);
  101. WavegenSetVoice(voice);
  102. WavegenInitSound();
  103. if(strcmp(param,"--compile")==0)
  104. {
  105. CompileInit();
  106. exit(0);
  107. }
  108. }
  109. gui_flag = 1;
  110. // It seems that the wctype functions don't work until the locale has been set
  111. // to something other than the default "C". Then, not only Latin1 but also the
  112. // other characters give the correct results with iswalpha() etc.
  113. if(setlocale(LC_CTYPE,"en_US.UTF-8") == NULL)
  114. {
  115. if(setlocale(LC_CTYPE,"UTF-8") == NULL)
  116. setlocale(LC_CTYPE,"");
  117. }
  118. // Create the main frame window
  119. myframe = new MyFrame(NULL, -1, AppName, wxPoint(0, 0), wxSize(1024, 768),
  120. wxDEFAULT_FRAME_STYLE |
  121. wxNO_FULL_REPAINT_ON_RESIZE |
  122. wxHSCROLL | wxVSCROLL);
  123. // Make a menubar
  124. myframe->SetMenuBar(MakeMenu(0));
  125. myframe->CreateStatusBar();
  126. myframe->Show(TRUE);
  127. SetTopWindow(myframe);
  128. wxInitAllImageHandlers();
  129. // wxImage::AddHandler(wxPNGHandler);
  130. return TRUE;
  131. }
  132. BEGIN_EVENT_TABLE(MyFrame, wxMDIParentFrame)
  133. EVT_CHAR(MyFrame::OnKey)
  134. EVT_MENU(MENU_ABOUT, MyFrame::OnAbout)
  135. EVT_MENU(MENU_SPECTRUM, MyFrame::OnNewWindow)
  136. EVT_MENU(MENU_SPECTRUM2, MyFrame::OnNewWindow)
  137. EVT_MENU(MENU_PROSODY, MyFrame::OnProsody)
  138. EVT_MENU(MENU_PARAMS, MyFrame::OnOptions)
  139. EVT_MENU(MENU_PATH0, MyFrame::OnOptions)
  140. EVT_MENU(MENU_PATH1, MyFrame::OnOptions)
  141. EVT_MENU(MENU_PATH2, MyFrame::OnOptions)
  142. EVT_MENU(MENU_PATH3, MyFrame::OnOptions)
  143. EVT_MENU(MENU_PATH4, MyFrame::OnOptions)
  144. EVT_MENU(MENU_COMPILE_PH, MyFrame::OnTools)
  145. EVT_MENU(MENU_COMPILE_DICT, MyFrame::OnTools)
  146. EVT_MENU(MENU_COMPILE_MBROLA, MyFrame::OnTools)
  147. EVT_MENU(MENU_CLOSE_ALL, MyFrame::OnQuit)
  148. EVT_MENU(MENU_QUIT, MyFrame::OnQuit)
  149. EVT_MENU(MENU_SPEAK_TRANSLATE, MyFrame::OnSpeak)
  150. EVT_MENU(MENU_SPEAK_RULES, MyFrame::OnSpeak)
  151. EVT_MENU(MENU_SPEAK_TEXT, MyFrame::OnSpeak)
  152. EVT_MENU(MENU_SPEAK_FILE, MyFrame::OnSpeak)
  153. EVT_MENU(MENU_SPEAK_STOP, MyFrame::OnSpeak)
  154. EVT_MENU(MENU_SPEAK_PAUSE, MyFrame::OnSpeak)
  155. EVT_MENU(MENU_SPEAK_VOICE, MyFrame::OnSpeak)
  156. EVT_MENU(MENU_SPEAK_VOICE_VARIANT, MyFrame::OnSpeak)
  157. EVT_MENU(MENU_LOAD_WAV, MyFrame::OnTools)
  158. EVT_MENU(MENU_VOWELCHART1, MyFrame::OnTools)
  159. EVT_MENU(MENU_VOWELCHART2, MyFrame::OnTools)
  160. EVT_MENU(MENU_VOWELCHART3, MyFrame::OnTools)
  161. EVT_MENU(MENU_LEXICON_RU, MyFrame::OnTools)
  162. EVT_MENU(MENU_LEXICON_DE, MyFrame::OnTools)
  163. EVT_MENU(MENU_TO_UTF8, MyFrame::OnTools)
  164. EVT_MENU(MENU_COUNT_WORDS, MyFrame::OnTools)
  165. EVT_MENU(MENU_TEST, MyFrame::OnTools)
  166. EVT_MENU(MENU_TEST2, MyFrame::OnTools)
  167. EVT_TIMER(1, MyFrame::OnTimer)
  168. EVT_SIZE(MyFrame::OnSize)
  169. EVT_SASH_DRAGGED_RANGE(ID_WINDOW_TOP, ID_WINDOW_BOTTOM, MyFrame::OnSashDrag)
  170. END_EVENT_TABLE()
  171. MyFrame::MyFrame(wxWindow *parent, const wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size,
  172. const long style):
  173. wxMDIParentFrame(parent, id, title, pos, size, style)
  174. {//===================================================================================================================
  175. // Main Frame constructor
  176. int error_flag = 0;
  177. int result;
  178. int param;
  179. // Create some dummy layout windows
  180. wxSashLayoutWindow *win;
  181. // Another window to the left of the client window
  182. win = new wxSashLayoutWindow(this, ID_WINDOW_LEFT2,
  183. wxDefaultPosition, wxSize(200, 30),
  184. wxNO_BORDER | wxSW_3D | wxCLIP_CHILDREN);
  185. win->SetDefaultSize(wxSize(208, 1000));
  186. win->SetOrientation(wxLAYOUT_VERTICAL);
  187. win->SetAlignment(wxLAYOUT_LEFT);
  188. // win->SetBackgroundColour(wxColour(0, 255, 255));
  189. win->SetSashVisible(wxSASH_RIGHT, TRUE);
  190. m_leftWindow2 = win;
  191. notebook = new wxNotebook(m_leftWindow2,-1);
  192. // notebook->AddPage(voicedlg,_T("Voice"),FALSE);
  193. formantdlg = new FormantDlg(notebook);
  194. notebook->AddPage(formantdlg,_T(" Spect"),FALSE);
  195. voicedlg = new VoiceDlg(notebook);
  196. transldlg = new TranslDlg(notebook);
  197. notebook->AddPage(transldlg,_T("Text"),TRUE);
  198. ConfigInit();
  199. WavegenInitSound();
  200. if((result = LoadPhData()) != 1)
  201. {
  202. if(result == -1)
  203. wxLogError(_T("Failed to load phoneme data,\nneeds espeak-data/phontab,phondata,phonindex\nPath = ")+wxString(path_home,wxConvLocal));
  204. else
  205. wxLogError(_T("Wrong version of espeak-data: 0x%x (expects 0x%x)"),result,version_phdata);
  206. error_flag = 1;
  207. }
  208. f_trans = stdout;
  209. option_ssml = 1;
  210. // if(LoadVoice(voice_name,0) == NULL)
  211. if(SetVoiceByName(voice_name2) != EE_OK)
  212. {
  213. if(error_flag==0)
  214. wxLogError(_T("Failed to load voice data"));
  215. strcpy(dictionary_name,"en");
  216. }
  217. else
  218. {
  219. SetVoiceTitle(voice_name2);
  220. }
  221. WavegenSetVoice(voice);
  222. for(param=0; param<N_SPEECH_PARAM; param++)
  223. param_stack[0].parameter[param] = param_defaults[param];
  224. SetParameter(espeakRATE,option_speed,0);
  225. SetSpeed(3);
  226. SynthesizeInit();
  227. InitSpectrumDisplay();
  228. InitProsodyDisplay();
  229. // InitWaveDisplay();
  230. espeak_ListVoices(NULL);
  231. m_timer.SetOwner(this,1);
  232. m_timer.Start(500); /* 0.5 timer */
  233. } // end of MyFrame::MyFrame
  234. void MyFrame::SetVoiceTitle(char *voice_name)
  235. {//==========================================
  236. SetTitle(AppName + _T(" - ") + wxString(voice_name,wxConvLocal) + _T(" voice"));
  237. }
  238. void MyFrame::OnKey(wxKeyEvent& event)
  239. {
  240. int key;
  241. key = event.GetKeyCode();
  242. if((currentcanvas != NULL) && (currentcanvas != FindFocus()))
  243. {
  244. if((key == WXK_F1) || (key == WXK_F2))
  245. {
  246. currentcanvas->OnKey(event);
  247. currentcanvas->SetFocus();
  248. return;
  249. }
  250. }
  251. event.Skip();
  252. }
  253. void MyFrame::OnTimer(wxTimerEvent &event)
  254. //****************************************
  255. {
  256. SynthOnTimer();
  257. }
  258. void MyFrame::OnQuit(wxCommandEvent& event)
  259. {
  260. switch(event.GetId())
  261. {
  262. case MENU_QUIT:
  263. Close(TRUE);
  264. break;
  265. case MENU_CLOSE_ALL:
  266. break;
  267. }
  268. }
  269. void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
  270. {//===================================================
  271. char buf[300];
  272. sprintf(buf,about_string,espeak_Info(NULL));
  273. (void)wxMessageBox(wxString(buf,wxConvLocal), _T("About eSpeak Editor"));
  274. }
  275. void OnOptions2(int event_id)
  276. {//==========================
  277. wxString string;
  278. int value;
  279. switch(event_id)
  280. {
  281. case MENU_PARAMS:
  282. value = wxGetNumberFromUser(_T(""),_T(""),_T("Speed"),option_speed,80,320);
  283. if(value > 0)
  284. {
  285. option_speed = value;
  286. SetParameter(espeakRATE,option_speed,0);
  287. SetSpeed(3);
  288. }
  289. break;
  290. case MENU_PATH0:
  291. string = wxFileSelector(_T("Master phonemes file"),wxFileName(path_phfile).GetPath(),
  292. _T(""),_T(""),_T("*"),wxOPEN);
  293. if(!string.IsEmpty())
  294. {
  295. path_phfile = string;
  296. }
  297. break;
  298. case MENU_PATH1:
  299. string = wxDirSelector(_T("Phoneme source directory"),path_phsource);
  300. if(!string.IsEmpty())
  301. {
  302. path_phsource = string;
  303. }
  304. break;
  305. case MENU_PATH2:
  306. string = wxDirSelector(_T("Dictionary source directory"),path_dictsource);
  307. if(!string.IsEmpty())
  308. {
  309. path_dictsource = string;
  310. }
  311. break;
  312. case MENU_PATH3:
  313. string = wxFileSelector(_T("Sound output file"),wxFileName(path_speech).GetPath(),
  314. _T(""),_T("WAV"),_T("*"),wxSAVE);
  315. if(!string.IsEmpty())
  316. {
  317. path_speech = string;
  318. }
  319. break;
  320. case MENU_PATH4:
  321. string = wxFileSelector(_T("Voice file to modify formant peaks"),wxFileName(path_speech).GetPath(),
  322. _T(""),_T(""),_T("*"),wxOPEN);
  323. if(!string.IsEmpty())
  324. {
  325. path_modifiervoice = string;
  326. }
  327. break;
  328. }
  329. ConfigSetPaths();
  330. }
  331. void MyFrame::OnOptions(wxCommandEvent& event)
  332. {//===========================================
  333. OnOptions2(event.GetId());
  334. }
  335. void MyFrame::OnTools(wxCommandEvent& event)
  336. {//=========================================
  337. int err;
  338. FILE *log;
  339. char fname_log[sizeof(path_dsource)+12];
  340. char err_fname[sizeof(path_home)+15];
  341. switch(event.GetId())
  342. {
  343. case MENU_TEST:
  344. TestTest(0);
  345. break;
  346. case MENU_TEST2:
  347. TestTest(2);
  348. break;
  349. case MENU_TO_UTF8:
  350. ConvertToUtf8();
  351. break;
  352. case MENU_COUNT_WORDS:
  353. MakeWordFreqList();
  354. break;
  355. case MENU_LEXICON_RU:
  356. case MENU_LEXICON_DE:
  357. CompareLexicon(event.GetId()); // Compare a lexicon with _rules translation
  358. break;
  359. case MENU_COMPILE_PH:
  360. CompileInit();
  361. break;
  362. case MENU_COMPILE_MBROLA:
  363. CompileMbrola();
  364. break;
  365. case MENU_COMPILE_DICT:
  366. sprintf(fname_log,"%s%s",path_dsource,"dict_log");
  367. log = fopen(fname_log,"w");
  368. if((err = CompileDictionary(path_dsource,dictionary_name,log,err_fname)) < 0)
  369. {
  370. wxLogError(_T("Can't access file:\n")+wxString(err_fname,wxConvLocal));
  371. wxString dir = wxDirSelector(_T("Directory containing dictionary files"),path_dictsource);
  372. if(!dir.IsEmpty())
  373. {
  374. path_dictsource = dir;
  375. strncpy0(path_dsource,path_dictsource.mb_str(wxConvLocal),sizeof(path_dsource)-1);
  376. strcat(path_dsource,"/");
  377. }
  378. break;
  379. }
  380. wxLogStatus(_T("Compiled '")+wxString(dictionary_name,wxConvLocal)+_T("', %d errors"),err);
  381. if(log != NULL)
  382. fclose(log);
  383. break;
  384. case MENU_VOWELCHART1:
  385. MakeVowelLists();
  386. break;
  387. case MENU_VOWELCHART2:
  388. VowelChart(2,NULL);
  389. break;
  390. case MENU_VOWELCHART3:
  391. VowelChart(3,NULL);
  392. break;
  393. case MENU_LOAD_WAV:
  394. // LoadWavFile();
  395. break;
  396. }
  397. }
  398. extern wxMenu *speak_menu;
  399. void MyFrame::OnSpeak(wxCommandEvent& event)
  400. {//=========================================
  401. switch(event.GetId())
  402. {
  403. case MENU_SPEAK_TRANSLATE:
  404. case MENU_SPEAK_RULES:
  405. case MENU_SPEAK_TEXT:
  406. transldlg->OnCommand(event);
  407. break;
  408. case MENU_SPEAK_FILE:
  409. transldlg->SpeakFile();
  410. break;
  411. case MENU_SPEAK_STOP:
  412. SpeakNextClause(NULL,NULL,2);
  413. break;
  414. case MENU_SPEAK_PAUSE:
  415. SpeakNextClause(NULL,NULL,3);
  416. if(SynthStatus() & 2)
  417. speak_menu->SetLabel(MENU_SPEAK_PAUSE,_T("&Resume"));
  418. else
  419. speak_menu->SetLabel(MENU_SPEAK_PAUSE,_T("&Pause"));
  420. break;
  421. case MENU_SPEAK_VOICE:
  422. transldlg->ReadVoice(0);
  423. SetVoiceTitle(voice_name2);
  424. break;
  425. case MENU_SPEAK_VOICE_VARIANT:
  426. transldlg->ReadVoice(1);
  427. SetVoiceTitle(voice_name2);
  428. break;
  429. }
  430. }
  431. void MyFrame::OnSashDrag(wxSashEvent& event)
  432. {
  433. if (event.GetDragStatus() == wxSASH_STATUS_OUT_OF_RANGE)
  434. return;
  435. switch (event.GetId())
  436. {
  437. case ID_WINDOW_TOP:
  438. {
  439. m_topWindow->SetDefaultSize(wxSize(1000, event.GetDragRect().height));
  440. break;
  441. }
  442. case ID_WINDOW_LEFT1:
  443. {
  444. m_leftWindow1->SetDefaultSize(wxSize(event.GetDragRect().width, 1000));
  445. break;
  446. }
  447. case ID_WINDOW_LEFT2:
  448. {
  449. m_leftWindow2->SetDefaultSize(wxSize(event.GetDragRect().width, 1000));
  450. break;
  451. }
  452. case ID_WINDOW_BOTTOM:
  453. {
  454. m_bottomWindow->SetDefaultSize(wxSize(1000, event.GetDragRect().height));
  455. break;
  456. }
  457. }
  458. wxLayoutAlgorithm layout;
  459. layout.LayoutMDIFrame(this);
  460. // Leaves bits of itself behind sometimes
  461. GetClientWindow()->Refresh();
  462. }
  463. void MyFrame::OnSize(wxSizeEvent& WXUNUSED(event))
  464. {
  465. wxLayoutAlgorithm layout;
  466. layout.LayoutMDIFrame(this);
  467. }
  468. // Note that SASHTEST_NEW_WINDOW and SASHTEST_ABOUT commands get passed
  469. // to the parent window for processing, so no need to
  470. // duplicate event handlers here.
  471. BEGIN_EVENT_TABLE(MyChild, wxMDIChildFrame)
  472. EVT_MENU(SPECTSEQ_CLOSE, MyChild::OnQuit)
  473. EVT_MENU(SPECTSEQ_SAVE, MyChild::OnSave)
  474. EVT_MENU(SPECTSEQ_SAVEAS, MyChild::OnSaveAs)
  475. EVT_MENU(SPECTSEQ_SAVESELECT, MyChild::OnSaveSelect)
  476. EVT_MENU(SPECTSEQ_SAVEPITCH, MyChild::OnSavePitchenv)
  477. EVT_ACTIVATE(MyChild::OnActivate)
  478. END_EVENT_TABLE()
  479. MyChild::MyChild(wxMDIParentFrame *parent, const wxString& title, const wxPoint& pos, const wxSize& size,
  480. const long style):
  481. wxMDIChildFrame(parent, -1, title, pos, size, style)
  482. {
  483. canvas = NULL;
  484. my_children.Append(this);
  485. }
  486. MyChild::~MyChild(void)
  487. {
  488. wxWindow *w;
  489. canvas = NULL;
  490. #ifndef PLATFORM_WINDOWS
  491. // bug in wxMDIChildFrame, we need to explicitly remove the ChildFrame from the ClientWindow
  492. w = myframe->GetClientWindow();
  493. w->RemoveChild(this);
  494. #endif
  495. my_children.DeleteObject(this);
  496. }
  497. //extern void CloseCanvas();
  498. void MyChild::OnQuit(wxCommandEvent& WXUNUSED(event))
  499. {
  500. Destroy();
  501. }
  502. void MyChild::OnSave(wxCommandEvent& WXUNUSED(event))
  503. {
  504. canvas->Save(canvas->savepath);
  505. }
  506. void MyChild::OnSaveAs(wxCommandEvent& WXUNUSED(event))
  507. {
  508. canvas->Save();
  509. }
  510. void MyChild::OnSaveSelect(wxCommandEvent& WXUNUSED(event))
  511. {
  512. canvas->Save(_T(""),1);
  513. }
  514. void MyChild::OnSavePitchenv(wxCommandEvent& WXUNUSED(event))
  515. {
  516. canvas->SavePitchenv(canvas->spectseq->pitchenv);
  517. }
  518. void MyChild::OnActivate(wxActivateEvent& event)
  519. {
  520. if(canvas)
  521. canvas->OnActivate(event.GetActive());
  522. }