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_PSTREAM_C
46 #define HTS_PSTREAM_C
47
48 #ifdef __cplusplus
49 #define HTS_PSTREAM_C_START extern "C" {
50 #define HTS_PSTREAM_C_END }
51 #else
52 #define HTS_PSTREAM_C_START
53 #define HTS_PSTREAM_C_END
54 #endif /* __CPLUSPLUS */
55
56 HTS_PSTREAM_C_START;
57
58 #include <math.h> /* for sqrt() */
59
60 /* hts_engine libraries */
61 #include "HTS_hidden.h"
62
63 /* HTS_finv: calculate 1.0/variance function */
HTS_finv(const double x)64 static double HTS_finv(const double x)
65 {
66 if (x >= INFTY2)
67 return 0.0;
68 if (x <= -INFTY2)
69 return 0.0;
70 if (x <= INVINF2 && x >= 0)
71 return INFTY;
72 if (x >= -INVINF2 && x < 0)
73 return -INFTY;
74
75 return (1.0 / x);
76 }
77
78 /* HTS_PStream_calc_wuw_and_wum: calcurate W'U^{-1}W and W'U^{-1}M */
HTS_PStream_calc_wuw_and_wum(HTS_PStream * pst,size_t m)79 static void HTS_PStream_calc_wuw_and_wum(HTS_PStream * pst, size_t m)
80 {
81 size_t t, i, j;
82 int shift;
83 double wu;
84
85 for (t = 0; t < pst->length; t++) {
86 /* initialize */
87 pst->sm.wum[t] = 0.0;
88 for (i = 0; i < pst->width; i++)
89 pst->sm.wuw[t][i] = 0.0;
90
91 /* calc WUW & WUM */
92 for (i = 0; i < pst->win_size; i++)
93 for (shift = pst->win_l_width[i]; shift <= pst->win_r_width[i]; shift++)
94 if (((int) t + shift >= 0) && ((int) t + shift < pst->length) && (pst->win_coefficient[i][-shift] != 0.0)) {
95 wu = pst->win_coefficient[i][-shift] * pst->sm.ivar[t + shift][i * pst->vector_length + m];
96 pst->sm.wum[t] += wu * pst->sm.mean[t + shift][i * pst->vector_length + m];
97 for (j = 0; (j < pst->width) && (t + j < pst->length); j++)
98 if (((int) j <= pst->win_r_width[i] + shift) && (pst->win_coefficient[i][j - shift] != 0.0))
99 pst->sm.wuw[t][j] += wu * pst->win_coefficient[i][j - shift];
100 }
101 }
102 }
103
104
105 /* HTS_PStream_ldl_factorization: Factorize W'*U^{-1}*W to L*D*L' (L: lower triangular, D: diagonal) */
HTS_PStream_ldl_factorization(HTS_PStream * pst)106 static void HTS_PStream_ldl_factorization(HTS_PStream * pst)
107 {
108 size_t t, i, j;
109
110 for (t = 0; t < pst->length; t++) {
111 for (i = 1; (i < pst->width) && (t >= i); i++)
112 pst->sm.wuw[t][0] -= pst->sm.wuw[t - i][i] * pst->sm.wuw[t - i][i] * pst->sm.wuw[t - i][0];
113
114 for (i = 1; i < pst->width; i++) {
115 for (j = 1; (i + j < pst->width) && (t >= j); j++)
116 pst->sm.wuw[t][i] -= pst->sm.wuw[t - j][j] * pst->sm.wuw[t - j][i + j] * pst->sm.wuw[t - j][0];
117 pst->sm.wuw[t][i] /= pst->sm.wuw[t][0];
118 }
119 }
120 }
121
122 /* HTS_PStream_forward_substitution: forward subtitution for mlpg */
HTS_PStream_forward_substitution(HTS_PStream * pst)123 static void HTS_PStream_forward_substitution(HTS_PStream * pst)
124 {
125 size_t t, i;
126
127 for (t = 0; t < pst->length; t++) {
128 pst->sm.g[t] = pst->sm.wum[t];
129 for (i = 1; (i < pst->width) && (t >= i); i++)
130 pst->sm.g[t] -= pst->sm.wuw[t - i][i] * pst->sm.g[t - i];
131 }
132 }
133
134 /* HTS_PStream_backward_substitution: backward subtitution for mlpg */
HTS_PStream_backward_substitution(HTS_PStream * pst,size_t m)135 static void HTS_PStream_backward_substitution(HTS_PStream * pst, size_t m)
136 {
137 size_t rev, t, i;
138
139 for (rev = 0; rev < pst->length; rev++) {
140 t = pst->length - 1 - rev;
141 pst->par[t][m] = pst->sm.g[t] / pst->sm.wuw[t][0];
142 for (i = 1; (i < pst->width) && (t + i < pst->length); i++)
143 pst->par[t][m] -= pst->sm.wuw[t][i] * pst->par[t + i][m];
144 }
145 }
146
147 /* HTS_PStream_calc_gv: subfunction for mlpg using GV */
HTS_PStream_calc_gv(HTS_PStream * pst,size_t m,double * mean,double * vari)148 static void HTS_PStream_calc_gv(HTS_PStream * pst, size_t m, double *mean, double *vari)
149 {
150 size_t t;
151
152 *mean = 0.0;
153 for (t = 0; t < pst->length; t++)
154 if (pst->gv_switch[t])
155 *mean += pst->par[t][m];
156 *mean /= pst->gv_length;
157 *vari = 0.0;
158 for (t = 0; t < pst->length; t++)
159 if (pst->gv_switch[t])
160 *vari += (pst->par[t][m] - *mean) * (pst->par[t][m] - *mean);
161 *vari /= pst->gv_length;
162 }
163
164 /* HTS_PStream_conv_gv: subfunction for mlpg using GV */
HTS_PStream_conv_gv(HTS_PStream * pst,size_t m)165 static void HTS_PStream_conv_gv(HTS_PStream * pst, size_t m)
166 {
167 size_t t;
168 double ratio;
169 double mean;
170 double vari;
171
172 HTS_PStream_calc_gv(pst, m, &mean, &vari);
173 ratio = sqrt(pst->gv_mean[m] / vari);
174 for (t = 0; t < pst->length; t++)
175 if (pst->gv_switch[t])
176 pst->par[t][m] = ratio * (pst->par[t][m] - mean) + mean;
177 }
178
179 /* HTS_PStream_calc_derivative: subfunction for mlpg using GV */
HTS_PStream_calc_derivative(HTS_PStream * pst,size_t m)180 static double HTS_PStream_calc_derivative(HTS_PStream * pst, size_t m)
181 {
182 size_t t, i;
183 double mean;
184 double vari;
185 double dv;
186 double h;
187 double gvobj;
188 double hmmobj;
189 double w = 1.0 / (pst->win_size * pst->length);
190
191 HTS_PStream_calc_gv(pst, m, &mean, &vari);
192 gvobj = -0.5 * W2 * vari * pst->gv_vari[m] * (vari - 2.0 * pst->gv_mean[m]);
193 dv = -2.0 * pst->gv_vari[m] * (vari - pst->gv_mean[m]) / pst->length;
194
195 for (t = 0; t < pst->length; t++) {
196 pst->sm.g[t] = pst->sm.wuw[t][0] * pst->par[t][m];
197 for (i = 1; i < pst->width; i++) {
198 if (t + i < pst->length)
199 pst->sm.g[t] += pst->sm.wuw[t][i] * pst->par[t + i][m];
200 if (t + 1 > i)
201 pst->sm.g[t] += pst->sm.wuw[t - i][i] * pst->par[t - i][m];
202 }
203 }
204
205 for (t = 0, hmmobj = 0.0; t < pst->length; t++) {
206 hmmobj += W1 * w * pst->par[t][m] * (pst->sm.wum[t] - 0.5 * pst->sm.g[t]);
207 h = -W1 * w * pst->sm.wuw[t][1 - 1] - W2 * 2.0 / (pst->length * pst->length) * ((pst->length - 1) * pst->gv_vari[m] * (vari - pst->gv_mean[m]) + 2.0 * pst->gv_vari[m] * (pst->par[t][m] - mean) * (pst->par[t][m] - mean));
208 if (pst->gv_switch[t])
209 pst->sm.g[t] = 1.0 / h * (W1 * w * (-pst->sm.g[t] + pst->sm.wum[t]) + W2 * dv * (pst->par[t][m] - mean));
210 else
211 pst->sm.g[t] = 1.0 / h * (W1 * w * (-pst->sm.g[t] + pst->sm.wum[t]));
212 }
213
214 return (-(hmmobj + gvobj));
215 }
216
217 /* HTS_PStream_gv_parmgen: function for mlpg using GV */
HTS_PStream_gv_parmgen(HTS_PStream * pst,size_t m)218 static void HTS_PStream_gv_parmgen(HTS_PStream * pst, size_t m)
219 {
220 size_t t, i;
221 double step = STEPINIT;
222 double prev = 0.0;
223 double obj;
224
225 if (pst->gv_length == 0)
226 return;
227
228 HTS_PStream_conv_gv(pst, m);
229 if (GV_MAX_ITERATION > 0) {
230 HTS_PStream_calc_wuw_and_wum(pst, m);
231 for (i = 1; i <= GV_MAX_ITERATION; i++) {
232 obj = HTS_PStream_calc_derivative(pst, m);
233 if (i > 1) {
234 if (obj > prev)
235 step *= STEPDEC;
236 if (obj < prev)
237 step *= STEPINC;
238 }
239 for (t = 0; t < pst->length; t++) {
240 if (pst->gv_switch[t])
241 pst->par[t][m] += step * pst->sm.g[t];
242 }
243 prev = obj;
244 }
245 }
246 }
247
248 /* HTS_PStream_mlpg: generate sequence of speech parameter vector maximizing its output probability for given pdf sequence */
HTS_PStream_mlpg(HTS_PStream * pst)249 static void HTS_PStream_mlpg(HTS_PStream * pst)
250 {
251 size_t m;
252
253 if (pst->length == 0)
254 return;
255
256 for (m = 0; m < pst->vector_length; m++) {
257 HTS_PStream_calc_wuw_and_wum(pst, m);
258 HTS_PStream_ldl_factorization(pst); /* LDL factorization */
259 HTS_PStream_forward_substitution(pst); /* forward substitution */
260 HTS_PStream_backward_substitution(pst, m); /* backward substitution */
261 if (pst->gv_length > 0)
262 HTS_PStream_gv_parmgen(pst, m);
263 }
264 }
265
266 /* HTS_PStreamSet_initialize: initialize parameter stream set */
HTS_PStreamSet_initialize(HTS_PStreamSet * pss)267 void HTS_PStreamSet_initialize(HTS_PStreamSet * pss)
268 {
269 pss->pstream = NULL;
270 pss->nstream = 0;
271 pss->total_frame = 0;
272 }
273
274 /* HTS_PStreamSet_create: parameter generation using GV weight */
HTS_PStreamSet_create(HTS_PStreamSet * pss,HTS_SStreamSet * sss,double * msd_threshold,double * gv_weight)275 HTS_Boolean HTS_PStreamSet_create(HTS_PStreamSet * pss, HTS_SStreamSet * sss, double *msd_threshold, double *gv_weight)
276 {
277 size_t i, j, k, l, m;
278 int shift;
279 size_t frame, msd_frame, state;
280
281 HTS_PStream *pst;
282 HTS_Boolean not_bound;
283
284 if (pss->nstream != 0) {
285 HTS_error(1, "HTS_PstreamSet_create: HTS_PStreamSet should be clear.\n");
286 return FALSE;
287 }
288
289 /* initialize */
290 pss->nstream = HTS_SStreamSet_get_nstream(sss);
291 pss->pstream = (HTS_PStream *) HTS_calloc(pss->nstream, sizeof(HTS_PStream));
292 pss->total_frame = HTS_SStreamSet_get_total_frame(sss);
293
294 /* create */
295 for (i = 0; i < pss->nstream; i++) {
296 pst = &pss->pstream[i];
297 if (HTS_SStreamSet_is_msd(sss, i) == TRUE) { /* for MSD */
298 pst->length = 0;
299 for (state = 0; state < HTS_SStreamSet_get_total_state(sss); state++)
300 if (HTS_SStreamSet_get_msd(sss, i, state) > msd_threshold[i])
301 pst->length += HTS_SStreamSet_get_duration(sss, state);
302 pst->msd_flag = (HTS_Boolean *) HTS_calloc(pss->total_frame, sizeof(HTS_Boolean));
303 for (state = 0, frame = 0; state < HTS_SStreamSet_get_total_state(sss); state++) {
304 if (HTS_SStreamSet_get_msd(sss, i, state) > msd_threshold[i]) {
305 for (j = 0; j < HTS_SStreamSet_get_duration(sss, state); j++) {
306 pst->msd_flag[frame] = TRUE;
307 frame++;
308 }
309 } else {
310 for (j = 0; j < HTS_SStreamSet_get_duration(sss, state); j++) {
311 pst->msd_flag[frame] = FALSE;
312 frame++;
313 }
314 }
315 }
316 } else { /* for non MSD */
317 pst->length = pss->total_frame;
318 pst->msd_flag = NULL;
319 }
320 pst->vector_length = HTS_SStreamSet_get_vector_length(sss, i);
321 pst->width = HTS_SStreamSet_get_window_max_width(sss, i) * 2 + 1; /* band width of R */
322 pst->win_size = HTS_SStreamSet_get_window_size(sss, i);
323 if (pst->length > 0) {
324 pst->sm.mean = HTS_alloc_matrix(pst->length, pst->vector_length * pst->win_size);
325 pst->sm.ivar = HTS_alloc_matrix(pst->length, pst->vector_length * pst->win_size);
326 pst->sm.wum = (double *) HTS_calloc(pst->length, sizeof(double));
327 pst->sm.wuw = HTS_alloc_matrix(pst->length, pst->width);
328 pst->sm.g = (double *) HTS_calloc(pst->length, sizeof(double));
329 pst->par = HTS_alloc_matrix(pst->length, pst->vector_length);
330 }
331 /* copy dynamic window */
332 pst->win_l_width = (int *) HTS_calloc(pst->win_size, sizeof(int));
333 pst->win_r_width = (int *) HTS_calloc(pst->win_size, sizeof(int));
334 pst->win_coefficient = (double **) HTS_calloc(pst->win_size, sizeof(double));
335 for (j = 0; j < pst->win_size; j++) {
336 pst->win_l_width[j] = HTS_SStreamSet_get_window_left_width(sss, i, j);
337 pst->win_r_width[j] = HTS_SStreamSet_get_window_right_width(sss, i, j);
338 if (pst->win_l_width[j] + pst->win_r_width[j] == 0)
339 pst->win_coefficient[j] = (double *)
340 HTS_calloc(-2 * pst->win_l_width[j] + 1, sizeof(double));
341 else
342 pst->win_coefficient[j] = (double *)
343 HTS_calloc(-2 * pst->win_l_width[j], sizeof(double));
344 pst->win_coefficient[j] -= pst->win_l_width[j];
345 for (shift = pst->win_l_width[j]; shift <= pst->win_r_width[j]; shift++)
346 pst->win_coefficient[j][shift] = HTS_SStreamSet_get_window_coefficient(sss, i, j, shift);
347 }
348 /* copy GV */
349 if (HTS_SStreamSet_use_gv(sss, i)) {
350 pst->gv_mean = (double *) HTS_calloc(pst->vector_length, sizeof(double));
351 pst->gv_vari = (double *) HTS_calloc(pst->vector_length, sizeof(double));
352 for (j = 0; j < pst->vector_length; j++) {
353 pst->gv_mean[j] = HTS_SStreamSet_get_gv_mean(sss, i, j) * gv_weight[i];
354 pst->gv_vari[j] = HTS_SStreamSet_get_gv_vari(sss, i, j);
355 }
356 pst->gv_switch = (HTS_Boolean *) HTS_calloc(pst->length, sizeof(HTS_Boolean));
357 if (HTS_SStreamSet_is_msd(sss, i) == TRUE) { /* for MSD */
358 for (state = 0, frame = 0, msd_frame = 0; state < HTS_SStreamSet_get_total_state(sss); state++)
359 for (j = 0; j < HTS_SStreamSet_get_duration(sss, state); j++, frame++)
360 if (pst->msd_flag[frame] == TRUE)
361 pst->gv_switch[msd_frame++] = HTS_SStreamSet_get_gv_switch(sss, i, state);
362 } else { /* for non MSD */
363 for (state = 0, frame = 0; state < HTS_SStreamSet_get_total_state(sss); state++)
364 for (j = 0; j < HTS_SStreamSet_get_duration(sss, state); j++)
365 pst->gv_switch[frame++] = HTS_SStreamSet_get_gv_switch(sss, i, state);
366 }
367 for (j = 0, pst->gv_length = 0; j < pst->length; j++)
368 if (pst->gv_switch[j])
369 pst->gv_length++;
370 } else {
371 pst->gv_switch = NULL;
372 pst->gv_length = 0;
373 pst->gv_mean = NULL;
374 pst->gv_vari = NULL;
375 }
376 /* copy pdfs */
377 if (HTS_SStreamSet_is_msd(sss, i) == TRUE) { /* for MSD */
378 for (state = 0, frame = 0, msd_frame = 0; state < HTS_SStreamSet_get_total_state(sss); state++) {
379 for (j = 0; j < HTS_SStreamSet_get_duration(sss, state); j++) {
380 if (pst->msd_flag[frame] == TRUE) {
381 /* check current frame is MSD boundary or not */
382 for (k = 0; k < pst->win_size; k++) {
383 not_bound = TRUE;
384 for (shift = pst->win_l_width[k]; shift <= pst->win_r_width[k]; shift++)
385 if ((int) frame + shift < 0 || (int) pss->total_frame <= (int) frame + shift || pst->msd_flag[frame + shift] != TRUE) {
386 not_bound = FALSE;
387 break;
388 }
389 for (l = 0; l < pst->vector_length; l++) {
390 m = pst->vector_length * k + l;
391 pst->sm.mean[msd_frame][m] = HTS_SStreamSet_get_mean(sss, i, state, m);
392 if (not_bound || k == 0)
393 pst->sm.ivar[msd_frame][m] = HTS_finv(HTS_SStreamSet_get_vari(sss, i, state, m));
394 else
395 pst->sm.ivar[msd_frame][m] = 0.0;
396 }
397 }
398 msd_frame++;
399 }
400 frame++;
401 }
402 }
403 } else { /* for non MSD */
404 for (state = 0, frame = 0; state < HTS_SStreamSet_get_total_state(sss); state++) {
405 for (j = 0; j < HTS_SStreamSet_get_duration(sss, state); j++) {
406 for (k = 0; k < pst->win_size; k++) {
407 not_bound = TRUE;
408 for (shift = pst->win_l_width[k]; shift <= pst->win_r_width[k]; shift++)
409 if ((int) frame + shift < 0 || (int) pss->total_frame <= (int) frame + shift) {
410 not_bound = FALSE;
411 break;
412 }
413 for (l = 0; l < pst->vector_length; l++) {
414 m = pst->vector_length * k + l;
415 pst->sm.mean[frame][m] = HTS_SStreamSet_get_mean(sss, i, state, m);
416 if (not_bound || k == 0)
417 pst->sm.ivar[frame][m] = HTS_finv(HTS_SStreamSet_get_vari(sss, i, state, m));
418 else
419 pst->sm.ivar[frame][m] = 0.0;
420 }
421 }
422 frame++;
423 }
424 }
425 }
426 /* parameter generation */
427 HTS_PStream_mlpg(pst);
428 }
429
430 return TRUE;
431 }
432
433 /* HTS_PStreamSet_get_nstream: get number of stream */
HTS_PStreamSet_get_nstream(HTS_PStreamSet * pss)434 size_t HTS_PStreamSet_get_nstream(HTS_PStreamSet * pss)
435 {
436 return pss->nstream;
437 }
438
439 /* HTS_PStreamSet_get_vector_length: get feature length */
HTS_PStreamSet_get_vector_length(HTS_PStreamSet * pss,size_t stream_index)440 size_t HTS_PStreamSet_get_vector_length(HTS_PStreamSet * pss, size_t stream_index)
441 {
442 return pss->pstream[stream_index].vector_length;
443 }
444
445 /* HTS_PStreamSet_get_total_frame: get total number of frame */
HTS_PStreamSet_get_total_frame(HTS_PStreamSet * pss)446 size_t HTS_PStreamSet_get_total_frame(HTS_PStreamSet * pss)
447 {
448 return pss->total_frame;
449 }
450
451 /* HTS_PStreamSet_get_parameter: get parameter */
HTS_PStreamSet_get_parameter(HTS_PStreamSet * pss,size_t stream_index,size_t frame_index,size_t vector_index)452 double HTS_PStreamSet_get_parameter(HTS_PStreamSet * pss, size_t stream_index, size_t frame_index, size_t vector_index)
453 {
454 return pss->pstream[stream_index].par[frame_index][vector_index];
455 }
456
457 /* HTS_PStreamSet_get_parameter_vector: get parameter vector*/
HTS_PStreamSet_get_parameter_vector(HTS_PStreamSet * pss,size_t stream_index,size_t frame_index)458 double *HTS_PStreamSet_get_parameter_vector(HTS_PStreamSet * pss, size_t stream_index, size_t frame_index)
459 {
460 return pss->pstream[stream_index].par[frame_index];
461 }
462
463 /* HTS_PStreamSet_get_msd_flag: get generated MSD flag per frame */
HTS_PStreamSet_get_msd_flag(HTS_PStreamSet * pss,size_t stream_index,size_t frame_index)464 HTS_Boolean HTS_PStreamSet_get_msd_flag(HTS_PStreamSet * pss, size_t stream_index, size_t frame_index)
465 {
466 return pss->pstream[stream_index].msd_flag[frame_index];
467 }
468
469 /* HTS_PStreamSet_is_msd: get MSD flag */
HTS_PStreamSet_is_msd(HTS_PStreamSet * pss,size_t stream_index)470 HTS_Boolean HTS_PStreamSet_is_msd(HTS_PStreamSet * pss, size_t stream_index)
471 {
472 return pss->pstream[stream_index].msd_flag ? TRUE : FALSE;
473 }
474
475 /* HTS_PStreamSet_clear: free parameter stream set */
HTS_PStreamSet_clear(HTS_PStreamSet * pss)476 void HTS_PStreamSet_clear(HTS_PStreamSet * pss)
477 {
478 size_t i, j;
479 HTS_PStream *pstream;
480
481 if (pss->pstream) {
482 for (i = 0; i < pss->nstream; i++) {
483 pstream = &pss->pstream[i];
484 if (pstream->sm.wum)
485 HTS_free(pstream->sm.wum);
486 if (pstream->sm.g)
487 HTS_free(pstream->sm.g);
488 if (pstream->sm.wuw)
489 HTS_free_matrix(pstream->sm.wuw, pstream->length);
490 if (pstream->sm.ivar)
491 HTS_free_matrix(pstream->sm.ivar, pstream->length);
492 if (pstream->sm.mean)
493 HTS_free_matrix(pstream->sm.mean, pstream->length);
494 if (pstream->par)
495 HTS_free_matrix(pstream->par, pstream->length);
496 if (pstream->msd_flag)
497 HTS_free(pstream->msd_flag);
498 if (pstream->win_coefficient) {
499 for (j = 0; j < pstream->win_size; j++) {
500 pstream->win_coefficient[j] += pstream->win_l_width[j];
501 HTS_free(pstream->win_coefficient[j]);
502 }
503 }
504 if (pstream->gv_mean)
505 HTS_free(pstream->gv_mean);
506 if (pstream->gv_vari)
507 HTS_free(pstream->gv_vari);
508 if (pstream->win_coefficient)
509 HTS_free(pstream->win_coefficient);
510 if (pstream->win_l_width)
511 HTS_free(pstream->win_l_width);
512 if (pstream->win_r_width)
513 HTS_free(pstream->win_r_width);
514 if (pstream->gv_switch)
515 HTS_free(pstream->gv_switch);
516 }
517 HTS_free(pss->pstream);
518 }
519 HTS_PStreamSet_initialize(pss);
520 }
521
522 HTS_PSTREAM_C_END;
523
524 #endif /* !HTS_PSTREAM_C */
525