1 /* ====================================================================
2 * Copyright (c) 1999-2004 Carnegie Mellon University. All rights
3 * reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * This work was supported in part by funding from the Defense Advanced
18 * Research Projects Agency and the National Science Foundation of the
19 * United States of America, and the CMU Sphinx Speech Consortium.
20 *
21 * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
22 * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
25 * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * ====================================================================
34 *
35 */
36 /*
37 * ms_mllr.c -- Application of MLLR regression matrices to codebook means
38 *
39 * **********************************************
40 * CMU ARPA Speech Project
41 *
42 * Copyright (c) 1996 Carnegie Mellon University.
43 * ALL RIGHTS RESERVED.
44 * **********************************************
45 *
46 * HISTORY
47 * $Log$
48 * Revision 1.5 2006/02/22 17:21:35 arthchan2003
49 * Merged from SPHINX3_5_2_RCI_IRII_BRANCH: 1, Added ms_mllr.[ch]
50 *
51 * Revision 1.4.4.1 2005/07/20 19:39:01 arthchan2003
52 * Added licences in ms_* series of code.
53 *
54 * Revision 1.4 2005/06/21 18:56:13 arthchan2003
55 * 1, Fixed doxygen documentation. 2, Added $ keyword.
56 *
57 * Revision 1.4 2005/06/19 04:50:02 archan
58 * Sphinx3 to s3.generic: allow multiple classes for MLLR
59 *
60 * Revision 1.3 2005/03/30 01:22:47 archan
61 * Fixed mistakes in last updates. Add
62 *
63 *
64 * 02-Dec-96 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
65 * Added reading of MLLR classes in transformation file. Currently must
66 * be 1.
67 *
68 * 26-Sep-96 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
69 * Started (copied from Vipul Parikh's implementation).
70 */
71
72
73 #include <stdio.h>
74 #include <stdlib.h>
75 #include <string.h>
76 #include <assert.h>
77
78 /* #include <s3.h>*/
79
80 #include "ms_mllr.h"
81
82
83 int32
ms_mllr_read_regmat(const char * regmatfile,float32 ***** A,float32 **** B,int32 * streamlen,int32 n_stream,int32 * nclass)84 ms_mllr_read_regmat(const char *regmatfile,
85 float32 ***** A,
86 float32 **** B,
87 int32 * streamlen, int32 n_stream, int32 * nclass)
88 {
89 int32 i, j, k, m, n, lnclass;
90 FILE *fp;
91 float32 ****lA, ***lB;
92
93 if ((fp = fopen(regmatfile, "r")) == NULL) {
94 E_ERROR("fopen(%s,r) failed\n", regmatfile);
95 return -1;
96 }
97 else
98 E_INFO("Reading MLLR transformation file %s\n", regmatfile);
99
100 if ((fscanf(fp, "%d", &n) != 1) || (n < 1))
101 return -1;
102 lnclass = n;
103
104 if ((fscanf(fp, "%d", &n) != 1) || (n != n_stream))
105 return -1;
106
107 lA = (float32 ****) ckd_calloc(n_stream, sizeof(float32 **));
108 lB = (float32 ***) ckd_calloc(n_stream, sizeof(float32 *));
109
110 for (i = 0; i < n_stream; ++i) {
111 lA[i] =
112 (float32 ***) ckd_calloc_3d(lnclass, streamlen[i],
113 streamlen[i], sizeof(float32));
114 lB[i] =
115 (float32 **) ckd_calloc_2d(lnclass, streamlen[i],
116 sizeof(float32));
117 }
118
119 for (i = 0; i < n_stream; ++i) {
120 if ((fscanf(fp, "%d", &n) != 1) || (streamlen[i] != n))
121 goto readerror;
122
123 for (m = 0; m < lnclass; ++m) {
124 for (j = 0; j < streamlen[i]; ++j) {
125 for (k = 0; k < streamlen[i]; ++k) {
126 if (fscanf(fp, "%f ", &lA[i][m][j][k]) != 1)
127 goto readerror;
128 }
129 }
130 for (j = 0; j < streamlen[i]; ++j) {
131 if (fscanf(fp, "%f ", &lB[i][m][j]) != 1)
132 goto readerror;
133 }
134 }
135 }
136
137 *A = lA;
138 *B = lB;
139 *nclass = lnclass;
140
141 fclose(fp);
142
143 return 0;
144
145 readerror:
146 E_ERROR("Error reading MLLR file %s\n", regmatfile);
147 for (i = 0; i < n_stream; ++i) {
148 ckd_free_3d((void ***) lA[i]);
149 ckd_free_2d((void **) lB[i]);
150 }
151 ckd_free(lA);
152 ckd_free(lB);
153 fclose(fp);
154
155 *A = NULL;
156 *B = NULL;
157
158 return -1;
159 }
160
161
162 int32
ms_mllr_free_regmat(float32 **** A,float32 *** B,int32 n_stream)163 ms_mllr_free_regmat(float32 **** A, float32 *** B, int32 n_stream)
164 {
165 int32 i;
166
167 for (i = 0; i < n_stream; i++) {
168 ckd_free_3d((void ***) A[i]);
169 ckd_free_2d((void **) B[i]);
170 }
171
172 ckd_free(A);
173 ckd_free(B);
174
175 return 0;
176 }
177
178
179 int32
ms_mllr_norm_mgau(float32 *** mean,int32 n_density,float32 **** A,float32 *** B,int32 * streamlen,int32 n_stream,int32 class)180 ms_mllr_norm_mgau(float32 *** mean,
181 int32 n_density,
182 float32 **** A,
183 float32 *** B,
184 int32 * streamlen, int32 n_stream, int32 class)
185 {
186 int32 s, d, l, m;
187 float64 *temp;
188
189 /* Transform codebook for each stream s */
190 for (s = 0; s < n_stream; s++) {
191 temp = (float64 *) ckd_calloc(streamlen[s], sizeof(float64));
192
193 /* Transform each density d in selected codebook */
194 for (d = 0; d < n_density; d++) {
195 for (l = 0; l < streamlen[s]; l++) {
196 temp[l] = 0.0;
197 for (m = 0; m < streamlen[s]; m++) {
198 temp[l] += A[s][class][l][m] * mean[s][d][m];
199 }
200 temp[l] += B[s][class][l];
201 }
202
203 for (l = 0; l < streamlen[s]; l++) {
204 mean[s][d][l] = (float32) temp[l];
205 }
206 }
207
208 ckd_free(temp);
209 }
210
211 return 0;
212 }
213