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.

voicedlg.cpp 8.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  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, write see: *
  17. * <http://www.gnu.org/licenses/>. *
  18. ***************************************************************************/
  19. #include "wx/wx.h"
  20. #include "speak_lib.h"
  21. #include "main.h"
  22. #include "speech.h"
  23. #include "phoneme.h"
  24. #include "synthesize.h"
  25. #include "voice.h"
  26. #include "spect.h"
  27. #include "options.h"
  28. #include "wx/dialog.h"
  29. #include "wx/textctrl.h"
  30. #include "wx/checkbox.h"
  31. #include "wx/txtstrm.h"
  32. #include "wx/wfstream.h"
  33. #include "wx/filename.h"
  34. VoiceDlg *voicedlg = NULL;
  35. voice_t voice_data;
  36. USHORT voice_pcnt[N_PEAKS+1][3];
  37. static void VoiceSetup()
  38. {//=====================
  39. int pk;
  40. voice_t *v = &voice_data;
  41. for(pk=0; pk<N_PEAKS; pk++)
  42. {
  43. v->freq[pk] = int(voice_pcnt[pk][0] * 2.56001 * voice_pcnt[N_PEAKS][0] / 100.0);
  44. v->height[pk] = int(voice_pcnt[pk][1] * 2.56001 * voice_pcnt[N_PEAKS][1] / 100.0);
  45. v->width[pk] = int(voice_pcnt[pk][2] * 2.56001 * voice_pcnt[N_PEAKS][2] / 100.0);
  46. }
  47. }
  48. static void VoiceInit()
  49. {//====================
  50. int pk, j;
  51. voice_t *v;
  52. v = &voice_data;
  53. v->pitch_base = 71 << 12;
  54. v->pitch_range = 0x1000; // default = 0x1000
  55. for(pk=0; pk<N_PEAKS+1; pk++)
  56. {
  57. for(j=0; j<3; j++)
  58. voice_pcnt[pk][j] = 100;
  59. }
  60. VoiceSetup();
  61. voice = v;
  62. } // end of voice_init
  63. #define VD_DEFAULTS 401
  64. #define VD_LOAD 402
  65. #define VD_SAVE 403
  66. #define VD_PITCHCHOICE 404
  67. #define VD_PITCH1 405
  68. #define VD_PITCH2 406
  69. #define VD_USEPITCH 407
  70. wxString pitchchoices[3] = {_T("From spectrum"),_T("Standard"),_T("Monotone")};
  71. BEGIN_EVENT_TABLE(VoiceDlg, wxPanel)
  72. EVT_BUTTON(VD_DEFAULTS,VoiceDlg::OnCommand)
  73. EVT_BUTTON(VD_LOAD,VoiceDlg::OnCommand)
  74. EVT_BUTTON(VD_SAVE,VoiceDlg::OnCommand)
  75. EVT_SPINCTRL(VD_PITCH1,VoiceDlg::OnSpin)
  76. EVT_SPINCTRL(VD_PITCH2,VoiceDlg::OnSpin)
  77. EVT_CHECKBOX(VD_USEPITCH,VoiceDlg::OnCommand)
  78. EVT_COMBOBOX(VD_PITCHCHOICE,VoiceDlg::OnCommand)
  79. END_EVENT_TABLE()
  80. VoiceDlg::VoiceDlg(wxWindow *parent) : wxPanel(parent)
  81. {//=========================================================
  82. int ix, j;
  83. int y;
  84. wxString string;
  85. voice_t *v;
  86. wxString captions[3] = {_T("Freq"),_T("Height"),_T("Width")};
  87. voice_p = v = &voice_data;
  88. VoiceInit();
  89. pitch1 = 80;
  90. pitch2 = 120;
  91. for(j=0; j<3; j++)
  92. new wxStaticText(this,-1,captions[j],wxPoint(34+j*56,6));
  93. y = 26;
  94. for(ix=0; ix<N_PEAKS+1; ix++)
  95. {
  96. if(ix==N_PEAKS)
  97. {
  98. string = _T("All");
  99. y += 8;
  100. }
  101. else
  102. string.Printf(_T("%2d"),ix);
  103. vd_labpk[ix] = new wxStaticText(this,-1,string,wxPoint(8,y+2));
  104. for(j=0; j<3; j++)
  105. {
  106. string.Printf(_T("%d"),voice_pcnt[ix][j]);
  107. vd[ix][j] = new wxSpinCtrl(this,-1,string,
  108. wxPoint(32+j*56,y),wxSize(52,22),wxSP_ARROW_KEYS,0,300);
  109. }
  110. y += 26;
  111. }
  112. for(ix=6; ix<N_PEAKS; ix++)
  113. vd[ix][2]->Hide();
  114. vd_defaults = new wxButton(this,VD_DEFAULTS,_T("Defaults"),wxPoint(32,293));
  115. y = 324;
  116. vd_pitch1 = new wxSpinCtrl(this,VD_PITCH1,_T("80"),
  117. wxPoint(32,y),wxSize(52,24),wxTE_CENTRE,60,500);
  118. vd_pitch2 = new wxSpinCtrl(this,VD_PITCH2,_T("120"),
  119. wxPoint(88,y),wxSize(52,24),wxTE_CENTRE,60,500);
  120. vd_lab[1] = new wxStaticText(this,-1,_T("Hz"),wxPoint(142,y+2));
  121. vd_usepitch = new wxCheckBox(this,VD_USEPITCH,_T("Pitch from spectrum"),
  122. wxPoint(4,y+24));
  123. // vd_load = new wxButton(this,VD_LOAD,_T("Load"),wxPoint(16,y+56));
  124. // vd_save = new wxButton(this,VD_SAVE,_T("Save"),wxPoint(106,y+56));
  125. y = 422;
  126. vd_duration = new wxTextCtrl(this,-1,_T(""),
  127. wxPoint(4,y),wxSize(52,24),wxTE_CENTRE);
  128. vd_lab[2] = new wxStaticText(this,-1,_T("Duration"),wxPoint(60,y+2));
  129. y = 422;
  130. vd_pitchchoice = new wxComboBox(this,VD_PITCHCHOICE,_T("Standard"),
  131. wxPoint(4,y+30),wxSize(192,24),3,pitchchoices);
  132. vd_pitchgraph = new ByteGraph(this,wxPoint(0,y+60),wxSize(200,100));
  133. vd_pitchgraph->SetData(128,env_fall);
  134. vd_pitchgraph->Show();
  135. } // end of VoiceDlg::VoiceDlg
  136. void VoiceDlg::OnCommand(wxCommandEvent& event)
  137. {//============================================
  138. // JSD EVT_COMBOBOX causes GDB lockup if a breakpoint is set
  139. int id;
  140. int ix, j;
  141. switch(id = event.GetId())
  142. {
  143. case VD_DEFAULTS:
  144. for(ix=0; ix<N_PEAKS+1; ix++)
  145. {
  146. for(j=0; j<3; j++)
  147. {
  148. voice_pcnt[ix][j] = 100;
  149. vd[ix][j]->SetValue(_T("100"));
  150. }
  151. }
  152. VoiceSetup();
  153. break;
  154. case VD_LOAD:
  155. // Load();
  156. break;
  157. case VD_SAVE:
  158. // Save();
  159. break;
  160. case VD_USEPITCH:
  161. case VD_PITCHCHOICE:
  162. if(currentcanvas != NULL)
  163. SetFromSpect(currentcanvas->spectseq);
  164. break;
  165. }
  166. if(currentcanvas != NULL) currentcanvas->SetFocus();
  167. } // end of VoiceDlg::OnCommand
  168. void VoiceDlg::ReadParams()
  169. {//========================
  170. int ix, j;
  171. pitchenv.pitch1 = vd_pitch1->GetValue();
  172. pitchenv.pitch2 = vd_pitch2->GetValue();
  173. voice_data.pitch_base = (pitchenv.pitch1 - 9) << 12;
  174. voice_data.pitch_range = (pitchenv.pitch2 - pitchenv.pitch1) * 108;
  175. for(ix=0; ix<N_PEAKS+1; ix++)
  176. {
  177. for(j=0; j<3; j++)
  178. {
  179. voice_pcnt[ix][j] = vd[ix][j]->GetValue();
  180. }
  181. }
  182. VoiceSetup();
  183. } // end of VoiceDlg::ReadParams
  184. void VoiceDlg::WriteParams()
  185. {//========================
  186. int ix;
  187. voice_t *v = voice;
  188. int val1, val2;
  189. val1 = (v->pitch_base >> 12) + 9;
  190. val2 = v->pitch_range/108 + val1;
  191. vd_pitch1->SetValue(val1);
  192. vd_pitch2->SetValue(val2);
  193. for(ix=0; ix<N_PEAKS; ix++)
  194. {
  195. vd[ix][0]->SetValue(int(float(v->freq[ix]) / 2.56001 + 0.5));
  196. vd[ix][1]->SetValue(int(float(v->height[ix]) / 2.56001 + 0.5));
  197. vd[ix][2]->SetValue(int(float(v->width[ix]) / 2.56001 + 0.5));
  198. }
  199. vd[ix][0]->SetValue(100);
  200. vd[ix][1]->SetValue(100);
  201. vd[ix][2]->SetValue(100);
  202. } // end of VoiceDlg::WriteParams
  203. void VoiceDlg::OnSpin(wxSpinEvent& event)
  204. {//======================================
  205. ReadParams();
  206. }
  207. #ifdef deleted
  208. void VoiceDlg::Save()
  209. {//==================
  210. int pk;
  211. wxString filename;
  212. FILE *f;
  213. filename = wxFileSelector(_T("Save voice"),path_voices,_T(""),_T(""),_T("*"),wxSAVE);
  214. if(filename.IsEmpty())
  215. return;
  216. f = fopen(filename.mb_str(wxConvLocal),"w");
  217. if(f == NULL)
  218. {
  219. wxLogError(_T("Failed to open '%s'"),filename.c_str());
  220. return;
  221. }
  222. wxFileName fn(filename);
  223. path_voices = fn.GetPath();
  224. ReadParams();
  225. fprintf(f,"%3d %3d\n",vd_pitch1->GetValue(),vd_pitch2->GetValue());
  226. for(pk=0; pk<N_PEAKS+1; pk++)
  227. {
  228. fprintf(f,"%3d %3d %3d\n",voice_pcnt[pk][0],voice_pcnt[pk][1],voice_pcnt[pk][2]);
  229. }
  230. fclose(f);
  231. } // end of VoiceDlg::Save
  232. void VoiceDlg::Load()
  233. {//===============================
  234. wxString filename;
  235. int pk, j;
  236. filename = wxFileSelector(_T("Load voice"),path_voices,_T(""),_T(""),_T("*"),wxOPEN);
  237. if(filename.IsEmpty()) return;
  238. wxFileInputStream stream(filename);
  239. if(stream.Ok() == FALSE)
  240. {
  241. wxLogError(_T("Failed to open '%s'"),filename.c_str());
  242. return;
  243. }
  244. wxFileName fn(filename);
  245. path_voices = fn.GetPath();
  246. wxTextInputStream s(stream);
  247. s >> pitch1;
  248. s >> pitch2;
  249. for(pk=0; pk<N_PEAKS+1; pk++)
  250. {
  251. for(j=0; j<3; j++)
  252. {
  253. s >> voice_pcnt[pk][j];
  254. SetSpinCtrl(vd[pk][j],voice_pcnt[pk][j]);
  255. }
  256. }
  257. SetSpinCtrl(voicedlg->vd_pitch1,pitch1);
  258. SetSpinCtrl(voicedlg->vd_pitch2,pitch2);
  259. ReadParams();
  260. } // end of VoiceDlg::Load
  261. #endif
  262. void VoiceDlg::SetFromSpect(SpectSeq* spect)
  263. {//=========================================
  264. if(spect==NULL) return;
  265. if(vd_pitchchoice->GetValue() == _T("From spectrum"))
  266. {
  267. pitchenv = spect->pitchenv;
  268. }
  269. else
  270. if(vd_pitchchoice->GetValue() == _T("Monotone"))
  271. {
  272. memset(pitchenv.env,127,128);
  273. }
  274. else
  275. if(vd_pitchchoice->GetValue() == _T("Standard"))
  276. {
  277. memcpy(pitchenv.env,env_fall,128);
  278. }
  279. vd_pitchgraph->SetData(128,pitchenv.env);
  280. vd_pitchgraph->Show();
  281. if(vd_usepitch->GetValue())
  282. {
  283. SetSpinCtrl(vd_pitch1,spect->pitch1);
  284. SetSpinCtrl(vd_pitch2,spect->pitch2);
  285. }
  286. else
  287. {
  288. SetSpinCtrl(vd_pitch1,pitch1);
  289. SetSpinCtrl(vd_pitch2,pitch2);
  290. }
  291. } // end of VoiceDlg::SetFromSpect