2 * MStarDict - International dictionary for Maemo.
3 * Copyright (C) 2010 Roman Moravcik
5 * base on code of stardict:
6 * Copyright (C) 2003-2007 Hu Zheng <huzheng_001@163.com>
8 * based on code of sdcv:
9 * Copyright (C) 2005-2006 Evgeniy <dushistov@mail.ru>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
36 #include <glib/gi18n.h>
39 #include <hildon/hildon.h>
43 #include "mstardict.hpp"
45 #include <espeak/speak_lib.h>
65 static TtsVoice voices[] = {
66 {"afrikaans", N_("Afrikaans")},
67 {"bosnian", N_("Bosnian")},
68 {"catalan", N_("Catalan")},
69 {"czech", N_("Czech")},
70 {"welsh-test", N_("Welsh")},
71 {"danish", N_("Danish")},
72 {"german", N_("German")},
73 {"greek", N_("Greek")},
74 {"en-scottish", N_("English (Scottish)")},
75 {"english", N_("English")},
76 {"lancashire", N_("English (Lancashire)")},
77 {"english_rp", N_("English (Received Pronunciation)")},
78 {"english_wmids", N_("English (West Midlands)")},
79 {"english-us", N_("English (American)")},
80 {"en-westindies", N_("English (Westindies)")},
81 {"esperanto", N_("Esperanto")},
82 {"spanish", N_("Spanish")},
83 {"spanish-latin-american", N_("Spanish (Latin American)")},
84 {"finnish", N_("Finnish")},
85 {"french", N_("French")},
86 {"french (Belgium)", N_("French (Belgium)")},
87 {"greek-ancient", N_("Greek (Ancient)")},
88 {"hindi", N_("Hindi")},
89 {"croatian", N_("Croatian")},
90 {"hungarian", N_("Hungarian")},
91 {"armenian", N_("Armenian")},
92 {"armenian-west", N_("Armenian (West)")},
93 {"indonesian-test", N_("Indonesian")},
94 {"icelandic-test", N_("Icelandic")},
95 {"italian", N_("Italian")},
96 {"lojban", N_("Lojban")},
97 {"kurdish", N_("Kurdish")},
98 {"latin", N_("Latin")},
99 {"latvian", N_("Latvian")},
100 {"macedonian-test", N_("Macedonian")},
101 {"dutch-test", N_("Dutch")},
102 {"norwegian", N_("Norwegian")},
103 {"papiamento-test", N_("Papiamento")},
104 {"polish", N_("Polish")},
105 {"brazil", N_("Brazil")},
106 {"portugal", N_("Portugal")},
107 {"romanian", N_("Romanian")},
108 {"russian_test", N_("Russian")},
109 {"slovak", N_("Slovak")},
110 {"albanian", N_("Albanian")},
111 {"serbian", N_("Serbian")},
112 {"swedish", N_("Swedish")},
113 {"swahihi-test", N_("Swahihi")},
114 {"tamil", N_("Tamil")},
115 {"turkish", N_("Turkish")},
116 {"vietnam", N_("Vietnamese")},
117 {"Mandarin", N_("Chinese (Mandarin)")},
118 {"cantonese", N_("Chinese (Cantonese)")},
119 {"akan-test", N_("Akam")},
120 {"amharic-test", N_("Amharic")},
121 {"azerbaijani-test", N_("Azerbaijani")},
122 {"bulgarian-test", N_("Bulgarian")},
123 {"dari-test", N_("Dari")},
124 {"divehi-test", N_("Divehi")},
125 {"georgian-test", N_("Georgian")},
126 {"haitian", N_("Haitian")},
127 {"kannada", N_("Kannada")},
128 {"kinyarwanda-test", N_("Kinyarwanda")},
129 {"malayalam", N_("Mlayalam")},
130 {"nahuatl - clasical", N_("Nahuatl (Clasical)")},
131 {"nepali-test", N_("Nepali")},
132 {"northern-sotho", N_("Northern Sotho")},
133 {"punjabi-test", N_("Punjabi")},
134 {"setswana-test", N_("Setswana")},
135 {"sinhala", N_("Sinhala")},
136 {"slovenian-test", N_("Slovenian")},
137 {"swahili-test", N_("Swahili")},
138 {"telugu", N_("Telugu")},
139 {"urdu-test", N_("Urdu")},
140 {"wolof-test", N_("Wolof")},
141 {"default", N_("Default")},
146 Tts::Tts(MStarDict *mStarDict)
149 bool tts_enabled = false;
150 int engine = ENGINE_NONE;
151 gchar *language = NULL;
152 int gender = GENDER_NONE;
154 oStarDict = mStarDict;
157 /* initialize espeak */
158 rate = espeak_Initialize(AUDIO_OUTPUT_PLAYBACK, 512, NULL, 0);
160 /* check if tts is enabled */
161 if (!oStarDict->oConf->GetBool("/apps/maemo/mstardict/tts_enabled", &tts_enabled)) {
166 /* read configured engine */
167 if (!oStarDict->oConf->GetInt("/apps/maemo/mstardict/tts_engine", &engine)) {
168 engine = ENGINE_ESPEAK;
171 /* read configured language */
172 if (!oStarDict->oConf->GetString("/apps/maemo/mstardict/tts_language", &language)) {
173 language = g_strdup("english");
176 /* read configured gender */
177 if (!oStarDict->oConf->GetInt("/apps/maemo/mstardict/tts_gender", &gender)) {
178 gender = GENDER_MALE;
180 SetVoice(engine, language, gender);
189 /* deinitialize espeak */
194 Tts::Enable(bool bEnable)
206 Tts::SetVoice(int engine, const gchar *language, int gender)
212 memset(&voice, 0, sizeof(espeak_VOICE));
213 voice.name = language;
214 voice.gender = gender;
216 espeak_SetVoiceByProperties(&voice);
220 Tts::SayText(const gchar *sText)
222 if (Engine == ENGINE_ESPEAK) {
223 espeak_Synth(sText, strlen(sText) + 1, 0, POS_CHARACTER, 0, espeakCHARS_UTF8, NULL, NULL);
225 } else if (Engine == ENGINE_REALPEOPLE) {
226 gchar *lower = g_utf8_strdown(sText, -1);
230 gchar *cmd = g_strdup_printf("paplay /home/user/MyDocs/mstardict/WyabdcRealPeopleTTS/%c/%s.wav", lower[0], lower);
246 const espeak_VOICE **espeak_voices;
247 GtkListStore *list_store;
251 list_store = gtk_list_store_new(N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
253 espeak_voices = espeak_ListVoices(NULL);
254 while (espeak_voices[i]) {
255 gchar *disp_name = NULL;
257 for (int j = 0; voices[j].name != NULL; j++) {
258 if (!strcmp(espeak_voices[i]->name, voices[j].name)) {
259 disp_name = g_strdup(_(voices[j].disp_name));
264 if (disp_name == NULL)
265 disp_name = g_strdup(espeak_voices[i]->name);
267 gtk_list_store_append(list_store, &iter);
268 gtk_list_store_set(list_store,
270 DISPNAME_COLUMN, disp_name,
271 NAME_COLUMN, espeak_voices[i]->name,
283 Tts::onTtsEnableButtonClicked(GtkButton *button,
286 if (hildon_check_button_get_active(HILDON_CHECK_BUTTON(button))) {
287 gtk_widget_set_sensitive(GTK_WIDGET(oTts->engine_espeak_button), TRUE);
288 gtk_widget_set_sensitive(GTK_WIDGET(oTts->engine_realpeople_button), TRUE);
289 gtk_widget_set_sensitive(GTK_WIDGET(oTts->gender_male_button), TRUE);
290 gtk_widget_set_sensitive(GTK_WIDGET(oTts->gender_female_button), TRUE);
291 gtk_widget_set_sensitive(GTK_WIDGET(oTts->language_button), TRUE);
293 gtk_widget_set_sensitive(GTK_WIDGET(oTts->engine_espeak_button), FALSE);
294 gtk_widget_set_sensitive(GTK_WIDGET(oTts->engine_realpeople_button), FALSE);
295 gtk_widget_set_sensitive(GTK_WIDGET(oTts->gender_male_button), FALSE);
296 gtk_widget_set_sensitive(GTK_WIDGET(oTts->gender_female_button), FALSE);
297 gtk_widget_set_sensitive(GTK_WIDGET(oTts->language_button), FALSE);
303 Tts::onTtsEngineButtonClicked(GtkWidget *button,
308 if (button != oTts->engine_realpeople_button)
309 button2 = oTts->engine_realpeople_button;
311 button2 = oTts->engine_espeak_button;
313 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
314 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button2), FALSE);
316 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button2), TRUE);
318 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(oTts->engine_espeak_button))) {
319 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(oTts->engine_realpeople_button), FALSE);
320 gtk_widget_set_sensitive(GTK_WIDGET(oTts->gender_male_button), TRUE);
321 gtk_widget_set_sensitive(GTK_WIDGET(oTts->gender_female_button), TRUE);
322 gtk_widget_set_sensitive(GTK_WIDGET(oTts->language_button), TRUE);
324 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(oTts->engine_realpeople_button), TRUE);
325 gtk_widget_set_sensitive(GTK_WIDGET(oTts->gender_male_button), FALSE);
326 gtk_widget_set_sensitive(GTK_WIDGET(oTts->gender_female_button), FALSE);
327 gtk_widget_set_sensitive(GTK_WIDGET(oTts->language_button), FALSE);
330 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(oTts->engine_realpeople_button))) {
331 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(oTts->engine_espeak_button), FALSE);
333 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(oTts->engine_espeak_button), TRUE);
340 Tts::onTtsGenderButtonClicked(GtkToggleButton *button1,
341 GtkToggleButton *button2)
343 if (gtk_toggle_button_get_active(button1))
344 gtk_toggle_button_set_active(button2, FALSE);
346 gtk_toggle_button_set_active(button2, TRUE);
351 Tts::CreateTtsConfWidget()
353 GtkWidget *frame, *vbox, *engine_hbox, *gender_hbox;
355 HildonTouchSelectorColumn *column;
356 GtkListStore *voices_list;
358 frame = gtk_frame_new(_("Text-To-Speech"));
360 vbox = gtk_vbox_new(FALSE, 0);
361 gtk_container_add(GTK_CONTAINER(frame), vbox);
363 /* enable tts button */
364 enable_button = hildon_check_button_new(HILDON_SIZE_FINGER_HEIGHT);
365 gtk_button_set_label(GTK_BUTTON(enable_button), _("Enable"));
366 gtk_box_pack_start(GTK_BOX(vbox), enable_button, TRUE, TRUE, 0);
368 /* engine selection */
369 engine_hbox = gtk_hbox_new(TRUE, 0);
370 gtk_box_pack_start(GTK_BOX(vbox), engine_hbox, TRUE, TRUE, 0);
372 engine_espeak_button = hildon_gtk_toggle_button_new(HILDON_SIZE_FINGER_HEIGHT);
373 gtk_button_set_label(GTK_BUTTON(engine_espeak_button), _("eSpeak"));
374 gtk_box_pack_start(GTK_BOX(engine_hbox), engine_espeak_button, TRUE, TRUE, 0);
376 engine_realpeople_button = hildon_gtk_toggle_button_new(HILDON_SIZE_FINGER_HEIGHT);
377 gtk_button_set_label(GTK_BUTTON(engine_realpeople_button), _("Real People"));
378 gtk_box_pack_start(GTK_BOX(engine_hbox), engine_realpeople_button, TRUE, TRUE, 0);
380 /* gender selection */
381 gender_hbox = gtk_hbox_new(TRUE, 0);
382 gtk_box_pack_start(GTK_BOX(vbox), gender_hbox, TRUE, TRUE, 0);
384 gender_male_button = hildon_gtk_toggle_button_new(HILDON_SIZE_FINGER_HEIGHT);
385 gtk_button_set_label(GTK_BUTTON(gender_male_button), _("Male"));
386 gtk_box_pack_start(GTK_BOX(gender_hbox), gender_male_button, TRUE, TRUE, 0);
388 gender_female_button = hildon_gtk_toggle_button_new(HILDON_SIZE_FINGER_HEIGHT);
389 gtk_button_set_label(GTK_BUTTON(gender_female_button), _("Female"));
390 gtk_box_pack_start(GTK_BOX(gender_hbox), gender_female_button, TRUE, TRUE, 0);
392 /* language picker button */
393 language_button = hildon_picker_button_new(HILDON_SIZE_FINGER_HEIGHT,
394 HILDON_BUTTON_ARRANGEMENT_VERTICAL);
395 hildon_button_set_title(HILDON_BUTTON(language_button), _("Language"));
396 hildon_button_set_alignment(HILDON_BUTTON(language_button), 0.0, 0.5, 1.0, 0.0);
397 hildon_button_set_title_alignment(HILDON_BUTTON(language_button), 0.0, 0.5);
398 gtk_box_pack_start(GTK_BOX(vbox), language_button, TRUE, TRUE, 0);
400 /* get list of voices */
401 voices_list = GetVoicesList();
403 /* sort list of voices */
404 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(voices_list),
405 DISPNAME_COLUMN, GTK_SORT_ASCENDING);
407 /* voices selector */
408 selector = hildon_touch_selector_new();
409 column = hildon_touch_selector_append_text_column(HILDON_TOUCH_SELECTOR(selector),
410 GTK_TREE_MODEL(voices_list), TRUE);
411 g_object_set(G_OBJECT(column), "text-column", DISPNAME_COLUMN, NULL);
413 hildon_picker_button_set_selector(HILDON_PICKER_BUTTON(language_button),
414 HILDON_TOUCH_SELECTOR(selector));
416 g_signal_connect(enable_button, "clicked", G_CALLBACK(onTtsEnableButtonClicked), this);
417 g_signal_connect(engine_espeak_button, "clicked", G_CALLBACK(onTtsEngineButtonClicked), this);
418 g_signal_connect(engine_realpeople_button, "clicked", G_CALLBACK(onTtsEngineButtonClicked), this);
419 g_signal_connect(gender_male_button, "clicked", G_CALLBACK(onTtsGenderButtonClicked), gender_female_button);
420 g_signal_connect(gender_female_button, "clicked", G_CALLBACK(onTtsGenderButtonClicked), gender_male_button);
426 Tts::TtsConfWidgetLoadConf()
428 HildonTouchSelector *selector;
430 int engine = ENGINE_NONE;
431 int gender = GENDER_NONE;
432 gchar *language = NULL;
434 gboolean iter_valid = TRUE;
437 hildon_check_button_set_active(HILDON_CHECK_BUTTON(enable_button), TRUE);
438 gtk_widget_set_sensitive(language_button, TRUE);
440 hildon_check_button_set_active(HILDON_CHECK_BUTTON(enable_button), FALSE);
441 gtk_widget_set_sensitive(language_button, FALSE);
444 if (oStarDict->oConf->GetInt("/apps/maemo/mstardict/tts_engine", &engine)) {
445 if (engine == ENGINE_ESPEAK)
446 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(engine_espeak_button), TRUE);
448 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(engine_realpeople_button), TRUE);
450 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(engine_espeak_button), TRUE);
453 if (oStarDict->oConf->GetInt("/apps/maemo/mstardict/tts_gender", &gender)) {
454 if (gender == GENDER_MALE)
455 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gender_male_button), TRUE);
457 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gender_female_button), TRUE);
459 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gender_male_button), TRUE);
462 if (oStarDict->oConf->GetString("/apps/maemo/mstardict/tts_language", &language)) {
464 selector = hildon_picker_button_get_selector(HILDON_PICKER_BUTTON(language_button));
465 model = hildon_touch_selector_get_model(HILDON_TOUCH_SELECTOR(selector), DISPNAME_COLUMN);
466 for (iter_valid = gtk_tree_model_get_iter_first(model, &iter); iter_valid; iter_valid = gtk_tree_model_iter_next(model, &iter)) {
468 gtk_tree_model_get(model, &iter, NAME_COLUMN, &tmp, -1);
469 if (strcmp(tmp, language) == 0) {
470 hildon_touch_selector_select_iter(HILDON_TOUCH_SELECTOR(selector), DISPNAME_COLUMN, &iter, FALSE);
477 hildon_picker_button_set_active (HILDON_PICKER_BUTTON (language_button), -1);
482 Tts::TtsConfWidgetSaveConf()
484 bool enabled = false;
485 HildonTouchSelector *selector;
487 int engine = ENGINE_NONE;
488 int gender = GENDER_NONE;
489 const gchar *language = NULL;
491 enabled = hildon_check_button_get_active(HILDON_CHECK_BUTTON(enable_button));
492 if (oStarDict->oConf->SetBool("/apps/maemo/mstardict/tts_enabled", enabled))
495 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(engine_espeak_button)))
496 engine = ENGINE_ESPEAK;
498 engine = ENGINE_REALPEOPLE;
499 oStarDict->oConf->SetInt("/apps/maemo/mstardict/tts_engine", engine);
501 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gender_male_button)))
502 gender = GENDER_MALE;
504 gender = GENDER_FEMALE;
505 oStarDict->oConf->SetInt("/apps/maemo/mstardict/tts_gender", gender);
510 if (hildon_picker_button_get_active(HILDON_PICKER_BUTTON(language_button)) > -1) {
511 selector = hildon_picker_button_get_selector(HILDON_PICKER_BUTTON(language_button));
512 if (hildon_touch_selector_get_selected(selector, DISPNAME_COLUMN, &iter)) {
513 gtk_tree_model_get(hildon_touch_selector_get_model(selector, DISPNAME_COLUMN), &iter, NAME_COLUMN, &language, -1);
515 /* fixme convert back disp_name */
516 if (oStarDict->oConf->SetString("/apps/maemo/mstardict/tts_language", language))
517 SetVoice(engine, language, gender);