From 680f375cc2fdb624ee77fc1b0d113e117ca40036 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 18 Feb 2009 13:53:15 +0000 Subject: [PATCH] MODENDP-198 git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@12135 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/switch_module_interfaces.h | 10 +++++ src/mod/endpoints/mod_sofia/mod_sofia.c | 2 +- src/switch_core_speech.c | 59 +++++++++++++++++++++++-- 3 files changed, 67 insertions(+), 4 deletions(-) diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index 67d1f31839..3178538056 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -420,6 +420,16 @@ struct switch_speech_handle { char *param; /*! the handle's memory pool */ switch_memory_pool_t *memory_pool; + switch_audio_resampler_t *resampler; + switch_buffer_t *buffer; + switch_byte_t *dbuf; + switch_size_t dbuflen; + /*! the current samplerate */ + uint32_t samplerate; + /*! the current native samplerate */ + uint32_t native_rate; + /*! the number of channels */ + /*! private data for the format module to store handle specific info */ void *private_info; }; diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 683573bbb5..a8660bbbf5 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1907,7 +1907,7 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t if (!strcasecmp(argv[1], "killgw")) { sofia_gateway_t *gateway_ptr; - if (argc < 2) { + if (argc < 3) { stream->write_function(stream, "-ERR missing gw name\n"); goto done; } diff --git a/src/switch_core_speech.c b/src/switch_core_speech.c index 0c10e1af49..56456057dc 100644 --- a/src/switch_core_speech.c +++ b/src/switch_core_speech.c @@ -80,7 +80,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_speech_open(switch_speech_handle_t * sh->rate = rate; sh->name = switch_core_strdup(pool, module_name); sh->samples = switch_samples_per_packet(rate, interval); - + sh->native_rate = rate; return sh->speech_interface->speech_open(sh, voice_name, rate, flags); } @@ -130,9 +130,56 @@ SWITCH_DECLARE(void) switch_core_speech_float_param_tts(switch_speech_handle_t * SWITCH_DECLARE(switch_status_t) switch_core_speech_read_tts(switch_speech_handle_t *sh, void *data, switch_size_t *datalen, uint32_t *rate, switch_speech_flag_t *flags) { - switch_assert(sh != NULL); + switch_status_t status; + switch_size_t want, orig_len = *datalen; - return sh->speech_interface->speech_read_tts(sh, data, datalen, rate, flags); + switch_assert(sh != NULL); + + want = *datalen; + + more: + + status = sh->speech_interface->speech_read_tts(sh, data, datalen, rate, flags); + + if (sh->native_rate && sh->samplerate && sh->native_rate != sh->samplerate) { + if (!sh->resampler) { + if (switch_resample_create(&sh->resampler, + sh->native_rate, sh->samplerate, (uint32_t) orig_len, SWITCH_RESAMPLE_QUALITY) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unable to create resampler!\n"); + return SWITCH_STATUS_GENERR; + } + } + + switch_resample_process(sh->resampler, data, *datalen); + + if (sh->resampler->to_len < want || sh->resampler->to_len > orig_len) { + if (!sh->buffer) { + int factor = sh->resampler->to_len * sh->samplerate / 1000; + switch_buffer_create_dynamic(&sh->buffer, factor, factor, 0); + switch_assert(sh->buffer); + } + if (!sh->dbuf || sh->dbuflen < sh->resampler->to_len * 2) { + sh->dbuflen = sh->resampler->to_len * 2; + sh->dbuf = switch_core_alloc(sh->memory_pool, sh->dbuflen); + } + switch_assert(sh->resampler->to_len <= sh->dbuflen); + + memcpy((int16_t *) sh->dbuf, sh->resampler->to, sh->resampler->to_len * 2); + switch_buffer_write(sh->buffer, sh->dbuf, sh->resampler->to_len * 2); + + if (switch_buffer_inuse(sh->buffer) < want * 2) { + *datalen = want; + goto more; + } + *datalen = switch_buffer_read(sh->buffer, data, orig_len * 2) / 2; + } else { + memcpy(data, sh->resampler->to, sh->resampler->to_len * 2); + *datalen = sh->resampler->to_len; + } + } + + + return *datalen ? SWITCH_STATUS_SUCCESS : status; } @@ -140,6 +187,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_speech_close(switch_speech_handle_t { switch_status_t status = sh->speech_interface->speech_close(sh, flags); + if (sh->buffer) { + switch_buffer_destroy(&sh->buffer); + } + + switch_resample_destroy(&sh->resampler); + UNPROTECT_INTERFACE(sh->speech_interface); if (switch_test_flag(sh, SWITCH_SPEECH_FLAG_FREE_POOL)) {