| @@ -588,9 +588,11 @@ int main(int argc, char **argv) | |||
| } | |||
| 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) { | |||
| espeak_ng_PrintStatusCodeMessage(result, stderr); | |||
| espeak_ng_ClearErrorContext(&context); | |||
| exit(1); | |||
| } | |||
| @@ -75,7 +75,7 @@ ESPEAK_NG_API void | |||
| espeak_ng_InitializePath(const char *path); | |||
| 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_InitializeOutput(espeak_ng_OUTPUT_MODE output_mode, | |||
| @@ -2725,7 +2725,7 @@ static espeak_ng_STATUS CompilePhonemeData2(const char *source, FILE *log) | |||
| fclose(f_phtab); | |||
| fclose(f_phcontents); | |||
| LoadPhData(NULL); | |||
| LoadPhData(NULL, NULL); | |||
| CompileReport(); | |||
| @@ -3029,7 +3029,7 @@ espeak_ng_STATUS espeak_ng_CompileIntonation(FILE *log) | |||
| 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; | |||
| } | |||
| @@ -37,21 +37,38 @@ espeak_ng_STATUS create_file_error_context(espeak_ng_ERROR_CONTEXT *context, esp | |||
| { | |||
| if (context) { | |||
| if (*context) { | |||
| free((*context)->filename); | |||
| free((*context)->path); | |||
| } else { | |||
| *context = malloc(sizeof(espeak_ng_ERROR_CONTEXT_)); | |||
| } | |||
| (*context)->filename = strdup(filename); | |||
| (*context)->path = strdup(filename); | |||
| (*context)->version = 0; | |||
| (*context)->expected_version = 0; | |||
| } | |||
| 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) | |||
| ESPEAK_NG_API void espeak_ng_ClearErrorContext(espeak_ng_ERROR_CONTEXT *context) | |||
| { | |||
| if (context && *context) { | |||
| free((*context)->filename); | |||
| free((*context)->path); | |||
| free(*context); | |||
| *context = NULL; | |||
| } | |||
| @@ -25,7 +25,9 @@ extern "C" | |||
| typedef struct espeak_ng_ERROR_CONTEXT_ | |||
| { | |||
| char *filename; | |||
| char *path; | |||
| int version; | |||
| int expected_version; | |||
| } espeak_ng_ERROR_CONTEXT_; | |||
| espeak_ng_STATUS | |||
| @@ -33,6 +35,12 @@ create_file_error_context(espeak_ng_ERROR_CONTEXT *context, | |||
| espeak_ng_STATUS status, | |||
| 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 | |||
| } | |||
| #endif | |||
| @@ -53,9 +53,11 @@ static espeak_ERROR status_to_espeak_error(espeak_ng_STATUS status) | |||
| ESPEAK_API int espeak_Initialize(espeak_AUDIO_OUTPUT output_type, int buf_length, const char *path, int options) | |||
| { | |||
| 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) { | |||
| espeak_ng_PrintStatusCodeMessage(result, stderr); | |||
| espeak_ng_ClearErrorContext(&context); | |||
| if ((options & espeakINITIALIZE_DONT_EXIT) == 0) | |||
| exit(1); | |||
| } | |||
| @@ -313,7 +313,7 @@ ESPEAK_NG_API void espeak_ng_InitializePath(const char *path) | |||
| #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 srate = 22050; // default sample rate 22050 Hz | |||
| @@ -328,7 +328,7 @@ ESPEAK_NG_API espeak_ng_STATUS espeak_ng_Initialize(void) | |||
| } | |||
| } | |||
| espeak_ng_STATUS result = LoadPhData(&srate); | |||
| espeak_ng_STATUS result = LoadPhData(&srate, context); | |||
| if (result != ENS_OK) | |||
| return result; | |||
| @@ -33,6 +33,7 @@ | |||
| #include "espeak_ng.h" | |||
| #include "speak_lib.h" | |||
| #include "error.h" | |||
| #include "speech.h" | |||
| #include "phoneme.h" | |||
| #include "synthesize.h" | |||
| @@ -72,7 +73,7 @@ int vowel_transition1; | |||
| 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; | |||
| @@ -83,10 +84,8 @@ static espeak_ng_STATUS ReadPhFile(void **ptr, const char *fname, int *size) | |||
| sprintf(buf, "%s%c%s", path_home, PATHSEP, fname); | |||
| 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) | |||
| Free(*ptr); | |||
| @@ -99,7 +98,7 @@ static espeak_ng_STATUS ReadPhFile(void **ptr, const char *fname, int *size) | |||
| int error = errno; | |||
| fclose(f_in); | |||
| Free(*ptr); | |||
| return error; | |||
| return create_file_error_context(context, error, buf); | |||
| } | |||
| fclose(f_in); | |||
| @@ -108,7 +107,7 @@ static espeak_ng_STATUS ReadPhFile(void **ptr, const char *fname, int *size) | |||
| return ENS_OK; | |||
| } | |||
| espeak_ng_STATUS LoadPhData(int *srate) | |||
| espeak_ng_STATUS LoadPhData(int *srate, espeak_ng_ERROR_CONTEXT *context) | |||
| { | |||
| int ix; | |||
| int n_phonemes; | |||
| @@ -119,13 +118,13 @@ espeak_ng_STATUS LoadPhData(int *srate) | |||
| int *pw; | |||
| 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; | |||
| if ((status = ReadPhFile((void **)&phoneme_index, "phonindex", NULL)) != ENS_OK) | |||
| if ((status = ReadPhFile((void **)&phoneme_index, "phonindex", NULL, context)) != ENS_OK) | |||
| 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; | |||
| if ((status = ReadPhFile((void **)&tunes, "intonations", &length)) != ENS_OK) | |||
| if ((status = ReadPhFile((void **)&tunes, "intonations", &length, context)) != ENS_OK) | |||
| return status; | |||
| wavefile_data = (unsigned char *)phondata_ptr; | |||
| n_tunes = length / sizeof(TUNE); | |||
| @@ -139,7 +138,7 @@ espeak_ng_STATUS LoadPhData(int *srate) | |||
| } | |||
| if (version != version_phdata) | |||
| return ENS_VERSION_MISMATCH; | |||
| return create_version_mismatch_error_context(context, path_home, version, version_phdata); | |||
| // set up phoneme tables | |||
| p = phoneme_tab_data; | |||
| @@ -499,7 +499,7 @@ unsigned int LookupSound(PHONEME_TAB *ph1, PHONEME_TAB *ph2, int which, int *mat | |||
| frameref_t *LookupSpect(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, int *n_frames, PHONEME_LIST *plist); | |||
| 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); | |||
| int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume); | |||
| @@ -575,9 +575,11 @@ int main(int argc, char **argv) | |||
| } | |||
| 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) { | |||
| espeak_ng_PrintStatusCodeMessage(result, stderr); | |||
| espeak_ng_ClearErrorContext(&context); | |||
| exit(1); | |||
| } | |||