닷넷으로 Text to Speech. 즉 입력 된 텍스트를 읽어주는 TTS를 해달라는 부탁으로 시작하게 된 삽질.
내가 사용하는 OS는 윈도 10이고 타겟은 윈도 7이였다. 윈도 TTS는 https://msdn.microsoft.com/en-us/library/hh361572(v=office.14).aspx 이곳에서 Runtime, Language Packs 두가지를 설치하면 된다고 되어있는데… 이상하게 아무리 재설치를해도 한글 음성이 지원되는 Voice 객체가 나타나지않았다.
윈도 제어판에서는 한글 음성이 나타나는데 닷넷에선 아무리 해도 나타나지않아 포기하고 C++로 Voice 객체를 조회해보았지만 역시나 실패. 혹시나해서 64비트로 빌드하여 다시 조회하니 Heami가 나타나는 것이였다.
그런것이였다. 윈 10은 32비트, 64비트 둘 다 한글 Voice가 재공되는 것이였다… 근데?! 뭐지? 싶어 닷넷 실행파일 띄워놓고 작업관리자 열어보니 32비트로 실행되고있고, 구글링해보니 http://stackoverflow.com/a/23351613 이 댓글이 나왔고, 프로젝트 속성을 보니 아래 옵션이 있었다.
32비트 기본 사용…!!! 32비트 기본이라니! 하.하!? VS2015에서 기본으로 체크되는 옵션인지 어떤지는 모르겠지만 회사에서 VS2015가 나오자마자 구입하였는데… 왠지 최근 만든 닷넷 어플들 32비트 모드로 동작하고있을거같다.
아마도 ActiveX라던지 COM Object, 기타 외부 네이티브 라이브러리가 32비트가 대다수라 생기는 문제가 많기때문에 이런걸 기본옵션으로 체크되어있는거같은데… 나같은 경우엔 그 반대라서 하루 삽질을 하였다.
아… 해결되어서 좋긴한데 왜 눈물이 나려하지… 내 시간은..
아래는 C++로 테스트한 대~충만든 코드.
#include <sapi.h> int test() { CComPtr<ISpVoice> cpVoice; if (FAILED(cpVoice.CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL))) { return -1; } CComPtr<ISpObjectTokenCategory> cpCategory; if (FAILED(cpCategory.CoCreateInstance(CLSID_SpObjectTokenCategory))) { return -1; } if (FAILED(cpCategory->SetId(SPCAT_VOICES, FALSE))) { return -1; } CComPtr<IEnumSpObjectTokens> cpEnum; if (FAILED(cpCategory->EnumTokens(NULL, NULL, &cpEnum))) { return -1; } ULONG count = 0; if (FAILED(cpEnum->GetCount(&count))) { return -1; } for (ULONG idx = 0; idx < count; idx++) { CComPtr<ISpObjectToken> cpToken; if (FAILED(cpEnum->Item(idx, &cpToken))) { return -1; } WCHAR *id = NULL; if (SUCCEEDED(cpToken->GetId(&id))) { wprintf(L"%s\n", id); CoTaskMemFree(id); } } return 0; } int main() { if (SUCCEEDED(::CoInitialize(NULL))) { test(); ::CoUninitialize(); } return 0; }