mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-09 17:52:08 -10:00
257 lines
4.4 KiB
C++
257 lines
4.4 KiB
C++
/*
|
|
* Code created by Thomas Whittaker (RT) for a FreeSpace 2 source code project
|
|
*
|
|
* You may not sell or otherwise commercially exploit the source or things you
|
|
* created based on the source.
|
|
*
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef FS2_SPEECH
|
|
#ifdef _WIN32
|
|
#if NDEBUG
|
|
#pragma message( "WARNING: You have not compiled speech into this build (use FS2_SPEECH)" )
|
|
#endif // NDEBUG
|
|
#endif // _WIN32
|
|
#else // to end-of-file ...
|
|
|
|
|
|
#ifdef LAUNCHER
|
|
#include "stdafx.h"
|
|
#endif //LAUNCHER
|
|
|
|
#ifdef _WIN32
|
|
#include <windows.h>
|
|
#include <sapi.h>
|
|
#include <sphelper.h>
|
|
|
|
ISpVoice *Voice_device;
|
|
#elif defined(SCP_UNIX)
|
|
#include <fcntl.h>
|
|
// #include <stdio.h>
|
|
|
|
int speech_dev = -1;
|
|
// FILE *speech_dev = NULL;
|
|
#else
|
|
#pragma error( "ERROR: Unknown platform, speech (FS2_SPEECH) is not supported" )
|
|
#endif //_WIN32
|
|
|
|
#include "globalincs/pstypes.h"
|
|
#include "speech.h"
|
|
|
|
|
|
bool Speech_init = false;
|
|
|
|
bool speech_init()
|
|
{
|
|
#ifdef _WIN32
|
|
HRESULT hr = CoCreateInstance(
|
|
CLSID_SpVoice,
|
|
NULL,
|
|
CLSCTX_ALL,
|
|
IID_ISpVoice,
|
|
(void **)&Voice_device);
|
|
|
|
Speech_init = SUCCEEDED(hr);
|
|
#else
|
|
|
|
speech_dev = open("/dev/speech", O_WRONLY | O_DIRECT);
|
|
// speech_dev = fopen("/dev/speech", "w");
|
|
|
|
if (speech_dev == -1) {
|
|
// if (speech_dev == NULL) {
|
|
mprintf(("Couldn't open '/dev/speech', turning text-to-speech off...\n"));
|
|
return false;
|
|
}
|
|
|
|
Speech_init = true;
|
|
#endif
|
|
|
|
return Speech_init;
|
|
}
|
|
|
|
void speech_deinit()
|
|
{
|
|
if(Speech_init == false) return;
|
|
|
|
#ifdef _WIN32
|
|
Voice_device->Release();
|
|
#else
|
|
close(speech_dev);
|
|
// fclose(speech_dev);
|
|
#endif
|
|
}
|
|
|
|
bool speech_play(const char *text)
|
|
{
|
|
if(Speech_init == false) return true;
|
|
if(text == NULL) return false;
|
|
|
|
#ifdef _WIN32
|
|
int len = strlen(text);
|
|
wchar_t Conversion_buffer[MAX_SPEECH_CHAR_LEN];
|
|
|
|
if(len > (MAX_SPEECH_CHAR_LEN - 1)) {
|
|
len = MAX_SPEECH_CHAR_LEN - 1;
|
|
}
|
|
|
|
int count = 0;
|
|
for(int i = 0; i < len; i++) {
|
|
if(text[i] == '$') {
|
|
i++;
|
|
continue;
|
|
}
|
|
|
|
Conversion_buffer[count] = (unsigned short) text[i];
|
|
count++;
|
|
}
|
|
|
|
Conversion_buffer[count] = '\0';
|
|
|
|
speech_stop();
|
|
return SUCCEEDED(Voice_device->Speak(Conversion_buffer, SPF_ASYNC, NULL));
|
|
#else
|
|
int len = strlen(text);
|
|
char Conversion_buffer[MAX_SPEECH_CHAR_LEN];
|
|
|
|
if(len > (MAX_SPEECH_CHAR_LEN - 1)) {
|
|
len = MAX_SPEECH_CHAR_LEN - 1;
|
|
}
|
|
|
|
int count = 0;
|
|
for(int i = 0; i < len; i++) {
|
|
if(text[i] == '$') {
|
|
i++;
|
|
continue;
|
|
}
|
|
|
|
Conversion_buffer[count] = text[i];
|
|
count++;
|
|
}
|
|
|
|
Conversion_buffer[count] = '\0';
|
|
|
|
if ( write(speech_dev, Conversion_buffer, count) == -1 )
|
|
return false;
|
|
// if (fwrite(Conversion_buffer, count, 1, speech_dev))
|
|
// fflush(speech_dev);
|
|
// else
|
|
// return false;
|
|
|
|
return true;
|
|
#endif //_WIN32
|
|
}
|
|
|
|
bool speech_pause()
|
|
{
|
|
if(Speech_init == false) return true;
|
|
#ifdef _WIN32
|
|
return SUCCEEDED(Voice_device->Pause());
|
|
#else
|
|
STUB_FUNCTION;
|
|
|
|
return true;
|
|
#endif
|
|
}
|
|
|
|
bool speech_resume()
|
|
{
|
|
if(Speech_init == false) return true;
|
|
#ifdef _WIN32
|
|
return SUCCEEDED(Voice_device->Resume());
|
|
#else
|
|
STUB_FUNCTION;
|
|
|
|
return true;
|
|
#endif
|
|
}
|
|
|
|
bool speech_stop()
|
|
{
|
|
if(Speech_init == false) return true;
|
|
#ifdef _WIN32
|
|
return SUCCEEDED(Voice_device->Speak( NULL, SPF_PURGEBEFORESPEAK, NULL ));
|
|
#else
|
|
STUB_FUNCTION;
|
|
|
|
return true;
|
|
#endif
|
|
}
|
|
|
|
bool speech_set_volume(unsigned short volume)
|
|
{
|
|
#ifdef _WIN32
|
|
return SUCCEEDED(Voice_device->SetVolume(volume));
|
|
#else
|
|
STUB_FUNCTION;
|
|
|
|
return true;
|
|
#endif
|
|
}
|
|
|
|
bool speech_set_voice(int voice)
|
|
{
|
|
#ifdef _WIN32
|
|
HRESULT hr;
|
|
CComPtr<ISpObjectToken> cpVoiceToken;
|
|
CComPtr<IEnumSpObjectTokens> cpEnum;
|
|
ULONG num_voices = 0;
|
|
|
|
//Enumerate the available voices
|
|
hr = SpEnumTokens(SPCAT_VOICES, NULL, NULL, &cpEnum);
|
|
|
|
if(FAILED(hr)) return false;
|
|
|
|
hr = cpEnum->GetCount(&num_voices);
|
|
|
|
if(FAILED(hr)) return false;
|
|
|
|
int count = 0;
|
|
// Obtain a list of available voice tokens, set the voice to the token, and call Speak
|
|
while (num_voices -- )
|
|
{
|
|
cpVoiceToken.Release();
|
|
|
|
hr = cpEnum->Next( 1, &cpVoiceToken, NULL );
|
|
|
|
if(FAILED(hr)) {
|
|
return false;
|
|
}
|
|
|
|
if(count == voice) {
|
|
return SUCCEEDED(Voice_device->SetVoice(cpVoiceToken));
|
|
}
|
|
|
|
count++;
|
|
}
|
|
return false;
|
|
#else
|
|
STUB_FUNCTION;
|
|
|
|
return true;
|
|
#endif
|
|
}
|
|
|
|
// Goober5000
|
|
bool speech_is_speaking()
|
|
{
|
|
#ifdef _WIN32
|
|
HRESULT hr;
|
|
SPVOICESTATUS pStatus;
|
|
|
|
hr = Voice_device->GetStatus(&pStatus, NULL);
|
|
if (FAILED(hr)) return false;
|
|
|
|
return (pStatus.dwRunningState != SPRS_DONE);
|
|
#else
|
|
STUB_FUNCTION;
|
|
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
#endif // FS2_SPEECH
|