} | } | ||||
espeak_ng_InitializePath(data_path); | espeak_ng_InitializePath(data_path); | ||||
espeak_ng_STATUS result = espeak_ng_Initialize(); | |||||
espeak_ng_ERROR_CONTEXT context = NULL; | |||||
espeak_ng_STATUS result = espeak_ng_Initialize(&context); | |||||
if (result != ENS_OK) { | if (result != ENS_OK) { | ||||
espeak_ng_PrintStatusCodeMessage(result, stderr); | espeak_ng_PrintStatusCodeMessage(result, stderr); | ||||
espeak_ng_ClearErrorContext(&context); | |||||
exit(1); | exit(1); | ||||
} | } | ||||
espeak_ng_InitializePath(const char *path); | espeak_ng_InitializePath(const char *path); | ||||
ESPEAK_NG_API espeak_ng_STATUS | ESPEAK_NG_API espeak_ng_STATUS | ||||
espeak_ng_Initialize(void); | |||||
espeak_ng_Initialize(espeak_ng_ERROR_CONTEXT *context); | |||||
ESPEAK_NG_API espeak_ng_STATUS | ESPEAK_NG_API espeak_ng_STATUS | ||||
espeak_ng_InitializeOutput(espeak_ng_OUTPUT_MODE output_mode, | espeak_ng_InitializeOutput(espeak_ng_OUTPUT_MODE output_mode, |
fclose(f_phtab); | fclose(f_phtab); | ||||
fclose(f_phcontents); | fclose(f_phcontents); | ||||
LoadPhData(NULL); | |||||
LoadPhData(NULL, NULL); | |||||
CompileReport(); | CompileReport(); | ||||
fprintf(log, "Compiled %d intonation tunes: %d errors.\n", n_tune_names, error_count); | fprintf(log, "Compiled %d intonation tunes: %d errors.\n", n_tune_names, error_count); | ||||
LoadPhData(NULL); | |||||
LoadPhData(NULL, NULL); | |||||
return error_count > 0 ? ENS_COMPILE_ERROR : ENS_OK; | return error_count > 0 ? ENS_COMPILE_ERROR : ENS_OK; | ||||
} | } |
{ | { | ||||
if (context) { | if (context) { | ||||
if (*context) { | if (*context) { | ||||
free((*context)->filename); | |||||
free((*context)->path); | |||||
} else { | } else { | ||||
*context = malloc(sizeof(espeak_ng_ERROR_CONTEXT_)); | *context = malloc(sizeof(espeak_ng_ERROR_CONTEXT_)); | ||||
} | } | ||||
(*context)->filename = strdup(filename); | |||||
(*context)->path = strdup(filename); | |||||
(*context)->version = 0; | |||||
(*context)->expected_version = 0; | |||||
} | } | ||||
return status; | return status; | ||||
} | } | ||||
espeak_ng_STATUS create_version_mismatch_error_context(espeak_ng_ERROR_CONTEXT *context, const char *path_home, int version, int expected_version) | |||||
{ | |||||
if (context) { | |||||
if (*context) { | |||||
free((*context)->path); | |||||
} else { | |||||
*context = malloc(sizeof(espeak_ng_ERROR_CONTEXT_)); | |||||
} | |||||
(*context)->path = strdup(path_home); | |||||
(*context)->version = version; | |||||
(*context)->expected_version = expected_version; | |||||
} | |||||
return ENS_VERSION_MISMATCH; | |||||
} | |||||
#pragma GCC visibility push(default) | #pragma GCC visibility push(default) | ||||
ESPEAK_NG_API void espeak_ng_ClearErrorContext(espeak_ng_ERROR_CONTEXT *context) | ESPEAK_NG_API void espeak_ng_ClearErrorContext(espeak_ng_ERROR_CONTEXT *context) | ||||
{ | { | ||||
if (context && *context) { | if (context && *context) { | ||||
free((*context)->filename); | |||||
free((*context)->path); | |||||
free(*context); | free(*context); | ||||
*context = NULL; | *context = NULL; | ||||
} | } |
typedef struct espeak_ng_ERROR_CONTEXT_ | typedef struct espeak_ng_ERROR_CONTEXT_ | ||||
{ | { | ||||
char *filename; | |||||
char *path; | |||||
int version; | |||||
int expected_version; | |||||
} espeak_ng_ERROR_CONTEXT_; | } espeak_ng_ERROR_CONTEXT_; | ||||
espeak_ng_STATUS | espeak_ng_STATUS | ||||
espeak_ng_STATUS status, | espeak_ng_STATUS status, | ||||
const char *filename); | const char *filename); | ||||
espeak_ng_STATUS | |||||
create_version_mismatch_error_context(espeak_ng_ERROR_CONTEXT *context, | |||||
const char *path, | |||||
int version, | |||||
int expected_version); | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
} | } | ||||
#endif | #endif |
ESPEAK_API int espeak_Initialize(espeak_AUDIO_OUTPUT output_type, int buf_length, const char *path, int options) | ESPEAK_API int espeak_Initialize(espeak_AUDIO_OUTPUT output_type, int buf_length, const char *path, int options) | ||||
{ | { | ||||
espeak_ng_InitializePath(path); | espeak_ng_InitializePath(path); | ||||
espeak_ng_STATUS result = espeak_ng_Initialize(); | |||||
espeak_ng_ERROR_CONTEXT context = NULL; | |||||
espeak_ng_STATUS result = espeak_ng_Initialize(&context); | |||||
if (result != ENS_OK) { | if (result != ENS_OK) { | ||||
espeak_ng_PrintStatusCodeMessage(result, stderr); | espeak_ng_PrintStatusCodeMessage(result, stderr); | ||||
espeak_ng_ClearErrorContext(&context); | |||||
if ((options & espeakINITIALIZE_DONT_EXIT) == 0) | if ((options & espeakINITIALIZE_DONT_EXIT) == 0) | ||||
exit(1); | exit(1); | ||||
} | } |
#endif | #endif | ||||
} | } | ||||
ESPEAK_NG_API espeak_ng_STATUS espeak_ng_Initialize(void) | |||||
ESPEAK_NG_API espeak_ng_STATUS espeak_ng_Initialize(espeak_ng_ERROR_CONTEXT *context) | |||||
{ | { | ||||
int param; | int param; | ||||
int srate = 22050; // default sample rate 22050 Hz | int srate = 22050; // default sample rate 22050 Hz | ||||
} | } | ||||
} | } | ||||
espeak_ng_STATUS result = LoadPhData(&srate); | |||||
espeak_ng_STATUS result = LoadPhData(&srate, context); | |||||
if (result != ENS_OK) | if (result != ENS_OK) | ||||
return result; | return result; | ||||
#include "espeak_ng.h" | #include "espeak_ng.h" | ||||
#include "speak_lib.h" | #include "speak_lib.h" | ||||
#include "error.h" | |||||
#include "speech.h" | #include "speech.h" | ||||
#include "phoneme.h" | #include "phoneme.h" | ||||
#include "synthesize.h" | #include "synthesize.h" | ||||
int FormantTransition2(frameref_t *seq, int *n_frames, unsigned int data1, unsigned int data2, PHONEME_TAB *other_ph, int which); | int FormantTransition2(frameref_t *seq, int *n_frames, unsigned int data1, unsigned int data2, PHONEME_TAB *other_ph, int which); | ||||
static espeak_ng_STATUS ReadPhFile(void **ptr, const char *fname, int *size) | |||||
static espeak_ng_STATUS ReadPhFile(void **ptr, const char *fname, int *size, espeak_ng_ERROR_CONTEXT *context) | |||||
{ | { | ||||
if (!ptr) return EINVAL; | if (!ptr) return EINVAL; | ||||
sprintf(buf, "%s%c%s", path_home, PATHSEP, fname); | sprintf(buf, "%s%c%s", path_home, PATHSEP, fname); | ||||
length = GetFileLength(buf); | length = GetFileLength(buf); | ||||
if ((f_in = fopen(buf, "rb")) == NULL) { | |||||
fprintf(stderr, "Can't read data file: '%s'\n", buf); | |||||
return errno; | |||||
} | |||||
if ((f_in = fopen(buf, "rb")) == NULL) | |||||
return create_file_error_context(context, errno, buf); | |||||
if (*ptr != NULL) | if (*ptr != NULL) | ||||
Free(*ptr); | Free(*ptr); | ||||
int error = errno; | int error = errno; | ||||
fclose(f_in); | fclose(f_in); | ||||
Free(*ptr); | Free(*ptr); | ||||
return error; | |||||
return create_file_error_context(context, error, buf); | |||||
} | } | ||||
fclose(f_in); | fclose(f_in); | ||||
return ENS_OK; | return ENS_OK; | ||||
} | } | ||||
espeak_ng_STATUS LoadPhData(int *srate) | |||||
espeak_ng_STATUS LoadPhData(int *srate, espeak_ng_ERROR_CONTEXT *context) | |||||
{ | { | ||||
int ix; | int ix; | ||||
int n_phonemes; | int n_phonemes; | ||||
int *pw; | int *pw; | ||||
espeak_ng_STATUS status; | espeak_ng_STATUS status; | ||||
if ((status = ReadPhFile((void **)&phoneme_tab_data, "phontab", NULL)) != ENS_OK) | |||||
if ((status = ReadPhFile((void **)&phoneme_tab_data, "phontab", NULL, context)) != ENS_OK) | |||||
return status; | return status; | ||||
if ((status = ReadPhFile((void **)&phoneme_index, "phonindex", NULL)) != ENS_OK) | |||||
if ((status = ReadPhFile((void **)&phoneme_index, "phonindex", NULL, context)) != ENS_OK) | |||||
return status; | return status; | ||||
if ((status = ReadPhFile((void **)&phondata_ptr, "phondata", NULL)) != ENS_OK) | |||||
if ((status = ReadPhFile((void **)&phondata_ptr, "phondata", NULL, context)) != ENS_OK) | |||||
return status; | return status; | ||||
if ((status = ReadPhFile((void **)&tunes, "intonations", &length)) != ENS_OK) | |||||
if ((status = ReadPhFile((void **)&tunes, "intonations", &length, context)) != ENS_OK) | |||||
return status; | return status; | ||||
wavefile_data = (unsigned char *)phondata_ptr; | wavefile_data = (unsigned char *)phondata_ptr; | ||||
n_tunes = length / sizeof(TUNE); | n_tunes = length / sizeof(TUNE); | ||||
} | } | ||||
if (version != version_phdata) | if (version != version_phdata) | ||||
return ENS_VERSION_MISMATCH; | |||||
return create_version_mismatch_error_context(context, path_home, version, version_phdata); | |||||
// set up phoneme tables | // set up phoneme tables | ||||
p = phoneme_tab_data; | p = phoneme_tab_data; |
frameref_t *LookupSpect(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, int *n_frames, PHONEME_LIST *plist); | frameref_t *LookupSpect(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, int *n_frames, PHONEME_LIST *plist); | ||||
unsigned char *LookupEnvelope(int ix); | unsigned char *LookupEnvelope(int ix); | ||||
espeak_ng_STATUS LoadPhData(int *srate); | |||||
espeak_ng_STATUS LoadPhData(int *srate, espeak_ng_ERROR_CONTEXT *context); | |||||
void SynthesizeInit(void); | void SynthesizeInit(void); | ||||
int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume); | int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume); |
} | } | ||||
espeak_ng_InitializePath(data_path); | espeak_ng_InitializePath(data_path); | ||||
espeak_ng_STATUS result = espeak_ng_Initialize(); | |||||
espeak_ng_ERROR_CONTEXT context = NULL; | |||||
espeak_ng_STATUS result = espeak_ng_Initialize(&context); | |||||
if (result != ENS_OK) { | if (result != ENS_OK) { | ||||
espeak_ng_PrintStatusCodeMessage(result, stderr); | espeak_ng_PrintStatusCodeMessage(result, stderr); | ||||
espeak_ng_ClearErrorContext(&context); | |||||
exit(1); | exit(1); | ||||
} | } | ||||