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_LABEL_C
46 #define HTS_LABEL_C
47 
48 #ifdef __cplusplus
49 #define HTS_LABEL_C_START extern "C" {
50 #define HTS_LABEL_C_END   }
51 #else
52 #define HTS_LABEL_C_START
53 #define HTS_LABEL_C_END
54 #endif                          /* __CPLUSPLUS */
55 
56 HTS_LABEL_C_START;
57 
58 #include <stdlib.h>             /* for atof() */
59 #include <ctype.h>              /* for isgraph(),isdigit() */
60 
61 /* hts_engine libraries */
62 #include "HTS_hidden.h"
63 
isdigit_string(char * str)64 static HTS_Boolean isdigit_string(char *str)
65 {
66    int i;
67 
68    if (sscanf(str, "%d", &i) == 1)
69       return TRUE;
70    else
71       return FALSE;
72 }
73 
74 /* HTS_Label_initialize: initialize label */
HTS_Label_initialize(HTS_Label * label)75 void HTS_Label_initialize(HTS_Label * label)
76 {
77    label->head = NULL;
78    label->size = 0;
79 }
80 
81 /* HTS_Label_check_time: check label */
HTS_Label_check_time(HTS_Label * label)82 static void HTS_Label_check_time(HTS_Label * label)
83 {
84    HTS_LabelString *lstring = label->head;
85    HTS_LabelString *next = NULL;
86 
87    if (lstring)
88       lstring->start = 0.0;
89    while (lstring) {
90       next = lstring->next;
91       if (!next)
92          break;
93       if (lstring->end < 0.0 && next->start >= 0.0)
94          lstring->end = next->start;
95       else if (lstring->end >= 0.0 && next->start < 0.0)
96          next->start = lstring->end;
97       if (lstring->start < 0.0)
98          lstring->start = -1.0;
99       if (lstring->end < 0.0)
100          lstring->end = -1.0;
101       lstring = next;
102    }
103 }
104 
105 /* HTS_Label_load: load label */
HTS_Label_load(HTS_Label * label,size_t sampling_rate,size_t fperiod,HTS_File * fp)106 static void HTS_Label_load(HTS_Label * label, size_t sampling_rate, size_t fperiod, HTS_File * fp)
107 {
108    char buff[HTS_MAXBUFLEN];
109    HTS_LabelString *lstring = NULL;
110    double start, end;
111    const double rate = (double) sampling_rate / ((double) fperiod * 1e+7);
112 
113    if (label->head || label->size != 0) {
114       HTS_error(1, "HTS_Label_load_from_fp: label is not initialized.\n");
115       return;
116    }
117 
118    /* parse label file */
119    while (HTS_get_token_from_fp(fp, buff)) {
120       if (!isgraph((int) buff[0]))
121          break;
122       label->size++;
123 
124       if (lstring) {
125          lstring->next = (HTS_LabelString *) HTS_calloc(1, sizeof(HTS_LabelString));
126          lstring = lstring->next;
127       } else {                  /* first time */
128          lstring = (HTS_LabelString *) HTS_calloc(1, sizeof(HTS_LabelString));
129          label->head = lstring;
130       }
131       if (isdigit_string(buff)) {       /* has frame infomation */
132          start = atof(buff);
133          HTS_get_token_from_fp(fp, buff);
134          end = atof(buff);
135          HTS_get_token_from_fp(fp, buff);
136          lstring->start = rate * start;
137          lstring->end = rate * end;
138       } else {
139          lstring->start = -1.0;
140          lstring->end = -1.0;
141       }
142       lstring->next = NULL;
143       lstring->name = HTS_strdup(buff);
144    }
145    HTS_Label_check_time(label);
146 }
147 
148 /* HTS_Label_load_from_fn: load label from file name */
HTS_Label_load_from_fn(HTS_Label * label,size_t sampling_rate,size_t fperiod,const char * fn)149 void HTS_Label_load_from_fn(HTS_Label * label, size_t sampling_rate, size_t fperiod, const char *fn)
150 {
151    HTS_File *fp = HTS_fopen_from_fn(fn, "r");
152    HTS_Label_load(label, sampling_rate, fperiod, fp);
153    HTS_fclose(fp);
154 }
155 
156 /* HTS_Label_load_from_strings: load label from strings */
HTS_Label_load_from_strings(HTS_Label * label,size_t sampling_rate,size_t fperiod,char ** lines,size_t num_lines)157 void HTS_Label_load_from_strings(HTS_Label * label, size_t sampling_rate, size_t fperiod, char **lines, size_t num_lines)
158 {
159    char buff[HTS_MAXBUFLEN];
160    HTS_LabelString *lstring = NULL;
161    size_t i;
162    size_t data_index;
163    double start, end;
164    const double rate = (double) sampling_rate / ((double) fperiod * 1e+7);
165 
166    if (label->head || label->size != 0) {
167       HTS_error(1, "HTS_Label_load_from_fp: label list is not initialized.\n");
168       return;
169    }
170    /* copy label */
171    for (i = 0; i < num_lines; i++) {
172       if (!isgraph((int) lines[i][0]))
173          break;
174       label->size++;
175 
176       if (lstring) {
177          lstring->next = (HTS_LabelString *) HTS_calloc(1, sizeof(HTS_LabelString));
178          lstring = lstring->next;
179       } else {                  /* first time */
180          lstring = (HTS_LabelString *) HTS_calloc(1, sizeof(HTS_LabelString));
181          label->head = lstring;
182       }
183       data_index = 0;
184       if (isdigit_string(lines[i])) {   /* has frame infomation */
185          HTS_get_token_from_string(lines[i], &data_index, buff);
186          start = atof(buff);
187          HTS_get_token_from_string(lines[i], &data_index, buff);
188          end = atof(buff);
189          HTS_get_token_from_string(lines[i], &data_index, buff);
190          lstring->name = HTS_strdup(buff);
191          lstring->start = rate * start;
192          lstring->end = rate * end;
193       } else {
194          lstring->start = -1.0;
195          lstring->end = -1.0;
196          lstring->name = HTS_strdup(lines[i]);
197       }
198       lstring->next = NULL;
199    }
200    HTS_Label_check_time(label);
201 }
202 
203 /* HTS_Label_get_size: get number of label string */
HTS_Label_get_size(HTS_Label * label)204 size_t HTS_Label_get_size(HTS_Label * label)
205 {
206    return label->size;
207 }
208 
209 /* HTS_Label_get_string: get label string */
HTS_Label_get_string(HTS_Label * label,size_t index)210 const char *HTS_Label_get_string(HTS_Label * label, size_t index)
211 {
212    size_t i;
213    HTS_LabelString *lstring = label->head;
214 
215    for (i = 0; i < index && lstring; i++)
216       lstring = lstring->next;
217    if (!lstring)
218       return NULL;
219    return lstring->name;
220 }
221 
222 /* HTS_Label_get_start_frame: get start frame */
HTS_Label_get_start_frame(HTS_Label * label,size_t index)223 double HTS_Label_get_start_frame(HTS_Label * label, size_t index)
224 {
225    size_t i;
226    HTS_LabelString *lstring = label->head;
227 
228    for (i = 0; i < index && lstring; i++)
229       lstring = lstring->next;
230    if (!lstring)
231       return -1.0;
232    return lstring->start;
233 }
234 
235 /* HTS_Label_get_end_frame: get end frame */
HTS_Label_get_end_frame(HTS_Label * label,size_t index)236 double HTS_Label_get_end_frame(HTS_Label * label, size_t index)
237 {
238    size_t i;
239    HTS_LabelString *lstring = label->head;
240 
241    for (i = 0; i < index && lstring; i++)
242       lstring = lstring->next;
243    if (!lstring)
244       return -1.0;
245    return lstring->end;
246 }
247 
248 /* HTS_Label_clear: free label */
HTS_Label_clear(HTS_Label * label)249 void HTS_Label_clear(HTS_Label * label)
250 {
251    HTS_LabelString *lstring, *next_lstring;
252 
253    for (lstring = label->head; lstring; lstring = next_lstring) {
254       next_lstring = lstring->next;
255       HTS_free(lstring->name);
256       HTS_free(lstring);
257    }
258    HTS_Label_initialize(label);
259 }
260 
261 HTS_LABEL_C_END;
262 
263 #endif                          /* !HTS_LABEL_C */
264