From 70571a440a7acb31c55dbf8c136ab18c8b264686 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Mon, 14 Dec 2020 12:51:27 +0800 Subject: [PATCH] [mod_test] add tts mock --- .gitignore | 1 + src/mod/applications/mod_test/Makefile.am | 7 +- src/mod/applications/mod_test/mod_test.c | 86 ++++++++- src/mod/applications/mod_test/test/test_tts.c | 165 ++++++++++++++++++ 4 files changed, 257 insertions(+), 2 deletions(-) create mode 100644 src/mod/applications/mod_test/test/test_tts.c diff --git a/.gitignore b/.gitignore index 0cc7c405b5..a4fb5ca6f6 100644 --- a/.gitignore +++ b/.gitignore @@ -261,6 +261,7 @@ libs/sofia-sip*/ libs/sofia-sip* src/mod/applications/mod_test/test/test_asr +src/mod/applications/mod_test/test/test_tts src/mod/event_handlers/mod_rayo/test/test_iks src/mod/event_handlers/mod_rayo/test/test_nlsml src/mod/event_handlers/mod_rayo/test/test_srgs diff --git a/src/mod/applications/mod_test/Makefile.am b/src/mod/applications/mod_test/Makefile.am index 5a961aad71..c4be724643 100644 --- a/src/mod/applications/mod_test/Makefile.am +++ b/src/mod/applications/mod_test/Makefile.am @@ -10,12 +10,17 @@ mod_test_la_SOURCES = mod_test_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(SOFIALA) libtestmod.la mod_test_la_LDFLAGS = -avoid-version -module -no-undefined -shared -noinst_PROGRAMS = test/test_asr +noinst_PROGRAMS = test/test_asr test/test_tts test_test_asr_SOURCES = test/test_asr.c test_test_asr_CFLAGS = $(AM_CFLAGS) -I. -DSWITCH_TEST_BASE_DIR_FOR_CONF=\"${abs_builddir}/test\" -DSWITCH_TEST_BASE_DIR_OVERRIDE=\"${abs_builddir}/test\" test_test_asr_LDFLAGS = $(AM_LDFLAGS) -avoid-version -no-undefined $(freeswitch_LDFLAGS) $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS) test_test_asr_LDADD = libtestmod.la +test_test_tts_SOURCES = test/test_tts.c +test_test_tts_CFLAGS = $(AM_CFLAGS) -I. -DSWITCH_TEST_BASE_DIR_FOR_CONF=\"${abs_builddir}/test\" -DSWITCH_TEST_BASE_DIR_OVERRIDE=\"${abs_builddir}/test\" +test_test_tts_LDFLAGS = $(AM_LDFLAGS) -avoid-version -no-undefined $(freeswitch_LDFLAGS) $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS) +test_test_tts_LDADD = libtestmod.la + TESTS = $(noinst_PROGRAMS) diff --git a/src/mod/applications/mod_test/mod_test.c b/src/mod/applications/mod_test/mod_test.c index c8ce62c39f..9791d7a611 100644 --- a/src/mod/applications/mod_test/mod_test.c +++ b/src/mod/applications/mod_test/mod_test.c @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2018, Anthony Minessale II + * Copyright (C) 2005-2020, Anthony Minessale II * * Version: MPL 1.1 * @@ -23,6 +23,7 @@ * * Contributor(s): * Chris Rienzo + * Seven Du * * * mod_test.c -- mock module interfaces for testing @@ -37,6 +38,10 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_test_shutdown); SWITCH_MODULE_RUNTIME_FUNCTION(mod_test_runtime); SWITCH_MODULE_DEFINITION(mod_test, mod_test_load, mod_test_shutdown, mod_test_runtime); +typedef struct { + char *text; + int samples; +} test_tts_t; typedef enum { ASRFLAG_READY = (1 << 0), @@ -360,9 +365,77 @@ static void test_asr_text_param(switch_asr_handle_t *ah, char *param, const char } } +static switch_status_t test_speech_open(switch_speech_handle_t *sh, const char *voice_name, int rate, int channels, switch_speech_flag_t *flags) +{ + test_tts_t *context = switch_core_alloc(sh->memory_pool, sizeof(test_tts_t)); + switch_assert(context); + context->samples = sh->samplerate; + sh->private_info = context; + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t test_speech_close(switch_speech_handle_t *sh, switch_speech_flag_t *flags) +{ + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t test_speech_feed_tts(switch_speech_handle_t *sh, char *text, switch_speech_flag_t *flags) +{ + test_tts_t *context = (test_tts_t *)sh->private_info; + + if (!zstr(text)) { + char *p = strstr(text, "silence://"); + + if (p) { + p += strlen("silence://"); + context->samples = atoi(p) * sh->samplerate / 1000; + } + + context->text = switch_core_strdup(sh->memory_pool, text); + } + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t test_speech_read_tts(switch_speech_handle_t *sh, void *data, switch_size_t *datalen, switch_speech_flag_t *flags) +{ + test_tts_t *context = (test_tts_t *)sh->private_info; + + if (context->samples <= 0) { + return SWITCH_STATUS_FALSE; + } + + if (context->samples < *datalen / 2 / sh->channels) { + *datalen = context->samples * 2 * sh->channels; + } + + context->samples -= *datalen / 2 / sh->channels; + memset(data, 0, *datalen); + + return SWITCH_STATUS_SUCCESS; +} + +static void test_speech_flush_tts(switch_speech_handle_t *sh) +{ +} + +static void test_speech_text_param_tts(switch_speech_handle_t *sh, char *param, const char *val) +{ +} + +static void test_speech_numeric_param_tts(switch_speech_handle_t *sh, char *param, int val) +{ +} + +static void test_speech_float_param_tts(switch_speech_handle_t *sh, char *param, double val) +{ +} + SWITCH_MODULE_LOAD_FUNCTION(mod_test_load) { switch_asr_interface_t *asr_interface; + switch_speech_interface_t *speech_interface = NULL; *module_interface = switch_loadable_module_create_module_interface(pool, modname); @@ -380,6 +453,17 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_test_load) asr_interface->asr_start_input_timers = test_asr_start_input_timers; asr_interface->asr_text_param = test_asr_text_param; + speech_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_SPEECH_INTERFACE); + speech_interface->interface_name = "test"; + speech_interface->speech_open = test_speech_open; + speech_interface->speech_close = test_speech_close; + speech_interface->speech_feed_tts = test_speech_feed_tts; + speech_interface->speech_read_tts = test_speech_read_tts; + speech_interface->speech_flush_tts = test_speech_flush_tts; + speech_interface->speech_text_param_tts = test_speech_text_param_tts; + speech_interface->speech_numeric_param_tts = test_speech_numeric_param_tts; + speech_interface->speech_float_param_tts = test_speech_float_param_tts; + return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/applications/mod_test/test/test_tts.c b/src/mod/applications/mod_test/test/test_tts.c new file mode 100644 index 0000000000..f1e4205f68 --- /dev/null +++ b/src/mod/applications/mod_test/test/test_tts.c @@ -0,0 +1,165 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2020, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Seven Du + * + * + * test_tts.c -- tests for mock test tts interface + * + */ +#include +#include + +FST_CORE_BEGIN(".") + +FST_MODULE_BEGIN(mod_test, test_asr) + +FST_SETUP_BEGIN() +{ + fst_requires_module("mod_tone_stream"); + fst_requires_module("mod_sndfile"); + fst_requires_module("mod_dptools"); +} +FST_SETUP_END() + +FST_TEARDOWN_BEGIN() +{ +} +FST_TEARDOWN_END() + + +FST_TEST_BEGIN(tts_8000) +{ + switch_speech_handle_t sh = { 0 }; + switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE; + switch_status_t status; + int sample_rate = 8000; + int interval = 20; + uint8_t data[320]; + size_t datalen = sizeof(data); + int read = 0; + + status = switch_core_speech_open(&sh, "test", "default", sample_rate, interval, 1, &flags, NULL); + fst_requires(status == SWITCH_STATUS_SUCCESS); + status = switch_core_speech_feed_tts(&sh, "text", &flags); + fst_requires(status == SWITCH_STATUS_SUCCESS); + do { + status = switch_core_speech_read_tts(&sh, data, &datalen, &flags); + read++; + } while (status == SWITCH_STATUS_SUCCESS); + + fst_check(read = sample_rate / interval); // samples of 1 second + switch_core_speech_close(&sh, &flags); +} +FST_TEST_END() + +FST_TEST_BEGIN(tts_48000) +{ + switch_speech_handle_t sh = { 0 }; + switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE; + switch_status_t status; + int sample_rate = 48000; + int interval = 20; + uint8_t data[320]; + size_t datalen = sizeof(data); + int read = 0; + + status = switch_core_speech_open(&sh, "test", "default", sample_rate, interval, 1, &flags, NULL); + fst_requires(status == SWITCH_STATUS_SUCCESS); + status = switch_core_speech_feed_tts(&sh, "text", &flags); + fst_requires(status == SWITCH_STATUS_SUCCESS); + do { + status = switch_core_speech_read_tts(&sh, data, &datalen, &flags); + read++; + } while (status == SWITCH_STATUS_SUCCESS); + + fst_check(read = sample_rate / interval); // samples of 1 second + switch_core_speech_close(&sh, &flags); +} +FST_TEST_END() + +FST_TEST_BEGIN(tts_48000_2) +{ + switch_speech_handle_t sh = { 0 }; + switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE; + switch_status_t status; + int sample_rate = 48000; + int interval = 20; + uint8_t data[320]; + size_t datalen = sizeof(data); + int read = 0; + + status = switch_core_speech_open(&sh, "test", "default", sample_rate, interval, 2, &flags, NULL); + fst_requires(status == SWITCH_STATUS_SUCCESS); + status = switch_core_speech_feed_tts(&sh, "text", &flags); + fst_requires(status == SWITCH_STATUS_SUCCESS); + do { + status = switch_core_speech_read_tts(&sh, data, &datalen, &flags); + read++; + } while (status == SWITCH_STATUS_SUCCESS); + + fst_check(read = sample_rate / interval); // samples of 1 second + switch_core_speech_close(&sh, &flags); +} +FST_TEST_END() + +FST_TEST_BEGIN(tts_time) +{ + switch_speech_handle_t sh = { 0 }; + switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE; + switch_status_t status; + int sample_rate = 8000; + int interval = 20; + uint8_t data[320]; + size_t datalen = sizeof(data); + int read = 0; + + status = switch_core_speech_open(&sh, "test", "default", sample_rate, interval, 1, &flags, NULL); + fst_requires(status == SWITCH_STATUS_SUCCESS); + status = switch_core_speech_feed_tts(&sh, "silence://3000", &flags); + fst_requires(status == SWITCH_STATUS_SUCCESS); + do { + status = switch_core_speech_read_tts(&sh, data, &datalen, &flags); + read++; + switch_yield(interval * 1000); + } while (status == SWITCH_STATUS_SUCCESS); + + fst_check(read = sample_rate / interval * 3); // samples of 3 second + fst_check_duration(3000, 500); + switch_core_speech_close(&sh, &flags); +} +FST_TEST_END() + +FST_TEST_BEGIN(unload_test) +{ + const char *err = NULL; + switch_sleep(1000000); + fst_check(switch_loadable_module_unload_module(SWITCH_GLOBAL_dirs.mod_dir, (char *)"mod_test", SWITCH_FALSE, &err) == SWITCH_STATUS_SUCCESS); +} +FST_TEST_END() + + +FST_MODULE_END() + +FST_CORE_END()