#include "Layout.hpp"
#include "Singleton.hpp"
#include "Slider.hpp"
+#include "TextToSpeech.hpp"
#include "VConf.hpp"
#include "setting-accessibility.h"
#include "utils.hpp"
#include <app.h>
#include <efl_extension.h>
-#include <tts_setting.h>
#include <vconf-internal-keys.h>
#include <vconf.h>
ScreenReaderSettingsPage::ScreenReaderSettingsPage()
: context_(Singleton<AppContext>::instance())
{
- int s_speed = -1;
- int s_speed_normal = -1;
- int s_speed_max = -1;
- int s_speed_min = -1;
-
auto genlist = Widget::make<Genlist>(context_.getNaviframe());
genlist->setMode(ELM_LIST_COMPRESS);
genlist->setStyle("dialogue");
DEBUG("Creating items");
- if (0 != tts_setting_initialize())
- ERROR("Fail to setting initialize");
-
- DEBUG("tts initialized");
- if (0 != tts_setting_get_speed(&s_speed))
- ERROR("Fail to get speed");
-
- if (0 != tts_setting_get_speed_range(&s_speed_min, &s_speed_normal, &s_speed_max))
- ERROR("Fail to get speed range");
- auto denominator = s_speed_max - s_speed_min;
- double s_speed_percent = 0.0;
- if (denominator != 0)
- s_speed_percent = (((double)s_speed - (double)s_speed_min) / ((double)denominator)) * 100;
- std::string buf = std::to_string(std::lround(s_speed_percent));
- DEBUG("TTS rate is %.0f", s_speed_percent);
-
- /* Item 1 : Speech Rate */
- speechRateItem_ = genlist->appendItem(
- {"type1", "IDS_ST_BODY_SPEECH_RATE", buf, [this](auto item) { this->createSpeechRatePopup(); }});
+ auto percentage = calculateSpeedPercentage();
+ speechRateItem_ = genlist->appendItem({"type1", "IDS_ST_BODY_SPEECH_RATE", percentage, [this](auto item) { this->createSpeechRatePopup(); }});
- tts_setting_set_speed_changed_cb(ttsSpeedChangedCb, speechRateItem_);
+ Singleton<TextToSpeech>::instance().addSpeedChangedCb([item = speechRateItem_](auto val) {
+ DEBUG("Speed changed to (%d)", val);
+ item->setDescription(std::to_string(val));
+ item->update();
+ });
auto item = genlist->appendItem({"multiline",
"IDS_ACCS_OPT_KEYBOARD_FEEDBACK_TTS",
"IDS_ACCS_OPT_ALWAYS_READ_OUT_KEYBOARD_INPUT_TTS",
[](auto item) {
- Singleton<VConfInterface>::instance().set(
- VCONFKEY_SETAPPL_ACCESSIBILITY_SCREEN_READER_KEYBOARD_FEEDBACK, item->getState());
+ Singleton<VConfInterface>::instance().set(VCONFKEY_SETAPPL_ACCESSIBILITY_SCREEN_READER_KEYBOARD_FEEDBACK, item->getState());
},
GenlistItem::WidgetType::toggle});
- item->setState(
- Singleton<VConfInterface>::instance().get(VCONFKEY_SETAPPL_ACCESSIBILITY_SCREEN_READER_KEYBOARD_FEEDBACK, false));
+ item->setState(Singleton<VConfInterface>::instance().get(VCONFKEY_SETAPPL_ACCESSIBILITY_SCREEN_READER_KEYBOARD_FEEDBACK, false));
item = genlist->appendItem({"type1",
"IDS_ACCS_MBODY_READ_OUT_USAGE_HINTS_ABB",
{},
[](auto item) {
- Singleton<VConfInterface>::instance().set(
- VCONFKEY_SETAPPL_ACCESSIBILITY_SCREEN_READER_DESCRIPTION, item->getState());
+ Singleton<VConfInterface>::instance().set(VCONFKEY_SETAPPL_ACCESSIBILITY_SCREEN_READER_DESCRIPTION, item->getState());
},
GenlistItem::WidgetType::toggle});
item->setState(Singleton<VConfInterface>::instance().get(VCONFKEY_SETAPPL_ACCESSIBILITY_SCREEN_READER_DESCRIPTION, false));
"IDS_ACCS_MBODY_VIBRATION_FEEDBACK",
{},
[](auto item) {
- Singleton<VConfInterface>::instance().set(
- VCONFKEY_SETAPPL_ACCESSIBILITY_SCREEN_READER_HAPTIC, item->getState());
+ Singleton<VConfInterface>::instance().set(VCONFKEY_SETAPPL_ACCESSIBILITY_SCREEN_READER_HAPTIC, item->getState());
},
GenlistItem::WidgetType::toggle});
item->setState(Singleton<VConfInterface>::instance().get(VCONFKEY_SETAPPL_ACCESSIBILITY_SCREEN_READER_HAPTIC, false));
"IDS_ACCS_MBODY_SOUND_FEEDBACK",
{},
[](auto item) {
- Singleton<VConfInterface>::instance().set(
- VCONFKEY_SETAPPL_ACCESSIBILITY_SCREEN_READER_SOUND_FEEDBACK, item->getState());
+ Singleton<VConfInterface>::instance().set(VCONFKEY_SETAPPL_ACCESSIBILITY_SCREEN_READER_SOUND_FEEDBACK, item->getState());
},
GenlistItem::WidgetType::toggle});
- item->setState(
- Singleton<VConfInterface>::instance().get(VCONFKEY_SETAPPL_ACCESSIBILITY_SCREEN_READER_SOUND_FEEDBACK, false));
+ item->setState(Singleton<VConfInterface>::instance().get(VCONFKEY_SETAPPL_ACCESSIBILITY_SCREEN_READER_SOUND_FEEDBACK, false));
- genlist->appendItem(
- {"type1", "IDS_ACCS_TMBODY_STATUS_BAR_INFORMATION", {}, [this](auto item) { this->mouseUpGendialListCb(); }});
+ genlist->appendItem({"type1", "IDS_ACCS_TMBODY_STATUS_BAR_INFORMATION", {}, [this](auto item) { this->mouseUpGendialListCb(); }});
genlist->appendItem({"multiline",
{},
"TAP_THE_SCREEN_WITH_TWO_FINGERS_MSG",
[this](auto item) {}});
- context_.getNaviframe()->pushBack("IDS_ST_OPT_SETTINGS", genlist, []() {
- if (0 != tts_setting_unset_speed_changed_cb())
- ERROR("Fail to unset speed changed cb");
-
- if (0 != tts_setting_unset_voice_changed_cb())
- ERROR("Fail to unset voice changed cb");
-
- if (0 != tts_setting_finalize()) {
- DEBUG("Fail to setting finalize");
- }
+ context_.getNaviframe()->pushBack("IDS_ST_OPT_SETTINGS", genlist, [this]() {
+ Singleton<TextToSpeech>::instance().clearSpeedChangedCallbacks();
});
}
screenreaderCheckbox->setState(vConfCheckData[i].state);
}
- genlist->blockScrolling(
- Elm_Scroller_Movement_Block(ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL | ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL));
+ genlist->blockScrolling(Elm_Scroller_Movement_Block(ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL | ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL));
genlist->setScrollbarsVisibility(ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
box->packEnd(genlist);
this->popup_->setPartContent("button2", btnDone);
}
-void ScreenReaderSettingsPage::ttsSpeedChangedCb(int speed, void *user_data)
-{
- DEBUG("=== Speed changed to (%d)", speed);
- auto item = static_cast<GenlistItem *>(user_data);
- item->setDescription(std::to_string(speed));
- item->update();
-}
-
void ScreenReaderSettingsPage::createSpeechRatePopup()
{
auto window = context_.getWindow();
slider->setIndicatorFormat("%1.0f");
slider->setRange(1, 15);
- int val = -1;
- if (0 != tts_setting_get_speed(&val))
- ERROR("Fail to get speed");
+ auto speed = Singleton<TextToSpeech>::instance().getSpeed();
slider->setStep(2);
- slider->setValue(val);
+ slider->setValue(speed);
layout->setPartContent("slider", slider);
auto cancelBtn = Widget::make<Button>(popup_, removeCb, "IDS_ST_BUTTON_CANCEL_ABB", "bottom");
popup_->setPartContent("button1", cancelBtn);
auto doneBtn = Widget::make<Button>(popup_,
- [p = popup_, window, slider]() {
- auto value = static_cast<int>(slider->getValue());
- if (0 != tts_setting_set_speed(value))
- WARNING("Setting speed to tts engine failed");
+ [p = popup_, window, slider, this]() {
+ auto val = static_cast<size_t>(slider->getValue());
+ Singleton<TextToSpeech>::instance().setSpeed(val);
window->removeChild(p);
},
"IDS_ST_SK3_DONE",
evas_object_event_callback_add(popup_->getObject(), EVAS_CALLBACK_DEL, onPopupDel, this);
}
-void ScreenReaderSettingsPage::onPopupDel(void *data, Evas *e, Evas_Object *obj, void *event_info)
+std::string ScreenReaderSettingsPage::calculateSpeedPercentage()
{
- int speed_val = -1;
- int s_speed_normal = -1;
- int s_speed_max = -1;
- int s_speed_min = -1;
-
- auto self = static_cast<ScreenReaderSettingsPage *>(data);
-
- if (0 != tts_setting_get_speed(&speed_val))
- ERROR("Failed to get speed");
+ auto speed = Singleton<TextToSpeech>::instance().getSpeed();
+ auto speedRange = Singleton<TextToSpeech>::instance().getSpeedRange();
- if (0 != tts_setting_get_speed_range(&s_speed_min, &s_speed_normal, &s_speed_max))
- ERROR("Fail to get speed range");
- auto denominator = s_speed_max - s_speed_min;
- double s_speed_percent = 0.0;
+ auto denominator = speedRange.max - speedRange.min;
+ auto speedPercent = 0.0;
if (denominator != 0)
- s_speed_percent = (((double)speed_val - (double)s_speed_min) / ((double)denominator)) * 100;
+ speedPercent = (static_cast<double>(speed - speedRange.min) / denominator) * 100;
- std::string buf = std::to_string(std::lround(s_speed_percent));
- DEBUG("Updating speed to %s", buf.c_str());
- self->speechRateItem_->setDescription(buf);
+ DEBUG("TTS rate is %.0f", speedPercent);
+ return std::to_string(std::lround(speedPercent));
+}
+
+void ScreenReaderSettingsPage::onPopupDel(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ auto self = static_cast<ScreenReaderSettingsPage *>(data);
+ auto percentage = self->calculateSpeedPercentage();
+ self->speechRateItem_->setDescription(percentage);
self->speechRateItem_->update();
}
--- /dev/null
+#include "TextToSpeech.hpp"
+
+TextToSpeech::TextToSpeech()
+{
+ if (auto ret = tts_create(&handle_)) {
+ ERROR("tts_create: %s", ttsErrorToString(ret).c_str());
+ return;
+ }
+
+ if (auto ret = tts_set_mode(handle_, TTS_MODE_DEFAULT)) {
+ ERROR("tts_set_mode: %s", ttsErrorToString(ret).c_str());
+ return;
+ }
+
+ if (auto ret = tts_prepare(handle_)) {
+ ERROR("tts_prepare: %s", ttsErrorToString(ret).c_str());
+ return;
+ }
+
+ if (auto ret = tts_setting_initialize())
+ ERROR("tts_setting_initialize: %s", ttsSettingErrorToString(ret).c_str());
+}
+
+TextToSpeech::~TextToSpeech()
+{
+ if (tts_setting_finalize())
+ WARNING("Fail to setting finalize");
+
+ if (tts_destroy(handle_))
+ WARNING("Fail to tts destroy");
+}
+
+void TextToSpeech::play(const std::string &text)
+{
+ int utterance = 0;
+ if (auto ret = tts_add_text(handle_, text.c_str(), nullptr, TTS_VOICE_TYPE_AUTO, TTS_SPEED_AUTO, &utterance))
+ ERROR("tts_add_text: %s", ttsErrorToString(ret).c_str());
+
+ if (auto ret = tts_play(handle_))
+ ERROR("tts_play: %s", ttsErrorToString(ret).c_str());
+}
+
+size_t TextToSpeech::getSpeed()
+{
+ int speed{};
+ auto ret = tts_setting_get_speed(&speed);
+ if (ret)
+ ERROR("tts_setting_get_speed: %s", ttsSettingErrorToString(ret).c_str());
+ else
+ return static_cast<size_t>(speed);
+
+ return {};
+}
+
+void TextToSpeech::setSpeed(size_t speed)
+{
+ auto ret = tts_setting_set_speed(speed);
+ if (ret)
+ ERROR("tts_setting_set_speed: %s", ttsSettingErrorToString(ret).c_str());
+}
+
+auto TextToSpeech::getSpeedRange() -> SpeedRange
+{
+ int min{};
+ int normal{};
+ int max{};
+
+ auto ret = tts_setting_get_speed_range(&min, &normal, &max);
+ if (ret)
+ ERROR("tts_setting_get_speed_range: %s", ttsSettingErrorToString(ret).c_str());
+ else
+ return {static_cast<size_t>(min), static_cast<size_t>(normal), static_cast<size_t>(max)};
+
+ return {};
+}
+
+void TextToSpeech::addSpeedChangedCb(std::function<void(size_t)> onChange)
+{
+ auto ret = tts_setting_set_speed_changed_cb(onSpeedChange, this);
+ if (ret)
+ ERROR("tts_setting_set_speed_changed_cb: %s", ttsSettingErrorToString(ret).c_str());
+ speedChangedCallbacks_.push_back(std::move(onChange));
+}
+
+void TextToSpeech::clearSpeedChangedCallbacks()
+{
+ speedChangedCallbacks_.clear();
+}
+
+std::string TextToSpeech::ttsErrorToString(int error)
+{
+ switch (error) {
+ case TTS_ERROR_NONE: {
+ return "no error";
+ }
+ case TTS_ERROR_INVALID_PARAMETER: {
+ return "invalid parameter";
+ }
+ case TTS_ERROR_OUT_OF_MEMORY: {
+ return "out of memory";
+ }
+ case TTS_ERROR_OPERATION_FAILED: {
+ return "operation failed";
+ }
+ case TTS_ERROR_INVALID_STATE: {
+ return "invalid state";
+ }
+ }
+
+ return "unknown error";
+}
+
+std::string TextToSpeech::ttsSettingErrorToString(int error)
+{
+ switch (error) {
+ case TTS_SETTING_ERROR_NONE: {
+ return "no error";
+ }
+ case TTS_SETTING_ERROR_INVALID_STATE: {
+ return "alread initialized";
+ }
+ case TTS_SETTING_ERROR_OPERATION_FAILED: {
+ return "operation failed";
+ }
+ case TTS_SETTING_ERROR_NOT_SUPPORTED: {
+ return "tts is not supported";
+ }
+ }
+
+ return "unknown error";
+}
+
+void TextToSpeech::onSpeedChange(int speed, void *user_data)
+{
+ auto self = static_cast<TextToSpeech *>(user_data);
+ for (auto it : self->speedChangedCallbacks_)
+ if (it)
+ it(speed);
+}
\ No newline at end of file