|
#include <windows.h> |
|
#include <sapi.h> // Include SAPI header |
|
#include <string> |
|
|
|
extern "C" __declspec(dllexport) int GetSAPI4Voices(char* buffer, int bufferSize) { |
|
ISpVoice* pVoice = nullptr; |
|
if (FAILED(CoInitialize(nullptr))) { |
|
return -1; // Failed to initialize COM |
|
} |
|
|
|
HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void**)&pVoice); |
|
if (FAILED(hr)) { |
|
CoUninitialize(); |
|
return -2; // Failed to create SAPI voice instance |
|
} |
|
|
|
// Enumerate voices |
|
IEnumSpObjectTokens* pVoiceTokens = nullptr; |
|
SpEnumTokens(SPCAT_VOICES, NULL, NULL, &pVoiceTokens); |
|
|
|
ULONG voiceCount; |
|
pVoiceTokens->GetCount(&voiceCount); |
|
|
|
std::string voiceList; |
|
for (ULONG i = 0; i < voiceCount; i++) { |
|
ISpObjectToken* pToken = nullptr; |
|
if (SUCCEEDED(pVoiceTokens->Item(i, &pToken))) { |
|
WCHAR* name = nullptr; |
|
pToken->GetStringValue(NULL, &name); |
|
voiceList += std::string(_bstr_t(name)) + "\n"; // Convert WCHAR* to std::string |
|
pToken->Release(); |
|
} |
|
} |
|
|
|
pVoiceTokens->Release(); |
|
pVoice->Release(); |
|
CoUninitialize(); |
|
|
|
// Copy to buffer |
|
if (voiceList.size() < bufferSize) { |
|
strcpy(buffer, voiceList.c_str()); |
|
return 0; // Success |
|
} |
|
return -3; // Buffer too small |
|
} |
|
|
|
extern "C" __declspec(dllexport) int SynthesizeSAPI4Text(const char* text) { |
|
ISpVoice* pVoice = nullptr; |
|
if (FAILED(CoInitialize(nullptr))) { |
|
return -1; // Failed to initialize COM |
|
} |
|
|
|
HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void**)&pVoice); |
|
if (FAILED(hr)) { |
|
CoUninitialize(); |
|
return -2; // Failed to create SAPI voice instance |
|
} |
|
|
|
// Convert text to WCHAR |
|
std::wstring wtext = std::wstring(text, text + strlen(text)); |
|
hr = pVoice->Speak(wtext.c_str(), SPF_DEFAULT, NULL); |
|
|
|
pVoice->Release(); |
|
CoUninitialize(); |
|
|
|
return SUCCEEDED(hr) ? 0 : -3; // Return success or error code |
|
} |