⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kdtree.c

📁 WinCE平台上的语音识别程序
💻 C
字号:
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- *//* ==================================================================== * Copyright (c) 2005 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. * * ==================================================================== * *//********************************************************************* * * File: kdtree.c *  * Description:  * 	Implement kd-trees using the BBI algorithm as detailed in * 	J. Frisch and I. Rogina, "The Bucket Box Intersection * 	Algorithm for fast approximate evaluation of Diagonal Mixture * 	Gaussians", Proceedings of ICASSP 1996. * * Author:  * 	David Huggins-Daines <dhuggins@cs.cmu.edu> *********************************************************************/#include <stdio.h>#include <assert.h>#include <string.h>#include <sphinx_config.h>#include "kdtree.h"#include "err.h"#include "ckd_alloc.h"#include "s2_semi_mgau.h"#define KDTREE_VERSION 1static int32read_tree_int(FILE * fp, const char *name, int32 * out, int32 optional){    char line[256];    int n;    n = fscanf(fp, "%255s %d", line, out);    if ((optional == 0 && n != 2) || strcmp(line, name)) {        E_ERROR("%s not found: %d %s %d\n", name, n, line, out);        return -1;    }    return n;}static int32read_tree_float(FILE * fp, const char *name, float32 * out, int32 optional){    char line[256];    int n;    n = fscanf(fp, "%255s %f", line, out);    if ((optional == 0 && n != 2) || strcmp(line, name)) {        E_ERROR("%s not found: %d %s %f\n", name, n, line, out);        return -1;    }    return n;}static int32read_bbi_list(FILE * fp, kd_tree_node_t * node, int32 maxbbi){    uint8 bbi_list[256];    int bbi, nbbi = 0, nr;    if (maxbbi == -1)        maxbbi = 256;    if ((nr = read_tree_int(fp, "bbi", &bbi, TRUE)) < 0)        return -1;    if (nr > 1) {        if (bbi >= 256) {            E_ERROR("BBI Gaussian %d out of range! %d\n", bbi);            return -1;        }        bbi_list[0] = bbi;        nbbi = 1;        while (fscanf(fp, "%d", &bbi)) {            if (feof(fp))                break;            if (bbi >= 256) {                E_ERROR("BBI Gaussian %d out of range!\n", bbi);                return -1;            }            if (nbbi < maxbbi)                bbi_list[nbbi++] = bbi;        }    }    if (node == NULL)        return 0;    if (nbbi > maxbbi)        nbbi = maxbbi;    node->n_bbi = nbbi;    if (nbbi) {        node->bbi = ckd_calloc(node->n_bbi, sizeof(*node->bbi));        memcpy(node->bbi, bbi_list, node->n_bbi * sizeof(*node->bbi));    }    return 0;}static int32read_kd_nodes(FILE * fp, kd_tree_t * tree, uint32 maxdepth, int32 maxbbi){    uint32 i, j, in, out;    int32 ilevel, olevel;    /* Balanced binary trees, so we have 2^nlevels-1 nodes. */    if (maxdepth == 0 || maxdepth > tree->n_level)        maxdepth = tree->n_level;    in = (1 << tree->n_level) - 1;    out = (1 << maxdepth) - 1;    tree->nodes = ckd_calloc(out, sizeof(kd_tree_node_t));    /* Nodes are read in depth-first ordering. */    for (j = i = 0; i < in; ++i) {        float32 split_plane;        int32 split_comp;        if (read_tree_int(fp, "NODE", &ilevel, FALSE) < 0)            break;        if (read_tree_int(fp, "split_comp", &split_comp, FALSE) < 0)            return -1;        if (read_tree_float(fp, "split_plane", &split_plane, FALSE) < 0)            return -1;        olevel = ilevel - (tree->n_level - maxdepth);        if (olevel > 0) {            /* Only create a node if we are above maxdepth */            assert(j < out);            tree->nodes[j].split_comp = split_comp;            tree->nodes[j].split_plane = FLOAT2MFCC(split_plane);            /* We only need the BBI list for leafnodes now. */            if (olevel == 1) {                if (read_bbi_list(fp, tree->nodes + j, maxbbi) < 0)                    return -1;            }            else {                if (read_bbi_list(fp, NULL, 0) < 0)                    return -1;            }            /* They are also full trees, hence: */            if (olevel > 1) {                tree->nodes[j].left = j + 1;                tree->nodes[j].right = j + (1 << (olevel - 1));            }            ++j;        }        else {                  /* Have to read the BBI list anyway. */            if (read_bbi_list(fp, NULL, 0) < 0)                return -1;        }    }    E_INFO("Read %d nodes\n", j);    return 0;}int32read_kd_trees(const char *infile, kd_tree_t *** out_trees,              uint32 * out_n_trees, uint32 maxdepth, int32 maxbbi){    FILE *fp;    char line[256];    int n, version;    uint32 i;    if ((fp = fopen(infile, "r")) == NULL) {        E_ERROR("Failed to open %s", infile);        return -1;    }    n = fscanf(fp, "%256s", line);    if (n != 1 || strcmp(line, "KD-TREES")) {        E_ERROR("%s doesn't appear to be a kd-tree file: %s\n",                infile, line);        return -1;    }    n = fscanf(fp, "%256s %d", line, &version);    if (n != 2 || strcmp(line, "version") || version > KDTREE_VERSION) {        E_ERROR("Unsupported kd-tree file format %s %d\n", line, version);        return -1;    }    if (read_tree_int(fp, "n_trees", out_n_trees, FALSE) < 0)        return -1;    *out_trees = ckd_calloc(*out_n_trees, sizeof(kd_tree_t **));    for (i = 0; i < *out_n_trees; ++i) {        kd_tree_t *tree;        uint32 n_density;        float32 threshold;        if (read_tree_int(fp, "TREE", &n, FALSE) < 0)            goto error_out;        if (n != i) {            E_ERROR("Tree number %d out of sequence\n", n);            goto error_out;        }        E_INFO("Reading tree for feature %d\n", i);        (*out_trees)[i] = tree = ckd_calloc(1, sizeof(*tree));        if (read_tree_int(fp, "n_density", &n_density, FALSE) < 0)            goto error_out;        if (n_density > 256) {            E_ERROR("Number of densities (%d) must be <= 256!\n", n_density);            goto error_out;        }        if (read_tree_int(fp, "n_comp", &tree->n_comp, FALSE) < 0)            goto error_out;        if (read_tree_int(fp, "n_level", &tree->n_level, FALSE) < 0)            goto error_out;        if (tree->n_level > 16) {            E_ERROR("Depth of tree (%d) must be < 16!\n", tree->n_level);            goto error_out;        }        if (read_tree_float(fp, "threshold", &threshold, FALSE) < 0)            goto error_out;        E_INFO("n_density %d n_comp %d n_level %d threshold %f\n",               n_density, tree->n_comp, tree->n_level, threshold);        if (read_kd_nodes(fp, tree, maxdepth, maxbbi) < 0)            goto error_out;        if (maxdepth)            tree->n_level = maxdepth;    }    fclose(fp);    return 0;  error_out:    fclose(fp);    for (i = 0; i < *out_n_trees; ++i) {        free_kd_tree((*out_trees)[i]);        (*out_trees)[i] = NULL;    }    ckd_free(*out_trees);    *out_trees = NULL;    return -1;}voidfree_kd_tree(kd_tree_t * tree){    uint32 i, n;    if (tree == NULL)        return;    /* Balanced binary trees, so we have 2^level-1 nodes. */    n = (1 << tree->n_level) - 1;    for (i = 0; i < n; ++i)        ckd_free(tree->nodes[n].bbi);    ckd_free(tree->nodes);    ckd_free(tree);}kd_tree_node_t *eval_kd_tree(kd_tree_t * tree, mfcc_t * feat, uint32 maxdepth){    uint32 node;    node = 0;                   /* Root of tree. */    while (tree->nodes[node].left && --maxdepth > 0) {        if (feat[tree->nodes[node].split_comp]            < tree->nodes[node].split_plane)            node = tree->nodes[node].left;        else            node = tree->nodes[node].right;    }    return tree->nodes + node;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -