-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtinytext2speech.h
88 lines (76 loc) · 1.63 KB
/
tinytext2speech.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// Developed by David Amador
// www.twitter.com/DJ_Link
#ifndef TINY_TEXT_2_SPEECH_H
#define TINY_TEXT_2_SPEECH_H
//Wrapping Win code to add MacOS later
#if defined(_WIN32)
#define TT2S_USING_WNDOWS
#include <sapi.h>
#endif
namespace ttspeech
{
class Speaker
{
public:
Speaker()
{
#if defined(TT2S_USING_WNDOWS)
if (FAILED(CoInitialize(nullptr)))
{
printf("Error to initialize COM");
}
const HRESULT hr = CoCreateInstance(CLSID_SpVoice, nullptr, CLSCTX_ALL, IID_ISpVoice, (void**)&_voice);
if (FAILED(hr))
{
printf("Error to CoCreateInstance ISpVoice");
}
_initialized = SUCCEEDED(hr);
#endif
}
~Speaker()
{
#if defined(TT2S_USING_WNDOWS)
if (_voice)
{
_voice->Release();
}
::CoUninitialize();
#endif
}
public:
void speak(const std::string& text) const
{
if (!_initialized)
{
return;
}
#if defined(TT2S_USING_WNDOWS)
ULONG stream_number;
const HRESULT hr = _voice->Speak(string2ws(text).c_str(), SPF_IS_NOT_XML | SPF_ASYNC | SPF_PURGEBEFORESPEAK, &stream_number);
if (FAILED(hr))
{
//TODO: Log or info
}
#endif
}
#if defined(TT2S_USING_WNDOWS)
private:
static std::wstring string2ws(const std::string& s)
{
const int slength = (int)s.length() + 1;
const int len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
wchar_t* buf = static_cast<wchar_t*>(malloc(sizeof(wchar_t) * len));
MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
std::wstring r(buf);
free(buf);
return r;
}
#endif
private:
#if defined(TT2S_USING_WNDOWS)
ISpVoice* _voice = nullptr;
#endif
bool _initialized = false;
};
}
#endif