summaryrefslogtreecommitdiffstats
path: root/media/sphinxbase/src/libsphinxbase/feat/cmn.c
diff options
context:
space:
mode:
Diffstat (limited to 'media/sphinxbase/src/libsphinxbase/feat/cmn.c')
-rw-r--r--media/sphinxbase/src/libsphinxbase/feat/cmn.c238
1 files changed, 238 insertions, 0 deletions
diff --git a/media/sphinxbase/src/libsphinxbase/feat/cmn.c b/media/sphinxbase/src/libsphinxbase/feat/cmn.c
new file mode 100644
index 000000000..c133c19a3
--- /dev/null
+++ b/media/sphinxbase/src/libsphinxbase/feat/cmn.c
@@ -0,0 +1,238 @@
+/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* ====================================================================
+ * Copyright (c) 1999-2004 Carnegie Mellon University. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * This work was supported in part by funding from the Defense Advanced
+ * Research Projects Agency and the National Science Foundation of the
+ * United States of America, and the CMU Sphinx Speech Consortium.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
+ * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ *
+ */
+/*
+ * cmn.c -- Various forms of cepstral mean normalization
+ *
+ * **********************************************
+ * CMU ARPA Speech Project
+ *
+ * Copyright (c) 1996 Carnegie Mellon University.
+ * ALL RIGHTS RESERVED.
+ * **********************************************
+ *
+ * HISTORY
+ * $Log$
+ * Revision 1.14 2006/02/24 15:57:47 egouvea
+ * Removed cmn = NULL from the cmn_free(), since it's pointless (my bad!).
+ *
+ * Removed cmn_prior, which was surrounded by #if 0/#endif, since the
+ * function is already in cmn_prior.c
+ *
+ * Revision 1.13 2006/02/23 03:47:49 arthchan2003
+ * Used Evandro's changes. Resolved conflicts.
+ *
+ *
+ * Revision 1.12 2006/02/23 00:48:23 egouvea
+ * Replaced loops resetting vectors with the more efficient memset()
+ *
+ * Revision 1.11 2006/02/22 23:43:55 arthchan2003
+ * Merged from the branch SPHINX3_5_2_RCI_IRII_BRANCH: Put data structure into the cmn_t structure.
+ *
+ * Revision 1.10.4.2 2005/10/17 04:45:57 arthchan2003
+ * Free stuffs in cmn and feat corectly.
+ *
+ * Revision 1.10.4.1 2005/07/05 06:25:08 arthchan2003
+ * Fixed dox-doc.
+ *
+ * Revision 1.10 2005/06/21 19:28:00 arthchan2003
+ * 1, Fixed doxygen documentation. 2, Added $ keyword.
+ *
+ * Revision 1.3 2005/03/30 01:22:46 archan
+ * Fixed mistakes in last updates. Add
+ *
+ *
+ * 20.Apr.2001 RAH (rhoughton@mediasite.com, ricky.houghton@cs.cmu.edu)
+ * Added cmn_free() and moved *mean and *var out global space and named them cmn_mean and cmn_var
+ *
+ * 28-Apr-1999 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
+ * Changed the name norm_mean() to cmn().
+ *
+ * 19-Jun-1996 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
+ * Changed to compute CMN over ALL dimensions of cep instead of 1..12.
+ *
+ * 04-Nov-1995 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
+ * Created.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <math.h>
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef _MSC_VER
+#pragma warning (disable: 4244)
+#endif
+
+#include "sphinxbase/ckd_alloc.h"
+#include "sphinxbase/err.h"
+#include "sphinxbase/cmn.h"
+
+/* NOTE! These must match the enum in cmn.h */
+const char *cmn_type_str[] = {
+ "none",
+ "current",
+ "prior"
+};
+static const int n_cmn_type_str = sizeof(cmn_type_str)/sizeof(cmn_type_str[0]);
+
+cmn_type_t
+cmn_type_from_str(const char *str)
+{
+ int i;
+
+ for (i = 0; i < n_cmn_type_str; ++i) {
+ if (0 == strcmp(str, cmn_type_str[i]))
+ return (cmn_type_t)i;
+ }
+ E_FATAL("Unknown CMN type '%s'\n", str);
+ return CMN_NONE;
+}
+
+cmn_t *
+cmn_init(int32 veclen)
+{
+ cmn_t *cmn;
+ cmn = (cmn_t *) ckd_calloc(1, sizeof(cmn_t));
+ cmn->veclen = veclen;
+ cmn->cmn_mean = (mfcc_t *) ckd_calloc(veclen, sizeof(mfcc_t));
+ cmn->cmn_var = (mfcc_t *) ckd_calloc(veclen, sizeof(mfcc_t));
+ cmn->sum = (mfcc_t *) ckd_calloc(veclen, sizeof(mfcc_t));
+ /* A front-end dependent magic number */
+ cmn->cmn_mean[0] = FLOAT2MFCC(12.0);
+ cmn->nframe = 0;
+ E_INFO("mean[0]= %.2f, mean[1..%d]= 0.0\n",
+ MFCC2FLOAT(cmn->cmn_mean[0]), veclen - 1);
+
+ return cmn;
+}
+
+
+void
+cmn(cmn_t *cmn, mfcc_t ** mfc, int32 varnorm, int32 n_frame)
+{
+ mfcc_t *mfcp;
+ mfcc_t t;
+ int32 i, f;
+ int32 n_pos_frame;
+
+ assert(mfc != NULL);
+
+ if (n_frame <= 0)
+ return;
+
+ /* If cmn->cmn_mean wasn't NULL, we need to zero the contents */
+ memset(cmn->cmn_mean, 0, cmn->veclen * sizeof(mfcc_t));
+
+ /* Find mean cep vector for this utterance */
+ for (f = 0, n_pos_frame = 0; f < n_frame; f++) {
+ mfcp = mfc[f];
+
+ /* Skip zero energy frames */
+ if (mfcp[0] < 0)
+ continue;
+
+ for (i = 0; i < cmn->veclen; i++) {
+ cmn->cmn_mean[i] += mfcp[i];
+ }
+
+ n_pos_frame++;
+ }
+
+ for (i = 0; i < cmn->veclen; i++)
+ cmn->cmn_mean[i] /= n_pos_frame;
+
+ E_INFO("CMN: ");
+ for (i = 0; i < cmn->veclen; i++)
+ E_INFOCONT("%5.2f ", MFCC2FLOAT(cmn->cmn_mean[i]));
+ E_INFOCONT("\n");
+ if (!varnorm) {
+ /* Subtract mean from each cep vector */
+ for (f = 0; f < n_frame; f++) {
+ mfcp = mfc[f];
+ for (i = 0; i < cmn->veclen; i++)
+ mfcp[i] -= cmn->cmn_mean[i];
+ }
+ }
+ else {
+ /* Scale cep vectors to have unit variance along each dimension, and subtract means */
+ /* If cmn->cmn_var wasn't NULL, we need to zero the contents */
+ memset(cmn->cmn_var, 0, cmn->veclen * sizeof(mfcc_t));
+
+ for (f = 0; f < n_frame; f++) {
+ mfcp = mfc[f];
+
+ for (i = 0; i < cmn->veclen; i++) {
+ t = mfcp[i] - cmn->cmn_mean[i];
+ cmn->cmn_var[i] += MFCCMUL(t, t);
+ }
+ }
+ for (i = 0; i < cmn->veclen; i++)
+ /* Inverse Std. Dev, RAH added type case from sqrt */
+ cmn->cmn_var[i] = FLOAT2MFCC(sqrt((float64)n_frame / MFCC2FLOAT(cmn->cmn_var[i])));
+
+ for (f = 0; f < n_frame; f++) {
+ mfcp = mfc[f];
+ for (i = 0; i < cmn->veclen; i++)
+ mfcp[i] = MFCCMUL((mfcp[i] - cmn->cmn_mean[i]), cmn->cmn_var[i]);
+ }
+ }
+}
+
+/*
+ * RAH, free previously allocated memory
+ */
+void
+cmn_free(cmn_t * cmn)
+{
+ if (cmn != NULL) {
+ if (cmn->cmn_var)
+ ckd_free((void *) cmn->cmn_var);
+
+ if (cmn->cmn_mean)
+ ckd_free((void *) cmn->cmn_mean);
+
+ if (cmn->sum)
+ ckd_free((void *) cmn->sum);
+
+ ckd_free((void *) cmn);
+ }
+}