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-2011 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 HTS106_PSTREAM_C
46 #define HTS106_PSTREAM_C
47
48 #ifdef __cplusplus
49 #define HTS106_PSTREAM_C_START extern "C" {
50 #define HTS106_PSTREAM_C_END }
51 #else
52 #define HTS106_PSTREAM_C_START
53 #define HTS106_PSTREAM_C_END
54 #endif /* __CPLUSPLUS */
55
56 HTS106_PSTREAM_C_START;
57
58 #include <math.h> /* for sqrt() */
59
60 /* hts_engine libraries */
61 #include "HTS106_hidden.h"
62
63 /* HTS106_finv: calculate 1.0/variance function */
HTS106_finv(const double x)64 static double HTS106_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 /* HTS106_PStream_calc_wuw_and_wum: calcurate W'U^{-1}W and W'U^{-1}M */
HTS106_PStream_calc_wuw_and_wum(HTS106_PStream * pst,const int m)79 static void HTS106_PStream_calc_wuw_and_wum(HTS106_PStream * pst, const int m)
80 {
81 int t, i, j, k;
82 double wu;
83
84 for (t = 0; t < pst->length; t++) {
85 /* initialize */
86 pst->sm.wum[t] = 0.0;
87 for (i = 0; i < pst->width; i++)
88 pst->sm.wuw[t][i] = 0.0;
89
90 /* calc WUW & WUM */
91 for (i = 0; i < pst->win_size; i++)
92 for (j = pst->win_l_width[i]; j <= pst->win_r_width[i]; j++)
93 if ((t + j >= 0) && (t + j < pst->length)
94 && (pst->win_coefficient[i][-j] != 0.0)) {
95 wu = pst->win_coefficient[i][-j] * pst->sm.ivar[t + j][i * pst->static_length + m];
96 pst->sm.wum[t] += wu * pst->sm.mean[t + j][i * pst->static_length + m];
97 for (k = 0; (k < pst->width) && (t + k < pst->length); k++)
98 if ((k - j <= pst->win_r_width[i])
99 && (pst->win_coefficient[i][k - j] != 0.0))
100 pst->sm.wuw[t][k] += wu * pst->win_coefficient[i][k - j];
101 }
102 }
103 }
104
105
106 /* HTS106_PStream_ldl_factorization: Factorize W'*U^{-1}*W to L*D*L' (L: lower triangular, D: diagonal) */
HTS106_PStream_ldl_factorization(HTS106_PStream * pst)107 static void HTS106_PStream_ldl_factorization(HTS106_PStream * pst)
108 {
109 int t, i, j;
110
111 for (t = 0; t < pst->length; t++) {
112 for (i = 1; (i < pst->width) && (t >= i); i++)
113 pst->sm.wuw[t][0] -= pst->sm.wuw[t - i][i] * pst->sm.wuw[t - i][i] * pst->sm.wuw[t - i][0];
114
115 for (i = 1; i < pst->width; i++) {
116 for (j = 1; (i + j < pst->width) && (t >= j); j++)
117 pst->sm.wuw[t][i] -= pst->sm.wuw[t - j][j] * pst->sm.wuw[t - j][i + j] * pst->sm.wuw[t - j][0];
118 pst->sm.wuw[t][i] /= pst->sm.wuw[t][0];
119 }
120 }
121 }
122
123 /* HTS106_PStream_forward_substitution: forward subtitution for mlpg */
HTS106_PStream_forward_substitution(HTS106_PStream * pst)124 static void HTS106_PStream_forward_substitution(HTS106_PStream * pst)
125 {
126 int t, i;
127
128 for (t = 0; t < pst->length; t++) {
129 pst->sm.g[t] = pst->sm.wum[t];
130 for (i = 1; (i < pst->width) && (t >= i); i++)
131 pst->sm.g[t] -= pst->sm.wuw[t - i][i] * pst->sm.g[t - i];
132 }
133 }
134
135 /* HTS106_PStream_backward_substitution: backward subtitution for mlpg */
HTS106_PStream_backward_substitution(HTS106_PStream * pst,const int m)136 static void HTS106_PStream_backward_substitution(HTS106_PStream * pst, const int m)
137 {
138 int t, i;
139
140 for (t = pst->length - 1; t >= 0; t--) {
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 /* HTS106_PStream_calc_gv: subfunction for mlpg using GV */
HTS106_PStream_calc_gv(HTS106_PStream * pst,const int m,double * mean,double * vari)148 static void HTS106_PStream_calc_gv(HTS106_PStream * pst, const int m, double *mean, double *vari)
149 {
150 int 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 /* HTS106_PStream_conv_gv: subfunction for mlpg using GV */
HTS106_PStream_conv_gv(HTS106_PStream * pst,const int m)165 static void HTS106_PStream_conv_gv(HTS106_PStream * pst, const int m)
166 {
167 int t;
168 double ratio;
169 double mean;
170 double vari;
171
172 HTS106_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 /* HTS106_PStream_calc_derivative: subfunction for mlpg using GV */
HTS106_PStream_calc_derivative(HTS106_PStream * pst,const int m)180 static double HTS106_PStream_calc_derivative(HTS106_PStream * pst, const int m)
181 {
182 int t, i;
183 double mean;
184 double vari;
185 double dv;
186 double h;
187 double gvobj;
188 double hmmobj;
189 const double w = 1.0 / (pst->win_size * pst->length);
190
191 HTS106_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 /* HTS106_PStream_gv_parmgen: function for mlpg using GV */
HTS106_PStream_gv_parmgen(HTS106_PStream * pst,const int m)218 static void HTS106_PStream_gv_parmgen(HTS106_PStream * pst, const int m)
219 {
220 int t, i;
221 double step = STEPINIT;
222 double prev = -LZERO;
223 double obj;
224
225 if (pst->gv_length == 0)
226 return;
227
228 HTS106_PStream_conv_gv(pst, m);
229 if (GV_MAX_ITERATION > 0) {
230 HTS106_PStream_calc_wuw_and_wum(pst, m);
231 for (i = 1; i <= GV_MAX_ITERATION; i++) {
232 obj = HTS106_PStream_calc_derivative(pst, m);
233 if (obj > prev)
234 step *= STEPDEC;
235 if (obj < prev)
236 step *= STEPINC;
237 for (t = 0; t < pst->length; t++)
238 pst->par[t][m] += step * pst->sm.g[t];
239 prev = obj;
240 }
241 }
242 }
243
244 /* HTS106_PStream_mlpg: generate sequence of speech parameter vector maximizing its output probability for given pdf sequence */
HTS106_PStream_mlpg(HTS106_PStream * pst)245 static void HTS106_PStream_mlpg(HTS106_PStream * pst)
246 {
247 int m;
248
249 if (pst->length == 0)
250 return;
251
252 for (m = 0; m < pst->static_length; m++) {
253 HTS106_PStream_calc_wuw_and_wum(pst, m);
254 HTS106_PStream_ldl_factorization(pst); /* LDL factorization */
255 HTS106_PStream_forward_substitution(pst); /* forward substitution */
256 HTS106_PStream_backward_substitution(pst, m); /* backward substitution */
257 if (pst->gv_length > 0)
258 HTS106_PStream_gv_parmgen(pst, m);
259 }
260 }
261
262 /* HTS106_PStreamSet_initialize: initialize parameter stream set */
HTS106_PStreamSet_initialize(HTS106_PStreamSet * pss)263 void HTS106_PStreamSet_initialize(HTS106_PStreamSet * pss)
264 {
265 pss->pstream = NULL;
266 pss->nstream = 0;
267 pss->total_frame = 0;
268 }
269
270 /* HTS106_PStreamSet_create: parameter generation using GV weight */
HTS106_PStreamSet_create(HTS106_PStreamSet * pss,HTS106_SStreamSet * sss,double * msd_threshold,double * gv_weight)271 HTS106_Boolean HTS106_PStreamSet_create(HTS106_PStreamSet * pss, HTS106_SStreamSet * sss, double *msd_threshold, double *gv_weight)
272 {
273 int i, j, k, l, m;
274 int frame, msd_frame, state;
275
276 HTS106_PStream *pst;
277 HTS106_Boolean not_bound;
278
279 if (pss->nstream) {
280 HTS106_error(1, "HTS106_PstreamSet_create: HTS106_PStreamSet should be clear.\n");
281 return FALSE;
282 }
283
284 /* initialize */
285 pss->nstream = HTS106_SStreamSet_get_nstream(sss);
286 pss->pstream = (HTS106_PStream *) HTS106_calloc(pss->nstream, sizeof(HTS106_PStream));
287 pss->total_frame = HTS106_SStreamSet_get_total_frame(sss);
288
289 /* create */
290 for (i = 0; i < pss->nstream; i++) {
291 pst = &pss->pstream[i];
292 if (HTS106_SStreamSet_is_msd(sss, i)) { /* for MSD */
293 pst->length = 0;
294 for (state = 0; state < HTS106_SStreamSet_get_total_state(sss); state++)
295 if (HTS106_SStreamSet_get_msd(sss, i, state) > msd_threshold[i])
296 pst->length += HTS106_SStreamSet_get_duration(sss, state);
297 pst->msd_flag = (HTS106_Boolean *) HTS106_calloc(pss->total_frame, sizeof(HTS106_Boolean));
298 for (state = 0, frame = 0; state < HTS106_SStreamSet_get_total_state(sss); state++)
299 if (HTS106_SStreamSet_get_msd(sss, i, state) > msd_threshold[i])
300 for (j = 0; j < HTS106_SStreamSet_get_duration(sss, state); j++) {
301 pst->msd_flag[frame] = TRUE;
302 frame++;
303 } else
304 for (j = 0; j < HTS106_SStreamSet_get_duration(sss, state); j++) {
305 pst->msd_flag[frame] = FALSE;
306 frame++;
307 }
308 } else { /* for non MSD */
309 pst->length = pss->total_frame;
310 pst->msd_flag = NULL;
311 }
312 pst->vector_length = HTS106_SStreamSet_get_vector_length(sss, i);
313 pst->width = HTS106_SStreamSet_get_window_max_width(sss, i) * 2 + 1; /* band width of R */
314 pst->win_size = HTS106_SStreamSet_get_window_size(sss, i);
315 pst->static_length = pst->vector_length / pst->win_size;
316 pst->sm.mean = HTS106_alloc_matrix(pst->length, pst->vector_length);
317 pst->sm.ivar = HTS106_alloc_matrix(pst->length, pst->vector_length);
318 pst->sm.wum = (double *) HTS106_calloc(pst->length, sizeof(double));
319 pst->sm.wuw = HTS106_alloc_matrix(pst->length, pst->width);
320 pst->sm.g = (double *) HTS106_calloc(pst->length, sizeof(double));
321 pst->par = HTS106_alloc_matrix(pst->length, pst->static_length);
322 /* copy dynamic window */
323 pst->win_l_width = (int *) HTS106_calloc(pst->win_size, sizeof(int));
324 pst->win_r_width = (int *) HTS106_calloc(pst->win_size, sizeof(int));
325 pst->win_coefficient = (double **) HTS106_calloc(pst->win_size, sizeof(double));
326 for (j = 0; j < pst->win_size; j++) {
327 pst->win_l_width[j] = HTS106_SStreamSet_get_window_left_width(sss, i, j);
328 pst->win_r_width[j] = HTS106_SStreamSet_get_window_right_width(sss, i, j);
329 if (pst->win_l_width[j] + pst->win_r_width[j] == 0)
330 pst->win_coefficient[j] = (double *)
331 HTS106_calloc(-2 * pst->win_l_width[j] + 1, sizeof(double));
332 else
333 pst->win_coefficient[j] = (double *)
334 HTS106_calloc(-2 * pst->win_l_width[j], sizeof(double));
335 pst->win_coefficient[j] -= pst->win_l_width[j];
336 for (k = pst->win_l_width[j]; k <= pst->win_r_width[j]; k++)
337 pst->win_coefficient[j][k] = HTS106_SStreamSet_get_window_coefficient(sss, i, j, k);
338 }
339 /* copy GV */
340 if (HTS106_SStreamSet_use_gv(sss, i)) {
341 pst->gv_mean = (double *) HTS106_calloc(pst->static_length, sizeof(double));
342 pst->gv_vari = (double *) HTS106_calloc(pst->static_length, sizeof(double));
343 for (j = 0; j < pst->static_length; j++) {
344 pst->gv_mean[j] = HTS106_SStreamSet_get_gv_mean(sss, i, j) * gv_weight[i];
345 pst->gv_vari[j] = HTS106_SStreamSet_get_gv_vari(sss, i, j);
346 }
347 pst->gv_switch = (HTS106_Boolean *) HTS106_calloc(pst->length, sizeof(HTS106_Boolean));
348 if (HTS106_SStreamSet_is_msd(sss, i)) { /* for MSD */
349 for (state = 0, frame = 0, msd_frame = 0; state < HTS106_SStreamSet_get_total_state(sss); state++)
350 for (j = 0; j < HTS106_SStreamSet_get_duration(sss, state); j++, frame++)
351 if (pst->msd_flag[frame])
352 pst->gv_switch[msd_frame++] = HTS106_SStreamSet_get_gv_switch(sss, i, state);
353 } else { /* for non MSD */
354 for (state = 0, frame = 0; state < HTS106_SStreamSet_get_total_state(sss); state++)
355 for (j = 0; j < HTS106_SStreamSet_get_duration(sss, state); j++)
356 pst->gv_switch[frame++] = HTS106_SStreamSet_get_gv_switch(sss, i, state);
357 }
358 for (j = 0, pst->gv_length = 0; j < pst->length; j++)
359 if (pst->gv_switch[j])
360 pst->gv_length++;
361 } else {
362 pst->gv_switch = NULL;
363 pst->gv_length = 0;
364 pst->gv_mean = NULL;
365 pst->gv_vari = NULL;
366 }
367 /* copy pdfs */
368 if (HTS106_SStreamSet_is_msd(sss, i)) { /* for MSD */
369 for (state = 0, frame = 0, msd_frame = 0; state < HTS106_SStreamSet_get_total_state(sss); state++)
370 for (j = 0; j < HTS106_SStreamSet_get_duration(sss, state); j++) {
371 if (pst->msd_flag[frame]) {
372 /* check current frame is MSD boundary or not */
373 for (k = 0; k < pst->win_size; k++) {
374 not_bound = TRUE;
375 for (l = pst->win_l_width[k]; l <= pst->win_r_width[k]; l++)
376 if (frame + l < 0 || pss->total_frame <= frame + l || !pst->msd_flag[frame + l]) {
377 not_bound = FALSE;
378 break;
379 }
380 for (l = 0; l < pst->static_length; l++) {
381 m = pst->static_length * k + l;
382 pst->sm.mean[msd_frame][m] = HTS106_SStreamSet_get_mean(sss, i, state, m);
383 if (not_bound || k == 0)
384 pst->sm.ivar[msd_frame][m] = HTS106_finv(HTS106_SStreamSet_get_vari(sss, i, state, m));
385 else
386 pst->sm.ivar[msd_frame][m] = 0.0;
387 }
388 }
389 msd_frame++;
390 }
391 frame++;
392 }
393 } else { /* for non MSD */
394 for (state = 0, frame = 0; state < HTS106_SStreamSet_get_total_state(sss); state++) {
395 for (j = 0; j < HTS106_SStreamSet_get_duration(sss, state); j++) {
396 for (k = 0; k < pst->win_size; k++) {
397 not_bound = TRUE;
398 for (l = pst->win_l_width[k]; l <= pst->win_r_width[k]; l++)
399 if (frame + l < 0 || pss->total_frame <= frame + l) {
400 not_bound = FALSE;
401 break;
402 }
403 for (l = 0; l < pst->static_length; l++) {
404 m = pst->static_length * k + l;
405 pst->sm.mean[frame][m] = HTS106_SStreamSet_get_mean(sss, i, state, m);
406 if (not_bound || k == 0)
407 pst->sm.ivar[frame][m] = HTS106_finv(HTS106_SStreamSet_get_vari(sss, i, state, m));
408 else
409 pst->sm.ivar[frame][m] = 0.0;
410 }
411 }
412 frame++;
413 }
414 }
415 }
416 /* parameter generation */
417 HTS106_PStream_mlpg(pst);
418 }
419
420 return TRUE;
421 }
422
423 /* HTS106_PStreamSet_get_nstream: get number of stream */
HTS106_PStreamSet_get_nstream(HTS106_PStreamSet * pss)424 int HTS106_PStreamSet_get_nstream(HTS106_PStreamSet * pss)
425 {
426 return pss->nstream;
427 }
428
429 /* HTS106_PStreamSet_get_static_length: get static features length */
HTS106_PStreamSet_get_static_length(HTS106_PStreamSet * pss,int stream_index)430 int HTS106_PStreamSet_get_static_length(HTS106_PStreamSet * pss, int stream_index)
431 {
432 return pss->pstream[stream_index].static_length;
433 }
434
435 /* HTS106_PStreamSet_get_total_frame: get total number of frame */
HTS106_PStreamSet_get_total_frame(HTS106_PStreamSet * pss)436 int HTS106_PStreamSet_get_total_frame(HTS106_PStreamSet * pss)
437 {
438 return pss->total_frame;
439 }
440
441 /* HTS106_PStreamSet_get_parameter: get parameter */
HTS106_PStreamSet_get_parameter(HTS106_PStreamSet * pss,int stream_index,int frame_index,int vector_index)442 double HTS106_PStreamSet_get_parameter(HTS106_PStreamSet * pss, int stream_index, int frame_index, int vector_index)
443 {
444 return pss->pstream[stream_index].par[frame_index][vector_index];
445 }
446
447 /* HTS106_PStreamSet_get_parameter_vector: get parameter vector*/
HTS106_PStreamSet_get_parameter_vector(HTS106_PStreamSet * pss,int stream_index,int frame_index)448 double *HTS106_PStreamSet_get_parameter_vector(HTS106_PStreamSet * pss, int stream_index, int frame_index)
449 {
450 return pss->pstream[stream_index].par[frame_index];
451 }
452
453 /* HTS106_PStreamSet_get_msd_flag: get generated MSD flag per frame */
HTS106_PStreamSet_get_msd_flag(HTS106_PStreamSet * pss,int stream_index,int frame_index)454 HTS106_Boolean HTS106_PStreamSet_get_msd_flag(HTS106_PStreamSet * pss, int stream_index, int frame_index)
455 {
456 return pss->pstream[stream_index].msd_flag[frame_index];
457 }
458
459 /* HTS106_PStreamSet_is_msd: get MSD flag */
HTS106_PStreamSet_is_msd(HTS106_PStreamSet * pss,int stream_index)460 HTS106_Boolean HTS106_PStreamSet_is_msd(HTS106_PStreamSet * pss, int stream_index)
461 {
462 return pss->pstream[stream_index].msd_flag ? TRUE : FALSE;
463 }
464
465 /* HTS106_PStreamSet_clear: free parameter stream set */
HTS106_PStreamSet_clear(HTS106_PStreamSet * pss)466 void HTS106_PStreamSet_clear(HTS106_PStreamSet * pss)
467 {
468 int i, j;
469 HTS106_PStream *pstream;
470
471 if (pss->pstream) {
472 for (i = 0; i < pss->nstream; i++) {
473 pstream = &pss->pstream[i];
474 HTS106_free(pstream->sm.wum);
475 HTS106_free(pstream->sm.g);
476 HTS106_free_matrix(pstream->sm.wuw, pstream->length);
477 HTS106_free_matrix(pstream->sm.ivar, pstream->length);
478 HTS106_free_matrix(pstream->sm.mean, pstream->length);
479 HTS106_free_matrix(pstream->par, pstream->length);
480 if (pstream->msd_flag)
481 HTS106_free(pstream->msd_flag);
482 for (j = pstream->win_size - 1; j >= 0; j--) {
483 pstream->win_coefficient[j] += pstream->win_l_width[j];
484 HTS106_free(pstream->win_coefficient[j]);
485 }
486 if (pstream->gv_mean)
487 HTS106_free(pstream->gv_mean);
488 if (pstream->gv_vari)
489 HTS106_free(pstream->gv_vari);
490 HTS106_free(pstream->win_coefficient);
491 HTS106_free(pstream->win_l_width);
492 HTS106_free(pstream->win_r_width);
493 if (pstream->gv_switch)
494 HTS106_free(pstream->gv_switch);
495 }
496 HTS106_free(pss->pstream);
497 }
498 HTS106_PStreamSet_initialize(pss);
499 }
500
501 HTS106_PSTREAM_C_END;
502
503 #endif /* !HTS106_PSTREAM_C */
504