From 2a6d92971d857c5b4d1e974cafc7082679043de0 Mon Sep 17 00:00:00 2001 From: Sergio Oller Date: Tue, 31 Oct 2017 19:58:41 +0100 Subject: [PATCH 1/2] Add mimic_context structure It replaces the mimic_plugins, mimic_voice_list and mimic_lang_list global variables, so the mimic library can be used simultaneously and independently. Work is still needed to deal with other global variables --- include/cst_cg.h | 4 +- include/cst_plugins.h | 21 ++-- include/mimic.h | 39 ++++-- main/mimic_main.c | 38 +++--- main/mimicvox_info_main.c | 6 +- main/t2p_main.c | 10 +- src/cg/cst_cg_load_voice.c | 17 ++- src/synth/cst_ssml.c | 25 ++-- src/synth/mimic.c | 241 +++++++++++++++++++++++++------------ src/utils/cst_plugins.c | 43 +++---- unittests/wave_test_main.c | 3 - 11 files changed, 275 insertions(+), 172 deletions(-) diff --git a/include/cst_cg.h b/include/cst_cg.h index 6ab3a7a..d5d7157 100644 --- a/include/cst_cg.h +++ b/include/cst_cg.h @@ -53,6 +53,7 @@ #include "cst_wave.h" #include "cst_audio.h" #include "cst_synth.h" /* for dur_stat */ +#include "mimic.h" typedef struct cst_cg_db_struct { /* Please do not change this structure, but if you do only add things @@ -135,8 +136,7 @@ cst_wave *mlsa_resynthesis(const cst_track *t, cst_audio_streaming_info *asc); cst_track *mlpg(const cst_track *param_track, cst_cg_db *cg_db); -cst_voice *cst_cg_load_voice(const char *voxdir, - const cst_lang lang_table[]); +cst_voice *cst_cg_load_voice(mimic_context *ctx, const char *voxdir); int cst_cg_dump_voice(const cst_voice *v, const cst_string *filename); #endif diff --git a/include/cst_plugins.h b/include/cst_plugins.h index b8e2a0c..8ef593d 100644 --- a/include/cst_plugins.h +++ b/include/cst_plugins.h @@ -37,29 +37,32 @@ #ifndef include_cst_plugins_h #define include_cst_plugins_h #include "mimic_core_config.h" + +struct mimic_context_s; +typedef struct mimic_context_s mimic_context; + #ifdef MIMIC_ENABLE_PLUGINS typedef struct mimic_plugin_s { char *name; int version; - void (*mimic_init)(void); - void (*mimic_exit)(void); + void (*mimic_init)(mimic_context *ctx); + void (*mimic_exit)(mimic_context *ctx); } mimic_plugin_t; typedef struct mimic_plugin_handler_s { void *handle; - mimic_plugin_t* plugin; + mimic_plugin_t *plugin; } mimic_plugin_handler_t; - -mimic_plugin_handler_t* mimic_plugin_load(const char *filename); -int mimic_plugin_unload(mimic_plugin_handler_t *plugin); -extern mimic_plugin_handler_t** mimic_plugins; + +mimic_plugin_handler_t* mimic_plugin_load(mimic_context *ctx, const char *filename); +int mimic_plugin_unload(mimic_context *ctx, mimic_plugin_handler_t *plugin); #endif -int mimic_plugins_init(); -void mimic_plugins_exit(); +int mimic_plugins_init(mimic_context *ctx); +void mimic_plugins_exit(mimic_context *ctx); #endif /*header */ diff --git a/include/mimic.h b/include/mimic.h index 368f75c..aa6c7ff 100644 --- a/include/mimic.h +++ b/include/mimic.h @@ -68,17 +68,28 @@ extern "C" { #include "cst_tokenstream.h" #include "cst_plugins.h" -MIMIC_CORE_PUBLIC extern cst_val *mimic_voice_list; -extern cst_lang mimic_lang_list[20]; +typedef struct mimic_context_s { + uint16_t version; + cst_voice **voices; + cst_lang **languages; + mimic_plugin_handler_t **plugins; + uint32_t num_voices; + uint32_t voices_size; + uint32_t num_languages; + uint32_t languages_size; + cst_voice *voice_selected; +} mimic_context; /* Public functions */ -MIMIC_CORE_PUBLIC int mimic_core_init(); -MIMIC_CORE_PUBLIC int mimic_core_exit(); +MIMIC_CORE_PUBLIC mimic_context *mimic_core_init(); +MIMIC_CORE_PUBLIC int mimic_core_exit(mimic_context *ctx); +MIMIC_CORE_PUBLIC mimic_context *mimic_core_init_no_plugins(); +MIMIC_CORE_PUBLIC int mimic_core_exit_no_plugins(mimic_context *ctx); /* General top level functions */ -MIMIC_CORE_PUBLIC const cst_lang *mimic_lang_select(const char *lang); -MIMIC_CORE_PUBLIC cst_voice *mimic_voice_select(const char *name); -MIMIC_CORE_PUBLIC cst_voice *mimic_voice_load(const char *voice_filename); +MIMIC_CORE_PUBLIC const cst_lang *mimic_lang_select(mimic_context *ctx, const char *lang); +MIMIC_CORE_PUBLIC cst_voice *mimic_voice_select(mimic_context *ctx, const char *name); +MIMIC_CORE_PUBLIC cst_voice *mimic_voice_load(mimic_context *ctx, const char *filename); MIMIC_CORE_PUBLIC int mimic_voice_dump(cst_voice *voice, const char *voice_filename); MIMIC_CORE_PUBLIC int mimic_file_to_speech(const char *filename, cst_voice *voice, const char *outtype, float *dur); @@ -86,10 +97,12 @@ MIMIC_CORE_PUBLIC int mimic_text_to_speech(const char *text, cst_voice *voice, const char *outtype, float *dur); MIMIC_CORE_PUBLIC int mimic_phones_to_speech(const char *text, cst_voice *voice, const char *outtype, float *dur); -MIMIC_CORE_PUBLIC int mimic_ssml_file_to_speech(const char *filename, cst_voice *voice, - const char *outtype, float *dur); -MIMIC_CORE_PUBLIC int mimic_ssml_text_to_speech(const char *text, cst_voice *voice, - const char *outtype, float *dur); +MIMIC_CORE_PUBLIC int mimic_ssml_file_to_speech( + mimic_context *ctx,const char *filename, cst_voice *voice, + const char *outtype, float *dur); +MIMIC_CORE_PUBLIC int mimic_ssml_text_to_speech( + mimic_context *ctx, const char *text, cst_voice *voice, + const char *outtype, float *dur); MIMIC_CORE_PUBLIC int mimic_voice_add_lex_addenda(cst_voice *v, const cst_string *lexfile); /* Lower lever user functions */ @@ -132,8 +145,8 @@ MIMIC_CORE_PUBLIC int mimic_voice_add_lex_addenda(cst_voice *v, const cst_string /* These functions are *not* thread-safe, they are designed to be called */ /* before the initial synthesis occurs */ - MIMIC_CORE_PUBLIC int mimic_add_voice(cst_voice *voice); - MIMIC_CORE_PUBLIC int mimic_add_lang(const char *langname, +MIMIC_CORE_PUBLIC int mimic_voice_add(mimic_context *ctx, cst_voice *voice); + MIMIC_CORE_PUBLIC int mimic_lang_add(mimic_context *ctx, const char *langname, void (*lang_init) (cst_voice *vox), cst_lexicon *(*lex_init) ()); /* These are init functions for generic grapheme based voices */ diff --git a/main/mimic_main.c b/main/mimic_main.c index b82f805..da2e4cc 100644 --- a/main/mimic_main.c +++ b/main/mimic_main.c @@ -118,19 +118,16 @@ static void mimic_usage() exit(0); } -static void mimic_voice_list_print(void) +static void mimic_voice_list_print(mimic_context *ctx) { - cst_voice *voice; - const cst_val *v; + size_t i; printf("Voices available: "); - for (v = mimic_voice_list; v; v = val_cdr(v)) + for (i = 0; i < ctx->num_voices;i++) { - voice = val_voice(val_car(v)); - printf("%s ", voice->name); + printf("%s ", ctx->voices[i]->name); } printf("\n"); - return; } @@ -234,14 +231,14 @@ int main(int argc, char **argv) ssml_mode = FALSE; extra_feats = new_features(); - mimic_core_init(); + mimic_context *ctx = mimic_core_init(); for (i = 1; i < argc; i++) { if (cst_streq(argv[i], "--version")) { mimic_version(); - mimic_core_exit(); + mimic_core_exit(ctx); return 1; } else if (cst_streq(argv[i], "-h") || cst_streq(argv[i], "--help") @@ -251,8 +248,9 @@ int main(int argc, char **argv) mimic_verbose = TRUE; else if (cst_streq(argv[i], "-lv")) { - mimic_voice_list_print(); + mimic_voice_list_print(ctx); delete_features(extra_feats); + mimic_core_exit(ctx); exit(0); } else if (cst_streq(argv[i], "-l")) @@ -269,7 +267,7 @@ int main(int argc, char **argv) } else if ((cst_streq(argv[i], "-voice")) && (i + 1 < argc)) { - desired_voice = mimic_voice_select(argv[i + 1]); + desired_voice = mimic_voice_select(ctx, argv[i + 1]); i++; } else if ((cst_streq(argv[i], "-add_lex")) && (i + 1 < argc)) @@ -361,14 +359,14 @@ int main(int argc, char **argv) if (filename == NULL) filename = "-"; /* stdin */ - if (desired_voice == 0) - desired_voice = mimic_voice_select(NULL); + if (desired_voice == NULL) + desired_voice = mimic_voice_select(ctx, NULL); - if (desired_voice == 0) + if (desired_voice == NULL) { fprintf(stderr, "No voice given and no voice precompiled\n"); delete_features(extra_feats); - mimic_core_exit(); + mimic_core_exit(ctx); return 1; } v = desired_voice; @@ -409,14 +407,14 @@ int main(int argc, char **argv) else if ((strchr(filename, ' ') && !explicit_filename) || explicit_text) { if (ssml_mode) - err = mimic_ssml_text_to_speech(filename, v, outtype, &durs); + err = mimic_ssml_text_to_speech(ctx, filename, v, outtype, &durs); else err = mimic_text_to_speech(filename, v, outtype, &durs); } else { if (ssml_mode) - err = mimic_ssml_file_to_speech(filename, v, outtype, &durs); + err = mimic_ssml_file_to_speech(ctx, filename, v, outtype, &durs); else err = mimic_file_to_speech(filename, v, outtype, &durs); } @@ -434,10 +432,6 @@ int main(int argc, char **argv) goto loop; delete_features(extra_feats); - delete_val(mimic_voice_list); - mimic_voice_list = 0; - /* cst_alloc_debug_summary(); */ - - mimic_core_exit(); + mimic_core_exit(ctx); return 0; } diff --git a/main/mimicvox_info_main.c b/main/mimicvox_info_main.c index 93c19c8..6a807f4 100644 --- a/main/mimicvox_info_main.c +++ b/main/mimicvox_info_main.c @@ -61,7 +61,7 @@ int main(int argc, char **argv) "-info Output general info on voice\n" "set/get features in a mimicvox voice.", args); - mimic_core_init(); + mimic_context *ctx = mimic_core_init(); if (!feat_present(args, "-voice")) { @@ -69,7 +69,7 @@ int main(int argc, char **argv) exit(-1); } voice_name = feat_string(args, "-voice"); - v = mimic_voice_load(voice_name); + v = mimic_voice_load(ctx, voice_name); if (v == NULL) { fprintf(stderr, "can't load voice %s\n", voice_name); @@ -100,7 +100,7 @@ int main(int argc, char **argv) printf("%s \"%s\"\n", feat, feat_string(v->features, feat)); } - mimic_core_exit(); + mimic_core_exit(ctx); return 0; diff --git a/main/t2p_main.c b/main/t2p_main.c index 72963d8..f7b81e6 100644 --- a/main/t2p_main.c +++ b/main/t2p_main.c @@ -50,10 +50,10 @@ static cst_utterance *no_wave_synth(cst_utterance *u) return u; } -static cst_voice *voice_no_wave(const char *lang_code, const char *dialect, +static cst_voice *voice_no_wave(mimic_context *ctx, const char *lang_code, const char *dialect, int use_addenda, int use_lexicon) { - const cst_lang *lang = mimic_lang_select(lang_code); + const cst_lang *lang = mimic_lang_select(ctx, lang_code); cst_voice *v = new_voice(); v->name = "no_wave_voice"; @@ -137,8 +137,8 @@ int main(int argc, char **argv) { use_lexicon = 0; } - mimic_core_init(); - v = voice_no_wave(lang, dialect, use_addenda, use_lexicon); + mimic_context *ctx = mimic_core_init(); + v = voice_no_wave(ctx, lang, dialect, use_addenda, use_lexicon); if (v == NULL) { cst_errmsg("Could not load voice with language '%s' and dialect '%s'\n", lang, dialect == NULL ? "" : dialect); @@ -164,6 +164,6 @@ int main(int argc, char **argv) delete_features(args); delete_val(files); - mimic_core_exit(); + mimic_core_exit(ctx); return 0; } diff --git a/src/cg/cst_cg_load_voice.c b/src/cg/cst_cg_load_voice.c index c024d19..ebbf363 100644 --- a/src/cg/cst_cg_load_voice.c +++ b/src/cg/cst_cg_load_voice.c @@ -43,12 +43,11 @@ #include "cst_cg_map.h" #include "cst_alloc.h" -cst_voice *cst_cg_load_voice(const char *filename, - const cst_lang * lang_table) +cst_voice *cst_cg_load_voice(mimic_context *ctx, const char *filename) { cst_voice *vox; cst_lexicon *lex = NULL; - int i, end_of_features; + int end_of_features; const char *language; const char *xname; cst_cg_db *cg_db; @@ -109,14 +108,12 @@ cst_voice *cst_cg_load_voice(const char *filename, language = mimic_get_param_string(vox->features, "language", ""); /* Search Lang table for lang_init() and lex_init(); */ - for (i = 0; lang_table[i].lang; i++) + const cst_lang *lang = mimic_lang_select(ctx, language); + + if (lang != NULL) { - if (cst_streq(language, lang_table[i].lang)) - { - (lang_table[i].lang_init) (vox); - lex = (lang_table[i].lex_init) (); - break; - } + (lang->lang_init) (vox); + lex = (lang->lex_init) (); } if (lex == NULL) { /* Language is not supported */ diff --git a/src/synth/cst_ssml.c b/src/synth/cst_ssml.c index 71d3e56..fb7d9ff 100644 --- a/src/synth/cst_ssml.c +++ b/src/synth/cst_ssml.c @@ -135,7 +135,8 @@ static cst_features *ssml_get_attributes(cst_tokenstream *ts) return a; } -static cst_utterance *ssml_apply_tag(const char *tag, +static cst_utterance *ssml_apply_tag(mimic_context *ctx, + const char *tag, cst_features *attributes, cst_utterance *u, cst_features *word_feats, @@ -262,7 +263,7 @@ static cst_utterance *ssml_apply_tag(const char *tag, if (cst_streq("start", feat_string(attributes, "_type"))) { vname = get_param_string(attributes, "_val0", ""); - nvoice = mimic_voice_select(vname); + nvoice = mimic_voice_select(ctx, vname); feat_set(feats, "current_voice", userdata_val(nvoice)); return NULL; /* cause an utterance break */ } @@ -289,7 +290,8 @@ static cst_utterance *ssml_apply_tag(const char *tag, return u; } -static float mimic_ssml_to_speech_ts(cst_tokenstream *ts, cst_voice *voice, +static float mimic_ssml_to_speech_ts(mimic_context *ctx, + cst_tokenstream *ts, cst_voice *voice, const char *outtype, float *durs) { /* This is a very ugly function, that might be better written with gotos */ @@ -383,7 +385,7 @@ static float mimic_ssml_to_speech_ts(cst_tokenstream *ts, cst_voice *voice, attributes = ssml_get_attributes(ts); token = ts_get(ts); /* skip ">" */ if (ssml_apply_tag - (tag, attributes, utt, ssml_word_feats, ssml_feats)) + (ctx, tag, attributes, utt, ssml_word_feats, ssml_feats)) ssml_eou = 0; else ssml_eou = 1; @@ -481,8 +483,10 @@ static float mimic_ssml_to_speech_ts(cst_tokenstream *ts, cst_voice *voice, return err; } -int mimic_ssml_file_to_speech(const char *filename, cst_voice *voice, - const char *outtype, float *dur) +int mimic_ssml_file_to_speech( + mimic_context *ctx, + const char *filename, cst_voice *voice, + const char *outtype, float *dur) { cst_tokenstream *ts; int fp; @@ -528,7 +532,7 @@ int mimic_ssml_file_to_speech(const char *filename, cst_voice *voice, delete_wave(w); } - err = mimic_ssml_to_speech_ts(ts, voice, outtype, dur); + err = mimic_ssml_to_speech_ts(ctx, ts, voice, outtype, dur); ts_close(ts); @@ -536,8 +540,9 @@ int mimic_ssml_file_to_speech(const char *filename, cst_voice *voice, } -int mimic_ssml_text_to_speech(const char *text, cst_voice *voice, - const char *outtype, float *dur) +int mimic_ssml_text_to_speech(mimic_context *ctx, + const char *text, cst_voice *voice, + const char *outtype, float *dur) { cst_tokenstream *ts; int fp; @@ -582,7 +587,7 @@ int mimic_ssml_text_to_speech(const char *text, cst_voice *voice, delete_wave(w); } - err = mimic_ssml_to_speech_ts(ts, voice, outtype, dur); + err = mimic_ssml_to_speech_ts(ctx, ts, voice, outtype, dur); ts_close(ts); diff --git a/src/synth/mimic.c b/src/synth/mimic.c index 7bf6528..704c053 100644 --- a/src/synth/mimic.c +++ b/src/synth/mimic.c @@ -48,31 +48,58 @@ #include "cst_audio.h" #include "cst_plugins.h" -/* TODO: Define a public mimic API */ +static mimic_context *mimic_context_init() +{ + mimic_context *ctx = cst_alloc(mimic_context, 1); + if (ctx == NULL) + { + return NULL; + } + ctx->version = 0; + ctx->voices = NULL; + ctx->languages = NULL; + ctx->plugins = NULL; + ctx->num_voices = 0; + ctx->voices_size = 32; + ctx->num_languages = 0; + ctx->languages_size = 32; + return ctx; +} -/* TODO: Create a mimic_state struct that contains all global variables - * and is returned at mimic_init and passed as needed - * through the mimic API */ - -/* This is a global, which isn't ideal, this may change */ -/* It is set when mimic_set_voice_list() is called which happens in */ -/* mimic_main() */ -cst_val *mimic_voice_list = 0; -cst_lang mimic_lang_list[20]; -static int mimic_lang_list_length = 0; +static void mimic_context_delete(mimic_context *ctx) +{ + cst_free(ctx->voices); + cst_free(ctx->languages); + cst_free(ctx); +} -int mimic_core_init() +mimic_context *mimic_core_init_no_plugins() { + mimic_context *ctx = mimic_context_init(); cst_regex_init(); mimic_audio_init(); - mimic_plugins_init(); - return 0; + return ctx; } -int mimic_core_exit() +mimic_context *mimic_core_init() +{ + mimic_context *ctx = mimic_core_init_no_plugins(); + mimic_plugins_init(ctx); + return ctx; +} + +int mimic_core_exit_no_plugins(mimic_context *ctx) { - mimic_plugins_exit(); mimic_audio_exit(); + mimic_context_delete(ctx); + return 0; +} + + +int mimic_core_exit(mimic_context *ctx) +{ + mimic_plugins_exit(ctx); + mimic_core_exit_no_plugins(ctx); return 0; } @@ -81,78 +108,130 @@ int mimic_voice_dump(cst_voice *voice, const char *filename) return cst_cg_dump_voice(voice, filename); } -cst_voice *mimic_voice_load(const char *filename) +cst_voice *mimic_voice_load(mimic_context *ctx, const char *filename) { /* Currently only supported for CG voices */ /* filename make be a local pathname or a url (http:/file:) */ cst_voice *v = NULL; - v = cst_cg_load_voice(filename, mimic_lang_list); + v = cst_cg_load_voice(ctx, filename); return v; } -int mimic_add_voice(cst_voice *voice) +int mimic_voice_add(mimic_context *ctx, cst_voice *voice) { - const cst_val *x; - if (voice) + if (ctx == NULL || voice == NULL) { - /* add to second place -- first is default voice */ - /* This is thread unsafe */ - if (mimic_voice_list) - { /* Other voices -- first is default, add this second */ - x = cons_val(voice_val(voice), val_cdr(mimic_voice_list)); - set_cdr(mimic_voice_list, x); - } - else - { /* Only voice so goes on front */ - mimic_voice_list = cons_val(voice_val(voice), mimic_voice_list); - } - + return FALSE; + } + if (mimic_voice_select(ctx, voice->name) != NULL) + { + cst_errmsg("Voice %s already loaded", voice->name); return TRUE; } - else - return FALSE; + if (ctx->num_voices == ctx->voices_size) + { + /* Grow ctx->voices */ + if (ctx->voices_size == 0) + { + ctx->voices = cst_alloc(cst_voice*, 32); + if (ctx->voices == NULL) + { + return FALSE; + } + ctx->voices_size = 32; + } else + { + cst_voice **v_old = ctx->voices; + ctx->voices = cst_alloc(cst_voice*, 2*ctx->voices_size); + if (ctx->voices == NULL) + { + ctx->voices = v_old; + return FALSE; + } + memcpy(ctx->voices, v_old, sizeof(cst_voice*) * ctx->voices_size); + cst_free(v_old); + ctx->voices_size = 2*ctx->voices_size; + } + } + ctx->voices[ctx->num_voices] = voice; + ctx->num_voices++; + return TRUE; +} + +cst_lang *mimic_lang_new( + const char *langname, + void (*lang_init) (cst_voice *vox), + cst_lexicon *(*lex_init) ()) +{ + cst_lang *lang = cst_alloc(cst_lang, 1); + if (lang == NULL) + { + return NULL; + } + lang->lang = langname; + lang->lang_init = lang_init; + lang->lex_init = lex_init; + return lang; } -int mimic_add_lang(const char *langname, +int mimic_lang_add(mimic_context *ctx, + const char *langname, void (*lang_init) (cst_voice *vox), cst_lexicon *(*lex_init) ()) { - size_t i; - for (i = 0; i < mimic_lang_list_length; i++) + if (ctx == NULL || langname == NULL) { - if (cst_streq(langname, mimic_lang_list[i].lang)) - { - return TRUE; - } + return FALSE; } - if (mimic_lang_list_length < 19) + if (mimic_lang_select(ctx, langname) != NULL) { - mimic_lang_list[mimic_lang_list_length].lang = langname; - mimic_lang_list[mimic_lang_list_length].lang_init = lang_init; - mimic_lang_list[mimic_lang_list_length].lex_init = lex_init; - mimic_lang_list_length++; - mimic_lang_list[mimic_lang_list_length].lang = NULL; + cst_errmsg("Language %s already loaded", langname); + return TRUE; } - else - { - cst_errmsg("Error: Language limit reached, could not add: '%s'\n", langname); - } + if (ctx->num_languages == ctx->languages_size) + { + /* Grow ctx->languages */ + if (ctx->languages_size == 0) + { + ctx->languages = cst_alloc(cst_lang*, 32); + if (ctx->languages == NULL) + { + return FALSE; + } + ctx->languages_size = 32; + } else + { + cst_lang **l_old = ctx->languages; + ctx->languages = cst_alloc(cst_lang*, 2*ctx->languages_size); + if (ctx->languages == NULL) + { + ctx->languages = l_old; + return FALSE; + } + memcpy(ctx->languages, l_old, sizeof(cst_lang*) * ctx->languages_size); + cst_free(l_old); + ctx->languages_size = 2*ctx->languages_size; + } + } + cst_lang *lang = mimic_lang_new(langname, lang_init, lex_init); + ctx->languages[ctx->num_languages] = lang; + ctx->num_languages++; return TRUE; } -const cst_lang* mimic_lang_select(const char *lang) +const cst_lang* mimic_lang_select(mimic_context *ctx, const char *lang) { size_t i; /* Search mimic_lang_list for lang_init() and lex_init(); */ - for (i = 0; mimic_lang_list[i].lang; ++i) + for (i = 0; ctx->num_languages; ++i) { - if (cst_streq(lang, mimic_lang_list[i].lang)) + if (cst_streq(lang, ctx->languages[i]->lang)) { - return &mimic_lang_list[i]; + return ctx->languages[i]; } } return NULL; @@ -160,28 +239,42 @@ const cst_lang* mimic_lang_select(const char *lang) -cst_voice *mimic_voice_select(const char *name) +cst_voice *mimic_voice_select(mimic_context *ctx, const char *name) { - const cst_val *v; cst_voice *voice; - if ((name == NULL) && (mimic_voice_list != NULL)) + if (ctx == NULL) { - return val_voice(val_car(mimic_voice_list)); + return NULL; } - if (mimic_voice_list != NULL) + if (ctx->voice_selected != NULL && name == NULL) { - for (v = mimic_voice_list; v; v = val_cdr(v)) + if (ctx->voice_selected != NULL) + { + return ctx->voice_selected; + } + if (ctx->num_voices > 0) + { + return ctx->voices[0]; + } + return NULL; + } + size_t i; + for (i=0;i < ctx->num_voices; i++) + { + if (cst_streq(name, ctx->voices[i]->name)) + { + /* short name */ + return ctx->voices[i]; + } + if (cst_streq(name, get_param_string(ctx->voices[i]->features, "name", ""))) + { + /* longer name */ + return ctx->voices[i]; + } + if (cst_streq(name, get_param_string(ctx->voices[i]->features, "pathname", ""))) { - voice = val_voice(val_car(v)); - if (cst_streq(name, voice->name)) /* short name */ - return voice; - if (cst_streq(name, get_param_string(voice->features, "name", ""))) - /* longer name */ - return voice; - if (cst_streq - (name, get_param_string(voice->features, "pathname", ""))) - /* even longer name (url) */ - return voice; + /* even longer name (url) */ + return ctx->voices[i]; } } @@ -189,11 +282,11 @@ cst_voice *mimic_voice_select(const char *name) cst_strchr(name, '/') || cst_strchr(name, '\\'))) { - voice = mimic_voice_load(name); + voice = mimic_voice_load(ctx, name); if (!voice) cst_errmsg("Error load voice: failed to load voice from %s\n", name); - mimic_add_voice(voice); + mimic_voice_add(ctx, voice); return voice; } return NULL; diff --git a/src/utils/cst_plugins.c b/src/utils/cst_plugins.c index 18a3aa0..c2e4b9d 100644 --- a/src/utils/cst_plugins.c +++ b/src/utils/cst_plugins.c @@ -41,9 +41,9 @@ #include "cst_error.h" #include "cst_string.h" #include "cst_plugins.h" +#include "mimic.h" #include #include -mimic_plugin_handler_t** mimic_plugins; #ifndef MIMIC_PLUGIN_DIR #error Missing MIMIC_PLUGIN_DIR definition @@ -70,7 +70,7 @@ const char* mimic_get_plugin_dir() /* POSIX compliant */ #include #include - mimic_plugin_handler_t* mimic_plugin_load(const char *filename) + mimic_plugin_handler_t* mimic_plugin_load(mimic_context *ctx, const char *filename) { void *handle; mimic_plugin_handler_t *plug_hdl = NULL; @@ -97,12 +97,12 @@ const char* mimic_get_plugin_dir() } plug_hdl->handle = handle; plug_hdl->plugin = plugin; - plugin->mimic_init(); + plugin->mimic_init(ctx); return plug_hdl; } - int mimic_plugin_unload(mimic_plugin_handler_t *plug_hdl) + int mimic_plugin_unload(mimic_context *ctx, mimic_plugin_handler_t *plug_hdl) { - plug_hdl->plugin->mimic_exit(); + plug_hdl->plugin->mimic_exit(ctx); dlclose(plug_hdl->handle); cst_free(plug_hdl); return 0; @@ -183,7 +183,7 @@ const char* mimic_get_plugin_dir() #include /* Microsoft Windows (64-bit) */ /* Microsoft Windows (32-bit) */ - mimic_plugin_handler_t* mimic_plugin_load(const char *filename) + mimic_plugin_handler_t* mimic_plugin_load(mimic_context *ctx, const char *filename) { mimic_plugin_handler_t *plug_hdl = NULL; HINSTANCE handle = NULL; @@ -207,12 +207,12 @@ const char* mimic_get_plugin_dir() } plug_hdl->handle = handle; plug_hdl->plugin = plugin; - plugin->mimic_init(); + plugin->mimic_init(ctx); return plug_hdl; } - int mimic_plugin_unload(mimic_plugin_handler_t *plug_hdl) + int mimic_plugin_unload(mimic_context *ctx, mimic_plugin_handler_t *plug_hdl) { - plug_hdl->plugin->mimic_exit(); + plug_hdl->plugin->mimic_exit(ctx); FreeLibrary(plug_hdl->handle); cst_free(plug_hdl); return 0; @@ -269,45 +269,46 @@ const char* mimic_get_plugin_dir() } #endif -int mimic_plugins_init() +int mimic_plugins_init(mimic_context *ctx) { size_t i; char **plugin_files = NULL; - if (mimic_plugins != NULL) + if (ctx->plugins != NULL) return 0; int num_plugins = list_all_plugins(&plugin_files); - mimic_plugins = cst_alloc(mimic_plugin_handler_t*, num_plugins+1); + ctx->plugins = cst_alloc(mimic_plugin_handler_t*, num_plugins+1); for (i = 0; iplugins[i] = mimic_plugin_load(ctx, plugin_files[i]); free(plugin_files[i]); } - mimic_plugins[num_plugins] = NULL; + ctx->plugins[num_plugins] = NULL; free(plugin_files); return 0; } -void mimic_plugins_exit() +void mimic_plugins_exit(mimic_context *ctx) { size_t i=0; - if (mimic_plugins != NULL) + if (ctx->plugins != NULL) { - for (i=0;mimic_plugins[i] != NULL;i++) + for (i=0;ctx->plugins[i] != NULL;i++) { - mimic_plugin_unload(mimic_plugins[i]); + mimic_plugin_unload(ctx, ctx->plugins[i]); } - cst_free(mimic_plugins); + cst_free(ctx->plugins); + ctx->plugins = NULL; } } #else /* No plugins */ -int mimic_plugins_init() +int mimic_plugins_init(mimic_context *ctx) { return 0; } -void mimic_plugins_exit() +void mimic_plugins_exit(mimic_context *ctx) { return; } diff --git a/unittests/wave_test_main.c b/unittests/wave_test_main.c index 9bdf755..dbd6c99 100644 --- a/unittests/wave_test_main.c +++ b/unittests/wave_test_main.c @@ -20,7 +20,6 @@ void test_copy(void) { cst_wave *w1 = new_wave(); cst_wave *w2; - mimic_core_init(); TEST_CHECK(cst_wave_load_riff(w1, A_WAV1) == 0); w2 = copy_wave(w1); TEST_CHECK(w1 != w2); @@ -33,7 +32,6 @@ void test_copy(void) TEST_CHECK(w1->samples[20] == w2->samples[20]); delete_wave(w1); delete_wave(w2); - mimic_core_exit(); } void test_concat(void) @@ -41,7 +39,6 @@ void test_concat(void) int original_len; cst_wave *w1 = new_wave(); cst_wave *w2 = new_wave(); - mimic_core_init(); TEST_CHECK(cst_wave_load_riff(w1, A_WAV1) == 0); TEST_CHECK(cst_wave_load_riff(w2, A_WAV2) == 0); original_len = w1->num_samples; From 530aa9033858f20301ac1af300493cecb9ec0e11 Mon Sep 17 00:00:00 2001 From: Sergio Oller Date: Wed, 1 Nov 2017 12:46:28 +0100 Subject: [PATCH 2/2] Make sigint_handler static --- main/mimic_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/mimic_main.c b/main/mimic_main.c index da2e4cc..9f247de 100644 --- a/main/mimic_main.c +++ b/main/mimic_main.c @@ -66,7 +66,7 @@ BOOL WINAPI windows_signal_handler(DWORD signum) return FALSE; } #else -void sigint_handler(int signum) +static void sigint_handler(int signum) { mimic_audio_shutdown(signum); }