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