SphinxBase 0.6
|
00001 /* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */ 00002 /* ==================================================================== 00003 * Copyright (c) 1999-2004 Carnegie Mellon University. All rights 00004 * reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 00010 * 1. Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * 00013 * 2. Redistributions in binary form must reproduce the above copyright 00014 * notice, this list of conditions and the following disclaimer in 00015 * the documentation and/or other materials provided with the 00016 * distribution. 00017 * 00018 * This work was supported in part by funding from the Defense Advanced 00019 * Research Projects Agency and the National Science Foundation of the 00020 * United States of America, and the CMU Sphinx Speech Consortium. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND 00023 * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 00024 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00025 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY 00026 * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00027 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00028 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00029 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00030 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00031 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00032 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00033 * 00034 * ==================================================================== 00035 * 00036 */ 00037 /* 00038 * cmn.c -- Various forms of cepstral mean normalization 00039 * 00040 * ********************************************** 00041 * CMU ARPA Speech Project 00042 * 00043 * Copyright (c) 1996 Carnegie Mellon University. 00044 * ALL RIGHTS RESERVED. 00045 * ********************************************** 00046 * 00047 * HISTORY 00048 * $Log$ 00049 * Revision 1.14 2006/02/24 15:57:47 egouvea 00050 * Removed cmn = NULL from the cmn_free(), since it's pointless (my bad!). 00051 * 00052 * Removed cmn_prior, which was surrounded by #if 0/#endif, since the 00053 * function is already in cmn_prior.c 00054 * 00055 * Revision 1.13 2006/02/23 03:47:49 arthchan2003 00056 * Used Evandro's changes. Resolved conflicts. 00057 * 00058 * 00059 * Revision 1.12 2006/02/23 00:48:23 egouvea 00060 * Replaced loops resetting vectors with the more efficient memset() 00061 * 00062 * Revision 1.11 2006/02/22 23:43:55 arthchan2003 00063 * Merged from the branch SPHINX3_5_2_RCI_IRII_BRANCH: Put data structure into the cmn_t structure. 00064 * 00065 * Revision 1.10.4.2 2005/10/17 04:45:57 arthchan2003 00066 * Free stuffs in cmn and feat corectly. 00067 * 00068 * Revision 1.10.4.1 2005/07/05 06:25:08 arthchan2003 00069 * Fixed dox-doc. 00070 * 00071 * Revision 1.10 2005/06/21 19:28:00 arthchan2003 00072 * 1, Fixed doxygen documentation. 2, Added $ keyword. 00073 * 00074 * Revision 1.3 2005/03/30 01:22:46 archan 00075 * Fixed mistakes in last updates. Add 00076 * 00077 * 00078 * 20.Apr.2001 RAH (rhoughton@mediasite.com, ricky.houghton@cs.cmu.edu) 00079 * Added cmn_free() and moved *mean and *var out global space and named them cmn_mean and cmn_var 00080 * 00081 * 28-Apr-1999 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University 00082 * Changed the name norm_mean() to cmn(). 00083 * 00084 * 19-Jun-1996 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University 00085 * Changed to compute CMN over ALL dimensions of cep instead of 1..12. 00086 * 00087 * 04-Nov-1995 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University 00088 * Created. 00089 */ 00090 00091 00092 #include <stdio.h> 00093 #include <stdlib.h> 00094 #include <string.h> 00095 #include <assert.h> 00096 #include <math.h> 00097 #ifdef HAVE_CONFIG_H 00098 #include <config.h> 00099 #endif 00100 00101 #ifdef _MSC_VER 00102 #pragma warning (disable: 4244) 00103 #endif 00104 00105 #include "sphinxbase/ckd_alloc.h" 00106 #include "sphinxbase/err.h" 00107 #include "sphinxbase/cmn.h" 00108 00109 /* NOTE! These must match the enum in cmn.h */ 00110 const char *cmn_type_str[] = { 00111 "none", 00112 "current", 00113 "prior" 00114 }; 00115 static const int n_cmn_type_str = sizeof(cmn_type_str)/sizeof(cmn_type_str[0]); 00116 00117 cmn_type_t 00118 cmn_type_from_str(const char *str) 00119 { 00120 int i; 00121 00122 for (i = 0; i < n_cmn_type_str; ++i) { 00123 if (0 == strcmp(str, cmn_type_str[i])) 00124 return (cmn_type_t)i; 00125 } 00126 E_FATAL("Unknown CMN type '%s'\n", str); 00127 return CMN_NONE; 00128 } 00129 00130 cmn_t * 00131 cmn_init(int32 veclen) 00132 { 00133 cmn_t *cmn; 00134 cmn = (cmn_t *) ckd_calloc(1, sizeof(cmn_t)); 00135 cmn->veclen = veclen; 00136 cmn->cmn_mean = (mfcc_t *) ckd_calloc(veclen, sizeof(mfcc_t)); 00137 cmn->cmn_var = (mfcc_t *) ckd_calloc(veclen, sizeof(mfcc_t)); 00138 cmn->sum = (mfcc_t *) ckd_calloc(veclen, sizeof(mfcc_t)); 00139 /* A front-end dependent magic number */ 00140 cmn->cmn_mean[0] = FLOAT2MFCC(12.0); 00141 cmn->nframe = 0; 00142 E_INFO("mean[0]= %.2f, mean[1..%d]= 0.0\n", 00143 MFCC2FLOAT(cmn->cmn_mean[0]), veclen - 1); 00144 00145 return cmn; 00146 } 00147 00148 00149 void 00150 cmn(cmn_t *cmn, mfcc_t ** mfc, int32 varnorm, int32 n_frame) 00151 { 00152 mfcc_t *mfcp; 00153 mfcc_t t; 00154 int32 i, f; 00155 00156 assert(mfc != NULL); 00157 00158 if (n_frame <= 0) 00159 return; 00160 00161 /* If cmn->cmn_mean wasn't NULL, we need to zero the contents */ 00162 memset(cmn->cmn_mean, 0, cmn->veclen * sizeof(mfcc_t)); 00163 00164 /* Find mean cep vector for this utterance */ 00165 for (f = 0; f < n_frame; f++) { 00166 mfcp = mfc[f]; 00167 for (i = 0; i < cmn->veclen; i++) { 00168 cmn->cmn_mean[i] += mfcp[i]; 00169 } 00170 } 00171 00172 for (i = 0; i < cmn->veclen; i++) 00173 cmn->cmn_mean[i] /= n_frame; 00174 00175 E_INFO("CMN: "); 00176 for (i = 0; i < cmn->veclen; i++) 00177 E_INFOCONT("%5.2f ", MFCC2FLOAT(cmn->cmn_mean[i])); 00178 E_INFOCONT("\n"); 00179 if (!varnorm) { 00180 /* Subtract mean from each cep vector */ 00181 for (f = 0; f < n_frame; f++) { 00182 mfcp = mfc[f]; 00183 for (i = 0; i < cmn->veclen; i++) 00184 mfcp[i] -= cmn->cmn_mean[i]; 00185 } 00186 } 00187 else { 00188 /* Scale cep vectors to have unit variance along each dimension, and subtract means */ 00189 /* If cmn->cmn_var wasn't NULL, we need to zero the contents */ 00190 memset(cmn->cmn_var, 0, cmn->veclen * sizeof(mfcc_t)); 00191 00192 for (f = 0; f < n_frame; f++) { 00193 mfcp = mfc[f]; 00194 00195 for (i = 0; i < cmn->veclen; i++) { 00196 t = mfcp[i] - cmn->cmn_mean[i]; 00197 cmn->cmn_var[i] += MFCCMUL(t, t); 00198 } 00199 } 00200 for (i = 0; i < cmn->veclen; i++) 00201 /* Inverse Std. Dev, RAH added type case from sqrt */ 00202 cmn->cmn_var[i] = FLOAT2MFCC(sqrt((float64)n_frame / MFCC2FLOAT(cmn->cmn_var[i]))); 00203 00204 for (f = 0; f < n_frame; f++) { 00205 mfcp = mfc[f]; 00206 for (i = 0; i < cmn->veclen; i++) 00207 mfcp[i] = MFCCMUL((mfcp[i] - cmn->cmn_mean[i]), cmn->cmn_var[i]); 00208 } 00209 } 00210 } 00211 00212 /* 00213 * RAH, free previously allocated memory 00214 */ 00215 void 00216 cmn_free(cmn_t * cmn) 00217 { 00218 if (cmn != NULL) { 00219 if (cmn->cmn_var) 00220 ckd_free((void *) cmn->cmn_var); 00221 00222 if (cmn->cmn_mean) 00223 ckd_free((void *) cmn->cmn_mean); 00224 00225 if (cmn->sum) 00226 ckd_free((void *) cmn->sum); 00227 00228 ckd_free((void *) cmn); 00229 } 00230 }