FS2_Open
Open source remastering of the Freespace 2 engine
speech.cpp
Go to the documentation of this file.
1 /*
2  * Code created by Thomas Whittaker (RT) for a FreeSpace 2 source code project
3  *
4  * You may not sell or otherwise commercially exploit the source or things you
5  * created based on the source.
6  *
7 */
8 
9 
10 
11 
12 
13 #ifndef FS2_SPEECH
14 #ifdef _WIN32
15 #if NDEBUG
16  #pragma message( "WARNING: You have not compiled speech into this build (use FS2_SPEECH)" )
17 #endif // NDEBUG
18 #endif // _WIN32
19 #else // to end-of-file ...
20 
21 
22 #ifdef LAUNCHER
23 #include "stdafx.h"
24 #endif //LAUNCHER
25 
26 #ifdef _WIN32
27  #include <windows.h>
28  #include <sapi.h>
29  #include <sphelper.h>
30 
31  ISpVoice *Voice_device;
32 #elif defined(SCP_UNIX)
33  #include <fcntl.h>
34 // #include <stdio.h>
35 
36  int speech_dev = -1;
37 // FILE *speech_dev = NULL;
38 #else
39  #pragma error( "ERROR: Unknown platform, speech (FS2_SPEECH) is not supported" )
40 #endif //_WIN32
41 
42 #include "globalincs/pstypes.h"
43 #include "speech.h"
44 
45 
46 bool Speech_init = false;
47 
48 bool speech_init()
49 {
50 #ifdef _WIN32
51  HRESULT hr = CoCreateInstance(
52  CLSID_SpVoice,
53  NULL,
54  CLSCTX_ALL,
55  IID_ISpVoice,
56  (void **)&Voice_device);
57 
58  Speech_init = SUCCEEDED(hr);
59 #else
60 
61  speech_dev = open("/dev/speech", O_WRONLY | O_DIRECT);
62 // speech_dev = fopen("/dev/speech", "w");
63 
64  if (speech_dev == -1) {
65 // if (speech_dev == NULL) {
66  mprintf(("Couldn't open '/dev/speech', turning text-to-speech off...\n"));
67  return false;
68  }
69 
70  Speech_init = true;
71 #endif
72 
73  return Speech_init;
74 }
75 
76 void speech_deinit()
77 {
78  if(Speech_init == false) return;
79 
80 #ifdef _WIN32
81  Voice_device->Release();
82 #else
83  close(speech_dev);
84 // fclose(speech_dev);
85 #endif
86 }
87 
88 bool speech_play(const char *text)
89 {
90  if(Speech_init == false) return true;
91  if(text == NULL) return false;
92 
93 #ifdef _WIN32
94  int len = strlen(text);
95  wchar_t Conversion_buffer[MAX_SPEECH_CHAR_LEN];
96 
97  if(len > (MAX_SPEECH_CHAR_LEN - 1)) {
98  len = MAX_SPEECH_CHAR_LEN - 1;
99  }
100 
101  int count = 0;
102  for(int i = 0; i < len; i++) {
103  if(text[i] == '$') {
104  i++;
105  continue;
106  }
107 
108  Conversion_buffer[count] = (unsigned short) text[i];
109  count++;
110  }
111 
112  Conversion_buffer[count] = '\0';
113 
114  speech_stop();
115  return SUCCEEDED(Voice_device->Speak(Conversion_buffer, SPF_ASYNC, NULL));
116 #else
117  int len = strlen(text);
118  char Conversion_buffer[MAX_SPEECH_CHAR_LEN];
119 
120  if(len > (MAX_SPEECH_CHAR_LEN - 1)) {
121  len = MAX_SPEECH_CHAR_LEN - 1;
122  }
123 
124  int count = 0;
125  for(int i = 0; i < len; i++) {
126  if(text[i] == '$') {
127  i++;
128  continue;
129  }
130 
131  Conversion_buffer[count] = text[i];
132  count++;
133  }
134 
135  Conversion_buffer[count] = '\0';
136 
137  if ( write(speech_dev, Conversion_buffer, count) == -1 )
138  return false;
139 // if (fwrite(Conversion_buffer, count, 1, speech_dev))
140 // fflush(speech_dev);
141 // else
142 // return false;
143 
144  return true;
145 #endif //_WIN32
146 }
147 
148 bool speech_pause()
149 {
150  if(Speech_init == false) return true;
151 #ifdef _WIN32
152  return SUCCEEDED(Voice_device->Pause());
153 #else
155 
156  return true;
157 #endif
158 }
159 
160 bool speech_resume()
161 {
162  if(Speech_init == false) return true;
163 #ifdef _WIN32
164  return SUCCEEDED(Voice_device->Resume());
165 #else
167 
168  return true;
169 #endif
170 }
171 
172 bool speech_stop()
173 {
174  if(Speech_init == false) return true;
175 #ifdef _WIN32
176  return SUCCEEDED(Voice_device->Speak( NULL, SPF_PURGEBEFORESPEAK, NULL ));
177 #else
179 
180  return true;
181 #endif
182 }
183 
184 bool speech_set_volume(unsigned short volume)
185 {
186 #ifdef _WIN32
187  return SUCCEEDED(Voice_device->SetVolume(volume));
188 #else
190 
191  return true;
192 #endif
193 }
194 
195 bool speech_set_voice(int voice)
196 {
197 #ifdef _WIN32
198  HRESULT hr;
199  CComPtr<ISpObjectToken> cpVoiceToken;
200  CComPtr<IEnumSpObjectTokens> cpEnum;
201  ULONG num_voices = 0;
202 
203  //Enumerate the available voices
204  hr = SpEnumTokens(SPCAT_VOICES, NULL, NULL, &cpEnum);
205 
206  if(FAILED(hr)) return false;
207 
208  hr = cpEnum->GetCount(&num_voices);
209 
210  if(FAILED(hr)) return false;
211 
212  int count = 0;
213  // Obtain a list of available voice tokens, set the voice to the token, and call Speak
214  while (num_voices -- )
215  {
216  cpVoiceToken.Release();
217 
218  hr = cpEnum->Next( 1, &cpVoiceToken, NULL );
219 
220  if(FAILED(hr)) {
221  return false;
222  }
223 
224  if(count == voice) {
225  return SUCCEEDED(Voice_device->SetVoice(cpVoiceToken));
226  }
227 
228  count++;
229  }
230  return false;
231 #else
233 
234  return true;
235 #endif
236 }
237 
238 // Goober5000
239 bool speech_is_speaking()
240 {
241 #ifdef _WIN32
242  HRESULT hr;
243  SPVOICESTATUS pStatus;
244 
245  hr = Voice_device->GetStatus(&pStatus, NULL);
246  if (FAILED(hr)) return false;
247 
248  return (pStatus.dwRunningState != SPRS_DONE);
249 #else
251 
252  return false;
253 #endif
254 }
255 
256 #endif // FS2_SPEECH
int i
Definition: multi_pxo.cpp:466
#define speech_play(text)
Definition: speech.h:35
#define speech_set_volume(volume)
Definition: speech.h:39
#define mprintf(args)
Definition: pstypes.h:238
#define speech_pause()
Definition: speech.h:36
#define speech_stop()
Definition: speech.h:38
#define speech_is_speaking()
Definition: speech.h:41
#define speech_resume()
Definition: speech.h:37
long HRESULT
Definition: vddraw.h:115
#define speech_deinit()
Definition: speech.h:34
#define speech_init()
Definition: speech.h:33
#define STUB_FUNCTION
Definition: config.h:67
GLint GLsizei count
Definition: Gl.h:1491
GLenum GLsizei len
Definition: Glext.h:6283
#define speech_set_voice(voice)
Definition: speech.h:40