1 /* ----------------------------------------------------------------- */
2 /* The HMM-Based Speech Synthesis Engine "hts_engine API" */
3 /* developed by HTS Working Group */
4 /* http://hts-engine.sourceforge.net/ */
5 /* ----------------------------------------------------------------- */
7 /* Copyright (c) 2001-2013 Nagoya Institute of Technology */
8 /* Department of Computer Science */
10 /* 2001-2008 Tokyo Institute of Technology */
11 /* Interdisciplinary Graduate School of */
12 /* Science and Engineering */
14 /* All rights reserved. */
16 /* Redistribution and use in source and binary forms, with or */
17 /* without modification, are permitted provided that the following */
18 /* conditions are met: */
20 /* - Redistributions of source code must retain the above copyright */
21 /* notice, this list of conditions and the following disclaimer. */
22 /* - Redistributions in binary form must reproduce the above */
23 /* copyright notice, this list of conditions and the following */
24 /* disclaimer in the documentation and/or other materials provided */
25 /* with the distribution. */
26 /* - Neither the name of the HTS working group nor the names of its */
27 /* contributors may be used to endorse or promote products derived */
28 /* from this software without specific prior written permission. */
30 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND */
31 /* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, */
32 /* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
33 /* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
34 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS */
35 /* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, */
36 /* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
37 /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
38 /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
39 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, */
40 /* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY */
41 /* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
42 /* POSSIBILITY OF SUCH DAMAGE. */
43 /* ----------------------------------------------------------------- */
49 #define HTS_AUDIO_C_START extern "C" {
50 #define HTS_AUDIO_C_END }
52 #define HTS_AUDIO_C_START
53 #define HTS_AUDIO_C_END
54 #endif /* __CPLUSPLUS */
58 #if !defined(AUDIO_PLAY_WIN32) && !defined(AUDIO_PLAY_PORTAUDIO) && !defined(AUDIO_PLAY_NONE)
59 #if defined(__WINCE__) || defined(_WINCE) || defined(_WINCE) || defined(__WINCE) || defined(__WIN32__) || defined(__WIN32) || defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
60 #define AUDIO_PLAY_WIN32
62 #define AUDIO_PLAY_NONE
63 #endif /* __WINCE__ || _WINCE || _WINCE || __WINCE || __WIN32__ || __WIN32 || _WIN32 || WIN32 || __CYGWIN__ || __MINGW32__ */
64 #endif /* !AUDIO_PLAY_WIN32 && !AUDIO_PLAY_PORTAUDIO && !AUDIO_PLAY_NONE */
66 /* hts_engine libralies */
67 #include "HTS_hidden.h"
69 #ifdef AUDIO_PLAY_WIN32
73 #define AUDIO_WAIT_BUFF_MS 10 /* wait time (0.01 sec) */
74 #define AUDIO_CHANNEL 1 /* monoral */
76 /* HTS_Audio: audio interface for Windows */
77 typedef struct _HTS_AudioInterface {
78 HWAVEOUT hwaveout; /* audio device handle */
79 WAVEFORMATEX waveformatex; /* wave formatex */
80 unsigned char which_buff; /* double buffering flag */
81 HTS_Boolean now_buff_1; /* double buffering flag */
82 HTS_Boolean now_buff_2; /* double buffering flag */
83 WAVEHDR buff_1; /* buffer */
84 WAVEHDR buff_2; /* buffer */
87 /* HTS_AudioInterface_callback_function: callback function from audio device */
88 static void CALLBACK HTS_AudioInterface_callback_function(HWAVEOUT hwaveout, UINT msg, DWORD user_data, DWORD param1, DWORD param2)
90 WAVEHDR *wavehdr = (WAVEHDR *) param1;
91 HTS_AudioInterface *audio_interface = (HTS_AudioInterface *) user_data;
93 if (msg == MM_WOM_DONE && wavehdr && (wavehdr->dwFlags & WHDR_DONE)) {
94 if (audio_interface->now_buff_1 == TRUE && wavehdr == &(audio_interface->buff_1)) {
95 audio_interface->now_buff_1 = FALSE;
96 } else if (audio_interface->now_buff_2 == TRUE && wavehdr == &(audio_interface->buff_2)) {
97 audio_interface->now_buff_2 = FALSE;
102 /* HTS_AudioInterface_write: send buffer to audio device */
103 static HTS_Boolean HTS_AudioInterface_write(HTS_AudioInterface * audio_interface, const short *buff, size_t buff_size)
107 if (audio_interface->which_buff == 1) {
108 while (audio_interface->now_buff_1 == TRUE)
109 Sleep(AUDIO_WAIT_BUFF_MS);
110 audio_interface->now_buff_1 = TRUE;
111 audio_interface->which_buff = 2;
112 memcpy(audio_interface->buff_1.lpData, buff, buff_size * sizeof(short));
113 audio_interface->buff_1.dwBufferLength = buff_size * sizeof(short);
114 result = waveOutWrite(audio_interface->hwaveout, &(audio_interface->buff_1), sizeof(WAVEHDR));
116 while (audio_interface->now_buff_2 == TRUE)
117 Sleep(AUDIO_WAIT_BUFF_MS);
118 audio_interface->now_buff_2 = TRUE;
119 audio_interface->which_buff = 1;
120 memcpy(audio_interface->buff_2.lpData, buff, buff_size * sizeof(short));
121 audio_interface->buff_2.dwBufferLength = buff_size * sizeof(short);
122 result = waveOutWrite(audio_interface->hwaveout, &(audio_interface->buff_2), sizeof(WAVEHDR));
125 if (result != MMSYSERR_NOERROR)
126 HTS_error(0, "hts_engine: Cannot send datablocks to your output audio device to play waveform.\n");
128 return (result == MMSYSERR_NOERROR) ? TRUE : FALSE;
131 /* HTS_AudioInterface_close: close audio device */
132 static void HTS_AudioInterface_close(HTS_AudioInterface * audio_interface)
137 result = waveOutReset(audio_interface->hwaveout);
138 if (result != MMSYSERR_NOERROR)
139 HTS_error(0, "hts_engine: Cannot stop and reset your output audio device.\n");
141 result = waveOutUnprepareHeader(audio_interface->hwaveout, &(audio_interface->buff_1), sizeof(WAVEHDR));
142 if (result != MMSYSERR_NOERROR)
143 HTS_error(0, "hts_engine: Cannot cleanup the audio datablocks to play waveform.\n");
144 result = waveOutUnprepareHeader(audio_interface->hwaveout, &(audio_interface->buff_2), sizeof(WAVEHDR));
145 if (result != MMSYSERR_NOERROR)
146 HTS_error(0, "hts_engine: Cannot cleanup the audio datablocks to play waveform.\n");
148 result = waveOutClose(audio_interface->hwaveout);
149 if (result != MMSYSERR_NOERROR)
150 HTS_error(0, "hts_engine: Failed to close your output audio device.\n");
151 if (audio_interface->buff_1.lpData != NULL)
152 HTS_free(audio_interface->buff_1.lpData);
153 if (audio_interface->buff_2.lpData != NULL)
154 HTS_free(audio_interface->buff_2.lpData);
156 HTS_free(audio_interface);
159 static HTS_AudioInterface *HTS_AudioInterface_open(size_t sampling_frequency, size_t max_buff_size)
161 HTS_AudioInterface *audio_interface;
164 /* make audio interface */
165 audio_interface = (HTS_AudioInterface *) HTS_calloc(1, sizeof(HTS_AudioInterface));
167 audio_interface->hwaveout = 0;
168 audio_interface->which_buff = 1;
169 audio_interface->now_buff_1 = FALSE;
170 audio_interface->now_buff_2 = FALSE;
173 audio_interface->waveformatex.wFormatTag = WAVE_FORMAT_PCM;
174 audio_interface->waveformatex.nChannels = AUDIO_CHANNEL;
175 audio_interface->waveformatex.nSamplesPerSec = sampling_frequency;
176 audio_interface->waveformatex.wBitsPerSample = sizeof(short) * 8;
177 audio_interface->waveformatex.nBlockAlign = AUDIO_CHANNEL * audio_interface->waveformatex.wBitsPerSample / 8;
178 audio_interface->waveformatex.nAvgBytesPerSec = sampling_frequency * audio_interface->waveformatex.nBlockAlign;
180 result = waveOutOpen(&audio_interface->hwaveout, WAVE_MAPPER, &audio_interface->waveformatex, (DWORD) HTS_AudioInterface_callback_function, (DWORD) audio_interface, CALLBACK_FUNCTION);
181 if (result != MMSYSERR_NOERROR) {
182 HTS_error(0, "hts_engine: Failed to open your output audio_interface device to play waveform.\n");
183 HTS_free(audio_interface);
188 audio_interface->buff_1.lpData = (LPSTR) HTS_calloc(max_buff_size, sizeof(short));
189 audio_interface->buff_1.dwBufferLength = max_buff_size * sizeof(short);
190 audio_interface->buff_1.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;
191 audio_interface->buff_1.dwLoops = 1;
192 audio_interface->buff_1.lpNext = 0;
193 audio_interface->buff_1.reserved = 0;
194 result = waveOutPrepareHeader(audio_interface->hwaveout, &(audio_interface->buff_1), sizeof(WAVEHDR));
195 if (result != MMSYSERR_NOERROR) {
196 HTS_error(0, "hts_engine: Cannot initialize audio_interface datablocks to play waveform.\n");
197 HTS_free(audio_interface->buff_1.lpData);
198 HTS_free(audio_interface);
201 audio_interface->buff_2.lpData = (LPSTR) HTS_calloc(max_buff_size, sizeof(short));
202 audio_interface->buff_2.dwBufferLength = max_buff_size * sizeof(short);
203 audio_interface->buff_2.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;
204 audio_interface->buff_2.dwLoops = 1;
205 audio_interface->buff_2.lpNext = 0;
206 audio_interface->buff_2.reserved = 0;
207 result = waveOutPrepareHeader(audio_interface->hwaveout, &(audio_interface->buff_2), sizeof(WAVEHDR));
208 if (result != MMSYSERR_NOERROR) {
209 HTS_error(0, "hts_engine: Cannot initialize audio_interface datablocks to play waveform.\n");
210 HTS_free(audio_interface->buff_1.lpData);
211 HTS_free(audio_interface->buff_2.lpData);
212 HTS_free(audio_interface);
216 return audio_interface;
219 /* HTS_Audio_initialize: initialize audio */
220 void HTS_Audio_initialize(HTS_Audio * audio)
225 audio->sampling_frequency = 0;
226 audio->max_buff_size = 0;
228 audio->buff_size = 0;
229 audio->audio_interface = NULL;
232 /* HTS_Audio_set_parameter: set parameters for audio */
233 void HTS_Audio_set_parameter(HTS_Audio * audio, size_t sampling_frequency, size_t max_buff_size)
238 if (audio->sampling_frequency == sampling_frequency && audio->max_buff_size == max_buff_size)
241 HTS_Audio_clear(audio);
243 if (sampling_frequency == 0 || max_buff_size == 0)
246 audio->audio_interface = HTS_AudioInterface_open(sampling_frequency, max_buff_size);
247 if (audio->audio_interface == NULL)
250 audio->sampling_frequency = sampling_frequency;
251 audio->max_buff_size = max_buff_size;
252 audio->buff = (short *) HTS_calloc(max_buff_size, sizeof(short));
253 audio->buff_size = 0;
256 /* HTS_Audio_write: send data to audio */
257 void HTS_Audio_write(HTS_Audio * audio, short data)
259 if (audio == NULL || audio->audio_interface == NULL)
262 audio->buff[audio->buff_size++] = data;
264 if (audio->buff_size >= audio->max_buff_size) {
265 if (HTS_AudioInterface_write((HTS_AudioInterface *) audio->audio_interface, audio->buff, audio->buff_size) != TRUE) {
266 HTS_Audio_clear(audio);
269 audio->buff_size = 0;
273 /* HTS_Audio_flush: flush remain data */
274 void HTS_Audio_flush(HTS_Audio * audio)
276 HTS_AudioInterface *audio_interface;
278 if (audio == NULL || audio->audio_interface == NULL)
281 audio_interface = (HTS_AudioInterface *) audio->audio_interface;
282 if (audio->buff_size > 0) {
283 if (HTS_AudioInterface_write(audio_interface, audio->buff, audio->buff_size) != TRUE) {
284 HTS_Audio_clear(audio);
287 audio->buff_size = 0;
289 while (audio_interface->now_buff_1 == TRUE || audio_interface->now_buff_2 == TRUE)
290 Sleep(AUDIO_WAIT_BUFF_MS);
293 /* HTS_Audio_clear: free audio */
294 void HTS_Audio_clear(HTS_Audio * audio)
296 HTS_AudioInterface *audio_interface;
298 if (audio == NULL || audio->audio_interface == NULL)
301 audio_interface = (HTS_AudioInterface *) audio->audio_interface;
302 HTS_AudioInterface_close(audio_interface);
303 if (audio->buff != NULL)
305 HTS_Audio_initialize(audio);
308 #endif /* AUDIO_PLAY_WIN32 */
310 #ifdef AUDIO_PLAY_PORTAUDIO
312 #include "portaudio.h"
314 /* HTS_AudioInterface: audio output for PortAudio */
315 typedef struct _HTS_AudioInterface {
316 PaStreamParameters parameters; /* parameters for output stream */
317 PaStream *stream; /* output stream */
318 } HTS_AudioInterface;
320 /* HTS_AudioInterface_write: send data to audio device */
321 static void HTS_AudioInterface_write(HTS_AudioInterface * audio_interface, const short *buff, size_t buff_size)
325 err = Pa_WriteStream(audio_interface->stream, buff, buff_size);
326 if (err != paNoError && err != paOutputUnderflowed)
327 HTS_error(0, "hts_engine: Cannot send datablocks to your output audio device to play waveform.\n");
330 /* HTS_AudioInterface_close: close audio device */
331 static void HTS_AudioInterface_close(HTS_AudioInterface * audio_interface)
335 err = Pa_StopStream(audio_interface->stream);
336 if (err != paNoError)
337 HTS_error(0, "hts_engine: Cannot stop your output audio device.\n");
338 err = Pa_CloseStream(audio_interface->stream);
339 if (err != paNoError)
340 HTS_error(0, "hts_engine: Failed to close your output audio device.\n");
343 HTS_free(audio_interface);
346 static HTS_AudioInterface *HTS_AudioInterface_open(size_t sampling_frequency, size_t max_buff_size)
348 HTS_AudioInterface *audio_interface;
351 audio_interface = HTS_calloc(1, sizeof(HTS_AudioInterface));
352 audio_interface->stream = NULL;
354 err = Pa_Initialize();
355 if (err != paNoError) {
356 HTS_error(0, "hts_engine: Failed to initialize your output audio device to play waveform.\n");
357 HTS_free(audio_interface);
361 audio_interface->parameters.device = Pa_GetDefaultOutputDevice();
362 audio_interface->parameters.channelCount = 1;
363 audio_interface->parameters.sampleFormat = paInt16;
364 audio_interface->parameters.suggestedLatency = Pa_GetDeviceInfo(audio_interface->parameters.device)->defaultLowOutputLatency;
365 audio_interface->parameters.hostApiSpecificStreamInfo = NULL;
367 err = Pa_OpenStream(&audio_interface->stream, NULL, &audio_interface->parameters, sampling_frequency, max_buff_size, paClipOff, NULL, NULL);
368 if (err != paNoError) {
369 HTS_error(0, "hts_engine: Failed to open your output audio device to play waveform.\n");
371 HTS_free(audio_interface);
375 err = Pa_StartStream(audio_interface->stream);
376 if (err != paNoError) {
377 HTS_error(0, "hts_engine: Failed to start your output audio device to play waveform.\n");
378 Pa_CloseStream(audio_interface->stream);
380 HTS_free(audio_interface);
384 return audio_interface;
387 /* HTS_Audio_initialize: initialize audio */
388 void HTS_Audio_initialize(HTS_Audio * audio)
393 audio->sampling_frequency = 0;
394 audio->max_buff_size = 0;
396 audio->buff_size = 0;
397 audio->audio_interface = NULL;
400 /* HTS_Audio_set_parameter: set parameters for audio */
401 void HTS_Audio_set_parameter(HTS_Audio * audio, size_t sampling_frequency, size_t max_buff_size)
406 if (audio->sampling_frequency == sampling_frequency && audio->max_buff_size == max_buff_size)
409 HTS_Audio_clear(audio);
411 if (sampling_frequency == 0 || max_buff_size == 0)
414 audio->audio_interface = HTS_AudioInterface_open(sampling_frequency, max_buff_size);
415 if (audio->audio_interface == NULL)
418 audio->sampling_frequency = sampling_frequency;
419 audio->max_buff_size = max_buff_size;
420 audio->buff = (short *) HTS_calloc(max_buff_size, sizeof(short));
421 audio->buff_size = 0;
424 /* HTS_Audio_write: send data to audio device */
425 void HTS_Audio_write(HTS_Audio * audio, short data)
430 audio->buff[audio->buff_size++] = data;
432 if (audio->buff_size >= audio->max_buff_size) {
433 if (audio->audio_interface != NULL)
434 HTS_AudioInterface_write((HTS_AudioInterface *) audio->audio_interface, audio->buff, audio->max_buff_size);
435 audio->buff_size = 0;
439 /* HTS_Audio_flush: flush remain data */
440 void HTS_Audio_flush(HTS_Audio * audio)
442 HTS_AudioInterface *audio_interface;
444 if (audio == NULL || audio->audio_interface == NULL)
447 audio_interface = (HTS_AudioInterface *) audio->audio_interface;
448 if (audio->buff_size > 0) {
449 HTS_AudioInterface_write(audio_interface, audio->buff, audio->buff_size);
450 audio->buff_size = 0;
454 /* HTS_Audio_clear: free audio */
455 void HTS_Audio_clear(HTS_Audio * audio)
457 HTS_AudioInterface *audio_interface;
459 if (audio == NULL || audio->audio_interface == NULL)
461 audio_interface = (HTS_AudioInterface *) audio->audio_interface;
463 HTS_Audio_flush(audio);
464 HTS_AudioInterface_close(audio_interface);
465 if (audio->buff != NULL)
466 HTS_free(audio->buff);
467 HTS_Audio_initialize(audio);
470 #endif /* AUDIO_PLAY_PORTAUDIO */
472 #ifdef AUDIO_PLAY_NONE
474 /* HTS_Audio_initialize: initialize audio */
475 void HTS_Audio_initialize(HTS_Audio * audio)
479 /* HTS_Audio_set_parameter: set parameters for audio */
480 void HTS_Audio_set_parameter(HTS_Audio * audio, size_t sampling_frequeny, size_t max_buff_size)
484 /* HTS_Audio_write: send data to audio */
485 void HTS_Audio_write(HTS_Audio * audio, short data)
489 /* HTS_Audio_flush: flush remain data */
490 void HTS_Audio_flush(HTS_Audio * audio)
494 /* HTS_Audio_clear: free audio */
495 void HTS_Audio_clear(HTS_Audio * audio)
499 #endif /* AUDIO_PLAY_NONE */
503 #endif /* !HTS_AUDIO_C */