199 lines
		
	
	
	
		
			6.7 KiB
			
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			199 lines
		
	
	
	
		
			6.7 KiB
			
		
	
	
	
		
			C++
		
	
	
	
	
	
// Copyright (c) 2013 The Chromium 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 "chrome/renderer/tts_dispatcher.h"
 | 
						|
 | 
						|
#include "base/strings/utf_string_conversions.h"
 | 
						|
#include "chrome/common/tts_messages.h"
 | 
						|
#include "chrome/common/tts_utterance_request.h"
 | 
						|
#include "content/public/renderer/render_thread.h"
 | 
						|
#include "third_party/WebKit/public/platform/WebCString.h"
 | 
						|
#include "third_party/WebKit/public/platform/WebSpeechSynthesisUtterance.h"
 | 
						|
#include "third_party/WebKit/public/platform/WebSpeechSynthesisVoice.h"
 | 
						|
#include "third_party/WebKit/public/platform/WebString.h"
 | 
						|
#include "third_party/WebKit/public/platform/WebVector.h"
 | 
						|
 | 
						|
using content::RenderThread;
 | 
						|
using blink::WebSpeechSynthesizerClient;
 | 
						|
using blink::WebSpeechSynthesisUtterance;
 | 
						|
using blink::WebSpeechSynthesisVoice;
 | 
						|
using blink::WebString;
 | 
						|
using blink::WebVector;
 | 
						|
 | 
						|
int TtsDispatcher::next_utterance_id_ = 1;
 | 
						|
 | 
						|
TtsDispatcher::TtsDispatcher(WebSpeechSynthesizerClient* client)
 | 
						|
    : synthesizer_client_(client) {
 | 
						|
  RenderThread::Get()->AddObserver(this);
 | 
						|
}
 | 
						|
 | 
						|
TtsDispatcher::~TtsDispatcher() {
 | 
						|
  RenderThread::Get()->RemoveObserver(this);
 | 
						|
}
 | 
						|
 | 
						|
bool TtsDispatcher::OnControlMessageReceived(const IPC::Message& message) {
 | 
						|
  IPC_BEGIN_MESSAGE_MAP(TtsDispatcher, 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 TtsDispatcher::updateVoiceList() {
 | 
						|
  RenderThread::Get()->Send(new TtsHostMsg_InitializeVoiceList());
 | 
						|
}
 | 
						|
 | 
						|
void TtsDispatcher::speak(const WebSpeechSynthesisUtterance& web_utterance) {
 | 
						|
  int id = next_utterance_id_++;
 | 
						|
 | 
						|
  utterance_id_map_[id] = web_utterance;
 | 
						|
 | 
						|
  TtsUtteranceRequest utterance;
 | 
						|
  utterance.id = id;
 | 
						|
  utterance.text = web_utterance.text().utf8();
 | 
						|
  utterance.lang = web_utterance.lang().utf8();
 | 
						|
  utterance.voice = web_utterance.voice().utf8();
 | 
						|
  utterance.volume = web_utterance.volume();
 | 
						|
  utterance.rate = web_utterance.rate();
 | 
						|
  utterance.pitch = web_utterance.pitch();
 | 
						|
  RenderThread::Get()->Send(new TtsHostMsg_Speak(utterance));
 | 
						|
}
 | 
						|
 | 
						|
void TtsDispatcher::pause() {
 | 
						|
  RenderThread::Get()->Send(new TtsHostMsg_Pause());
 | 
						|
}
 | 
						|
 | 
						|
void TtsDispatcher::resume() {
 | 
						|
  RenderThread::Get()->Send(new TtsHostMsg_Resume());
 | 
						|
}
 | 
						|
 | 
						|
void TtsDispatcher::cancel() {
 | 
						|
  RenderThread::Get()->Send(new TtsHostMsg_Cancel());
 | 
						|
}
 | 
						|
 | 
						|
WebSpeechSynthesisUtterance TtsDispatcher::FindUtterance(int utterance_id) {
 | 
						|
  base::hash_map<int, WebSpeechSynthesisUtterance>::const_iterator iter =
 | 
						|
      utterance_id_map_.find(utterance_id);
 | 
						|
  if (iter == utterance_id_map_.end())
 | 
						|
    return WebSpeechSynthesisUtterance();
 | 
						|
  return iter->second;
 | 
						|
}
 | 
						|
 | 
						|
void TtsDispatcher::OnSetVoiceList(const std::vector<TtsVoice>& voices) {
 | 
						|
  WebVector<WebSpeechSynthesisVoice> out_voices(voices.size());
 | 
						|
  for (size_t i = 0; i < voices.size(); ++i) {
 | 
						|
    out_voices[i] = WebSpeechSynthesisVoice();
 | 
						|
    out_voices[i].setVoiceURI(WebString::fromUTF8(voices[i].voice_uri));
 | 
						|
    out_voices[i].setName(WebString::fromUTF8(voices[i].name));
 | 
						|
    out_voices[i].setLanguage(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 TtsDispatcher::OnDidStartSpeaking(int utterance_id) {
 | 
						|
  if (utterance_id_map_.find(utterance_id) == utterance_id_map_.end())
 | 
						|
    return;
 | 
						|
 | 
						|
  WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
 | 
						|
  if (utterance.isNull())
 | 
						|
    return;
 | 
						|
 | 
						|
  synthesizer_client_->didStartSpeaking(utterance);
 | 
						|
}
 | 
						|
 | 
						|
void TtsDispatcher::OnDidFinishSpeaking(int utterance_id) {
 | 
						|
  WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
 | 
						|
  if (utterance.isNull())
 | 
						|
    return;
 | 
						|
 | 
						|
  synthesizer_client_->didFinishSpeaking(utterance);
 | 
						|
  utterance_id_map_.erase(utterance_id);
 | 
						|
}
 | 
						|
 | 
						|
void TtsDispatcher::OnDidPauseSpeaking(int utterance_id) {
 | 
						|
  WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
 | 
						|
  if (utterance.isNull())
 | 
						|
    return;
 | 
						|
 | 
						|
  synthesizer_client_->didPauseSpeaking(utterance);
 | 
						|
}
 | 
						|
 | 
						|
void TtsDispatcher::OnDidResumeSpeaking(int utterance_id) {
 | 
						|
  WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
 | 
						|
  if (utterance.isNull())
 | 
						|
    return;
 | 
						|
 | 
						|
  synthesizer_client_->didResumeSpeaking(utterance);
 | 
						|
}
 | 
						|
 | 
						|
void TtsDispatcher::OnWordBoundary(int utterance_id, int char_index) {
 | 
						|
  CHECK(char_index >= 0);
 | 
						|
 | 
						|
  WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
 | 
						|
  if (utterance.isNull())
 | 
						|
    return;
 | 
						|
 | 
						|
  synthesizer_client_->wordBoundaryEventOccurred(
 | 
						|
      utterance, static_cast<unsigned>(char_index));
 | 
						|
}
 | 
						|
 | 
						|
void TtsDispatcher::OnSentenceBoundary(int utterance_id, int char_index) {
 | 
						|
  CHECK(char_index >= 0);
 | 
						|
 | 
						|
  WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
 | 
						|
  if (utterance.isNull())
 | 
						|
    return;
 | 
						|
 | 
						|
  synthesizer_client_->sentenceBoundaryEventOccurred(
 | 
						|
      utterance, static_cast<unsigned>(char_index));
 | 
						|
}
 | 
						|
 | 
						|
void TtsDispatcher::OnMarkerEvent(int utterance_id, int char_index) {
 | 
						|
  // Not supported yet.
 | 
						|
}
 | 
						|
 | 
						|
void TtsDispatcher::OnWasInterrupted(int utterance_id) {
 | 
						|
  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 TtsDispatcher::OnWasCancelled(int utterance_id) {
 | 
						|
  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 TtsDispatcher::OnSpeakingErrorOccurred(int utterance_id,
 | 
						|
                                            const std::string& error_message) {
 | 
						|
  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);
 | 
						|
}
 |