SphinxBase  5prealpha
cmn.c
1 /* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* ====================================================================
3  * Copyright (c) 1999-2004 Carnegie Mellon University. All rights
4  * reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
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
16  * distribution.
17  *
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.
21  *
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.
33  *
34  * ====================================================================
35  *
36  */
37 /*
38  * cmn.c -- Various forms of cepstral mean normalization
39  */
40 
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <assert.h>
45 #include <math.h>
46 #ifdef HAVE_CONFIG_H
47 #include <config.h>
48 #endif
49 
50 #ifdef _MSC_VER
51 #pragma warning (disable: 4244)
52 #endif
53 
54 #include "sphinxbase/ckd_alloc.h"
55 #include "sphinxbase/err.h"
56 #include "sphinxbase/cmn.h"
57 
58 /* NOTE! These must match the enum in cmn.h */
59 const char *cmn_type_str[] = {
60  "none",
61  "batch",
62  "live"
63 };
64 const char *cmn_alt_type_str[] = {
65  "none",
66  "current",
67  "prior"
68 };
69 static const int n_cmn_type_str = sizeof(cmn_type_str)/sizeof(cmn_type_str[0]);
70 
72 cmn_type_from_str(const char *str)
73 {
74  int i;
75 
76  for (i = 0; i < n_cmn_type_str; ++i) {
77  if (0 == strcmp(str, cmn_type_str[i]) || 0 == strcmp(str, cmn_alt_type_str[i]))
78  return (cmn_type_t)i;
79  }
80  E_FATAL("Unknown CMN type '%s'\n", str);
81  return CMN_NONE;
82 }
83 
84 cmn_t *
85 cmn_init(int32 veclen)
86 {
87  cmn_t *cmn;
88  cmn = (cmn_t *) ckd_calloc(1, sizeof(cmn_t));
89  cmn->veclen = veclen;
90  cmn->cmn_mean = (mfcc_t *) ckd_calloc(veclen, sizeof(mfcc_t));
91  cmn->cmn_var = (mfcc_t *) ckd_calloc(veclen, sizeof(mfcc_t));
92  cmn->sum = (mfcc_t *) ckd_calloc(veclen, sizeof(mfcc_t));
93  cmn->nframe = 0;
94 
95  return cmn;
96 }
97 
98 
99 void
100 cmn(cmn_t *cmn, mfcc_t ** mfc, int32 varnorm, int32 n_frame)
101 {
102  mfcc_t *mfcp;
103  mfcc_t t;
104  int32 i, f;
105  int32 n_pos_frame;
106 
107  assert(mfc != NULL);
108 
109  if (n_frame <= 0)
110  return;
111 
112  /* If cmn->cmn_mean wasn't NULL, we need to zero the contents */
113  memset(cmn->cmn_mean, 0, cmn->veclen * sizeof(mfcc_t));
114 
115  /* Find mean cep vector for this utterance */
116  for (f = 0, n_pos_frame = 0; f < n_frame; f++) {
117  mfcp = mfc[f];
118 
119  /* Skip zero energy frames */
120  if (mfcp[0] < 0)
121  continue;
122 
123  for (i = 0; i < cmn->veclen; i++) {
124  cmn->cmn_mean[i] += mfcp[i];
125  }
126 
127  n_pos_frame++;
128  }
129 
130  for (i = 0; i < cmn->veclen; i++)
131  cmn->cmn_mean[i] /= n_pos_frame;
132 
133  E_INFO("CMN: ");
134  for (i = 0; i < cmn->veclen; i++)
135  E_INFOCONT("%5.2f ", MFCC2FLOAT(cmn->cmn_mean[i]));
136  E_INFOCONT("\n");
137  if (!varnorm) {
138  /* Subtract mean from each cep vector */
139  for (f = 0; f < n_frame; f++) {
140  mfcp = mfc[f];
141  for (i = 0; i < cmn->veclen; i++)
142  mfcp[i] -= cmn->cmn_mean[i];
143  }
144  }
145  else {
146  /* Scale cep vectors to have unit variance along each dimension, and subtract means */
147  /* If cmn->cmn_var wasn't NULL, we need to zero the contents */
148  memset(cmn->cmn_var, 0, cmn->veclen * sizeof(mfcc_t));
149 
150  for (f = 0; f < n_frame; f++) {
151  mfcp = mfc[f];
152 
153  for (i = 0; i < cmn->veclen; i++) {
154  t = mfcp[i] - cmn->cmn_mean[i];
155  cmn->cmn_var[i] += MFCCMUL(t, t);
156  }
157  }
158  for (i = 0; i < cmn->veclen; i++)
159  /* Inverse Std. Dev, RAH added type case from sqrt */
160  cmn->cmn_var[i] = FLOAT2MFCC(sqrt((float64)n_frame / MFCC2FLOAT(cmn->cmn_var[i])));
161 
162  for (f = 0; f < n_frame; f++) {
163  mfcp = mfc[f];
164  for (i = 0; i < cmn->veclen; i++)
165  mfcp[i] = MFCCMUL((mfcp[i] - cmn->cmn_mean[i]), cmn->cmn_var[i]);
166  }
167  }
168 }
169 
170 /*
171  * RAH, free previously allocated memory
172  */
173 void
174 cmn_free(cmn_t * cmn)
175 {
176  if (cmn != NULL) {
177  if (cmn->cmn_var)
178  ckd_free((void *) cmn->cmn_var);
179 
180  if (cmn->cmn_mean)
181  ckd_free((void *) cmn->cmn_mean);
182 
183  if (cmn->sum)
184  ckd_free((void *) cmn->sum);
185 
186  ckd_free((void *) cmn);
187  }
188 }
#define E_INFO(...)
Print logging information to standard error stream.
Definition: err.h:114
#define ckd_calloc(n, sz)
Macros to simplify the use of above functions.
Definition: ckd_alloc.h:248
Sphinx&#39;s memory allocation/deallocation routines.
Apply Cepstral Mean Normalization (CMN) to the set of input mfc frames.
#define E_INFOCONT(...)
Continue printing the information to standard error stream.
Definition: err.h:119
SPHINXBASE_EXPORT void ckd_free(void *ptr)
Test and free a 1-D array.
Definition: ckd_alloc.c:244
SPHINXBASE_EXPORT void cmn(cmn_t *cmn, mfcc_t **mfc, int32 varnorm, int32 n_frame)
CMN for the whole sentence.
Definition: cmn.c:100
Implementation of logging routines.
SPHINXBASE_EXPORT cmn_type_t cmn_type_from_str(const char *str)
Convert string representation (from command-line) to cmn_type_t.
Definition: cmn.c:72
wrapper of operation of the cepstral mean normalization.
Definition: cmn.h:128
enum cmn_type_e cmn_type_t
Types of cepstral mean normalization to apply to the features.
SPHINXBASE_EXPORT const char * cmn_type_str[]
String representations of cmn_type_t values.
Definition: cmn.c:59
#define E_FATAL(...)
Exit with non-zero status after error message.
Definition: err.h:81
mfcc_t * cmn_mean
Temporary variable: current means.
Definition: cmn.h:129
mfcc_t * cmn_var
Temporary variables: stored the cmn variance.
Definition: cmn.h:130
mfcc_t * sum
The sum of the cmn frames.
Definition: cmn.h:131
int32 veclen
Length of cepstral vector.
Definition: cmn.h:133
int32 nframe
Number of frames.
Definition: cmn.h:132