2006-02-26 20:23:23 +00:00
|
|
|
/*
|
|
|
|
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
|
|
|
* Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
|
|
|
|
*
|
|
|
|
* 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 <anthmct@yahoo.com>
|
|
|
|
* Portions created by the Initial Developer are Copyright (C)
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
*
|
|
|
|
* Anthony Minessale II <anthmct@yahoo.com>
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* mod_cepstral.c -- Cepstral Interface
|
2006-07-17 18:05:13 +00:00
|
|
|
*
|
2006-07-17 18:19:00 +00:00
|
|
|
* Contains some material derived from the Cepstral Swift SDK, by
|
|
|
|
* permission. You are free to copy and modify the source under the
|
|
|
|
* terms of FreeSWITCH itself, without additional permission from
|
|
|
|
* Cepstral
|
|
|
|
*
|
2006-02-26 20:23:23 +00:00
|
|
|
*
|
|
|
|
*/
|
2006-03-30 23:02:50 +00:00
|
|
|
#ifdef __ICC
|
|
|
|
#pragma warning (disable:188)
|
|
|
|
#endif
|
2007-03-12 05:13:43 +00:00
|
|
|
#ifdef MACOSX
|
|
|
|
#include <swift/swift.h>
|
|
|
|
#else
|
2006-03-03 19:59:00 +00:00
|
|
|
#include <swift.h>
|
2007-03-12 05:13:43 +00:00
|
|
|
#endif
|
2006-02-26 20:23:23 +00:00
|
|
|
#include <switch.h>
|
|
|
|
|
2006-09-08 18:57:24 +00:00
|
|
|
#define MY_BUF_LEN 1024 * 32
|
|
|
|
#define MY_BLOCK_SIZE MY_BUF_LEN
|
2006-06-08 01:58:37 +00:00
|
|
|
|
2007-03-18 17:15:29 +00:00
|
|
|
#undef SWIFT_FAILED
|
|
|
|
#define SWIFT_FAILED(r) ((void *)(r) < (void *)0)
|
|
|
|
|
2007-06-13 17:06:10 +00:00
|
|
|
SWITCH_MODULE_LOAD_FUNCTION(mod_cepstral_load);
|
|
|
|
SWITCH_MODULE_DEFINITION(mod_cepstral, mod_cepstral_load, NULL, NULL);
|
2006-02-26 20:23:23 +00:00
|
|
|
|
|
|
|
static swift_engine *engine;
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
swift_background_t tts_stream;
|
|
|
|
swift_port *port;
|
|
|
|
swift_params *params;
|
|
|
|
swift_voice *voice;
|
|
|
|
switch_mutex_t *audio_lock;
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_buffer_t *audio_buffer;
|
2006-02-26 20:23:23 +00:00
|
|
|
int done;
|
|
|
|
int done_gen;
|
|
|
|
} cepstral_t;
|
|
|
|
|
|
|
|
|
|
|
|
/* This callback caches the audio in the buffer */
|
2007-03-29 22:31:56 +00:00
|
|
|
static swift_result_t write_audio(swift_event * event, swift_event_t type, void *udata)
|
2006-02-26 20:23:23 +00:00
|
|
|
{
|
|
|
|
cepstral_t *cepstral;
|
2007-03-29 22:31:56 +00:00
|
|
|
swift_event_t rv = SWIFT_SUCCESS;
|
|
|
|
void *buf = NULL;
|
|
|
|
int len = 0, i = 0;
|
|
|
|
|
2006-02-26 20:23:23 +00:00
|
|
|
cepstral = udata;
|
|
|
|
assert(cepstral != NULL);
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-06-08 01:58:37 +00:00
|
|
|
if (!cepstral->port || cepstral->done || cepstral->done_gen) {
|
2007-03-29 22:31:56 +00:00
|
|
|
return SWIFT_UNKNOWN_ERROR;
|
2006-06-08 01:58:37 +00:00
|
|
|
}
|
|
|
|
|
2006-02-26 20:23:23 +00:00
|
|
|
/* Only proceed when we have success */
|
2007-03-29 22:31:56 +00:00
|
|
|
if (!SWIFT_FAILED((rv = swift_event_get_audio(event, &buf, &len)))) {
|
|
|
|
while (!cepstral->done) {
|
2006-06-08 01:58:37 +00:00
|
|
|
switch_mutex_lock(cepstral->audio_lock);
|
|
|
|
if (switch_buffer_write(cepstral->audio_buffer, buf, len) > 0) {
|
|
|
|
switch_mutex_unlock(cepstral->audio_lock);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
switch_mutex_unlock(cepstral->audio_lock);
|
|
|
|
if (!cepstral->done) {
|
|
|
|
for (i = 0; i < 10; i++) {
|
|
|
|
switch_yield(10000);
|
|
|
|
if (cepstral->done) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-02-26 20:23:23 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
cepstral->done = 1;
|
|
|
|
}
|
|
|
|
|
2006-06-08 01:58:37 +00:00
|
|
|
if (cepstral->done) {
|
|
|
|
rv = SWIFT_UNKNOWN_ERROR;
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
|
|
|
return rv;
|
2006-02-26 20:23:23 +00:00
|
|
|
}
|
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
static switch_status_t cepstral_speech_open(switch_speech_handle_t *sh, char *voice_name, int rate, switch_speech_flag_t *flags)
|
2006-02-26 20:23:23 +00:00
|
|
|
{
|
2006-11-09 05:39:04 +00:00
|
|
|
cepstral_t *cepstral = switch_core_alloc(sh->memory_pool, sizeof(*cepstral));
|
|
|
|
char srate[25];
|
2006-02-26 20:23:23 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if (!cepstral) {
|
|
|
|
return SWITCH_STATUS_MEMERR;
|
|
|
|
}
|
2006-02-26 20:23:23 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if (switch_buffer_create_dynamic(&cepstral->audio_buffer, MY_BLOCK_SIZE, MY_BUF_LEN, 0) != SWITCH_STATUS_SUCCESS) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Write Buffer Failed!\n");
|
|
|
|
return SWITCH_STATUS_MEMERR;
|
|
|
|
}
|
2006-02-26 20:23:23 +00:00
|
|
|
|
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
switch_mutex_init(&cepstral->audio_lock, SWITCH_MUTEX_NESTED, sh->memory_pool);
|
2006-02-26 20:23:23 +00:00
|
|
|
|
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
cepstral->params = swift_params_new(NULL);
|
|
|
|
swift_params_set_string(cepstral->params, "audio/encoding", "pcm16");
|
2007-12-12 21:53:32 +00:00
|
|
|
switch_snprintf(srate, sizeof(srate), "%d", rate);
|
2006-11-09 05:39:04 +00:00
|
|
|
swift_params_set_string(cepstral->params, "audio/sampling-rate", srate);
|
2006-02-26 20:23:23 +00:00
|
|
|
|
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
/* Open a Swift Port through which to make TTS calls */
|
|
|
|
if (SWIFT_FAILED(cepstral->port = swift_port_open(engine, cepstral->params))) {
|
2007-11-23 18:50:54 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open Swift Port.\n");
|
2006-11-09 05:39:04 +00:00
|
|
|
goto all_done;
|
|
|
|
}
|
2006-02-26 20:23:23 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if (voice_name && SWIFT_FAILED(swift_port_set_voice_by_name(cepstral->port, voice_name))) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid voice %s!\n", voice_name);
|
|
|
|
voice_name = NULL;
|
|
|
|
}
|
2006-06-08 19:22:54 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if (!voice_name) {
|
|
|
|
/* Find the first voice on the system */
|
|
|
|
if ((cepstral->voice = swift_port_find_first_voice(cepstral->port, NULL, NULL)) == NULL) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find any voices!\n");
|
|
|
|
goto all_done;
|
2006-02-26 20:23:23 +00:00
|
|
|
}
|
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
/* Set the voice found by find_first_voice() as the port's current voice */
|
2007-03-29 22:31:56 +00:00
|
|
|
if (SWIFT_FAILED(swift_port_set_voice(cepstral->port, cepstral->voice))) {
|
2006-11-09 05:39:04 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set voice.\n");
|
|
|
|
goto all_done;
|
|
|
|
}
|
2006-06-08 19:22:54 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
voice_name = (char *) swift_voice_get_attribute(cepstral->voice, "name");
|
|
|
|
}
|
2006-02-26 20:23:23 +00:00
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
if (voice_name) {
|
|
|
|
switch_copy_string(sh->voice, voice_name, sizeof(sh->voice));
|
2006-02-26 20:23:23 +00:00
|
|
|
}
|
|
|
|
|
2006-11-09 05:39:04 +00:00
|
|
|
swift_port_set_callback(cepstral->port, &write_audio, SWIFT_EVENT_AUDIO, cepstral);
|
|
|
|
|
|
|
|
sh->private_info = cepstral;
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
|
|
|
all_done:
|
2006-02-26 20:23:23 +00:00
|
|
|
return SWITCH_STATUS_FALSE;
|
|
|
|
}
|
|
|
|
|
2006-04-29 23:43:28 +00:00
|
|
|
static switch_status_t cepstral_speech_close(switch_speech_handle_t *sh, switch_speech_flag_t *flags)
|
2006-02-26 20:23:23 +00:00
|
|
|
{
|
|
|
|
cepstral_t *cepstral;
|
|
|
|
|
|
|
|
assert(sh != NULL);
|
|
|
|
cepstral = sh->private_info;
|
|
|
|
assert(cepstral != NULL);
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-06-08 01:58:37 +00:00
|
|
|
|
|
|
|
cepstral->done = 1;
|
|
|
|
cepstral->done_gen = 1;
|
|
|
|
swift_port_stop(cepstral->port, SWIFT_ASYNC_ANY, SWIFT_EVENT_NOW);
|
2006-02-26 20:23:23 +00:00
|
|
|
/* Close the Swift Port and Engine */
|
2007-03-29 22:31:56 +00:00
|
|
|
if (NULL != cepstral->port)
|
|
|
|
swift_port_close(cepstral->port);
|
2006-02-26 20:23:23 +00:00
|
|
|
//if (NULL != cepstral->engine) swift_engine_close(cepstral->engine);
|
|
|
|
|
|
|
|
cepstral->port = NULL;
|
|
|
|
//cepstral->engine = NULL;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-09-08 18:57:24 +00:00
|
|
|
switch_buffer_destroy(&cepstral->audio_buffer);
|
|
|
|
|
2006-02-26 20:23:23 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2006-04-29 23:43:28 +00:00
|
|
|
static switch_status_t cepstral_speech_feed_tts(switch_speech_handle_t *sh, char *text, switch_speech_flag_t *flags)
|
2006-02-26 20:23:23 +00:00
|
|
|
{
|
|
|
|
cepstral_t *cepstral;
|
2006-06-09 15:15:58 +00:00
|
|
|
const char *fp = "file:";
|
2007-03-29 22:31:56 +00:00
|
|
|
int len = (int) strlen(fp);
|
2006-02-26 20:23:23 +00:00
|
|
|
|
|
|
|
assert(sh != NULL);
|
|
|
|
cepstral = sh->private_info;
|
|
|
|
assert(cepstral != NULL);
|
|
|
|
|
2006-06-08 01:58:37 +00:00
|
|
|
cepstral->done_gen = 0;
|
|
|
|
cepstral->done = 0;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-06-08 01:58:37 +00:00
|
|
|
cepstral->tts_stream = NULL;
|
2006-09-21 01:38:37 +00:00
|
|
|
|
2006-06-09 15:15:58 +00:00
|
|
|
if (!strncasecmp(text, fp, len)) {
|
|
|
|
text += len;
|
2006-07-24 18:56:20 +00:00
|
|
|
if (switch_strlen_zero(text)) {
|
|
|
|
return SWITCH_STATUS_FALSE;
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
swift_port_speak_file(cepstral->port, text, NULL, &cepstral->tts_stream, NULL);
|
2006-06-09 15:15:58 +00:00
|
|
|
} else {
|
2007-03-29 22:31:56 +00:00
|
|
|
char *to_say;
|
2006-07-24 18:56:20 +00:00
|
|
|
if (switch_strlen_zero(text)) {
|
|
|
|
return SWITCH_STATUS_FALSE;
|
|
|
|
}
|
2006-10-25 16:17:54 +00:00
|
|
|
|
2007-10-11 13:56:21 +00:00
|
|
|
if ((to_say = switch_mprintf("<break time=\"1000ms\"/> %s <break time=\"1000ms\"/>", text))) {
|
2007-03-29 22:31:56 +00:00
|
|
|
swift_port_speak_text(cepstral->port, to_say, 0, NULL, &cepstral->tts_stream, NULL);
|
|
|
|
switch_safe_free(to_say);
|
|
|
|
}
|
2006-06-09 15:15:58 +00:00
|
|
|
}
|
2006-02-26 20:23:23 +00:00
|
|
|
|
2006-07-24 18:56:20 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
2006-02-26 20:23:23 +00:00
|
|
|
}
|
|
|
|
|
2006-06-08 01:58:37 +00:00
|
|
|
static void cepstral_speech_flush_tts(switch_speech_handle_t *sh)
|
|
|
|
{
|
|
|
|
cepstral_t *cepstral;
|
|
|
|
|
|
|
|
cepstral = sh->private_info;
|
2007-03-29 22:31:56 +00:00
|
|
|
assert(cepstral != NULL);
|
2006-06-08 01:58:37 +00:00
|
|
|
|
|
|
|
cepstral->done_gen = 1;
|
2007-03-29 22:31:56 +00:00
|
|
|
cepstral->done = 1;
|
2006-06-08 01:58:37 +00:00
|
|
|
if (cepstral->audio_buffer) {
|
|
|
|
switch_mutex_lock(cepstral->audio_lock);
|
|
|
|
switch_buffer_zero(cepstral->audio_buffer);
|
|
|
|
switch_mutex_unlock(cepstral->audio_lock);
|
|
|
|
}
|
|
|
|
swift_port_stop(cepstral->port, SWIFT_ASYNC_ANY, SWIFT_EVENT_NOW);
|
|
|
|
}
|
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
static switch_status_t cepstral_speech_read_tts(switch_speech_handle_t *sh, void *data, size_t *datalen, uint32_t * rate, switch_speech_flag_t *flags)
|
2006-02-26 20:23:23 +00:00
|
|
|
{
|
|
|
|
cepstral_t *cepstral;
|
2006-02-27 04:33:58 +00:00
|
|
|
size_t desired = *datalen;
|
2006-04-29 23:43:28 +00:00
|
|
|
switch_status_t status = SWITCH_STATUS_FALSE;
|
2006-02-27 04:33:58 +00:00
|
|
|
size_t used, padding = 0;
|
2006-02-26 20:23:23 +00:00
|
|
|
|
|
|
|
assert(sh != NULL);
|
|
|
|
cepstral = sh->private_info;
|
|
|
|
assert(cepstral != NULL);
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
while (!cepstral->done) {
|
2006-02-26 20:23:23 +00:00
|
|
|
if (!cepstral->done_gen) {
|
2006-06-08 01:58:37 +00:00
|
|
|
int check = swift_port_status(cepstral->port, cepstral->tts_stream);
|
|
|
|
|
|
|
|
if (!check == SWIFT_STATUS_RUNNING) {
|
2006-02-26 20:23:23 +00:00
|
|
|
cepstral->done_gen = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-06-08 01:58:37 +00:00
|
|
|
switch_mutex_lock(cepstral->audio_lock);
|
2006-02-26 20:23:23 +00:00
|
|
|
used = switch_buffer_inuse(cepstral->audio_buffer);
|
2006-06-08 01:58:37 +00:00
|
|
|
switch_mutex_unlock(cepstral->audio_lock);
|
2007-03-29 22:31:56 +00:00
|
|
|
|
|
|
|
|
2006-02-26 20:23:23 +00:00
|
|
|
if (!used && cepstral->done_gen) {
|
2006-06-08 01:58:37 +00:00
|
|
|
|
|
|
|
status = SWITCH_STATUS_BREAK;
|
2006-02-26 20:23:23 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* wait for the right amount of data (unless there is no blocking flag) */
|
|
|
|
if (used < desired) {
|
|
|
|
if (cepstral->done_gen) {
|
|
|
|
padding = desired - used;
|
|
|
|
desired = used;
|
|
|
|
}
|
|
|
|
if (!(*flags & SWITCH_SPEECH_FLAG_BLOCKING)) {
|
|
|
|
*datalen = 0;
|
|
|
|
status = SWITCH_STATUS_SUCCESS;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
switch_yield(1000);
|
|
|
|
continue;
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-02-26 20:23:23 +00:00
|
|
|
/* There is enough, read it and return */
|
|
|
|
switch_mutex_lock(cepstral->audio_lock);
|
|
|
|
*datalen = switch_buffer_read(cepstral->audio_buffer, data, desired);
|
|
|
|
if (padding) {
|
2006-02-27 04:33:58 +00:00
|
|
|
size_t x = 0;
|
2006-02-26 20:23:23 +00:00
|
|
|
unsigned char *p = data;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
|
|
|
for (x = 0; x < padding; x++) {
|
2006-02-26 20:23:23 +00:00
|
|
|
*(p + x) = 0;
|
|
|
|
(*datalen)++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch_mutex_unlock(cepstral->audio_lock);
|
|
|
|
status = SWITCH_STATUS_SUCCESS;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-02-26 20:23:23 +00:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2006-06-08 19:22:54 +00:00
|
|
|
static void cepstral_text_param_tts(switch_speech_handle_t *sh, char *param, char *val)
|
|
|
|
{
|
|
|
|
cepstral_t *cepstral;
|
|
|
|
|
|
|
|
cepstral = sh->private_info;
|
|
|
|
assert(cepstral != NULL);
|
|
|
|
|
|
|
|
if (!strcasecmp(param, "voice")) {
|
|
|
|
char *voice_name = val;
|
|
|
|
if (!strcasecmp(voice_name, "next")) {
|
|
|
|
if ((cepstral->voice = swift_port_find_next_voice(cepstral->port))) {
|
2007-03-29 22:31:56 +00:00
|
|
|
if (SWIFT_FAILED(swift_port_set_voice(cepstral->port, cepstral->voice))) {
|
2006-06-08 19:22:54 +00:00
|
|
|
cepstral->done = cepstral->done_gen = 1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
voice_name = (char *) swift_voice_get_attribute(cepstral->voice, "name");
|
|
|
|
} else {
|
|
|
|
voice_name = NULL;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (voice_name && SWIFT_FAILED(swift_port_set_voice_by_name(cepstral->port, voice_name))) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid voice %s!\n", voice_name);
|
|
|
|
voice_name = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!voice_name) {
|
2007-03-29 22:31:56 +00:00
|
|
|
/* Find the first voice on the system */
|
|
|
|
if ((cepstral->voice = swift_port_find_first_voice(cepstral->port, NULL, NULL)) == NULL) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find any voices!\n");
|
2006-06-08 19:22:54 +00:00
|
|
|
cepstral->done = cepstral->done_gen = 1;
|
|
|
|
return;
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
2006-06-08 19:22:54 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
/* Set the voice found by find_first_voice() as the port's current voice */
|
|
|
|
if (SWIFT_FAILED(swift_port_set_voice(cepstral->port, cepstral->voice))) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set voice.\n");
|
2006-06-08 19:22:54 +00:00
|
|
|
cepstral->done = cepstral->done_gen = 1;
|
|
|
|
return;
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
2006-06-08 19:22:54 +00:00
|
|
|
|
|
|
|
voice_name = (char *) swift_voice_get_attribute(cepstral->voice, "name");
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
2006-06-08 19:22:54 +00:00
|
|
|
|
|
|
|
if (voice_name) {
|
|
|
|
switch_copy_string(sh->voice, voice_name, sizeof(sh->voice));
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
swift_port_set_param_string(cepstral->port, param, val, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void cepstral_numeric_param_tts(switch_speech_handle_t *sh, char *param, int val)
|
|
|
|
{
|
|
|
|
cepstral_t *cepstral;
|
|
|
|
|
|
|
|
cepstral = sh->private_info;
|
|
|
|
assert(cepstral != NULL);
|
|
|
|
|
|
|
|
swift_port_set_param_int(cepstral->port, param, val, NULL);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void cepstral_float_param_tts(switch_speech_handle_t *sh, char *param, double val)
|
|
|
|
{
|
|
|
|
cepstral_t *cepstral;
|
|
|
|
|
|
|
|
cepstral = sh->private_info;
|
|
|
|
assert(cepstral != NULL);
|
|
|
|
|
|
|
|
swift_port_set_param_float(cepstral->port, param, val, NULL);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2007-06-13 17:06:10 +00:00
|
|
|
SWITCH_MODULE_LOAD_FUNCTION(mod_cepstral_load)
|
2006-02-26 20:23:23 +00:00
|
|
|
{
|
2007-06-20 07:15:53 +00:00
|
|
|
switch_speech_interface_t *speech_interface;
|
2006-02-26 20:23:23 +00:00
|
|
|
|
|
|
|
/* Open the Swift TTS Engine */
|
2007-03-29 22:31:56 +00:00
|
|
|
if (SWIFT_FAILED(engine = swift_engine_open(NULL))) {
|
2006-04-16 06:05:53 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open Swift Engine.");
|
2006-02-26 20:23:23 +00:00
|
|
|
return SWITCH_STATUS_GENERR;
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-02-26 20:23:23 +00:00
|
|
|
/* connect my internal structure to the blank pointer passed to me */
|
2007-06-20 07:15:53 +00:00
|
|
|
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
|
|
|
|
speech_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_SPEECH_INTERFACE);
|
|
|
|
speech_interface->interface_name = "cepstral";
|
|
|
|
speech_interface->speech_open = cepstral_speech_open;
|
|
|
|
speech_interface->speech_close = cepstral_speech_close;
|
|
|
|
speech_interface->speech_feed_tts = cepstral_speech_feed_tts;
|
|
|
|
speech_interface->speech_read_tts = cepstral_speech_read_tts;
|
|
|
|
speech_interface->speech_flush_tts = cepstral_speech_flush_tts;
|
|
|
|
speech_interface->speech_text_param_tts = cepstral_text_param_tts;
|
|
|
|
speech_interface->speech_numeric_param_tts = cepstral_numeric_param_tts;
|
|
|
|
speech_interface->speech_float_param_tts = cepstral_float_param_tts;
|
2006-02-26 20:23:23 +00:00
|
|
|
|
|
|
|
/* indicate that the module should continue to be loaded */
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
2006-11-27 22:30:48 +00:00
|
|
|
|
|
|
|
/* For Emacs:
|
|
|
|
* Local Variables:
|
|
|
|
* mode:c
|
2008-02-03 22:14:57 +00:00
|
|
|
* indent-tabs-mode:t
|
2006-11-27 22:30:48 +00:00
|
|
|
* tab-width:4
|
|
|
|
* c-basic-offset:4
|
|
|
|
* End:
|
|
|
|
* For VIM:
|
|
|
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
|
|
|
*/
|