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-2015  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    /* monaural */
75 #ifdef _M_X64
76 #define AUDIO_POINTER_TYPE DWORD_PTR
77 #else
78 #define AUDIO_POINTER_TYPE DWORD
79 #endif
80 
81 /* HTS_Audio: audio interface for Windows */
82 typedef struct _HTS_AudioInterface {
83    HWAVEOUT hwaveout;           /* audio device handle */
84    WAVEFORMATEX waveformatex;   /* wave formatex */
85    unsigned char which_buff;    /* double buffering flag */
86    HTS_Boolean now_buff_1;      /* double buffering flag */
87    HTS_Boolean now_buff_2;      /* double buffering flag */
88    WAVEHDR buff_1;              /* buffer */
89    WAVEHDR buff_2;              /* buffer */
90 } HTS_AudioInterface;
91 
92 /* HTS_AudioInterface_callback_function: callback function from audio device */
HTS_AudioInterface_callback_function(HWAVEOUT hwaveout,UINT msg,AUDIO_POINTER_TYPE user_data,AUDIO_POINTER_TYPE param1,AUDIO_POINTER_TYPE param2)93 static void CALLBACK HTS_AudioInterface_callback_function(HWAVEOUT hwaveout, UINT msg, AUDIO_POINTER_TYPE user_data, AUDIO_POINTER_TYPE param1, AUDIO_POINTER_TYPE param2)
94 {
95    WAVEHDR *wavehdr = (WAVEHDR *) param1;
96    HTS_AudioInterface *audio_interface = (HTS_AudioInterface *) user_data;
97 
98    if (msg == MM_WOM_DONE && wavehdr && (wavehdr->dwFlags & WHDR_DONE)) {
99       if (audio_interface->now_buff_1 == TRUE && wavehdr == &(audio_interface->buff_1)) {
100          audio_interface->now_buff_1 = FALSE;
101       } else if (audio_interface->now_buff_2 == TRUE && wavehdr == &(audio_interface->buff_2)) {
102          audio_interface->now_buff_2 = FALSE;
103       }
104    }
105 }
106 
107 /* HTS_AudioInterface_write: send buffer to audio device */
HTS_AudioInterface_write(HTS_AudioInterface * audio_interface,const short * buff,size_t buff_size)108 static HTS_Boolean HTS_AudioInterface_write(HTS_AudioInterface * audio_interface, const short *buff, size_t buff_size)
109 {
110    MMRESULT result;
111 
112    if (audio_interface->which_buff == 1) {
113       while (audio_interface->now_buff_1 == TRUE)
114          Sleep(AUDIO_WAIT_BUFF_MS);
115       audio_interface->now_buff_1 = TRUE;
116       audio_interface->which_buff = 2;
117       memcpy(audio_interface->buff_1.lpData, buff, buff_size * sizeof(short));
118       audio_interface->buff_1.dwBufferLength = (DWORD) buff_size *sizeof(short);
119       result = waveOutWrite(audio_interface->hwaveout, &(audio_interface->buff_1), sizeof(WAVEHDR));
120    } else {
121       while (audio_interface->now_buff_2 == TRUE)
122          Sleep(AUDIO_WAIT_BUFF_MS);
123       audio_interface->now_buff_2 = TRUE;
124       audio_interface->which_buff = 1;
125       memcpy(audio_interface->buff_2.lpData, buff, buff_size * sizeof(short));
126       audio_interface->buff_2.dwBufferLength = (DWORD) buff_size *sizeof(short);
127       result = waveOutWrite(audio_interface->hwaveout, &(audio_interface->buff_2), sizeof(WAVEHDR));
128    }
129 
130    if (result != MMSYSERR_NOERROR)
131       HTS_error(0, "hts_engine: Cannot send datablocks to your output audio device to play waveform.\n");
132 
133    return (result == MMSYSERR_NOERROR) ? TRUE : FALSE;
134 }
135 
136 /* HTS_AudioInterface_close: close audio device */
HTS_AudioInterface_close(HTS_AudioInterface * audio_interface)137 static void HTS_AudioInterface_close(HTS_AudioInterface * audio_interface)
138 {
139    MMRESULT result;
140 
141    /* stop audio */
142    result = waveOutReset(audio_interface->hwaveout);
143    if (result != MMSYSERR_NOERROR)
144       HTS_error(0, "hts_engine: Cannot stop and reset your output audio device.\n");
145    /* unprepare */
146    result = waveOutUnprepareHeader(audio_interface->hwaveout, &(audio_interface->buff_1), sizeof(WAVEHDR));
147    if (result != MMSYSERR_NOERROR)
148       HTS_error(0, "hts_engine: Cannot cleanup the audio datablocks to play waveform.\n");
149    result = waveOutUnprepareHeader(audio_interface->hwaveout, &(audio_interface->buff_2), sizeof(WAVEHDR));
150    if (result != MMSYSERR_NOERROR)
151       HTS_error(0, "hts_engine: Cannot cleanup the audio datablocks to play waveform.\n");
152    /* close */
153    result = waveOutClose(audio_interface->hwaveout);
154    if (result != MMSYSERR_NOERROR)
155       HTS_error(0, "hts_engine: Failed to close your output audio device.\n");
156    if (audio_interface->buff_1.lpData != NULL)
157       HTS_free(audio_interface->buff_1.lpData);
158    if (audio_interface->buff_2.lpData != NULL)
159       HTS_free(audio_interface->buff_2.lpData);
160 
161    HTS_free(audio_interface);
162 }
163 
HTS_AudioInterface_open(size_t sampling_frequency,size_t max_buff_size)164 static HTS_AudioInterface *HTS_AudioInterface_open(size_t sampling_frequency, size_t max_buff_size)
165 {
166    HTS_AudioInterface *audio_interface;
167    MMRESULT result;
168 
169    /* make audio interface */
170    audio_interface = (HTS_AudioInterface *) HTS_calloc(1, sizeof(HTS_AudioInterface));
171 
172    audio_interface->hwaveout = 0;
173    audio_interface->which_buff = 1;
174    audio_interface->now_buff_1 = FALSE;
175    audio_interface->now_buff_2 = FALSE;
176 
177    /* format */
178    audio_interface->waveformatex.wFormatTag = WAVE_FORMAT_PCM;
179    audio_interface->waveformatex.nChannels = AUDIO_CHANNEL;
180    audio_interface->waveformatex.nSamplesPerSec = (DWORD) sampling_frequency;
181    audio_interface->waveformatex.wBitsPerSample = sizeof(short) * 8;
182    audio_interface->waveformatex.nBlockAlign = AUDIO_CHANNEL * audio_interface->waveformatex.wBitsPerSample / 8;
183    audio_interface->waveformatex.nAvgBytesPerSec = (DWORD) sampling_frequency *audio_interface->waveformatex.nBlockAlign;
184    /* open */
185    result = waveOutOpen(&audio_interface->hwaveout, WAVE_MAPPER, &audio_interface->waveformatex, (AUDIO_POINTER_TYPE) HTS_AudioInterface_callback_function, (AUDIO_POINTER_TYPE) audio_interface, CALLBACK_FUNCTION);
186    if (result != MMSYSERR_NOERROR) {
187       HTS_error(0, "hts_engine: Failed to open your output audio_interface device to play waveform.\n");
188       HTS_free(audio_interface);
189       return NULL;
190    }
191 
192    /* prepare */
193    audio_interface->buff_1.lpData = (LPSTR) HTS_calloc(max_buff_size, sizeof(short));
194    audio_interface->buff_1.dwBufferLength = (DWORD) max_buff_size *sizeof(short);
195    audio_interface->buff_1.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;
196    audio_interface->buff_1.dwLoops = 1;
197    audio_interface->buff_1.lpNext = 0;
198    audio_interface->buff_1.reserved = 0;
199    result = waveOutPrepareHeader(audio_interface->hwaveout, &(audio_interface->buff_1), sizeof(WAVEHDR));
200    if (result != MMSYSERR_NOERROR) {
201       HTS_error(0, "hts_engine: Cannot initialize audio_interface datablocks to play waveform.\n");
202       HTS_free(audio_interface->buff_1.lpData);
203       HTS_free(audio_interface);
204       return NULL;
205    }
206    audio_interface->buff_2.lpData = (LPSTR) HTS_calloc(max_buff_size, sizeof(short));
207    audio_interface->buff_2.dwBufferLength = (DWORD) max_buff_size *sizeof(short);
208    audio_interface->buff_2.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;
209    audio_interface->buff_2.dwLoops = 1;
210    audio_interface->buff_2.lpNext = 0;
211    audio_interface->buff_2.reserved = 0;
212    result = waveOutPrepareHeader(audio_interface->hwaveout, &(audio_interface->buff_2), sizeof(WAVEHDR));
213    if (result != MMSYSERR_NOERROR) {
214       HTS_error(0, "hts_engine: Cannot initialize audio_interface datablocks to play waveform.\n");
215       HTS_free(audio_interface->buff_1.lpData);
216       HTS_free(audio_interface->buff_2.lpData);
217       HTS_free(audio_interface);
218       return NULL;
219    }
220 
221    return audio_interface;
222 }
223 
224 /* HTS_Audio_initialize: initialize audio */
HTS_Audio_initialize(HTS_Audio * audio)225 void HTS_Audio_initialize(HTS_Audio * audio)
226 {
227    if (audio == NULL)
228       return;
229 
230    audio->sampling_frequency = 0;
231    audio->max_buff_size = 0;
232    audio->buff = NULL;
233    audio->buff_size = 0;
234    audio->audio_interface = NULL;
235 }
236 
237 /* HTS_Audio_set_parameter: set parameters for audio */
HTS_Audio_set_parameter(HTS_Audio * audio,size_t sampling_frequency,size_t max_buff_size)238 void HTS_Audio_set_parameter(HTS_Audio * audio, size_t sampling_frequency, size_t max_buff_size)
239 {
240    if (audio == NULL)
241       return;
242 
243    if (audio->sampling_frequency == sampling_frequency && audio->max_buff_size == max_buff_size)
244       return;
245 
246    HTS_Audio_clear(audio);
247 
248    if (sampling_frequency == 0 || max_buff_size == 0)
249       return;
250 
251    audio->audio_interface = HTS_AudioInterface_open(sampling_frequency, max_buff_size);
252    if (audio->audio_interface == NULL)
253       return;
254 
255    audio->sampling_frequency = sampling_frequency;
256    audio->max_buff_size = max_buff_size;
257    audio->buff = (short *) HTS_calloc(max_buff_size, sizeof(short));
258    audio->buff_size = 0;
259 }
260 
261 /* HTS_Audio_write: send data to audio */
HTS_Audio_write(HTS_Audio * audio,short data)262 void HTS_Audio_write(HTS_Audio * audio, short data)
263 {
264    if (audio == NULL || audio->audio_interface == NULL)
265       return;
266 
267    audio->buff[audio->buff_size++] = data;
268 
269    if (audio->buff_size >= audio->max_buff_size) {
270       if (HTS_AudioInterface_write((HTS_AudioInterface *) audio->audio_interface, audio->buff, audio->buff_size) != TRUE) {
271          HTS_Audio_clear(audio);
272          return;
273       }
274       audio->buff_size = 0;
275    }
276 }
277 
278 /* HTS_Audio_flush: flush remain data */
HTS_Audio_flush(HTS_Audio * audio)279 void HTS_Audio_flush(HTS_Audio * audio)
280 {
281    HTS_AudioInterface *audio_interface;
282 
283    if (audio == NULL || audio->audio_interface == NULL)
284       return;
285 
286    audio_interface = (HTS_AudioInterface *) audio->audio_interface;
287    if (audio->buff_size > 0) {
288       if (HTS_AudioInterface_write(audio_interface, audio->buff, audio->buff_size) != TRUE) {
289          HTS_Audio_clear(audio);
290          return;
291       }
292       audio->buff_size = 0;
293    }
294    while (audio_interface->now_buff_1 == TRUE || audio_interface->now_buff_2 == TRUE)
295       Sleep(AUDIO_WAIT_BUFF_MS);
296 }
297 
298 /* HTS_Audio_clear: free audio */
HTS_Audio_clear(HTS_Audio * audio)299 void HTS_Audio_clear(HTS_Audio * audio)
300 {
301    HTS_AudioInterface *audio_interface;
302 
303    if (audio == NULL || audio->audio_interface == NULL)
304       return;
305 
306    audio_interface = (HTS_AudioInterface *) audio->audio_interface;
307    HTS_AudioInterface_close(audio_interface);
308    if (audio->buff != NULL)
309       free(audio->buff);
310    HTS_Audio_initialize(audio);
311 }
312 
313 #endif                          /* AUDIO_PLAY_WIN32 */
314 
315 #ifdef AUDIO_PLAY_PORTAUDIO
316 
317 #include "portaudio.h"
318 
319 /* HTS_AudioInterface: audio output for PortAudio */
320 typedef struct _HTS_AudioInterface {
321    PaStreamParameters parameters;       /* parameters for output stream */
322    PaStream *stream;            /* output stream */
323 } HTS_AudioInterface;
324 
325 /* HTS_AudioInterface_write: send data to audio device */
HTS_AudioInterface_write(HTS_AudioInterface * audio_interface,const short * buff,size_t buff_size)326 static void HTS_AudioInterface_write(HTS_AudioInterface * audio_interface, const short *buff, size_t buff_size)
327 {
328    PaError err;
329 
330    err = Pa_WriteStream(audio_interface->stream, buff, buff_size);
331    if (err != paNoError && err != paOutputUnderflowed)
332       HTS_error(0, "hts_engine: Cannot send datablocks to your output audio device to play waveform.\n");
333 }
334 
335 /* HTS_AudioInterface_close: close audio device */
HTS_AudioInterface_close(HTS_AudioInterface * audio_interface)336 static void HTS_AudioInterface_close(HTS_AudioInterface * audio_interface)
337 {
338    PaError err;
339 
340    err = Pa_StopStream(audio_interface->stream);
341    if (err != paNoError)
342       HTS_error(0, "hts_engine: Cannot stop your output audio device.\n");
343    err = Pa_CloseStream(audio_interface->stream);
344    if (err != paNoError)
345       HTS_error(0, "hts_engine: Failed to close your output audio device.\n");
346    Pa_Terminate();
347 
348    HTS_free(audio_interface);
349 }
350 
HTS_AudioInterface_open(size_t sampling_frequency,size_t max_buff_size)351 static HTS_AudioInterface *HTS_AudioInterface_open(size_t sampling_frequency, size_t max_buff_size)
352 {
353    HTS_AudioInterface *audio_interface;
354    PaError err;
355 
356    audio_interface = HTS_calloc(1, sizeof(HTS_AudioInterface));
357    audio_interface->stream = NULL;
358 
359    err = Pa_Initialize();
360    if (err != paNoError) {
361       HTS_error(0, "hts_engine: Failed to initialize your output audio device to play waveform.\n");
362       HTS_free(audio_interface);
363       return NULL;
364    }
365 
366    audio_interface->parameters.device = Pa_GetDefaultOutputDevice();
367    audio_interface->parameters.channelCount = 1;
368    audio_interface->parameters.sampleFormat = paInt16;
369    audio_interface->parameters.suggestedLatency = Pa_GetDeviceInfo(audio_interface->parameters.device)->defaultLowOutputLatency;
370    audio_interface->parameters.hostApiSpecificStreamInfo = NULL;
371 
372    err = Pa_OpenStream(&audio_interface->stream, NULL, &audio_interface->parameters, sampling_frequency, max_buff_size, paClipOff, NULL, NULL);
373    if (err != paNoError) {
374       HTS_error(0, "hts_engine: Failed to open your output audio device to play waveform.\n");
375       Pa_Terminate();
376       HTS_free(audio_interface);
377       return NULL;
378    }
379 
380    err = Pa_StartStream(audio_interface->stream);
381    if (err != paNoError) {
382       HTS_error(0, "hts_engine: Failed to start your output audio device to play waveform.\n");
383       Pa_CloseStream(audio_interface->stream);
384       Pa_Terminate();
385       HTS_free(audio_interface);
386       return NULL;
387    }
388 
389    return audio_interface;
390 }
391 
392 /* HTS_Audio_initialize: initialize audio */
HTS_Audio_initialize(HTS_Audio * audio)393 void HTS_Audio_initialize(HTS_Audio * audio)
394 {
395    if (audio == NULL)
396       return;
397 
398    audio->sampling_frequency = 0;
399    audio->max_buff_size = 0;
400    audio->buff = NULL;
401    audio->buff_size = 0;
402    audio->audio_interface = NULL;
403 }
404 
405 /* HTS_Audio_set_parameter: set parameters for audio */
HTS_Audio_set_parameter(HTS_Audio * audio,size_t sampling_frequency,size_t max_buff_size)406 void HTS_Audio_set_parameter(HTS_Audio * audio, size_t sampling_frequency, size_t max_buff_size)
407 {
408    if (audio == NULL)
409       return;
410 
411    if (audio->sampling_frequency == sampling_frequency && audio->max_buff_size == max_buff_size)
412       return;
413 
414    HTS_Audio_clear(audio);
415 
416    if (sampling_frequency == 0 || max_buff_size == 0)
417       return;
418 
419    audio->audio_interface = HTS_AudioInterface_open(sampling_frequency, max_buff_size);
420    if (audio->audio_interface == NULL)
421       return;
422 
423    audio->sampling_frequency = sampling_frequency;
424    audio->max_buff_size = max_buff_size;
425    audio->buff = (short *) HTS_calloc(max_buff_size, sizeof(short));
426    audio->buff_size = 0;
427 }
428 
429 /* HTS_Audio_write: send data to audio device */
HTS_Audio_write(HTS_Audio * audio,short data)430 void HTS_Audio_write(HTS_Audio * audio, short data)
431 {
432    if (audio == NULL)
433       return;
434 
435    audio->buff[audio->buff_size++] = data;
436 
437    if (audio->buff_size >= audio->max_buff_size) {
438       if (audio->audio_interface != NULL)
439          HTS_AudioInterface_write((HTS_AudioInterface *) audio->audio_interface, audio->buff, audio->max_buff_size);
440       audio->buff_size = 0;
441    }
442 }
443 
444 /* HTS_Audio_flush: flush remain data */
HTS_Audio_flush(HTS_Audio * audio)445 void HTS_Audio_flush(HTS_Audio * audio)
446 {
447    HTS_AudioInterface *audio_interface;
448 
449    if (audio == NULL || audio->audio_interface == NULL)
450       return;
451 
452    audio_interface = (HTS_AudioInterface *) audio->audio_interface;
453    if (audio->buff_size > 0) {
454       HTS_AudioInterface_write(audio_interface, audio->buff, audio->buff_size);
455       audio->buff_size = 0;
456    }
457 }
458 
459 /* HTS_Audio_clear: free audio */
HTS_Audio_clear(HTS_Audio * audio)460 void HTS_Audio_clear(HTS_Audio * audio)
461 {
462    HTS_AudioInterface *audio_interface;
463 
464    if (audio == NULL || audio->audio_interface == NULL)
465       return;
466    audio_interface = (HTS_AudioInterface *) audio->audio_interface;
467 
468    HTS_Audio_flush(audio);
469    HTS_AudioInterface_close(audio_interface);
470    if (audio->buff != NULL)
471       HTS_free(audio->buff);
472    HTS_Audio_initialize(audio);
473 }
474 
475 #endif                          /* AUDIO_PLAY_PORTAUDIO */
476 
477 #ifdef AUDIO_PLAY_NONE
478 
479 /* HTS_Audio_initialize: initialize audio */
HTS_Audio_initialize(HTS_Audio * audio)480 void HTS_Audio_initialize(HTS_Audio * audio)
481 {
482 }
483 
484 /* HTS_Audio_set_parameter: set parameters for audio */
HTS_Audio_set_parameter(HTS_Audio * audio,size_t sampling_frequeny,size_t max_buff_size)485 void HTS_Audio_set_parameter(HTS_Audio * audio, size_t sampling_frequeny, size_t max_buff_size)
486 {
487 }
488 
489 /* HTS_Audio_write: send data to audio */
HTS_Audio_write(HTS_Audio * audio,short data)490 void HTS_Audio_write(HTS_Audio * audio, short data)
491 {
492 }
493 
494 /* HTS_Audio_flush: flush remain data */
HTS_Audio_flush(HTS_Audio * audio)495 void HTS_Audio_flush(HTS_Audio * audio)
496 {
497 }
498 
499 /* HTS_Audio_clear: free audio */
HTS_Audio_clear(HTS_Audio * audio)500 void HTS_Audio_clear(HTS_Audio * audio)
501 {
502 }
503 
504 #endif                          /* AUDIO_PLAY_NONE */
505 
506 HTS_AUDIO_C_END;
507 
508 #endif                          /* !HTS_AUDIO_C */
509