I'm trying to use Microsoft SAPI for synthesize multiple WAVE files from strings, each string is processed in its own thread. For producing threads I'm using Microsoft Thread Pool API. It seems that SAPI couldn't work in such environment, because ISpVoice::Speak() randomly crashes when it called in parallel threads. There is no crash if Thread pool capacity equals 1 (only one thread running in fact) or ISpVoice::Speak() is called under critical section.
VOID CALLBACK ExecProc(PTP_CALLBACK_INSTANCE Instance, PVOID Parameter, PTP_WORK Work){ HRESULT hr = CoInitialize(nullptr); const LPCWSTR sText = L"Test text for text-to-speech."; CString sFileName; sFileName.Format(L"%s\\%zu.wav", g_BaseFolder, nIndex); // D:\Test\%nIndex%.wav CComPtr<ISpVoice> pVoice; hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void**)&pVoice); CComPtr<ISpStream> cpStream; CSpStreamFormat cAudioFmt; hr = cAudioFmt.AssignFormat(SPSF_44kHz16BitMono); hr = SPBindToFile((LPWSTR)(LPCWSTR)sFilename, SPFM_CREATE_ALWAYS, &cpStream, &cAudioFmt.FormatId(), cAudioFmt.WaveFormatExPtr()); hr = pVoice->SetOutput(cpStream, TRUE); ULONG nCount = 0; CComPtr<IEnumSpObjectTokens> cpEnum; hr = SpEnumTokens(SPCAT_VOICES, NULL, NULL, &cpEnum); CComPtr<ISpObjectToken> cpToken; hr = cpEnum->Item(0, &cpToken); hr = pVoice->SetVoice(cpToken); hr = pVoice->Speak(sText, SPF_DEFAULT, NULL); cpStream = nullptr; cpToken = nullptr; pVoice = nullptr; CoUninitialize();}

Unhandled exception screenshot
I've tried:
- create minimal test code with minumum of side constraints;
- use different concurrency model (using CoInitializeEx);
- do not use SPBindToFile and create own ISpStream instead.
I can't find official info if it allowed to use Speak+BindToFile in multithreading, as well as information about the opposite.
If Speak doesn't crash, output wave file created and correct.
Thank you!