// if this is hit in something like a content-only unit test.
NOTREACHED();
return nullptr;
-#elif BUILDFLAG(IS_TIZEN)
- LOG(ERROR) << " returning nullptr ";
- return nullptr;
#else
return TtsPlatformImpl::GetInstance();
#endif
// Set default values. |voice| intentionally left null.
mojom_utterance_->text = text;
mojom_utterance_->lang = String("");
+
+#if defined(TIZEN_WEB_SPEECH_RECOGNITION)
+ mojom_utterance_->volume = mojom::blink::kSpeechSynthesisDefaultVolume;
+ mojom_utterance_->rate = mojom::blink::kSpeechSynthesisDefaultRate;
+ mojom_utterance_->pitch = mojom::blink::kSpeechSynthesisDefaultPitch;
+#else
mojom_utterance_->volume = mojom::blink::kSpeechSynthesisDoublePrefNotSet;
mojom_utterance_->rate = mojom::blink::kSpeechSynthesisDoublePrefNotSet;
mojom_utterance_->pitch = mojom::blink::kSpeechSynthesisDoublePrefNotSet;
+#endif
}
SpeechSynthesisUtterance::~SpeechSynthesisUtterance() = default;
"//tizen_src/build:libefl-extension",
"//tizen_src/build:security-manager",
"//tizen_src/build:libsecurity-manager",
- "//tizen_src/build:tts",
- "//tizen_src/build:libtts",
]
if (is_tizen) {
external_content_browser_efl_configs += [
"//tizen_src/build:stt",
"//tizen_src/build:libstt",
+ "//tizen_src/build:tts",
+ "//tizen_src/build:libtts",
]
if (tizen_product_tv) {
external_content_browser_efl_configs += [
"tracing/tracing_ui.cc",
"tracing/tracing_ui.h",
]
-
- external_content_browser_efl_sources += [
- # "//tizen_src/chromium_impl/content/browser/device_sensors/data_fetcher_impl_tizen.cc",
- # "//tizen_src/chromium_impl/content/browser/device_sensors/data_fetcher_impl_tizen.h",
- # "//tizen_src/chromium_impl/content/browser/device_sensors/data_fetcher_shared_memory_tizen.cc",
- "//tizen_src/chromium_impl/content/browser/speech/tts_message_filter_efl.cc",
- "//tizen_src/chromium_impl/content/browser/speech/tts_message_filter_efl.h",
- "//tizen_src/chromium_impl/content/browser/speech/tts_tizen.cc",
- "//tizen_src/chromium_impl/content/browser/speech/tts_tizen.h",
- ]
}
if (tizen_multimedia_support) {
external_content_browser_efl_sources += [
"//tizen_src/chromium_impl/content/browser/speech/speech_recognizer_impl_tizen.h",
"//tizen_src/chromium_impl/content/browser/speech/tizen_speech_recognition_manager_delegate.cc",
"//tizen_src/chromium_impl/content/browser/speech/tizen_speech_recognition_manager_delegate.h",
- ]
+ "//tizen_src/chromium_impl/content/browser/speech/tts_platform_impl_tizen.cc",
+ "//tizen_src/chromium_impl/content/browser/speech/tts_platform_impl_tizen.h",
+ ]
}
+++ /dev/null
-// Copyright (c) 2014 Samsung Electronics All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/speech/tts_message_filter_efl.h"
-
-#include "base/bind.h"
-#include "content/public/browser/browser_context.h"
-#include "content/public/browser/render_process_host.h"
-
-namespace content {
-
-TtsMessageFilterEfl::TtsMessageFilterEfl()
- : BrowserMessageFilter(TtsMsgStart) {
- tts_tizen_.reset(new TtsTizen(this));
-}
-
-TtsMessageFilterEfl::~TtsMessageFilterEfl() {
-}
-
-void TtsMessageFilterEfl::OverrideThreadForMessage(
- const IPC::Message& message, BrowserThread::ID* thread) {
- switch (message.type()) {
- case TtsHostMsg_InitializeVoiceList::ID:
- case TtsHostMsg_Speak::ID:
- case TtsHostMsg_Pause::ID:
- case TtsHostMsg_Resume::ID:
- case TtsHostMsg_Cancel::ID:
- *thread = BrowserThread::UI;
- break;
- default:
- NOTREACHED();
- }
-}
-
-bool TtsMessageFilterEfl::OnMessageReceived(const IPC::Message& message) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(TtsMessageFilterEfl, message)
- IPC_MESSAGE_HANDLER(TtsHostMsg_InitializeVoiceList, OnInitializeVoiceList)
- IPC_MESSAGE_HANDLER(TtsHostMsg_Speak, OnSpeak)
- IPC_MESSAGE_HANDLER(TtsHostMsg_Pause, OnPause)
- IPC_MESSAGE_HANDLER(TtsHostMsg_Resume, OnResume)
- IPC_MESSAGE_HANDLER(TtsHostMsg_Cancel, OnCancel)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
-
-void TtsMessageFilterEfl::OnChannelClosing() {
- NOTIMPLEMENTED();
-}
-
-void TtsMessageFilterEfl::OnInitializeVoiceList() {
- if(!tts_tizen_->IsTtsInitialized())
- tts_tizen_->Init();
-
- const std::vector<TtsVoice>& voices = tts_tizen_->GetVoiceList();
- Send(new TtsMsg_SetVoiceList(voices));
-}
-
-void TtsMessageFilterEfl::OnSpeak(const TtsUtteranceRequest& request) {
- tts_tizen_->Speak(request);
-}
-
-void TtsMessageFilterEfl::OnPause() {
- tts_tizen_->Pause();
-}
-
-void TtsMessageFilterEfl::OnResume() {
- tts_tizen_->Resume();
-}
-
-void TtsMessageFilterEfl::OnCancel() {
- tts_tizen_->Cancel();
-}
-
-void TtsMessageFilterEfl::DidFinishSpeaking(int utteranceid) {
- Send(new TtsMsg_DidFinishSpeaking(utteranceid));
-}
-
-void TtsMessageFilterEfl::DidResumeSpeaking(int utteranceid) {
- Send(new TtsMsg_DidResumeSpeaking(utteranceid));
-}
-
-void TtsMessageFilterEfl::DidPauseSpeaking(int utteranceid) {
- Send(new TtsMsg_DidPauseSpeaking(utteranceid));
-}
-
-void TtsMessageFilterEfl::DidStartSpeaking(int utteranceid) {
- Send(new TtsMsg_DidStartSpeaking(utteranceid));
-}
-
-void TtsMessageFilterEfl::SpeakingErrorOccurred(int utteranceid, const std::string& reason) {
- Send(new TtsMsg_SpeakingErrorOccurred(utteranceid, reason));
-}
-
-} // namespace content
+++ /dev/null
-// Copyright (c) 2014 Samsung Electronics Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BROWSER_SPEECH_TTS_MESSAGE_FILTER_H_
-#define BROWSER_SPEECH_TTS_MESSAGE_FILTER_H_
-
-#include "base/memory/weak_ptr.h"
-#include "content/browser/speech/tts_tizen.h"
-#include "content/common/content_export.h"
-#include "content/common/tts_messages_efl.h"
-#include "content/public/browser/browser_message_filter.h"
-
-namespace content {
-class TtsTizen;
-
-// Handle IPC message from browser process to renderer process.
-class CONTENT_EXPORT TtsMessageFilterEfl
- : public content::BrowserMessageFilter,
- public base::SupportsWeakPtr<TtsMessageFilterEfl> {
- public:
- TtsMessageFilterEfl();
-
- TtsMessageFilterEfl(const TtsMessageFilterEfl&) = delete;
- TtsMessageFilterEfl& operator=(const TtsMessageFilterEfl&) = delete;
-
- // content::BrowserMessageFilter implementation.
- void OverrideThreadForMessage(
- const IPC::Message& message,
- content::BrowserThread::ID* thread) override;
- bool OnMessageReceived(const IPC::Message& message) override;
- void OnChannelClosing() override;
-
- void DidFinishSpeaking(int utteranceid);
- void DidResumeSpeaking(int utteranceid);
- void DidPauseSpeaking(int utteranceid);
- void DidStartSpeaking(int utteranceid);
- void SpeakingErrorOccurred(int utteranceid, const std::string& reason);
-
- private:
- ~TtsMessageFilterEfl() override;
-
- void OnInitializeVoiceList();
- void OnSpeak(const TtsUtteranceRequest& utterance);
- void OnPause();
- void OnResume();
- void OnCancel();
-
- std::unique_ptr<TtsTizen> tts_tizen_;
-};
-
-} // namespace content
-
-#endif // BROWSER_SPEECH_TTS_MESSAGE_FILTER_H_
--- /dev/null
+// Copyright (c) 2014 Samsung Electronics Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/speech/tts_platform_impl_tizen.h"
+
+#include "base/bind.h"
+#include "base/debug/leak_annotations.h"
+#include "base/logging.h"
+#include "base/memory/singleton.h"
+#include "base/task/thread_pool.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace content {
+
+namespace {
+
+const char kUriPrefix[] = "localhost:";
+const std::string kAuto = "Auto";
+const std::string kMale = "Male";
+const std::string kFemale = "Female";
+const std::string kChild = "Child";
+
+std::string VoiceTypeToName(tts_voice_type_e type) {
+ switch (type) {
+ case TTS_VOICE_TYPE_AUTO:
+ return kAuto;
+ case TTS_VOICE_TYPE_MALE:
+ return kMale;
+ case TTS_VOICE_TYPE_FEMALE:
+ return kFemale;
+ case TTS_VOICE_TYPE_CHILD:
+ return kChild;
+ }
+ return kAuto;
+}
+
+tts_voice_type_e VoiceNameToType(std::string name) {
+ if (name == kAuto)
+ return TTS_VOICE_TYPE_AUTO;
+ else if (name == kMale)
+ return TTS_VOICE_TYPE_MALE;
+ else if (name == kFemale)
+ return TTS_VOICE_TYPE_FEMALE;
+ else if (name == kChild)
+ return TTS_VOICE_TYPE_CHILD;
+ else
+ return TTS_VOICE_TYPE_AUTO;
+}
+
+#define ENUM_CASE(x) \
+ case x: \
+ return #x
+
+const std::string ErrorToString(tts_error_e error) {
+ switch (error) {
+ ENUM_CASE(TTS_ERROR_NONE);
+ ENUM_CASE(TTS_ERROR_OUT_OF_MEMORY);
+ ENUM_CASE(TTS_ERROR_IO_ERROR);
+ ENUM_CASE(TTS_ERROR_INVALID_PARAMETER);
+ ENUM_CASE(TTS_ERROR_OUT_OF_NETWORK);
+ ENUM_CASE(TTS_ERROR_INVALID_STATE);
+ ENUM_CASE(TTS_ERROR_INVALID_VOICE);
+ ENUM_CASE(TTS_ERROR_ENGINE_NOT_FOUND);
+ ENUM_CASE(TTS_ERROR_TIMED_OUT);
+ ENUM_CASE(TTS_ERROR_OPERATION_FAILED);
+ ENUM_CASE(TTS_ERROR_AUDIO_POLICY_BLOCKED);
+ default:
+ LOG(WARNING) << "TTS: Unknown tts_error_e! (code=" << error << ")";
+ }
+ return "Unknown Error";
+}
+
+const std::string StateToString(tts_state_e state) {
+ switch (state) {
+ ENUM_CASE(TTS_STATE_CREATED);
+ ENUM_CASE(TTS_STATE_READY);
+ ENUM_CASE(TTS_STATE_PLAYING);
+ ENUM_CASE(TTS_STATE_PAUSED);
+ default:
+ LOG(WARNING) << "TTS: Unknown tts_state_e! (code=" << state << ")";
+ }
+ return "Unknown State";
+}
+
+// Tizen will not accept '-' in language string. Convert to '_'.
+const std::string ConvertLangString(std::string lang) {
+ int pos = lang.find('-');
+ if (pos != std::string::npos)
+ lang.replace(pos, 1, "_");
+ return lang;
+}
+
+} // namespace
+
+#if BUILDFLAG(IS_TIZEN_TV)
+tts_mode_e TtsPlatformImplTizen::tts_mode_ = TTS_MODE_SCREEN_READER;
+#else
+tts_mode_e TtsPlatformImplTizen::tts_mode_ = TTS_MODE_DEFAULT;
+#endif
+
+// Send a TTS event notification to the TTS controller.
+void SendTtsEvent(int utterance_id,
+ TtsEventType event_type,
+ int char_index,
+ int length) {
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(&TtsController::OnTtsEvent,
+ base::Unretained(TtsController::GetInstance()),
+ utterance_id, event_type, char_index, length,
+ std::string()));
+}
+
+void TtsStateChangedCallback(tts_h tts_handle,
+ tts_state_e previous,
+ tts_state_e current,
+ void* user_data) {
+ TtsPlatformImplTizen* _this = static_cast<TtsPlatformImplTizen*>(user_data);
+ LOG(INFO) << "TTS: utterance_id " << _this->GetUtteranceId()
+ << " State Changed from " << StateToString(previous) << " to "
+ << StateToString(current);
+
+ if (TTS_STATE_CREATED == previous && TTS_STATE_READY == current) {
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
+ base::BindOnce(&TtsPlatformImplTizen::TtsInitialized,
+ base::Unretained(TtsPlatformImplTizen::GetInstance())));
+ } else if (TTS_STATE_PAUSED == previous && TTS_STATE_PLAYING == current) {
+ SendTtsEvent(_this->GetUtteranceId(), TTS_EVENT_RESUME,
+ _this->GetUtteranceText().size(), 0);
+ } else if (TTS_STATE_PLAYING == previous && TTS_STATE_PAUSED == current) {
+ SendTtsEvent(_this->GetUtteranceId(), TTS_EVENT_PAUSE,
+ _this->GetUtteranceText().size(), 0);
+ } else if ((TTS_STATE_PLAYING == previous || TTS_STATE_PAUSED == previous) &&
+ TTS_STATE_READY == current) {
+ _this->OnUtteranceStoped();
+ }
+}
+
+void TtsUtteranceStartedCallback(tts_h tts_handle,
+ int utterance_id,
+ void* user_data) {
+ TtsPlatformImplTizen* _this = static_cast<TtsPlatformImplTizen*>(user_data);
+ if (_this->GetPlatformUttId() != utterance_id) {
+ LOG(ERROR) << "TTS: utterance ID mismatch (" << _this->GetUtteranceId()
+ << ") platform ID " << _this->GetPlatformUttId();
+ return;
+ }
+
+ LOG(INFO) << "TTS: utterance_id " << _this->GetUtteranceId() << " started";
+ SendTtsEvent(_this->GetUtteranceId(), TTS_EVENT_START,
+ _this->GetUtteranceText().size(), 0);
+}
+
+void TtsUtteranceCompletedCallback(tts_h tts_handle,
+ int utterance_id,
+ void* user_data) {
+ TtsPlatformImplTizen* _this = static_cast<TtsPlatformImplTizen*>(user_data);
+ if (_this->GetPlatformUttId() != utterance_id) {
+ LOG(ERROR) << "TTS: utterance ID mismatch (" << _this->GetUtteranceId()
+ << ") platform ID " << _this->GetPlatformUttId();
+ return;
+ }
+
+ LOG(INFO) << "TTS: utterance_id " << _this->GetUtteranceId()
+ << " completed. ";
+ _this->OnUtteranceCompletedCallback();
+}
+
+void TtsErrorCallback(tts_h tts_handle,
+ int utterance_id,
+ tts_error_e reason,
+ void* user_data) {
+ TtsPlatformImplTizen* _this = static_cast<TtsPlatformImplTizen*>(user_data);
+ if (_this->GetPlatformUttId() != utterance_id) {
+ LOG(ERROR) << "TTS: utterance ID mismatch (" << _this->GetUtteranceId()
+ << ") platform ID " << _this->GetPlatformUttId();
+ return;
+ }
+
+ LOG(ERROR) << "TTS: utterance_id " << _this->GetUtteranceId() << " Error - "
+ << ErrorToString(reason);
+ SendTtsEvent(_this->GetUtteranceId(), TTS_EVENT_ERROR,
+ _this->GetUtteranceText().size(), 0);
+}
+
+bool TtsSupportedVoiceCallback(tts_h tts_handle,
+ const char* language,
+ int voice_type,
+ void* user_data) {
+ TtsPlatformImplTizen* _this = static_cast<TtsPlatformImplTizen*>(user_data);
+ _this->AddVoice(std::string(language), voice_type);
+ return true;
+}
+
+void TtsDefaultVoiceChangedCallback(tts_h tts_handle,
+ const char* previous_language,
+ int previous_voice_type,
+ const char* current_language,
+ int current_voice_type,
+ void* user_data) {
+ TtsPlatformImplTizen* _this = static_cast<TtsPlatformImplTizen*>(user_data);
+ _this->ChangeTtsDefaultVoice(current_language, current_voice_type);
+}
+
+int GetTtsVoiceSpeed(tts_h tts_handle, float rate) {
+ // TTS engine dependent capability.
+ const float kRateMin = 0.6f, kRateMax = 2.0f, kRateNormal = 1.0f;
+
+ int tts_speed_min = 0, tts_speed_normal = 0, tts_speed_max = 0;
+ int ret = tts_get_speed_range(tts_handle, &tts_speed_min, &tts_speed_normal,
+ &tts_speed_max);
+ if (ret != TTS_ERROR_NONE) {
+ LOG(ERROR) << "TTS: tts_get_speed_range() failed - "
+ << ErrorToString(static_cast<tts_error_e>(ret));
+ return TTS_SPEED_AUTO;
+ }
+
+ if (rate <= kRateMin)
+ return tts_speed_min;
+
+ if (rate >= kRateMax)
+ return tts_speed_max;
+
+ // Piecewise linear interpolation from |rate| to TTS internal speed value.
+ if (rate < kRateNormal)
+ return static_cast<int>(
+ tts_speed_min +
+ (rate - kRateMin) *
+ ((tts_speed_normal - tts_speed_min) / (kRateNormal - kRateMin)));
+ else
+ return static_cast<int>(
+ tts_speed_normal +
+ (rate - kRateNormal) *
+ ((tts_speed_max - tts_speed_normal) / (kRateMax - kRateNormal)));
+}
+
+void DestroyOnUI(tts_h tts_handle) {
+ if (!tts_handle)
+ return;
+
+ LOG(INFO) << "TTS: Calling tts_destroy";
+ int ret = tts_destroy(tts_handle);
+ if (ret != TTS_ERROR_NONE) {
+ LOG(ERROR) << "TTS: Fail to tts_destroy - "
+ << ErrorToString(static_cast<tts_error_e>(ret));
+ }
+}
+
+// static
+TtsPlatformImplTizen* TtsPlatformImplTizen::GetInstance() {
+ return base::Singleton<TtsPlatformImplTizen>::get();
+}
+
+// static
+TtsPlatformImpl* TtsPlatformImpl::GetInstance() {
+ return TtsPlatformImplTizen::GetInstance();
+}
+
+TtsPlatformImplTizen::TtsPlatformImplTizen() {
+ Initialize();
+}
+
+TtsPlatformImplTizen::~TtsPlatformImplTizen() {
+ LOG(INFO) << "TTS: TtsPlatformImplTizen instance [ " << (void*)this
+ << " ] destruct";
+ if (!tts_handle_) {
+ LOG(INFO) << "TTS: TtsPlatformImplTizen instance [ " << (void*)this
+ << " ] destruct, no handle, finished";
+ return;
+ }
+
+ if (is_initialized_) {
+ tts_state_e tts_state = TTS_STATE_CREATED;
+ int ret = tts_get_state(tts_handle_, &tts_state);
+ if (ret != TTS_ERROR_NONE) {
+ LOG(ERROR) << "TTS: Fail to tts_get_state - "
+ << ErrorToString(static_cast<tts_error_e>(ret));
+ }
+
+ if (TTS_STATE_PAUSED == tts_state || TTS_STATE_PLAYING == tts_state) {
+ ret = tts_stop(tts_handle_);
+ if (ret != TTS_ERROR_NONE) {
+ LOG(ERROR) << "TTS: Fail to stop - "
+ << ErrorToString(static_cast<tts_error_e>(ret));
+ }
+ }
+
+ ret = tts_unprepare(tts_handle_);
+ if (ret != TTS_ERROR_NONE) {
+ LOG(ERROR) << "TTS: Fail to unprepare - "
+ << ErrorToString(static_cast<tts_error_e>(ret));
+ }
+ is_initialized_ = false;
+ }
+
+ int ret = tts_unset_state_changed_cb(tts_handle_);
+ if (ret != TTS_ERROR_NONE) {
+ LOG(ERROR) << "TTS: Fail to tts_unset_state_changed_cb - "
+ << ErrorToString(static_cast<tts_error_e>(ret));
+ }
+
+ ret = tts_unset_utterance_completed_cb(tts_handle_);
+ if (ret != TTS_ERROR_NONE) {
+ LOG(ERROR) << "TTS: Fail to tts_unset_utterance_completed_cb - "
+ << ErrorToString(static_cast<tts_error_e>(ret));
+ }
+
+ ret = tts_unset_utterance_started_cb(tts_handle_);
+ if (ret != TTS_ERROR_NONE) {
+ LOG(ERROR) << "TTS: Fail to tts_unset_utterance_started_cb - "
+ << ErrorToString(static_cast<tts_error_e>(ret));
+ }
+
+ ret = tts_unset_error_cb(tts_handle_);
+ if (ret != TTS_ERROR_NONE) {
+ LOG(ERROR) << "TTS: Fail to tts_unset_error_cb - "
+ << ErrorToString(static_cast<tts_error_e>(ret));
+ }
+
+ ret = tts_unset_default_voice_changed_cb(tts_handle_);
+ if (ret != TTS_ERROR_NONE) {
+ LOG(ERROR) << "TTS: Fail to tts_unset_default_voice_changed_cb - "
+ << ErrorToString(static_cast<tts_error_e>(ret));
+ }
+
+ // TTS destruction is not thread safe, call destory from UI.
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(&DestroyOnUI, tts_handle_));
+
+ tts_handle_ = NULL;
+ LOG(INFO) << "TTS: TtsPlatformImplTizen instance [ " << (void*)this
+ << " ] destruct, finished";
+}
+
+bool TtsPlatformImplTizen::Initialize() {
+ int ret = tts_create(&tts_handle_);
+ if (ret != TTS_ERROR_NONE) {
+ LOG(ERROR) << "TTS: Fail to create - "
+ << ErrorToString(static_cast<tts_error_e>(ret));
+ return false;
+ }
+
+ StoreTtsDefaultVoice();
+
+ // Set callbacks
+ if (!SetTtsCallback())
+ return false;
+
+ LOG(INFO) << __func__ << " tts_mode #" << tts_mode_;
+ ret = tts_set_mode(tts_handle_, tts_mode_);
+ if (ret != TTS_ERROR_NONE) {
+ LOG(ERROR) << "TTS: Fail to set mode - "
+ << ErrorToString(static_cast<tts_error_e>(ret));
+ }
+ ret = tts_prepare(tts_handle_);
+ if (ret != TTS_ERROR_NONE) {
+ LOG(ERROR) << "TTS: Fail to prepare - "
+ << ErrorToString(static_cast<tts_error_e>(ret));
+ return false;
+ }
+ return true;
+}
+
+void TtsPlatformImplTizen::StoreTtsDefaultVoice() {
+ char* language = NULL;
+ int voice_type;
+ int ret = tts_get_default_voice(tts_handle_, &language, &voice_type);
+ if (ret != TTS_ERROR_NONE) {
+ LOG(ERROR) << "TTS: Fail to get default voice - "
+ << ErrorToString(static_cast<tts_error_e>(ret));
+
+ // Even if ret != TTS_ERROR_NONE, do not return here.
+ // Set the default values.
+ const char kDefaultLanguage[] = "en_GB";
+ default_language_ = kDefaultLanguage;
+ default_voice_ = TTS_VOICE_TYPE_AUTO;
+ } else {
+ DCHECK(language);
+ default_language_ = language;
+ free(language);
+ default_voice_ = voice_type;
+ }
+}
+
+bool TtsPlatformImplTizen::SetTtsCallback() {
+ int ret =
+ tts_set_state_changed_cb(tts_handle_, TtsStateChangedCallback, this);
+ if (ret != TTS_ERROR_NONE) {
+ LOG(ERROR) << "TTS: Unable to set state callback - "
+ << ErrorToString(static_cast<tts_error_e>(ret));
+ return false;
+ }
+
+ ret = tts_set_utterance_started_cb(tts_handle_, TtsUtteranceStartedCallback,
+ this);
+ if (ret != TTS_ERROR_NONE) {
+ LOG(ERROR) << "TTS: Fail to set utterance started callback - "
+ << ErrorToString(static_cast<tts_error_e>(ret));
+ return false;
+ }
+
+ ret = tts_set_utterance_completed_cb(tts_handle_,
+ TtsUtteranceCompletedCallback, this);
+ if (ret != TTS_ERROR_NONE) {
+ LOG(ERROR) << "TTS: Fail to set utterance completed callback - "
+ << ErrorToString(static_cast<tts_error_e>(ret));
+ return false;
+ }
+
+ ret = tts_set_error_cb(tts_handle_, TtsErrorCallback, this);
+ if (ret != TTS_ERROR_NONE) {
+ LOG(ERROR) << "TTS: Fail to set error callback - "
+ << ErrorToString(static_cast<tts_error_e>(ret));
+ return false;
+ }
+
+ ret = tts_foreach_supported_voices(tts_handle_, TtsSupportedVoiceCallback,
+ this);
+ if (ret != TTS_ERROR_NONE) {
+ LOG(ERROR) << "TTS: Fail to get supported voices - "
+ << ErrorToString(static_cast<tts_error_e>(ret));
+ return false;
+ }
+
+ ret = tts_set_default_voice_changed_cb(tts_handle_,
+ TtsDefaultVoiceChangedCallback, this);
+ if (ret != TTS_ERROR_NONE) {
+ LOG(ERROR) << "TTS: Fail to set default voice changed callback - "
+ << ErrorToString(static_cast<tts_error_e>(ret));
+ return false;
+ }
+ return true;
+}
+
+bool TtsPlatformImplTizen::PlatformImplSupported() {
+ return true;
+}
+
+bool TtsPlatformImplTizen::PlatformImplInitialized() {
+ return true;
+}
+
+void TtsPlatformImplTizen::TtsInitialized() {
+ is_initialized_ = true;
+ if (utterance_pending_) {
+ SpeakStoredUtterance();
+ utterance_pending_ = false;
+ }
+}
+
+void TtsPlatformImplTizen::Speak(
+ int utterance_id,
+ const std::string& utterance,
+ const std::string& lang,
+ const VoiceData& voice,
+ const UtteranceContinuousParameters& params,
+ base::OnceCallback<void(bool)> on_speak_finished) {
+ utterance_.utterance_id = utterance_id;
+ utterance_.utterance = utterance;
+ utterance_.language = lang;
+ utterance_.voice_name = voice.name;
+ utterance_.volume = params.volume;
+ utterance_.rate = params.rate;
+ utterance_.pitch = params.pitch;
+ utterance_.on_speak_finished = std::move(on_speak_finished);
+ should_speak_ = true;
+
+ // TTS package can be litle slow at times. Always wait for READY state.
+ if (!is_initialized_ || is_speaking_) {
+ LOG(INFO) << "TTS: Storing utterance " << utterance_id
+ << " state :" << StateToString(GetTtsState());
+ utterance_pending_ = true;
+ return;
+ }
+
+ SpeakStoredUtterance();
+}
+
+void TtsPlatformImplTizen::SpeakStoredUtterance() {
+ LOG(INFO) << "TTS: Speak utterance " << utterance_.utterance_id << " text #"
+ << utterance_.utterance;
+ std::string current_language = default_language_;
+ if (!utterance_.language.empty())
+ current_language = ConvertLangString(utterance_.language);
+
+ int voiceType = static_cast<int>(default_voice_);
+ if (!utterance_.voice_name.empty())
+ voiceType = static_cast<int>(VoiceNameToType(utterance_.voice_name));
+ int textSpeed = GetTtsVoiceSpeed(tts_handle_, utterance_.rate);
+ int ret = tts_add_text(tts_handle_, utterance_.utterance.c_str(),
+ current_language.c_str(), voiceType, textSpeed,
+ &utterance_.platform_utt_id);
+ if (ret != TTS_ERROR_NONE) {
+ LOG(ERROR) << "TTS: Fail to add text. Error - "
+ << ErrorToString(static_cast<tts_error_e>(ret)) << " in "
+ << GetTtsState();
+ SendTtsEvent(utterance_.utterance_id, TTS_EVENT_ERROR,
+ utterance_.utterance.size(), 0);
+ std::move(utterance_.on_speak_finished).Run(false);
+ return;
+ }
+
+ if (should_speak_)
+ Play();
+}
+
+bool TtsPlatformImplTizen::StopSpeaking() {
+ // TTS package can be litle slow at times.
+ if (!is_initialized_ && utterance_pending_) {
+ LOG(INFO) << "TTS: not initialized. Ignore pending utterance "
+ << utterance_.utterance_id
+ << " state :" << StateToString(GetTtsState());
+ should_speak_ = false;
+ return true;
+ }
+
+ tts_state_e current_state = GetTtsState();
+ if (current_state != TTS_STATE_PLAYING && current_state != TTS_STATE_PAUSED) {
+ LOG(WARNING) << "TTS: Ignoring stop. ID: " << utterance_.utterance_id
+ << " state " << StateToString(current_state);
+ is_speaking_ = false;
+ return true;
+ }
+
+ LOG(INFO) << "TTS: Stop. ID: " << utterance_.utterance_id;
+ int ret = tts_stop(tts_handle_);
+ if (ret != TTS_ERROR_NONE) {
+ LOG(ERROR) << "TTS: Fail to stop. Error - "
+ << ErrorToString(static_cast<tts_error_e>(ret)) << " in "
+ << StateToString(current_state);
+ SendTtsEvent(utterance_.utterance_id, TTS_EVENT_ERROR,
+ utterance_.utterance.size(), 0);
+ return false;
+ }
+
+ return true;
+}
+
+bool TtsPlatformImplTizen::Play() {
+ tts_state_e current_state = GetTtsState();
+ if (current_state == TTS_STATE_PLAYING) {
+ LOG(WARNING) << "TTS: Already in play state. ID: "
+ << utterance_.utterance_id;
+ return false;
+ }
+
+ if (current_state != TTS_STATE_READY && current_state != TTS_STATE_PAUSED) {
+ LOG(WARNING) << "TTS: Ignoring play. ID: " << utterance_.utterance_id
+ << " state " << StateToString(current_state);
+ return false;
+ }
+
+ LOG(INFO) << "TTS: Play. ID: " << utterance_.utterance_id;
+ int ret = tts_play(tts_handle_);
+ if (ret != (int)TTS_ERROR_NONE) {
+ LOG(ERROR) << "TTS: Fail to play. Error - "
+ << ErrorToString(static_cast<tts_error_e>(ret)) << " in "
+ << StateToString(current_state);
+ SendTtsEvent(utterance_.utterance_id, TTS_EVENT_ERROR,
+ utterance_.utterance.size(), 0);
+ return false;
+ }
+
+ is_speaking_ = true;
+ return true;
+}
+
+void TtsPlatformImplTizen::Pause() {
+ // TTS package can be litle slow at times.
+ if (!is_initialized_ && utterance_pending_) {
+ LOG(INFO) << "TTS: not initialized. Ignore pending utterance "
+ << utterance_.utterance_id
+ << " state :" << StateToString(GetTtsState());
+ should_speak_ = false;
+ SendTtsEvent(utterance_.utterance_id, TTS_EVENT_PAUSE,
+ GetUtteranceText().size(), 0);
+ return;
+ }
+
+ if (GetTtsState() != TTS_STATE_PLAYING) {
+ LOG(WARNING) << "TTS: Ignoring pause. ID: " << utterance_.utterance_id
+ << " state " << StateToString(GetTtsState());
+ return;
+ }
+
+ LOG(INFO) << "TTS: Pause. ID: " << utterance_.utterance_id;
+ int ret = tts_pause(tts_handle_);
+ if (ret != TTS_ERROR_NONE) {
+ LOG(ERROR) << "TTS: Fail to pause - "
+ << ErrorToString(static_cast<tts_error_e>(ret)) << " in "
+ << StateToString(GetTtsState());
+ SendTtsEvent(utterance_.utterance_id, TTS_EVENT_ERROR,
+ utterance_.utterance.size(), 0);
+ }
+}
+
+void TtsPlatformImplTizen::Resume() {
+ Play();
+}
+
+bool TtsPlatformImplTizen::IsSpeaking() {
+ return is_speaking_;
+}
+
+tts_state_e TtsPlatformImplTizen::GetTtsState() {
+ tts_state_e current_state;
+ tts_get_state(tts_handle_, ¤t_state);
+ return current_state;
+}
+
+void TtsPlatformImplTizen::ChangeTtsDefaultVoice(const std::string language,
+ const int voice_type) {
+ default_language_ = language;
+ default_voice_ = voice_type;
+}
+
+void TtsPlatformImplTizen::GetVoices(std::vector<VoiceData>* out_voices) {
+ for (auto it = voice_list_.begin(); it != voice_list_.end(); ++it) {
+ out_voices->push_back(VoiceData());
+ VoiceData& voice = out_voices->back();
+ voice.native = it->native;
+ voice.name = it->name;
+ voice.lang = it->lang;
+ voice.events.insert(TTS_EVENT_START);
+ voice.events.insert(TTS_EVENT_END);
+ voice.events.insert(TTS_EVENT_INTERRUPTED);
+ voice.events.insert(TTS_EVENT_ERROR);
+ voice.events.insert(TTS_EVENT_PAUSE);
+ voice.events.insert(TTS_EVENT_RESUME);
+ }
+}
+
+void TtsPlatformImplTizen::AddVoice(std::string language,
+ tts_voice_type_e type) {
+ voice_list_.push_back(VoiceData());
+ VoiceData& data = voice_list_.back();
+ data.native = true;
+ data.name = VoiceTypeToName(type);
+ data.lang = language;
+}
+
+void TtsPlatformImplTizen::OnUtteranceCompletedCallback() {
+ StopSpeaking();
+ std::move(utterance_.on_speak_finished).Run(true);
+ SendTtsEvent(utterance_.utterance_id, TTS_EVENT_END,
+ utterance_.utterance.size(), 0);
+}
+
+} // namespace content
--- /dev/null
+// Copyright (c) 2014 Samsung Electronics Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BROWSER_SPEECH_TTS_PLATFORM_IMPL_TIZEN_H_
+#define BROWSER_SPEECH_TTS_PLATFORM_IMPL_TIZEN_H_
+
+#include "content/browser/speech/tts_platform_impl.h"
+
+#include <tts.h>
+#include <vector>
+#include "base/functional/callback.h"
+
+namespace content {
+
+typedef int tts_voice_type_e;
+
+class TtsPlatformImplTizen : public TtsPlatformImpl {
+ public:
+ void TtsInitialized();
+ const std::string& GetUtteranceText() const { return utterance_.language; }
+ int GetUtteranceId() const { return utterance_.utterance_id; }
+ int GetPlatformUttId() const { return utterance_.platform_utt_id; }
+
+ // Get voices one by one from tts engine, append them into a voice list
+ void AddVoice(std::string language, tts_voice_type_e name);
+ void ChangeTtsDefaultVoice(const std::string, const int);
+
+ void OnUtteranceCompletedCallback();
+ void OnUtteranceStoped() { is_speaking_ = false; }
+
+ // Get the single instance of this class.
+ static TtsPlatformImplTizen* GetInstance();
+ static void SetTtsMode(tts_mode_e tts_mode) { tts_mode_ = tts_mode; }
+
+ private:
+ struct TtsUtterance {
+ int utterance_id;
+ int platform_utt_id = -1;
+ std::string utterance;
+ std::string language;
+ std::string voice_name;
+ double volume;
+ double rate;
+ double pitch;
+ base::OnceCallback<void(bool)> on_speak_finished;
+ };
+
+ bool PlatformImplSupported() override;
+ bool PlatformImplInitialized() override;
+ void Speak(int utterance_id,
+ const std::string& utterance,
+ const std::string& lang,
+ const VoiceData& voice,
+ const UtteranceContinuousParameters& params,
+ base::OnceCallback<void(bool)> on_speak_finished) override;
+ bool StopSpeaking() override;
+ void Pause() override;
+ void Resume() override;
+ bool IsSpeaking() override;
+ void GetVoices(std::vector<VoiceData>* out_voices) override;
+
+ TtsPlatformImplTizen();
+ ~TtsPlatformImplTizen();
+
+ bool Initialize();
+ bool Play();
+ tts_state_e GetTtsState();
+
+ // Create and Set tts and tts callback. If any of these failes, tts will not
+ // work at all.
+ bool SetTtsCallback();
+ void StoreTtsDefaultVoice();
+ void SpeakStoredUtterance();
+
+ tts_h tts_handle_ = NULL;
+ std::string default_language_;
+ tts_voice_type_e default_voice_ = TTS_VOICE_TYPE_AUTO;
+
+ static tts_mode_e tts_mode_;
+
+ TtsUtterance utterance_;
+ bool utterance_pending_ = false;
+
+ // TTS initialization is slow. Play should be ignored if pause / stop command
+ // is received.
+ bool should_speak_ = false;
+
+ // This variable stores list of voicees that tts engine support.
+ std::vector<VoiceData> voice_list_;
+
+ // This variable check whether tts is initialized.
+ // It will be true when tts engine set the variable tts_.
+ bool is_initialized_ = false;
+ bool is_speaking_ = false;
+
+ friend struct base::DefaultSingletonTraits<TtsPlatformImplTizen>;
+
+ base::WeakPtrFactory<TtsPlatformImplTizen> weak_factory_{this};
+
+ TtsPlatformImplTizen(const TtsPlatformImplTizen&) = delete;
+ TtsPlatformImplTizen& operator=(const TtsPlatformImplTizen&) = delete;
+};
+
+} // namespace content
+
+#endif // BROWSER_SPEECH_TTS_PLATFORM_IMPL_TIZEN_H_
+++ /dev/null
-// Copyright (c) 2014 Samsung Electronics Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/speech/tts_tizen.h"
-
-#include <vector>
-
-#include "base/logging.h"
-
-namespace content {
-namespace {
-const char kUriPrefix[] = "localhost:";
-const std::string kAuto = "Auto";
-const std::string kMale = "Male";
-const std::string kFemale = "Female";
-const std::string kChild = "Child";
-
-std::string VoiceTypeToName(tts_voice_type_e type) {
- switch (type) {
- case TTS_VOICE_TYPE_AUTO:
- return kAuto;
- case TTS_VOICE_TYPE_MALE:
- return kMale;
- case TTS_VOICE_TYPE_FEMALE:
- return kFemale;
- case TTS_VOICE_TYPE_CHILD:
- return kChild;
- }
- return kAuto;
-}
-
-tts_voice_type_e VoiceNameToType(std::string name) {
- if (name == kAuto)
- return TTS_VOICE_TYPE_AUTO;
- else if (name == kMale)
- return TTS_VOICE_TYPE_MALE;
- else if (name == kFemale)
- return TTS_VOICE_TYPE_FEMALE;
- else if (name == kChild)
- return TTS_VOICE_TYPE_CHILD;
- else
- return TTS_VOICE_TYPE_AUTO;
-}
-
-const std::string ErrorToString(tts_error_e error) {
- switch (error) {
- case TTS_ERROR_NONE:
- return "Successful";
- case TTS_ERROR_OUT_OF_MEMORY:
- return "Out of Memory";
- case TTS_ERROR_IO_ERROR:
- return "I/O error";
- case TTS_ERROR_INVALID_PARAMETER:
- return "Invalid parameter";
- case TTS_ERROR_OUT_OF_NETWORK:
- return "Out of network";
- case TTS_ERROR_INVALID_STATE:
- return "Invalid state";
- case TTS_ERROR_INVALID_VOICE:
- return "Invalid voice";
- case TTS_ERROR_ENGINE_NOT_FOUND:
- return "No available engine";
- case TTS_ERROR_TIMED_OUT:
- return "No answer from the daemon";
- case TTS_ERROR_OPERATION_FAILED:
- return "Operation failed";
- case TTS_ERROR_AUDIO_POLICY_BLOCKED:
- return "Audio policy blocked";
- default:
- return "Unknown Error";
- }
-}
-
-void TtsStateChangedCallback(tts_h tts_handle, tts_state_e previous, tts_state_e current,
- void* user_data) {
- TtsTizen* _this = static_cast<TtsTizen*>(user_data);
-
- if (TTS_STATE_CREATED == previous && TTS_STATE_READY == current)
- _this->TtsReady();
- else if (TTS_STATE_PAUSED == previous &&
- TTS_STATE_PLAYING == current && _this->GetUtterance().id)
- _this->GetTtsMessageFilterEfl()->DidResumeSpeaking(_this->GetUtterance().id);
- else if (TTS_STATE_PLAYING == previous &&
- TTS_STATE_PAUSED == current && _this->GetUtterance().id)
- _this->GetTtsMessageFilterEfl()->DidPauseSpeaking(_this->GetUtterance().id);
-}
-
-void TtsUtteranceStartedCallback(tts_h tts_handle, int utteranceId, void* user_data) {
- TtsTizen* _this = static_cast<TtsTizen*>(user_data);
- if (_this->GetUtterance().id)
- _this->GetTtsMessageFilterEfl()->
- DidStartSpeaking(_this->GetUtterance().id);
-}
-
-void TtsUtteranceCompletedCallback(tts_h tts_handle, int utteranceId, void *user_data) {
- TtsTizen* _this = static_cast<TtsTizen*>(user_data);
- if (_this->GetUtterance().id)
- _this->GetTtsMessageFilterEfl()->
- DidFinishSpeaking(_this->GetUtterance().id);
-}
-
-void TtsErrorCallback(tts_h tts_handle, int utteranceId, tts_error_e reason, void* user_data) {
- TtsTizen* _this = static_cast<TtsTizen*>(user_data);
- if (_this->GetUtterance().id)
- _this->GetTtsMessageFilterEfl()->
- SpeakingErrorOccurred(_this->GetUtterance().id, ErrorToString(reason));
-}
-
-bool TtsSupportedVoiceCallback(tts_h tts_handle,
- const char* language,
- int voice_type, void* user_data) {
- TtsTizen* _this = static_cast<TtsTizen*>(user_data);
- int currentVoiceType = voice_type;
- _this->AddVoice(std::string(language), currentVoiceType);
- return true;
-}
-
-bool InitializeTtsEngine(tts_h* tts_handle) {
- int ret = tts_create(tts_handle);
- if (ret != TTS_ERROR_NONE) {
- LOG(ERROR) << "Fail to create TTS: " << ErrorToString(static_cast<tts_error_e>(ret));
- *tts_handle = NULL;
- return false;
- }
- ret = tts_set_mode(*tts_handle, TTS_MODE_DEFAULT);
- if (ret != TTS_ERROR_NONE) {
- LOG(ERROR) << "Fail to set TTS mode: " << ErrorToString(static_cast<tts_error_e>(ret));
- }
- ret = tts_prepare(*tts_handle);
- if (ret != TTS_ERROR_NONE) {
- LOG(ERROR) << "Fail to prepare TTS: " << ErrorToString(static_cast<tts_error_e>(ret));
- *tts_handle = NULL;
- return false;
- }
- return true;
-}
-
-int GetTtsVoiceSpeed(tts_h tts_handle, float rate) {
- // TTS engine dependent capability.
- const float kRateMin = 0.6f, kRateMax = 2.0f, kRateNormal = 1.0f;
-
- int tts_speed_min = 0, tts_speed_normal = 0, tts_speed_max = 0;
- int ret = tts_get_speed_range(tts_handle,
- &tts_speed_min, &tts_speed_normal, &tts_speed_max);
- if (ret != TTS_ERROR_NONE) {
- LOG(ERROR) << "TTS: tts_get_speed_range() failed";
- return TTS_SPEED_AUTO;
- }
-
- if (rate <= kRateMin)
- return tts_speed_min;
-
- if (rate >= kRateMax)
- return tts_speed_max;
-
- // Piecewise linear interpolation from |rate| to TTS internal speed value.
- if (rate < kRateNormal)
- return static_cast<int>(tts_speed_min + (rate - kRateMin)
- * ((tts_speed_normal - tts_speed_min) / (kRateNormal - kRateMin)));
- else
- return static_cast<int>(tts_speed_normal + (rate - kRateNormal)
- * ((tts_speed_max - tts_speed_normal) / (kRateMax - kRateNormal)));
-}
-
-} // namespace
-
-TtsTizen::TtsTizen(TtsMessageFilterEfl* tts_message_filter_efl)
- : tts_message_filter_efl_(tts_message_filter_efl),
- tts_handle_(NULL),
- default_voice_(TTS_VOICE_TYPE_AUTO),
- tts_initialized_(false),
- tts_state_ready_(false),
- utterance_waiting_(false) {
-}
-
-TtsTizen::~TtsTizen() {
- if(tts_initialized_ && tts_handle_)
- {
- int ret = tts_unset_state_changed_cb(tts_handle_) &&
- tts_unset_utterance_completed_cb(tts_handle_) &&
- tts_unset_error_cb(tts_handle_);
-
- if (ret != TTS_ERROR_NONE)
- LOG(ERROR) << "TTS: Fail to unset callbacks";
-
- ret = tts_unprepare(tts_handle_);
- if (ret != TTS_ERROR_NONE)
- LOG(ERROR) << "TTS: Fail to unprepare";
-
- tts_destroy(tts_handle_);
- tts_handle_ = NULL;
- tts_initialized_ = false;
- }
-}
-
-bool TtsTizen::Init() {
- tts_initialized_ = InitializeTtsEngine(&tts_handle_);
- if (!tts_initialized_) {
- return false;
- }
-
- SetTtsDefaultVoice();
-
- // Set callbacks
- SetTtsCallback(this);
- return true;
-}
-
-void TtsTizen::SetTtsDefaultVoice() {
- char* language = NULL;
- int voice_type;
- int ret = tts_get_default_voice(tts_handle_, &language, &voice_type);
- if (ret != TTS_ERROR_NONE) {
- LOG(ERROR) << "TTS: Fail to get default voice";
- // Even if ret != TTS_ERROR_NONE, do not return here.
- // Set the default values.
- const char kDefaultLanguage[] = "en_GB";
- default_language_ = kDefaultLanguage;
- default_voice_ = TTS_VOICE_TYPE_AUTO;
- } else {
- DCHECK(language);
- default_language_ = language;
- free(language);
- default_voice_ = voice_type;
- }
-}
-
-
-void TtsTizen::SetTtsCallback(void* tts_data) {
- int ret = tts_set_state_changed_cb(tts_handle_, TtsStateChangedCallback, tts_data);
- if (ret != TTS_ERROR_NONE)
- LOG(ERROR) << "TTS: Unable to set state callback";
-
- ret = tts_set_utterance_started_cb(tts_handle_, TtsUtteranceStartedCallback, tts_data);
- if (ret != TTS_ERROR_NONE)
- LOG(ERROR) << "TTS: Fail to set utterance started callback";
-
- ret = tts_set_utterance_completed_cb(tts_handle_, TtsUtteranceCompletedCallback, tts_data);
- if (ret != TTS_ERROR_NONE)
- LOG(ERROR) << "TTS: Fail to set utterance completed callback";
-
- ret = tts_set_error_cb(tts_handle_, TtsErrorCallback, this);
- if (ret != TTS_ERROR_NONE)
- LOG(ERROR) << "TTS: Fail to set error callback";
-
- ret = tts_foreach_supported_voices(tts_handle_, TtsSupportedVoiceCallback, this);
- if (ret != TTS_ERROR_NONE)
- LOG(ERROR) << "TTS: Fail to get supported voices";
-}
-
-const std::vector<TtsVoice>& TtsTizen::GetVoiceList() {
- return voice_list_;
-}
-
-void TtsTizen::TtsReady() {
- tts_state_ready_ = true;
- if (utterance_waiting_)
- SpeakStoredUtterance();
- utterance_waiting_ = false;
-}
-
-void TtsTizen::Speak(const TtsUtteranceRequest& utterance) {
- utterance_ = utterance;
- if (!tts_state_ready_) {
- utterance_waiting_ = true;
- return;
- }
- SpeakStoredUtterance();
-}
-
-void TtsTizen::SpeakStoredUtterance() {
- if (utterance_.text.empty()) {
- return;
- }
- std::string current_language = default_language_;
- if (!utterance_.lang.empty())
- current_language = utterance_.lang;
-
- int voiceType = static_cast<int>(default_voice_);
- if (!utterance_.voice.empty())
- voiceType = static_cast<int>(VoiceNameToType(utterance_.voice));
- int textSpeed = GetTtsVoiceSpeed(tts_handle_, utterance_.rate);
- int utteranceId = utterance_.id;
- int ret = tts_add_text(tts_handle_, utterance_.text.c_str(), current_language.c_str(),
- voiceType, textSpeed, &utteranceId);
- if (ret != TTS_ERROR_NONE) {
- LOG(ERROR) << "TTS: Fail to add text";
- GetTtsMessageFilterEfl()->
- SpeakingErrorOccurred(utterance_.id, ErrorToString(static_cast<tts_error_e>(ret)));
- return;
- }
- tts_state_e current_state;
- tts_get_state(tts_handle_, ¤t_state);
- if (TTS_STATE_PLAYING != current_state)
- ret = tts_play(tts_handle_);
-
- if (ret != TTS_ERROR_NONE) {
- LOG(ERROR) << "TTS: Play Error occured";
- GetTtsMessageFilterEfl()->
- SpeakingErrorOccurred(utterance_.id, ErrorToString(static_cast<tts_error_e>(ret)));
- return;
- }
-}
-
-void TtsTizen::Pause() {
- if (!utterance_.id)
- return;
-
- int ret = tts_pause(tts_handle_);
- if (ret != TTS_ERROR_NONE) {
- LOG(ERROR) << "TTS: Fail to pause #tts_pause";
- GetTtsMessageFilterEfl()->
- SpeakingErrorOccurred(utterance_.id, ErrorToString(static_cast<tts_error_e>(ret)));
- }
-}
-
-void TtsTizen::Resume() {
- if (!utterance_.id)
- return;
-
- int ret = tts_play(tts_handle_);
- if (ret != TTS_ERROR_NONE) {
- LOG(ERROR) << "TTS: Fail to resume";
- GetTtsMessageFilterEfl()->
- SpeakingErrorOccurred(utterance_.id, ErrorToString(static_cast<tts_error_e>(ret)));
- }
-}
-
-void TtsTizen::Cancel() {
- int ret = tts_stop(tts_handle_);
- if (ret != TTS_ERROR_NONE) {
- LOG(ERROR) << "TTS: Fail to cancel";
- GetTtsMessageFilterEfl()->
- SpeakingErrorOccurred(utterance_.id, ErrorToString(static_cast<tts_error_e>(ret)));
- }
- GetTtsMessageFilterEfl()->DidFinishSpeaking(utterance_.id);
-}
-
-void TtsTizen::AddVoice(std::string language, tts_voice_type_e type) {
- TtsVoice voice;
- std::string uri(kUriPrefix);
- uri.append(VoiceTypeToName(type));
- uri.append("/");
- uri.append(language);
-
- voice.voice_uri = uri ;
- voice.name = VoiceTypeToName(type);
- voice.lang = language;
- voice.is_default = (language == default_language_);
- voice_list_.push_back(voice);
-}
-
-} // namespace content
+++ /dev/null
-// Copyright (c) 2014 Samsung Electronics Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BROWSER_SPEECH_TTS_TIZEN_H_
-#define BROWSER_SPEECH_TTS_TIZEN_H_
-
-#include "build/tizen_version.h"
-
-typedef int tts_voice_type_e;
-
-#include "content/browser/speech/tts_message_filter_efl.h"
-#include "content/common/tts_utterance_request_efl.h"
-
-#include <tts.h>
-#include <vector>
-
-namespace content {
-class TtsMessageFilterEfl;
-
-// TtsTizen is the class that actually communicate with tts engine.
-// It handles tts instance, callbacks and callback returns
-class TtsTizen {
- public:
- TtsTizen(TtsMessageFilterEfl* tts_message_filter_efl);
- ~TtsTizen();
- bool Init();
-
- // Return voice list
- const std::vector<TtsVoice>& GetVoiceList();
- void Speak(const TtsUtteranceRequest& utterance);
- void Pause();
- void Resume();
- void Cancel();
- tts_h GetTTS() { return tts_handle_; }
- TtsMessageFilterEfl* GetTtsMessageFilterEfl() {
- return tts_message_filter_efl_; }
- const TtsUtteranceRequest& GetUtterance() const { return utterance_; }
- void TtsReady();
-
- // Get voices one by one from tts engine, append them into a voice list
- void AddVoice(std::string language, tts_voice_type_e name);
- bool IsTtsInitialized() const { return tts_initialized_; }
-
- private:
- // Create and Set tts and tts callback. If any of these failes, tts will not work at all.
- void SetTtsCallback(void* tts_data);
- void SetTtsDefaultVoice();
- void SpeakStoredUtterance();
- TtsMessageFilterEfl* tts_message_filter_efl_;
- TtsUtteranceRequest utterance_;
- tts_h tts_handle_;
- std::string default_language_;
- tts_voice_type_e default_voice_;
-
- // This variable stores list of voicees that tts engine support.
- std::vector<TtsVoice> voice_list_;
-
- // This variable check whether tts is initialized.
- // It will be true when tts engine set the variable tts_.
- bool tts_initialized_;
-
- // This variable check whether tts is ready, after initialized.
- // Initial value is false and it will be true when tts state change to
- // TTS_STATE_CREATED && TTS_STATE_READY.
- bool tts_state_ready_;
-
- // This variable check whether any utterance is currently wating to speak.
- bool utterance_waiting_;
-};
-
-} // namespace content
-
-#endif // BROWSER_SPEECH_TTS_TIZEN_H_
"//tizen_src/chromium_impl/content/renderer/common_renderer_client.h",
]
-if (!ewk_bringup) { #FIXME:m85 bringup
- if (is_tizen) {
- external_content_renderer_efl_sources += [
- "//tizen_src/chromium_impl/content/renderer/tts_dispatcher_efl.cc",
- "//tizen_src/chromium_impl/content/renderer/tts_dispatcher_efl.h",
- ]
- }
-}
if (tizen_multimedia_support) {
#"media/audio_decoder.cc",
#"media/audio_decoder.h",
+++ /dev/null
-// Copyright (c) 2014 Samsung Electronics Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/tts_dispatcher_efl.h"
-
-#include "base/logging.h"
-#include "base/strings/utf_string_conversions.h"
-#include "content/common/tts_messages_efl.h"
-#include "content/common/tts_utterance_request_efl.h"
-#include "content/public/renderer/render_thread.h"
-#include "third_party/blink/public/platform/web_speech_synthesis_utterance.h"
-#include "third_party/blink/public/platform/web_speech_synthesis_voice.h"
-#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/public/platform/web_vector.h"
-
-namespace content {
-
-int TtsDispatcherEfl::next_utterance_id_ = 1;
-
-static const std::vector<TtsVoice>& getDefaultVoiceList() {
- static std::vector<TtsVoice> default_voices(
- 1, TtsVoice("localhost:Female/en_US", "Female", "en_US", false, false));
-
- return default_voices;
-}
-
-TtsDispatcherEfl::TtsDispatcherEfl(blink::WebSpeechSynthesizerClient* client)
- : synthesizer_client_(client) {
- content::RenderThread::Get()->AddObserver(this);
- OnSetVoiceList(getDefaultVoiceList());
-}
-
-TtsDispatcherEfl::~TtsDispatcherEfl() {
- content::RenderThread::Get()->RemoveObserver(this);
-}
-
-bool TtsDispatcherEfl::OnControlMessageReceived(const IPC::Message& message) {
- IPC_BEGIN_MESSAGE_MAP(TtsDispatcherEfl, message)
- IPC_MESSAGE_HANDLER(TtsMsg_SetVoiceList, OnSetVoiceList)
- IPC_MESSAGE_HANDLER(TtsMsg_DidStartSpeaking, OnDidStartSpeaking)
- IPC_MESSAGE_HANDLER(TtsMsg_DidFinishSpeaking, OnDidFinishSpeaking)
- IPC_MESSAGE_HANDLER(TtsMsg_DidPauseSpeaking, OnDidPauseSpeaking)
- IPC_MESSAGE_HANDLER(TtsMsg_DidResumeSpeaking, OnDidResumeSpeaking)
- IPC_MESSAGE_HANDLER(TtsMsg_WordBoundary, OnWordBoundary)
- IPC_MESSAGE_HANDLER(TtsMsg_SentenceBoundary, OnSentenceBoundary)
- IPC_MESSAGE_HANDLER(TtsMsg_MarkerEvent, OnMarkerEvent)
- IPC_MESSAGE_HANDLER(TtsMsg_WasInterrupted, OnWasInterrupted)
- IPC_MESSAGE_HANDLER(TtsMsg_WasCancelled, OnWasCancelled)
- IPC_MESSAGE_HANDLER(TtsMsg_SpeakingErrorOccurred, OnSpeakingErrorOccurred)
- IPC_END_MESSAGE_MAP()
-
- // Always return false because there may be multiple TtsDispatchers
- // and we want them all to have a chance to handle this message.
- return false;
-}
-
-void TtsDispatcherEfl::UpdateVoiceList() {
- content::RenderThread::Get()->Send(new TtsHostMsg_InitializeVoiceList());
-}
-
-void TtsDispatcherEfl::Speak(
- const blink::WebSpeechSynthesisUtterance& web_utterance) {
- int id = next_utterance_id_++;
-
- utterance_id_map_[id] = web_utterance;
-
- TtsUtteranceRequest utterance;
- utterance.id = id;
- utterance.text = web_utterance.GetText().Utf8();
- if (!web_utterance.Lang().IsEmpty() &&
- web_utterance.Lang().Utf8().at(2) == '-')
- utterance.lang = web_utterance.Lang().Utf8().replace(2, 1, "_");
- utterance.voice = web_utterance.Voice().Utf8();
- utterance.volume = web_utterance.Volume();
- utterance.rate = web_utterance.Rate();
- utterance.pitch = web_utterance.Pitch();
- content::RenderThread::Get()->Send(new TtsHostMsg_Speak(utterance));
-}
-
-void TtsDispatcherEfl::Pause() {
- content::RenderThread::Get()->Send(new TtsHostMsg_Pause());
-}
-
-void TtsDispatcherEfl::Resume() {
- content::RenderThread::Get()->Send(new TtsHostMsg_Resume());
-}
-
-void TtsDispatcherEfl::Cancel() {
- content::RenderThread::Get()->Send(new TtsHostMsg_Cancel());
-}
-
-blink::WebSpeechSynthesisUtterance TtsDispatcherEfl::FindUtterance(int utterance_id) {
- const auto iter = utterance_id_map_.find(utterance_id);
- if (iter == utterance_id_map_.end())
- return blink::WebSpeechSynthesisUtterance();
- return iter->second;
-}
-
-void TtsDispatcherEfl::OnSetVoiceList(const std::vector<TtsVoice>& voices) {
- blink::WebVector<blink::WebSpeechSynthesisVoice> out_voices(voices.size());
- for (size_t i = 0; i < voices.size(); ++i) {
- out_voices[i].SetVoiceURI(blink::WebString::FromUTF8(voices[i].voice_uri));
- out_voices[i].SetName(blink::WebString::FromUTF8(voices[i].name));
- out_voices[i].SetLanguage(blink::WebString::FromUTF8(voices[i].lang));
- out_voices[i].SetIsLocalService(voices[i].local_service);
- out_voices[i].SetIsDefault(voices[i].is_default);
- }
- synthesizer_client_->SetVoiceList(out_voices);
-}
-
-void TtsDispatcherEfl::OnDidStartSpeaking(int utterance_id) {
- if (utterance_id_map_.find(utterance_id) == utterance_id_map_.end())
- return;
-
- blink::WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
- if (utterance.IsNull())
- return;
-
- synthesizer_client_->DidStartSpeaking(utterance);
-}
-
-void TtsDispatcherEfl::OnDidFinishSpeaking(int utterance_id) {
- blink::WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
- if (utterance.IsNull())
- return;
-
- synthesizer_client_->DidFinishSpeaking(utterance);
- utterance_id_map_.erase(utterance_id);
-}
-
-void TtsDispatcherEfl::OnDidPauseSpeaking(int utterance_id) {
- blink::WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
- if (utterance.IsNull())
- return;
-
- synthesizer_client_->DidPauseSpeaking(utterance);
-}
-
-void TtsDispatcherEfl::OnDidResumeSpeaking(int utterance_id) {
- blink::WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
- if (utterance.IsNull())
- return;
-
- synthesizer_client_->DidResumeSpeaking(utterance);
-}
-
-void TtsDispatcherEfl::OnWordBoundary(int utterance_id, int char_index) {
- CHECK(char_index >= 0);
-
- blink::WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
- if (utterance.IsNull())
- return;
-
- synthesizer_client_->WordBoundaryEventOccurred(
- utterance, static_cast<unsigned>(char_index), 0);
-}
-
-void TtsDispatcherEfl::OnSentenceBoundary(int utterance_id, int char_index) {
- CHECK(char_index >= 0);
-
- blink::WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
- if (utterance.IsNull())
- return;
-
- synthesizer_client_->SentenceBoundaryEventOccurred(
- utterance, static_cast<unsigned>(char_index), 0);
-}
-
-void TtsDispatcherEfl::OnMarkerEvent(int utterance_id, int char_index) {
- // Not supported yet.
-}
-
-void TtsDispatcherEfl::OnWasInterrupted(int utterance_id) {
- blink::WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
- if (utterance.IsNull())
- return;
-
- // The web speech API doesn't support "interrupted".
- synthesizer_client_->DidFinishSpeaking(utterance);
- utterance_id_map_.erase(utterance_id);
-}
-
-void TtsDispatcherEfl::OnWasCancelled(int utterance_id) {
- blink::WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
- if (utterance.IsNull())
- return;
-
- // The web speech API doesn't support "cancelled".
- synthesizer_client_->DidFinishSpeaking(utterance);
- utterance_id_map_.erase(utterance_id);
-}
-
-void TtsDispatcherEfl::OnSpeakingErrorOccurred(int utterance_id,
- const std::string& error_message) {
- blink::WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
- if (utterance.IsNull())
- return;
-
- // The web speech API doesn't support an error message.
- synthesizer_client_->SpeakingErrorOccurred(utterance);
- utterance_id_map_.erase(utterance_id);
-}
-
-} // namespace content
+++ /dev/null
-// Copyright (c) 2014 Samsung Electronics Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef RENDERER_TTS_DISPATCHER_H_
-#define RENDERER_TTS_DISPATCHER_H_
-
-#include <vector>
-
-#include "base/compiler_specific.h"
-#include "content/common/content_export.h"
-#include "content/public/renderer/render_thread_observer.h"
-#include "third_party/blink/public/platform/web_speech_synthesizer.h"
-#include "third_party/blink/public/platform/web_speech_synthesizer_client.h"
-
-namespace IPC {
-class Message;
-}
-
-namespace content {
-
-struct TtsVoice;
-
-// TtsDispatcher is a delegate for methods used by Blink for speech synthesis
-// APIs. It's the complement of TtsDispatcherHost (owned by RenderViewHost).
-// Each TtsDispatcher is owned by the WebSpeechSynthesizerClient in Blink;
-// it registers itself to listen to IPC upon construction and unregisters
-// itself when deleted. There can be multiple TtsDispatchers alive at once,
-// so each one routes IPC messages to its WebSpeechSynthesizerClient only if
-// the utterance id (which is globally unique) matches.
-class CONTENT_EXPORT TtsDispatcherEfl
- : public blink::WebSpeechSynthesizer,
- public content::RenderThreadObserver {
- public:
- explicit TtsDispatcherEfl(blink::WebSpeechSynthesizerClient* client);
-
- private:
- ~TtsDispatcherEfl() override;
-
- TtsDispatcherEfl(const TtsDispatcherEfl&) = delete;
- TtsDispatcherEfl& operator=(const TtsDispatcherEfl&) = delete;
-
- // RenderThreadObserver override.
- bool OnControlMessageReceived(const IPC::Message& message) override;
-
- // blink::WebSpeechSynthesizer implementation.
- void UpdateVoiceList() override;
- void Speak(const blink::WebSpeechSynthesisUtterance& utterance) override;
- void Pause() override;
- void Resume() override;
- void Cancel() override;
-
- blink::WebSpeechSynthesisUtterance FindUtterance(int utterance_id);
-
- void OnSetVoiceList(const std::vector<TtsVoice>& voices);
- void OnDidStartSpeaking(int utterance_id);
- void OnDidFinishSpeaking(int utterance_id);
- void OnDidPauseSpeaking(int utterance_id);
- void OnDidResumeSpeaking(int utterance_id);
- void OnWordBoundary(int utterance_id, int char_index);
- void OnSentenceBoundary(int utterance_id, int char_index);
- void OnMarkerEvent(int utterance_id, int char_index);
- void OnWasInterrupted(int utterance_id);
- void OnWasCancelled(int utterance_id);
- void OnSpeakingErrorOccurred(int utterance_id,
- const std::string& error_message);
-
- // The WebKit client class that we use to send events back to the JS world.
- // Weak reference, this will be valid as long as this object exists.
- blink::WebSpeechSynthesizerClient* synthesizer_client_;
-
- // Next utterance id, used to map response IPCs to utterance objects.
- static int next_utterance_id_;
-
- // Map from id to utterance objects.
- std::map<int, blink::WebSpeechSynthesisUtterance> utterance_id_map_;
-};
-
-} // namespace content
-
-#endif // RENDERER_TTS_DISPATCHER_H_
#if BUILDFLAG(IS_TIZEN)
#include <vconf.h>
-#include "content/browser/speech/tts_message_filter_efl.h"
#endif
#include "private/ewk_notification_private.h"
#if !defined(EWK_BRINGUP) // FIXME: m94 bringup
host->AddFilter(new editing::EditorClientObserver(host->GetID()));
#endif
-#if BUILDFLAG(IS_TIZEN)
- host->AddFilter(new TtsMessageFilterEfl());
-#endif
}
content::DevToolsManagerDelegate*
#include "usermedia_permission_popup.h"
#include "web_contents_delegate_efl.h"
+#if defined(TIZEN_WEB_SPEECH_RECOGNITION)
+#include "content/browser/speech/tts_platform_impl_tizen.h"
+#endif
+
static Eina_Bool _ewk_view_default_user_media_permission(
Evas_Object*, Ewk_User_Media_Permission_Request*, void*);
}
Eina_Bool ewk_view_tts_mode_set(Evas_Object* view, ewk_tts_mode tts_mode) {
- LOG_EWK_API_MOCKUP();
- return false;
+#if defined(TIZEN_WEB_SPEECH_RECOGNITION)
+ switch (tts_mode) {
+ case EWK_TTS_MODE_DEFAULT:
+ content::TtsPlatformImplTizen::SetTtsMode(TTS_MODE_DEFAULT);
+ break;
+ case EWK_TTS_MODE_NOTIFICATION:
+ content::TtsPlatformImplTizen::SetTtsMode(TTS_MODE_NOTIFICATION);
+ break;
+ case EWK_TTS_MODE_SCREEN_READER:
+ content::TtsPlatformImplTizen::SetTtsMode(TTS_MODE_SCREEN_READER);
+ break;
+ default:
+ LOG(ERROR) << "Not supported TTS mode: " << static_cast<int>(tts_mode);
+ return EINA_FALSE;
+ }
+ return EINA_TRUE;
+#else
+ LOG_EWK_API_MOCKUP("API unavailable.");
+ return EINA_FALSE;
+#endif
}
Eina_Bool ewk_view_javascript_message_handler_add(
#include "third_party/blink/public/web/web_view.h"
#include "url/gurl.h"
-#if defined(TIZEN_MULTIMEDIA_SUPPORT)
-#include "content/common/tts_messages_efl.h"
-#include "content/renderer/tts_dispatcher_efl.h"
-#endif
-
#if defined(TIZEN_AUTOFILL_SUPPORT)
#include "components/autofill/content/renderer/autofill_agent.h"
#include "components/autofill/content/renderer/autofill_assistant_agent.h"