1 /* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* ====================================================================
3 * Copyright (c) 1999-2004 Carnegie Mellon University. All rights
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
18 * This work was supported in part by funding from the Defense Advanced
19 * Research Projects Agency and the National Science Foundation of the
20 * United States of America, and the CMU Sphinx Speech Consortium.
22 * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
23 * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
26 * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 * ====================================================================
38 * cmn.c -- Various forms of cepstral mean normalization
40 * **********************************************
41 * CMU ARPA Speech Project
43 * Copyright (c) 1996 Carnegie Mellon University.
44 * ALL RIGHTS RESERVED.
45 * **********************************************
49 * Revision 1.14 2006/02/24 15:57:47 egouvea
50 * Removed cmn = NULL from the cmn_free(), since it's pointless (my bad!).
52 * Removed cmn_prior, which was surrounded by #if 0/#endif, since the
53 * function is already in cmn_prior.c
55 * Revision 1.13 2006/02/23 03:47:49 arthchan2003
56 * Used Evandro's changes. Resolved conflicts.
59 * Revision 1.12 2006/02/23 00:48:23 egouvea
60 * Replaced loops resetting vectors with the more efficient memset()
62 * Revision 1.11 2006/02/22 23:43:55 arthchan2003
63 * Merged from the branch SPHINX3_5_2_RCI_IRII_BRANCH: Put data structure into the cmn_t structure.
65 * Revision 1.10.4.2 2005/10/17 04:45:57 arthchan2003
66 * Free stuffs in cmn and feat corectly.
68 * Revision 1.10.4.1 2005/07/05 06:25:08 arthchan2003
71 * Revision 1.10 2005/06/21 19:28:00 arthchan2003
72 * 1, Fixed doxygen documentation. 2, Added $ keyword.
74 * Revision 1.3 2005/03/30 01:22:46 archan
75 * Fixed mistakes in last updates. Add
78 * 20.Apr.2001 RAH (rhoughton@mediasite.com, ricky.houghton@cs.cmu.edu)
79 * Added cmn_free() and moved *mean and *var out global space and named them cmn_mean and cmn_var
81 * 28-Apr-1999 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
82 * Changed the name norm_mean() to cmn().
84 * 19-Jun-1996 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
85 * Changed to compute CMN over ALL dimensions of cep instead of 1..12.
87 * 04-Nov-1995 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
102 #pragma warning (disable: 4244)
105 #include "sphinxbase/ckd_alloc.h"
106 #include "sphinxbase/err.h"
107 #include "sphinxbase/cmn.h"
109 /* NOTE! These must match the enum in cmn.h */
110 const char *cmn_type_str[] = {
115 static const int n_cmn_type_str = sizeof(cmn_type_str)/sizeof(cmn_type_str[0]);
118 cmn_type_from_str(const char *str)
122 for (i = 0; i < n_cmn_type_str; ++i) {
123 if (0 == strcmp(str, cmn_type_str[i]))
124 return (cmn_type_t)i;
126 E_FATAL("Unknown CMN type '%s'\n", str);
131 cmn_init(int32 veclen)
134 cmn = (cmn_t *) ckd_calloc(1, sizeof(cmn_t));
135 cmn->veclen = veclen;
136 cmn->cmn_mean = (mfcc_t *) ckd_calloc(veclen, sizeof(mfcc_t));
137 cmn->cmn_var = (mfcc_t *) ckd_calloc(veclen, sizeof(mfcc_t));
138 cmn->sum = (mfcc_t *) ckd_calloc(veclen, sizeof(mfcc_t));
139 /* A front-end dependent magic number */
140 cmn->cmn_mean[0] = FLOAT2MFCC(12.0);
142 E_INFO("mean[0]= %.2f, mean[1..%d]= 0.0\n",
143 MFCC2FLOAT(cmn->cmn_mean[0]), veclen - 1);
150 cmn(cmn_t *cmn, mfcc_t ** mfc, int32 varnorm, int32 n_frame)
161 /* If cmn->cmn_mean wasn't NULL, we need to zero the contents */
162 memset(cmn->cmn_mean, 0, cmn->veclen * sizeof(mfcc_t));
164 /* Find mean cep vector for this utterance */
165 for (f = 0; f < n_frame; f++) {
167 for (i = 0; i < cmn->veclen; i++) {
168 cmn->cmn_mean[i] += mfcp[i];
172 for (i = 0; i < cmn->veclen; i++)
173 cmn->cmn_mean[i] /= n_frame;
176 for (i = 0; i < cmn->veclen; i++)
177 E_INFOCONT("%5.2f ", MFCC2FLOAT(cmn->cmn_mean[i]));
180 /* Subtract mean from each cep vector */
181 for (f = 0; f < n_frame; f++) {
183 for (i = 0; i < cmn->veclen; i++)
184 mfcp[i] -= cmn->cmn_mean[i];
188 /* Scale cep vectors to have unit variance along each dimension, and subtract means */
189 /* If cmn->cmn_var wasn't NULL, we need to zero the contents */
190 memset(cmn->cmn_var, 0, cmn->veclen * sizeof(mfcc_t));
192 for (f = 0; f < n_frame; f++) {
195 for (i = 0; i < cmn->veclen; i++) {
196 t = mfcp[i] - cmn->cmn_mean[i];
197 cmn->cmn_var[i] += MFCCMUL(t, t);
200 for (i = 0; i < cmn->veclen; i++)
201 /* Inverse Std. Dev, RAH added type case from sqrt */
202 cmn->cmn_var[i] = FLOAT2MFCC(sqrt((float64)n_frame / MFCC2FLOAT(cmn->cmn_var[i])));
204 for (f = 0; f < n_frame; f++) {
206 for (i = 0; i < cmn->veclen; i++)
207 mfcp[i] = MFCCMUL((mfcp[i] - cmn->cmn_mean[i]), cmn->cmn_var[i]);
213 * RAH, free previously allocated memory
216 cmn_free(cmn_t * cmn)
220 ckd_free((void *) cmn->cmn_var);
223 ckd_free((void *) cmn->cmn_mean);
226 ckd_free((void *) cmn->sum);
228 ckd_free((void *) cmn);