1 /* Copyright (C) 2012, 2013 Olga Yakovleva <yakovleva.o.v@gmail.com> */ 2 3 /* This program is free software: you can redistribute it and/or modify */ 4 /* it under the terms of the GNU Lesser General Public License as published by */ 5 /* the Free Software Foundation, either version 2.1 of the License, or */ 6 /* (at your option) any later version. */ 7 8 /* This program is distributed in the hope that it will be useful, */ 9 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 10 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ 11 /* GNU Lesser General Public License for more details. */ 12 13 /* You should have received a copy of the GNU Lesser General Public License */ 14 /* along with this program. If not, see <http://www.gnu.org/licenses/>. */ 15 16 #include <new> 17 #include "utils.hpp" 18 #include "ISpTTSEngineImpl.hpp" 19 #include "SpeakImpl.hpp" 20 21 namespace RHVoice 22 { 23 namespace sapi 24 { SetObjectToken(ISpObjectToken * pToken)25 STDMETHODIMP ISpTTSEngineImpl::SetObjectToken(ISpObjectToken *pToken) 26 { 27 if(pToken==0) 28 return E_INVALIDARG; 29 try 30 { 31 ISpDataKeyPtr attr; 32 if(FAILED(pToken->OpenKey(L"Attributes",&attr))) 33 return E_INVALIDARG; 34 utils::out_ptr<wchar_t> name(CoTaskMemFree); 35 if(FAILED(attr->GetStringValue(L"Name",name.address()))) 36 return E_INVALIDARG; 37 voice_profile new_profile=get_engine()->create_voice_profile(utils::wstring_to_string(name.get())); 38 if(new_profile.empty()) 39 return E_INVALIDARG; 40 profile=new_profile; 41 token=pToken; 42 return S_OK; 43 } 44 catch(const std::bad_alloc&) 45 { 46 return E_OUTOFMEMORY; 47 } 48 catch(...) 49 { 50 return E_UNEXPECTED; 51 } 52 } 53 GetObjectToken(ISpObjectToken ** ppToken)54 STDMETHODIMP ISpTTSEngineImpl::GetObjectToken(ISpObjectToken **ppToken) 55 { 56 if(ppToken==0) 57 return E_POINTER; 58 *ppToken=0; 59 if(token) 60 { 61 token.AddRef(); 62 *ppToken=token.GetInterfacePtr(); 63 return S_OK; 64 } 65 else 66 return E_UNEXPECTED; 67 } 68 GetOutputFormat(const GUID * pTargetFmtId,const WAVEFORMATEX * pTargetWaveFormatEx,GUID * pOutputFormatId,WAVEFORMATEX ** ppCoMemOutputWaveFormatEx)69 STDMETHODIMP ISpTTSEngineImpl::GetOutputFormat([[maybe_unused]] const GUID *pTargetFmtId, [[maybe_unused]] const WAVEFORMATEX *pTargetWaveFormatEx,GUID *pOutputFormatId,WAVEFORMATEX **ppCoMemOutputWaveFormatEx) 70 { 71 if(pOutputFormatId==0) 72 return E_POINTER; 73 if(ppCoMemOutputWaveFormatEx==0) 74 return E_POINTER; 75 *pOutputFormatId=SPDFID_WaveFormatEx; 76 *ppCoMemOutputWaveFormatEx=0; 77 WAVEFORMATEX *pwfex=reinterpret_cast<WAVEFORMATEX*>(CoTaskMemAlloc(sizeof(WAVEFORMATEX))); 78 if(pwfex==0) 79 return E_OUTOFMEMORY; 80 pwfex->wFormatTag=0x0001; 81 pwfex->nChannels=1; 82 pwfex->nSamplesPerSec=((get_engine()->quality==quality_min)?16000:24000); 83 pwfex->wBitsPerSample=16; 84 pwfex->nBlockAlign=pwfex->nChannels*pwfex->wBitsPerSample/8; 85 pwfex->nAvgBytesPerSec=pwfex->nSamplesPerSec*pwfex->nBlockAlign; 86 pwfex->cbSize=0; 87 *ppCoMemOutputWaveFormatEx=pwfex; 88 return S_OK; 89 } 90 Speak(DWORD dwSpeakFlags,REFGUID rguidFormatId,const WAVEFORMATEX * pWaveFormatEx,const SPVTEXTFRAG * pTextFragList,ISpTTSEngineSite * pOutputSite)91 STDMETHODIMP ISpTTSEngineImpl::Speak([[maybe_unused]] DWORD dwSpeakFlags, [[maybe_unused]] REFGUID rguidFormatId, [[maybe_unused]] const WAVEFORMATEX *pWaveFormatEx,const SPVTEXTFRAG *pTextFragList,ISpTTSEngineSite *pOutputSite) 92 { 93 if(pTextFragList==0) 94 return E_INVALIDARG; 95 if(pOutputSite==0) 96 return E_INVALIDARG; 97 try 98 { 99 SpeakImpl::init_params p; 100 p.input=pTextFragList; 101 p.caller=pOutputSite; 102 p.profile=profile; 103 SpeakImpl s(p); 104 s(); 105 return S_OK; 106 } 107 catch(const std::bad_alloc&) 108 { 109 return E_OUTOFMEMORY; 110 } 111 catch(...) 112 { 113 return E_UNEXPECTED; 114 } 115 } 116 } 117 } 118