flightgear/3rdparty/hts_engine_API/lib/HTS_label.c
2022-10-20 20:29:11 +08:00

264 lines
8.9 KiB
C

/* ----------------------------------------------------------------- */
/* The HMM-Based Speech Synthesis Engine "hts_engine API" */
/* developed by HTS Working Group */
/* http://hts-engine.sourceforge.net/ */
/* ----------------------------------------------------------------- */
/* */
/* Copyright (c) 2001-2015 Nagoya Institute of Technology */
/* Department of Computer Science */
/* */
/* 2001-2008 Tokyo Institute of Technology */
/* Interdisciplinary Graduate School of */
/* Science and Engineering */
/* */
/* All rights reserved. */
/* */
/* Redistribution and use in source and binary forms, with or */
/* without modification, are permitted provided that the following */
/* conditions are met: */
/* */
/* - Redistributions of source code must retain the above copyright */
/* notice, this list of conditions and the following disclaimer. */
/* - 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. */
/* - Neither the name of the HTS working group nor the names of its */
/* contributors may be used to endorse or promote products derived */
/* from this software without specific prior written permission. */
/* */
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND */
/* CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT OWNER OR CONTRIBUTORS */
/* 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. */
/* ----------------------------------------------------------------- */
#ifndef HTS_LABEL_C
#define HTS_LABEL_C
#ifdef __cplusplus
#define HTS_LABEL_C_START extern "C" {
#define HTS_LABEL_C_END }
#else
#define HTS_LABEL_C_START
#define HTS_LABEL_C_END
#endif /* __CPLUSPLUS */
HTS_LABEL_C_START;
#include <stdlib.h> /* for atof() */
#include <ctype.h> /* for isgraph(),isdigit() */
/* hts_engine libraries */
#include "HTS_hidden.h"
static HTS_Boolean isdigit_string(char *str)
{
int i;
if (sscanf(str, "%d", &i) == 1)
return TRUE;
else
return FALSE;
}
/* HTS_Label_initialize: initialize label */
void HTS_Label_initialize(HTS_Label * label)
{
label->head = NULL;
label->size = 0;
}
/* HTS_Label_check_time: check label */
static void HTS_Label_check_time(HTS_Label * label)
{
HTS_LabelString *lstring = label->head;
HTS_LabelString *next = NULL;
if (lstring)
lstring->start = 0.0;
while (lstring) {
next = lstring->next;
if (!next)
break;
if (lstring->end < 0.0 && next->start >= 0.0)
lstring->end = next->start;
else if (lstring->end >= 0.0 && next->start < 0.0)
next->start = lstring->end;
if (lstring->start < 0.0)
lstring->start = -1.0;
if (lstring->end < 0.0)
lstring->end = -1.0;
lstring = next;
}
}
/* HTS_Label_load: load label */
static void HTS_Label_load(HTS_Label * label, size_t sampling_rate, size_t fperiod, HTS_File * fp)
{
char buff[HTS_MAXBUFLEN];
HTS_LabelString *lstring = NULL;
double start, end;
const double rate = (double) sampling_rate / ((double) fperiod * 1e+7);
if (label->head || label->size != 0) {
HTS_error(1, "HTS_Label_load_from_fp: label is not initialized.\n");
return;
}
/* parse label file */
while (HTS_get_token_from_fp(fp, buff)) {
if (!isgraph((int) buff[0]))
break;
label->size++;
if (lstring) {
lstring->next = (HTS_LabelString *) HTS_calloc(1, sizeof(HTS_LabelString));
lstring = lstring->next;
} else { /* first time */
lstring = (HTS_LabelString *) HTS_calloc(1, sizeof(HTS_LabelString));
label->head = lstring;
}
if (isdigit_string(buff)) { /* has frame infomation */
start = atof(buff);
HTS_get_token_from_fp(fp, buff);
end = atof(buff);
HTS_get_token_from_fp(fp, buff);
lstring->start = rate * start;
lstring->end = rate * end;
} else {
lstring->start = -1.0;
lstring->end = -1.0;
}
lstring->next = NULL;
lstring->name = HTS_strdup(buff);
}
HTS_Label_check_time(label);
}
/* HTS_Label_load_from_fn: load label from file name */
void HTS_Label_load_from_fn(HTS_Label * label, size_t sampling_rate, size_t fperiod, const char *fn)
{
HTS_File *fp = HTS_fopen_from_fn(fn, "r");
HTS_Label_load(label, sampling_rate, fperiod, fp);
HTS_fclose(fp);
}
/* HTS_Label_load_from_strings: load label from strings */
void HTS_Label_load_from_strings(HTS_Label * label, size_t sampling_rate, size_t fperiod, char **lines, size_t num_lines)
{
char buff[HTS_MAXBUFLEN];
HTS_LabelString *lstring = NULL;
size_t i;
size_t data_index;
double start, end;
const double rate = (double) sampling_rate / ((double) fperiod * 1e+7);
if (label->head || label->size != 0) {
HTS_error(1, "HTS_Label_load_from_fp: label list is not initialized.\n");
return;
}
/* copy label */
for (i = 0; i < num_lines; i++) {
if (!isgraph((int) lines[i][0]))
break;
label->size++;
if (lstring) {
lstring->next = (HTS_LabelString *) HTS_calloc(1, sizeof(HTS_LabelString));
lstring = lstring->next;
} else { /* first time */
lstring = (HTS_LabelString *) HTS_calloc(1, sizeof(HTS_LabelString));
label->head = lstring;
}
data_index = 0;
if (isdigit_string(lines[i])) { /* has frame infomation */
HTS_get_token_from_string(lines[i], &data_index, buff);
start = atof(buff);
HTS_get_token_from_string(lines[i], &data_index, buff);
end = atof(buff);
HTS_get_token_from_string(lines[i], &data_index, buff);
lstring->name = HTS_strdup(buff);
lstring->start = rate * start;
lstring->end = rate * end;
} else {
lstring->start = -1.0;
lstring->end = -1.0;
lstring->name = HTS_strdup(lines[i]);
}
lstring->next = NULL;
}
HTS_Label_check_time(label);
}
/* HTS_Label_get_size: get number of label string */
size_t HTS_Label_get_size(HTS_Label * label)
{
return label->size;
}
/* HTS_Label_get_string: get label string */
const char *HTS_Label_get_string(HTS_Label * label, size_t index)
{
size_t i;
HTS_LabelString *lstring = label->head;
for (i = 0; i < index && lstring; i++)
lstring = lstring->next;
if (!lstring)
return NULL;
return lstring->name;
}
/* HTS_Label_get_start_frame: get start frame */
double HTS_Label_get_start_frame(HTS_Label * label, size_t index)
{
size_t i;
HTS_LabelString *lstring = label->head;
for (i = 0; i < index && lstring; i++)
lstring = lstring->next;
if (!lstring)
return -1.0;
return lstring->start;
}
/* HTS_Label_get_end_frame: get end frame */
double HTS_Label_get_end_frame(HTS_Label * label, size_t index)
{
size_t i;
HTS_LabelString *lstring = label->head;
for (i = 0; i < index && lstring; i++)
lstring = lstring->next;
if (!lstring)
return -1.0;
return lstring->end;
}
/* HTS_Label_clear: free label */
void HTS_Label_clear(HTS_Label * label)
{
HTS_LabelString *lstring, *next_lstring;
for (lstring = label->head; lstring; lstring = next_lstring) {
next_lstring = lstring->next;
HTS_free(lstring->name);
HTS_free(lstring);
}
HTS_Label_initialize(label);
}
HTS_LABEL_C_END;
#endif /* !HTS_LABEL_C */