tts_dispatcher.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/renderer/tts_dispatcher.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/basictypes.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/utf_string_conversions.h" 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/tts_messages.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/tts_utterance_request.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/renderer/render_thread.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "third_party/WebKit/Source/Platform/chromium/public/WebCString.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "third_party/WebKit/Source/Platform/chromium/public/WebSpeechSynthesisUtterance.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "third_party/WebKit/Source/Platform/chromium/public/WebSpeechSynthesisVoice.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "third_party/WebKit/Source/Platform/chromium/public/WebString.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "third_party/WebKit/Source/Platform/chromium/public/WebVector.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using content::RenderThread; 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using WebKit::WebSpeechSynthesizerClient; 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using WebKit::WebSpeechSynthesisUtterance; 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using WebKit::WebSpeechSynthesisVoice; 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using WebKit::WebString; 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using WebKit::WebVector; 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int TtsDispatcher::next_utterance_id_ = 1; 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TtsDispatcher::TtsDispatcher(WebSpeechSynthesizerClient* client) 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : synthesizer_client_(client), 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) main_loop_(base::MessageLoopProxy::current()) { 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RenderThread::Get()->AddFilter(this); 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TtsDispatcher::~TtsDispatcher() { 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool TtsDispatcher::OnMessageReceived(const IPC::Message& message) { 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool handled = true; 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(TtsDispatcher, message) 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPC_MESSAGE_HANDLER(TtsMsg_SetVoiceList, OnSetVoiceList) 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPC_MESSAGE_HANDLER(TtsMsg_DidStartSpeaking, OnDidStartSpeaking) 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPC_MESSAGE_HANDLER(TtsMsg_DidFinishSpeaking, OnDidFinishSpeaking) 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPC_MESSAGE_HANDLER(TtsMsg_DidPauseSpeaking, OnDidPauseSpeaking) 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPC_MESSAGE_HANDLER(TtsMsg_DidResumeSpeaking, OnDidResumeSpeaking) 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPC_MESSAGE_HANDLER(TtsMsg_WordBoundary, OnWordBoundary) 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPC_MESSAGE_HANDLER(TtsMsg_SentenceBoundary, OnSentenceBoundary) 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPC_MESSAGE_HANDLER(TtsMsg_MarkerEvent, OnMarkerEvent) 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPC_MESSAGE_HANDLER(TtsMsg_WasInterrupted, OnWasInterrupted) 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPC_MESSAGE_HANDLER(TtsMsg_WasCancelled, OnWasCancelled) 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPC_MESSAGE_HANDLER(TtsMsg_SpeakingErrorOccurred, OnSpeakingErrorOccurred) 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false) 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPC_END_MESSAGE_MAP() 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return handled; 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TtsDispatcher::updateVoiceList() { 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RenderThread::Get()->Send(new TtsHostMsg_InitializeVoiceList()); 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TtsDispatcher::speak(const WebSpeechSynthesisUtterance& web_utterance) { 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int id = next_utterance_id_++; 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) utterance_id_map_[id] = web_utterance; 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TtsUtteranceRequest utterance; 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) utterance.id = id; 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) utterance.text = web_utterance.text().utf8(); 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) utterance.lang = web_utterance.lang().utf8(); 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) utterance.voice = web_utterance.voice().utf8(); 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) utterance.volume = web_utterance.volume(); 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) utterance.rate = web_utterance.rate(); 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) utterance.pitch = web_utterance.pitch(); 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RenderThread::Get()->Send(new TtsHostMsg_Speak(utterance)); 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TtsDispatcher::pause() { 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RenderThread::Get()->Send(new TtsHostMsg_Pause()); 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TtsDispatcher::resume() { 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RenderThread::Get()->Send(new TtsHostMsg_Resume()); 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TtsDispatcher::cancel() { 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RenderThread::Get()->Send(new TtsHostMsg_Cancel()); 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)WebSpeechSynthesisUtterance TtsDispatcher::FindUtterance(int utterance_id) { 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::hash_map<int, WebSpeechSynthesisUtterance>::const_iterator iter = 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) utterance_id_map_.find(utterance_id); 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (iter == utterance_id_map_.end()) 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return WebSpeechSynthesisUtterance(); 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return iter->second; 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TtsDispatcher::OnSetVoiceList(const std::vector<TtsVoice>& voices) { 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebVector<WebSpeechSynthesisVoice> out_voices(voices.size()); 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < voices.size(); ++i) { 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) out_voices[i] = WebSpeechSynthesisVoice(); 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) out_voices[i].setVoiceURI(WebString::fromUTF8(voices[i].voice_uri)); 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) out_voices[i].setName(WebString::fromUTF8(voices[i].name)); 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) out_voices[i].setLanguage(WebString::fromUTF8(voices[i].lang)); 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) out_voices[i].setIsLocalService(voices[i].local_service); 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) out_voices[i].setIsDefault(voices[i].is_default); 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) synthesizer_client_->setVoiceList(out_voices); 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TtsDispatcher::OnDidStartSpeaking(int utterance_id) { 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (utterance_id_map_.find(utterance_id) == utterance_id_map_.end()) 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id); 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (utterance.isNull()) 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) synthesizer_client_->didStartSpeaking(utterance); 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TtsDispatcher::OnDidFinishSpeaking(int utterance_id) { 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id); 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (utterance.isNull()) 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) synthesizer_client_->didFinishSpeaking(utterance); 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) utterance_id_map_.erase(utterance_id); 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TtsDispatcher::OnDidPauseSpeaking(int utterance_id) { 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id); 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (utterance.isNull()) 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) synthesizer_client_->didPauseSpeaking(utterance); 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TtsDispatcher::OnDidResumeSpeaking(int utterance_id) { 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id); 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (utterance.isNull()) 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) synthesizer_client_->didResumeSpeaking(utterance); 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TtsDispatcher::OnWordBoundary(int utterance_id, int char_index) { 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK(char_index >= 0); 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id); 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (utterance.isNull()) 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) synthesizer_client_->wordBoundaryEventOccurred( 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) utterance, static_cast<unsigned>(char_index)); 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TtsDispatcher::OnSentenceBoundary(int utterance_id, int char_index) { 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK(char_index >= 0); 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id); 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (utterance.isNull()) 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) synthesizer_client_->sentenceBoundaryEventOccurred( 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) utterance, static_cast<unsigned>(char_index)); 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TtsDispatcher::OnMarkerEvent(int utterance_id, int char_index) { 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Not supported yet. 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TtsDispatcher::OnWasInterrupted(int utterance_id) { 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id); 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (utterance.isNull()) 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The web speech API doesn't support "interrupted". 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) synthesizer_client_->didFinishSpeaking(utterance); 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) utterance_id_map_.erase(utterance_id); 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TtsDispatcher::OnWasCancelled(int utterance_id) { 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id); 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (utterance.isNull()) 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The web speech API doesn't support "cancelled". 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) synthesizer_client_->didFinishSpeaking(utterance); 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) utterance_id_map_.erase(utterance_id); 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TtsDispatcher::OnSpeakingErrorOccurred(int utterance_id, 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error_message) { 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id); 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (utterance.isNull()) 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The web speech API doesn't support an error message. 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) synthesizer_client_->speakingErrorOccurred(utterance); 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) utterance_id_map_.erase(utterance_id); 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 200