PocketSphinx  0.6
src/libpocketsphinx/ps_mllr.c
Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
00002 /* ====================================================================
00003  * Copyright (c) 2009 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 
00042 /* System headers. */
00043 #include <stdio.h>
00044 
00045 /* SphinxBase headers. */
00046 #include <sphinxbase/ckd_alloc.h>
00047 
00048 /* Local headers. */
00049 #include "acmod.h"
00050 
00051 ps_mllr_t *
00052 ps_mllr_read(char const *regmatfile)
00053 {
00054     ps_mllr_t *mllr;
00055     FILE *fp;
00056     int n, i, m, j, k;
00057 
00058     mllr = ckd_calloc(1, sizeof(*mllr));
00059     mllr->refcnt = 1;
00060 
00061     if ((fp = fopen(regmatfile, "r")) == NULL) {
00062         E_ERROR_SYSTEM("Failed to open MLLR file '%s' for reading: %s\n", regmatfile, strerror(errno));
00063         goto error_out;
00064     }
00065     else
00066         E_INFO("Reading MLLR transformation file %s\n", regmatfile);
00067 
00068     if ((fscanf(fp, "%d", &n) != 1) || (n < 1)) {
00069         E_ERROR("Failed to read number of MLLR classes\n");
00070         goto error_out;
00071     }
00072     mllr->n_class = n;
00073 
00074     if ((fscanf(fp, "%d", &n) != 1)) {
00075         E_ERROR("Failed to read number of feature streams\n");
00076         goto error_out;
00077     }
00078     mllr->n_feat = n;
00079     mllr->veclen = ckd_calloc(mllr->n_feat, sizeof(*mllr->veclen));
00080 
00081     mllr->A = (float32 ****) ckd_calloc(mllr->n_feat, sizeof(float32 **));
00082     mllr->b = (float32 ***) ckd_calloc(mllr->n_feat, sizeof(float32 *));
00083     mllr->h = (float32 ***) ckd_calloc(mllr->n_feat, sizeof(float32 *));
00084 
00085     for (i = 0; i < mllr->n_feat; ++i) {
00086         if (fscanf(fp, "%d", &n) != 1) {
00087             E_ERROR("Failed to read stream length for feature %d\n", i);
00088             goto error_out;
00089         }
00090         mllr->veclen[i] = n;
00091         mllr->A[i] =
00092             (float32 ***) ckd_calloc_3d(mllr->n_class, mllr->veclen[i],
00093                                         mllr->veclen[i], sizeof(float32));
00094         mllr->b[i] =
00095             (float32 **) ckd_calloc_2d(mllr->n_class, mllr->veclen[i],
00096                                        sizeof(float32));
00097         mllr->h[i] =
00098             (float32 **) ckd_calloc_2d(mllr->n_class, mllr->veclen[i],
00099                                        sizeof(float32));
00100 
00101         for (m = 0; m < mllr->n_class; ++m) {
00102             for (j = 0; j < mllr->veclen[i]; ++j) {
00103                 for (k = 0; k < mllr->veclen[i]; ++k) {
00104                     if (fscanf(fp, "%f ", &mllr->A[i][m][j][k]) != 1) {
00105                         E_ERROR("Failed reading MLLR rotation (%d,%d,%d,%d)\n",
00106                                 i, m, j, k);
00107                         goto error_out;
00108                     }
00109                 }
00110             }
00111             for (j = 0; j < mllr->veclen[i]; ++j) {
00112                 if (fscanf(fp, "%f ", &mllr->b[i][m][j]) != 1) {
00113                     E_ERROR("Failed reading MLLR bias (%d,%d,%d)\n",
00114                             i, m, j);
00115                     goto error_out;
00116                 }
00117             }
00118             for (j = 0; j < mllr->veclen[i]; ++j) {
00119                 if (fscanf(fp, "%f ", &mllr->h[i][m][j]) != 1) {
00120                     E_ERROR("Failed reading MLLR variance scale (%d,%d,%d)\n",
00121                             i, m, j);
00122                     goto error_out;
00123                 }
00124             }
00125         }
00126     }
00127     fclose(fp);
00128     return mllr;
00129 
00130 error_out:
00131     if (fp)
00132         fclose(fp);
00133     ps_mllr_free(mllr);
00134     return NULL;
00135 }
00136 
00137 ps_mllr_t *
00138 ps_mllr_retain(ps_mllr_t *mllr)
00139 {
00140     ++mllr->refcnt;
00141     return mllr;
00142 }
00143 
00144 int
00145 ps_mllr_free(ps_mllr_t *mllr)
00146 {
00147     int i;
00148 
00149     if (mllr == NULL)
00150         return 0;
00151     if (--mllr->refcnt > 0)
00152         return mllr->refcnt;
00153 
00154     for (i = 0; i < mllr->n_feat; ++i) {
00155         if (mllr->A)
00156             ckd_free_3d(mllr->A[i]);
00157         if (mllr->b)
00158             ckd_free_2d(mllr->b[i]);
00159         if (mllr->h)
00160             ckd_free_2d(mllr->h[i]);
00161     }
00162     ckd_free(mllr->veclen);
00163     ckd_free(mllr->A);
00164     ckd_free(mllr->b);
00165     ckd_free(mllr->h);
00166     ckd_free(mllr);
00167 
00168     return 0;
00169 }