TTS转换有很多第三方库,比如科大讯飞的sdk就很好用,但是对于一些简单的需求,用windows(win7)的sapi就可以了。
sapi运用是很简单,但是在很多电脑上就上放不出声音,原因是这些电脑系统不是官网下载的,TTS功能被阉割了,本文记录的主要就是修复这个问题。
由于不同电脑缺少的语音组件不同,所以试了一堆修复包,也不知道这些修复包谁有用,总之不行全执行一遍就行。
为了以后下载方便,把他们存在了百度云盘中,地址:链接: https://pan.baidu.com/s/1PbryiE0gaW835zqwd52mCg 提取码: haee
自带一个示例程序tts_helloworld.
#include <array>
#include <list>
#include <algorithm>
#include "stdafx.h"
#include "../Include/sapi.h"
#include "../Include/sphelper.h"
#define _CRT_SECURE_NO_WARNINGS
#pragma comment(lib,"../Lib/sapi.lib")
int Speak(const char *Text)
{
ISpVoice *pVoice = NULL;
WCHAR Wchar[1024];
MultiByteToWideChar(CP_ACP, 0, Text, strlen(Text) + 1, Wchar, 1024 / sizeof(Wchar[0]));
//初始化COM接口
if (FAILED(::CoInitialize(NULL)))
return -1;
//获取SpVoice接口
HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void**)&pVoice);
if (SUCCEEDED(hr))
{
ISpObjectToken *p = NULL;
hr = SpFindBestToken(SPCAT_VOICES, L"language=804", L"Name=VM Lily", &p);
if (SUCCEEDED(hr))//说话人控制
{
pVoice->SetVoice(p);
}
pVoice->SetRate(-2);
pVoice->SetVolume(100);
hr = pVoice->Speak(Wchar, 0, NULL);
pVoice->Release();
pVoice = NULL;
}
//释放com资源
::CoUninitialize();
return 0;
}
int SaveVoice(const char *Text, const char* FileName)
{
CComPtr<ISpVoice> m_cpVoice;
WCHAR Wchar[1024];
MultiByteToWideChar(CP_ACP, 0, Text, strlen(Text) + 1, Wchar, 1024 / sizeof(Wchar[0]));
//初始化COM接口
if (FAILED(::CoInitialize(NULL)))
return -1;
HRESULT hr = m_cpVoice.CoCreateInstance(CLSID_SpVoice);
if (SUCCEEDED(hr))
{
USES_CONVERSION;
CComPtr<ISpStream> cpWavStream;
CComPtr<ISpStreamFormat> cpOldStream;
CSpStreamFormat OriginalFmt;
hr = m_cpVoice->GetOutputStream(&cpOldStream);
if (hr == S_OK)
hr = OriginalFmt.AssignFormat(cpOldStream);
else
hr = E_FAIL;
if (SUCCEEDED(hr))
hr = SPBindToFile(FileName, SPFM_CREATE_ALWAYS, &cpWavStream, &OriginalFmt.FormatId(), OriginalFmt.WaveFormatExPtr());
if (SUCCEEDED(hr))
hr = m_cpVoice->SetOutput(cpWavStream, TRUE);
if (SUCCEEDED(hr))
{
ISpObjectToken *p = NULL;
hr = SpFindBestToken(SPCAT_VOICES, L"language=804", L"Name=Microsoft lili", &p);
if (SUCCEEDED(hr))//说话人控制
{
m_cpVoice->SetVoice(p);
}
m_cpVoice->SetRate(-2);
m_cpVoice->SetVolume(100);
hr = m_cpVoice->Speak(Wchar, SPF_ASYNC | SPF_IS_NOT_XML, 0);
}
m_cpVoice->WaitUntilDone(INFINITE);
cpWavStream.Release();
m_cpVoice->SetOutput(cpOldStream, FALSE);
m_cpVoice.Release();
m_cpVoice = NULL;
}
::CoUninitialize();
return 0;
}