错误在这一行:
std::wstring xml = L"<pitch absmiddle='" + std::to_wstring(pitch) + L"'>Pitch Adjust</pitch>";
错误是:命名空间“std”没有成员“to_wstring”
我还收到两个错误:'to_wstring':不是'std'的成员
“to_wstring”:未找到标识符
我试图在visual studio中更改C/C++中的应用程序属性>语言>C++语言标准转换为ISO C++20标准(/std:C++20),但在单击应用并确定并重建后,错误仍然存在。所以我试着把它改成17,也改成14,但错误仍然存在。
属性设置的屏幕截图:
以下是任何情况下的完整代码:
#include "pch.h"
#include "WindowsVoice.h"
#include <sapi.h>
namespace WindowsVoice {
static ISpVoice* pVoice = NULL; // Global voice pointer
void speechThreadFunc()
{
if (FAILED(::CoInitializeEx(NULL, COINITBASE_MULTITHREADED)))
{
theStatusMessage = L"Failed to initialize COM for Voice.";
return;
}
HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void**)&pVoice);
if (!SUCCEEDED(hr))
{
theStatusMessage = L"Failed to create Voice instance.";
return;
}
theStatusMessage = L"Speech ready.";
SPVOICESTATUS voiceStatus;
wchar_t* priorText = nullptr;
while (!shouldTerminate)
{
pVoice->GetStatus(&voiceStatus, NULL);
if (voiceStatus.dwRunningState == SPRS_IS_SPEAKING)
{
if (priorText == nullptr)
theStatusMessage = L"Error: SPRS_IS_SPEAKING but text is NULL";
else
{
theStatusMessage = L"Speaking: ";
theStatusMessage.append(priorText);
if (!theSpeechQueue.empty())
{
theMutex.lock();
if (lstrcmpW(theSpeechQueue.front(), priorText) == 0)
{
delete[] theSpeechQueue.front();
theSpeechQueue.pop_front();
}
theMutex.unlock();
}
}
}
else
{
theStatusMessage = L"Waiting.";
if (priorText != NULL)
{
delete[] priorText;
priorText = NULL;
}
if (!theSpeechQueue.empty())
{
theMutex.lock();
priorText = theSpeechQueue.front();
theSpeechQueue.pop_front();
theMutex.unlock();
pVoice->Speak(priorText, SPF_IS_XML | SPF_ASYNC, NULL);
}
}
Sleep(50);
}
pVoice->Pause();
pVoice->Release();
theStatusMessage = L"Speech thread terminated.";
}
void addToSpeechQueue(const char* text)
{
if (text)
{
int len = strlen(text) + 1;
wchar_t* wText = new wchar_t[len];
memset(wText, 0, len);
::MultiByteToWideChar(CP_UTF8, NULL, text, -1, wText, len);
theMutex.lock();
theSpeechQueue.push_back(wText);
theMutex.unlock();
}
}
void clearSpeechQueue()
{
theMutex.lock();
theSpeechQueue.clear();
theMutex.unlock();
}
void initSpeech()
{
shouldTerminate = false;
if (theSpeechThread != nullptr)
{
theStatusMessage = L"Windows Voice thread already started.";
return;
}
theStatusMessage = L"Starting Windows Voice.";
theSpeechThread = new std::thread(WindowsVoice::speechThreadFunc);
}
void destroySpeech()
{
if (theSpeechThread == nullptr)
{
theStatusMessage = L"Speech thread already destroyed or not started.";
return;
}
theStatusMessage = L"Destroying speech.";
shouldTerminate = true;
theSpeechThread->join();
theSpeechQueue.clear();
delete theSpeechThread;
theSpeechThread = nullptr;
CoUninitialize();
theStatusMessage = L"Speech destroyed.";
}
void statusMessage(char* msg, int msgLen)
{
size_t count;
wcstombs_s(&count, msg, msgLen, theStatusMessage.c_str(), msgLen);
}
// New Functions for Rate, Volume, and Pitch
void setSpeechRate(int rate)
{
if (pVoice)
pVoice->SetRate(rate);
}
void setSpeechVolume(int volume)
{
if (pVoice)
pVoice->SetVolume(volume);
}
void setSpeechPitch(int pitch)
{
if (pVoice)
{
std::wstring xml = L"<pitch absmiddle='" + std::to_wstring(pitch) + L"'>Pitch Adjust</pitch>";
pVoice->Speak(xml.c_str(), SPF_IS_XML | SPF_ASYNC, NULL);
}
}
}
BOOL APIENTRY DllMain(HMODULE, DWORD ul_reason_for_call, LPVOID)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}