]> git.mxchange.org Git - flightgear.git/blob - 3rdparty/hts_engine_API/lib/HTS_audio.c
cc6bcb7f029ba5b5648db30a4e990929127b5e04
[flightgear.git] / 3rdparty / hts_engine_API / lib / HTS_audio.c
1 /* ----------------------------------------------------------------- */
2 /*           The HMM-Based Speech Synthesis Engine "hts_engine API"  */
3 /*           developed by HTS Working Group                          */
4 /*           http://hts-engine.sourceforge.net/                      */
5 /* ----------------------------------------------------------------- */
6 /*                                                                   */
7 /*  Copyright (c) 2001-2013  Nagoya Institute of Technology          */
8 /*                           Department of Computer Science          */
9 /*                                                                   */
10 /*                2001-2008  Tokyo Institute of Technology           */
11 /*                           Interdisciplinary Graduate School of    */
12 /*                           Science and Engineering                 */
13 /*                                                                   */
14 /* All rights reserved.                                              */
15 /*                                                                   */
16 /* Redistribution and use in source and binary forms, with or        */
17 /* without modification, are permitted provided that the following   */
18 /* conditions are met:                                               */
19 /*                                                                   */
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.   */
29 /*                                                                   */
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 /* ----------------------------------------------------------------- */
44
45 #ifndef HTS_AUDIO_C
46 #define HTS_AUDIO_C
47
48 #ifdef __cplusplus
49 #define HTS_AUDIO_C_START extern "C" {
50 #define HTS_AUDIO_C_END   }
51 #else
52 #define HTS_AUDIO_C_START
53 #define HTS_AUDIO_C_END
54 #endif                          /* __CPLUSPLUS */
55
56 HTS_AUDIO_C_START;
57
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
61 #else
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 */
65
66 /* hts_engine libralies */
67 #include "HTS_hidden.h"
68
69 #ifdef AUDIO_PLAY_WIN32
70
71 #include <windows.h>
72 #include <mmsystem.h>
73 #define AUDIO_WAIT_BUFF_MS 10   /* wait time (0.01 sec) */
74 #define AUDIO_CHANNEL 1         /* monoral */
75
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 */
85 } HTS_AudioInterface;
86
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)
89 {
90    WAVEHDR *wavehdr = (WAVEHDR *) param1;
91    HTS_AudioInterface *audio_interface = (HTS_AudioInterface *) user_data;
92
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;
98       }
99    }
100 }
101
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)
104 {
105    MMRESULT result;
106
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));
115    } else {
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));
123    }
124
125    if (result != MMSYSERR_NOERROR)
126       HTS_error(0, "hts_engine: Cannot send datablocks to your output audio device to play waveform.\n");
127
128    return (result == MMSYSERR_NOERROR) ? TRUE : FALSE;
129 }
130
131 /* HTS_AudioInterface_close: close audio device */
132 static void HTS_AudioInterface_close(HTS_AudioInterface * audio_interface)
133 {
134    MMRESULT result;
135
136    /* stop audio */
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");
140    /* unprepare */
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");
147    /* close */
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);
155
156    HTS_free(audio_interface);
157 }
158
159 static HTS_AudioInterface *HTS_AudioInterface_open(size_t sampling_frequency, size_t max_buff_size)
160 {
161    HTS_AudioInterface *audio_interface;
162    MMRESULT result;
163
164    /* make audio interface */
165    audio_interface = (HTS_AudioInterface *) HTS_calloc(1, sizeof(HTS_AudioInterface));
166
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;
171
172    /* format */
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;
179    /* open */
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);
184       return NULL;
185    }
186
187    /* prepare */
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);
199       return NULL;
200    }
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);
213       return NULL;
214    }
215
216    return audio_interface;
217 }
218
219 /* HTS_Audio_initialize: initialize audio */
220 void HTS_Audio_initialize(HTS_Audio * audio)
221 {
222    if (audio == NULL)
223       return;
224
225    audio->sampling_frequency = 0;
226    audio->max_buff_size = 0;
227    audio->buff = NULL;
228    audio->buff_size = 0;
229    audio->audio_interface = NULL;
230 }
231
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)
234 {
235    if (audio == NULL)
236       return;
237
238    if (audio->sampling_frequency == sampling_frequency && audio->max_buff_size == max_buff_size)
239       return;
240
241    HTS_Audio_clear(audio);
242
243    if (sampling_frequency == 0 || max_buff_size == 0)
244       return;
245
246    audio->audio_interface = HTS_AudioInterface_open(sampling_frequency, max_buff_size);
247    if (audio->audio_interface == NULL)
248       return;
249
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;
254 }
255
256 /* HTS_Audio_write: send data to audio */
257 void HTS_Audio_write(HTS_Audio * audio, short data)
258 {
259    if (audio == NULL || audio->audio_interface == NULL)
260       return;
261
262    audio->buff[audio->buff_size++] = data;
263
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);
267          return;
268       }
269       audio->buff_size = 0;
270    }
271 }
272
273 /* HTS_Audio_flush: flush remain data */
274 void HTS_Audio_flush(HTS_Audio * audio)
275 {
276    HTS_AudioInterface *audio_interface;
277
278    if (audio == NULL || audio->audio_interface == NULL)
279       return;
280
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);
285          return;
286       }
287       audio->buff_size = 0;
288    }
289    while (audio_interface->now_buff_1 == TRUE || audio_interface->now_buff_2 == TRUE)
290       Sleep(AUDIO_WAIT_BUFF_MS);
291 }
292
293 /* HTS_Audio_clear: free audio */
294 void HTS_Audio_clear(HTS_Audio * audio)
295 {
296    HTS_AudioInterface *audio_interface;
297
298    if (audio == NULL || audio->audio_interface == NULL)
299       return;
300
301    audio_interface = (HTS_AudioInterface *) audio->audio_interface;
302    HTS_AudioInterface_close(audio_interface);
303    if (audio->buff != NULL)
304       free(audio->buff);
305    HTS_Audio_initialize(audio);
306 }
307
308 #endif                          /* AUDIO_PLAY_WIN32 */
309
310 #ifdef AUDIO_PLAY_PORTAUDIO
311
312 #include "portaudio.h"
313
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;
319
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)
322 {
323    PaError err;
324
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");
328 }
329
330 /* HTS_AudioInterface_close: close audio device */
331 static void HTS_AudioInterface_close(HTS_AudioInterface * audio_interface)
332 {
333    PaError err;
334
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");
341    Pa_Terminate();
342
343    HTS_free(audio_interface);
344 }
345
346 static HTS_AudioInterface *HTS_AudioInterface_open(size_t sampling_frequency, size_t max_buff_size)
347 {
348    HTS_AudioInterface *audio_interface;
349    PaError err;
350
351    audio_interface = HTS_calloc(1, sizeof(HTS_AudioInterface));
352    audio_interface->stream = NULL;
353
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);
358       return NULL;
359    }
360
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;
366
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");
370       Pa_Terminate();
371       HTS_free(audio_interface);
372       return NULL;
373    }
374
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);
379       Pa_Terminate();
380       HTS_free(audio_interface);
381       return NULL;
382    }
383
384    return audio_interface;
385 }
386
387 /* HTS_Audio_initialize: initialize audio */
388 void HTS_Audio_initialize(HTS_Audio * audio)
389 {
390    if (audio == NULL)
391       return;
392
393    audio->sampling_frequency = 0;
394    audio->max_buff_size = 0;
395    audio->buff = NULL;
396    audio->buff_size = 0;
397    audio->audio_interface = NULL;
398 }
399
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)
402 {
403    if (audio == NULL)
404       return;
405
406    if (audio->sampling_frequency == sampling_frequency && audio->max_buff_size == max_buff_size)
407       return;
408
409    HTS_Audio_clear(audio);
410
411    if (sampling_frequency == 0 || max_buff_size == 0)
412       return;
413
414    audio->audio_interface = HTS_AudioInterface_open(sampling_frequency, max_buff_size);
415    if (audio->audio_interface == NULL)
416       return;
417
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;
422 }
423
424 /* HTS_Audio_write: send data to audio device */
425 void HTS_Audio_write(HTS_Audio * audio, short data)
426 {
427    if (audio == NULL)
428       return;
429
430    audio->buff[audio->buff_size++] = data;
431
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;
436    }
437 }
438
439 /* HTS_Audio_flush: flush remain data */
440 void HTS_Audio_flush(HTS_Audio * audio)
441 {
442    HTS_AudioInterface *audio_interface;
443
444    if (audio == NULL || audio->audio_interface == NULL)
445       return;
446
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;
451    }
452 }
453
454 /* HTS_Audio_clear: free audio */
455 void HTS_Audio_clear(HTS_Audio * audio)
456 {
457    HTS_AudioInterface *audio_interface;
458
459    if (audio == NULL || audio->audio_interface == NULL)
460       return;
461    audio_interface = (HTS_AudioInterface *) audio->audio_interface;
462
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);
468 }
469
470 #endif                          /* AUDIO_PLAY_PORTAUDIO */
471
472 #ifdef AUDIO_PLAY_NONE
473
474 /* HTS_Audio_initialize: initialize audio */
475 void HTS_Audio_initialize(HTS_Audio * audio)
476 {
477 }
478
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)
481 {
482 }
483
484 /* HTS_Audio_write: send data to audio */
485 void HTS_Audio_write(HTS_Audio * audio, short data)
486 {
487 }
488
489 /* HTS_Audio_flush: flush remain data */
490 void HTS_Audio_flush(HTS_Audio * audio)
491 {
492 }
493
494 /* HTS_Audio_clear: free audio */
495 void HTS_Audio_clear(HTS_Audio * audio)
496 {
497 }
498
499 #endif                          /* AUDIO_PLAY_NONE */
500
501 HTS_AUDIO_C_END;
502
503 #endif                          /* !HTS_AUDIO_C */