1 /* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* ====================================================================
3 * Copyright (c) 2006 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 * ====================================================================
37 /*********************************************************************
42 * Allows a caller to choose a warping function.
43 *********************************************************************/
45 /* static char rcsid[] = "@(#)$Id: fe_warp.c,v 1.2 2006/02/17 00:31:34 egouvea Exp $";*/
47 #include "fe_warp_inverse_linear.h"
48 #include "fe_warp_affine.h"
49 #include "fe_warp_piecewise_linear.h"
52 #include "sphinxbase/err.h"
59 /* This is for aliases for each of the entries below. Currently not
62 static char *__name2id[] = {
69 static char *name2id[] = {
76 static fe_warp_conf_t fe_warp_conf[FE_WARP_ID_MAX + 1] = {
77 {fe_warp_inverse_linear_set_parameters,
78 fe_warp_inverse_linear_doc,
79 fe_warp_inverse_linear_id,
80 fe_warp_inverse_linear_n_param,
81 fe_warp_inverse_linear_warped_to_unwarped,
82 fe_warp_inverse_linear_unwarped_to_warped,
83 fe_warp_inverse_linear_print}, /* Inverse linear warping */
84 {fe_warp_affine_set_parameters,
87 fe_warp_affine_n_param,
88 fe_warp_affine_warped_to_unwarped,
89 fe_warp_affine_unwarped_to_warped,
90 fe_warp_affine_print}, /* Affine warping */
91 {fe_warp_piecewise_linear_set_parameters,
92 fe_warp_piecewise_linear_doc,
93 fe_warp_piecewise_linear_id,
94 fe_warp_piecewise_linear_n_param,
95 fe_warp_piecewise_linear_warped_to_unwarped,
96 fe_warp_piecewise_linear_unwarped_to_warped,
97 fe_warp_piecewise_linear_print}, /* Piecewise_Linear warping */
101 fe_warp_set(melfb_t *mel, const char *id_name)
105 for (i = 0; name2id[i]; i++) {
106 if (strcmp(id_name, name2id[i]) == 0) {
112 if (name2id[i] == NULL) {
113 for (i = 0; __name2id[i]; i++) {
114 if (strcmp(id_name, __name2id[i]) == 0) {
119 if (__name2id[i] == NULL) {
120 E_ERROR("Unimplemented warping function %s\n", id_name);
121 E_ERROR("Implemented functions are:\n");
122 for (i = 0; name2id[i]; i++) {
123 fprintf(stderr, "\t%s\n", name2id[i]);
125 mel->warp_id = FE_WARP_ID_NONE;
127 return FE_START_ERROR;
135 fe_warp_set_parameters(melfb_t *mel, char const *param_str, float sampling_rate)
137 if (mel->warp_id <= FE_WARP_ID_MAX) {
138 fe_warp_conf[mel->warp_id].set_parameters(param_str, sampling_rate);
140 else if (mel->warp_id == FE_WARP_ID_NONE) {
141 E_FATAL("feat module must be configured w/ a valid ID\n");
145 ("fe_warp module misconfigured with invalid fe_warp_id %u\n",
151 fe_warp_doc(melfb_t *mel)
153 if (mel->warp_id <= FE_WARP_ID_MAX) {
154 return fe_warp_conf[mel->warp_id].doc();
156 else if (mel->warp_id == FE_WARP_ID_NONE) {
157 E_FATAL("fe_warp module must be configured w/ a valid ID\n");
161 ("fe_warp module misconfigured with invalid fe_warp_id %u\n",
169 fe_warp_id(melfb_t *mel)
171 if (mel->warp_id <= FE_WARP_ID_MAX) {
172 assert(mel->warp_id == fe_warp_conf[mel->warp_id].id());
175 else if (mel->warp_id != FE_WARP_ID_NONE) {
177 ("fe_warp module misconfigured with invalid fe_warp_id %u\n",
181 return FE_WARP_ID_NONE;
185 fe_warp_n_param(melfb_t *mel)
187 if (mel->warp_id <= FE_WARP_ID_MAX) {
188 return fe_warp_conf[mel->warp_id].n_param();
190 else if (mel->warp_id == FE_WARP_ID_NONE) {
191 E_FATAL("fe_warp module must be configured w/ a valid ID\n");
195 ("fe_warp module misconfigured with invalid fe_warp_id %u\n",
203 fe_warp_warped_to_unwarped(melfb_t *mel, float nonlinear)
205 if (mel->warp_id <= FE_WARP_ID_MAX) {
206 return fe_warp_conf[mel->warp_id].warped_to_unwarped(nonlinear);
208 else if (mel->warp_id == FE_WARP_ID_NONE) {
209 E_FATAL("fe_warp module must be configured w/ a valid ID\n");
213 ("fe_warp module misconfigured with invalid fe_warp_id %u\n",
221 fe_warp_unwarped_to_warped(melfb_t *mel,float linear)
223 if (mel->warp_id <= FE_WARP_ID_MAX) {
224 return fe_warp_conf[mel->warp_id].unwarped_to_warped(linear);
226 else if (mel->warp_id == FE_WARP_ID_NONE) {
227 E_FATAL("fe_warp module must be configured w/ a valid ID\n");
231 ("fe_warp module misconfigured with invalid fe_warp_id %u\n",
239 fe_warp_print(melfb_t *mel, const char *label)
241 if (mel->warp_id <= FE_WARP_ID_MAX) {
242 fe_warp_conf[mel->warp_id].print(label);
244 else if (mel->warp_id == FE_WARP_ID_NONE) {
245 E_FATAL("fe_warp module must be configured w/ a valid ID\n");
249 ("fe_warp module misconfigured with invalid fe_warp_id %u\n",
255 * Log record. Maintained by RCS.
257 * $Log: fe_warp.c,v $
258 * Revision 1.2 2006/02/17 00:31:34 egouvea
259 * Removed switch -melwarp. Changed the default for window length to
260 * 0.025625 from 0.256 (so that a window at 16kHz sampling rate has
261 * exactly 410 samples). Cleaned up include's. Replaced some E_FATAL()
262 * with E_WARN() and return.
264 * Revision 1.1 2006/02/16 00:18:26 egouvea
265 * Implemented flexible warping function. The user can specify at run
266 * time which of several shapes they want to use. Currently implemented
267 * are an affine function (y = ax + b), an inverse linear (y = a/x) and a
268 * piecewise linear (y = ax, up to a frequency F, and then it "breaks" so
269 * Nyquist frequency matches in both scales.
271 * Added two switches, -warp_type and -warp_params. The first specifies
272 * the type, which valid values:
274 * -inverse or inverse_linear
276 * -piecewise or piecewise_linear
278 * The inverse_linear is the same as implemented by EHT. The -mel_warp
279 * switch was kept for compatibility (maybe remove it in the
280 * future?). The code is compatible with EHT's changes: cepstra created
281 * from code after his changes should be the same as now. Scripts that
282 * worked with his changes should work now without changes. Tested a few
283 * cases, same results.