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