45#include <sys/socket.h>
47#include <netinet/in.h>
66#define FESTIVAL_CONFIG "festival.conf"
68#define MAXFESTLEN 2048
87static char *
app =
"Festival";
96 static char *file_stuff_key =
"ft_StUfF_key";
107 for (k = 0; file_stuff_key[k] !=
'\0';) {
111 if ((*size) + k + 1 >= bufflen) {
113 bufflen += bufflen / 4;
120 if (file_stuff_key[k] ==
c)
122 else if ((
c ==
'X') && (file_stuff_key[k+1] ==
'\0')) {
124 for (i = 0; i < k; i++, (*size)++)
125 buff[*size] = file_stuff_key[i];
129 for (i = 0; i < k; i++, (*size)++)
130 buff[*size] = file_stuff_key[i];
143#if __BYTE_ORDER == __BIG_ENDIAN
158#if __BYTE_ORDER == __BIG_ENDIAN
159 for (x = 0; x < length; x += 2) {
160 c = *(waveform + x + 1);
161 *(waveform + x + 1) = *(waveform + x);
166 if (write(0, waveform, length) < 0) {
211 myf.f.src = __PRETTY_FUNCTION__;
212 myf.f.data.ptr = myf.frdata;
241 if (needed >
sizeof(myf.frdata)) {
243 (
int)
sizeof(myf.frdata) / 2, needed/2);
244 needed =
sizeof(myf.frdata);
246 res = read(fds[0], myf.frdata, needed);
249 myf.f.samples = res / 2;
272 if (!res && owriteformat)
283 struct sockaddr_in serv_addr;
287 const char *cachedir;
289 const char *festivalcommand;
298 unsigned char MD5Res[16];
299 char MD5Hex[33] =
"";
310 char *newfestivalcommand;
352 const char *startcmd =
"(tts_textasterisk \"";
353 const char *endcmd =
"\" 'file)(quit)\n";
355 strln = strlen(startcmd) + strlen(
args.text) + strlen(endcmd) + 1;
357 snprintf(newfestivalcommand, strln,
"%s%s%s", startcmd,
args.text, endcmd);
358 festivalcommand = newfestivalcommand;
361 newfestivalcommand =
ast_alloca(strlen(festivalcommand) + strlen(
args.text) + 1);
363 for (x = 0, j = 0; x < strlen(festivalcommand); x++) {
364 if (festivalcommand[x] ==
'\\' && festivalcommand[x + 1] ==
'n') {
365 newfestivalcommand[j++] =
'\n';
367 }
else if (festivalcommand[x] ==
'\\') {
368 newfestivalcommand[j++] = festivalcommand[x + 1];
370 }
else if (festivalcommand[x] ==
'%' && festivalcommand[x + 1] ==
's') {
371 sprintf(&newfestivalcommand[j],
"%s",
args.text);
372 j += strlen(
args.text);
375 newfestivalcommand[j++] = festivalcommand[x];
377 newfestivalcommand[j] =
'\0';
378 festivalcommand = newfestivalcommand;
381 if (
args.interrupt && !strcasecmp(
args.interrupt,
"any"))
384 ast_debug(1,
"Text passed to festival server : %s\n",
args.text);
387 fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
395 memset(&serv_addr, 0,
sizeof(serv_addr));
397 if ((serv_addr.sin_addr.s_addr = inet_addr(host)) == -1) {
412 serv_addr.sin_family = AF_INET;
413 serv_addr.sin_port = htons(port);
415 if (connect(fd, (
struct sockaddr *)&serv_addr,
sizeof(serv_addr)) != 0) {
430 for (i = 0; i < 16; i++) {
431 snprintf(koko,
sizeof(koko),
"%X", (
unsigned)MD5Res[i]);
432 strncat(MD5Hex, koko,
sizeof(MD5Hex) - strlen(MD5Hex) - 1);
436 if (strlen(cachedir) +
sizeof(MD5Hex) + 1 <=
MAXFESTLEN && (usecache == -1)) {
437 snprintf(cachefile,
sizeof(cachefile),
"%s/%s", cachedir, MD5Hex);
438 fdesc = open(cachefile, O_RDWR);
443 strln = strlen(
args.text);
444 ast_debug(1,
"line length : %d\n", strln);
445 if (write(fdesc,&strln,
sizeof(
int)) < 0) {
448 if (write(fdesc,data,strln) < 0) {
451 seekpos = lseek(fdesc, 0, SEEK_CUR);
452 ast_debug(1,
"Seek position : %d\n", seekpos);
455 if (read(fdesc,&strln,
sizeof(
int)) !=
sizeof(
int)) {
458 ast_debug(1,
"Cache file exists, strln=%d, strlen=%d\n", strln, (
int)strlen(
args.text));
459 if (strlen(
args.text) == strln) {
461 if (read(fdesc,&bigstring,strln) != strln) {
464 bigstring[strln] = 0;
465 if (strcmp(bigstring,
args.text) == 0) {
476 if (readcache == 1) {
481 ast_debug(1,
"Passing text to festival...\n");
482 fs = fdopen(dup(fd),
"wb");
484 fprintf(fs,
"%s", festivalcommand);
490 if (writecache == 1) {
491 ast_debug(1,
"Writing result to cache...\n");
492 while ((strln = read(fd, buffer, 16384)) != 0) {
493 if (write(fdesc,buffer,strln) < 0) {
499 fd = open(cachefile, O_RDWR);
500 lseek(fd, seekpos, SEEK_SET);
503 ast_debug(1,
"Passing data to channel...\n");
509 for (n = 0; n < 3; ) {
510 read_data = read(fd, ack + n, 3 - n);
514 if (read_data == -1) {
523 if (strcmp(ack,
"WV\n") == 0) {
530 }
else if (strcmp(ack,
"LP\n") == 0) {
533 waveform[filesize] =
'\0';
537 }
else if (strcmp(ack,
"ER\n") == 0) {
542 }
while (strcmp(ack,
"OK\n") != 0);
static int send_waveform_to_fd(char *waveform, int length, int fd)
static int send_waveform_to_channel(struct ast_channel *chan, char *waveform, int length, char *intkeys)
static char * socket_receive_file_to_buff(int fd, int *size)
static int festival_exec(struct ast_channel *chan, const char *vdata)
static int load_module(void)
Load the module.
static int unload_module(void)
AST_MODULE_INFO_STANDARD_EXTENDED(ASTERISK_GPL_KEY, "Simple Festival Interface")
Asterisk main include file. File version handling, generic pbx functions.
int ast_set_priority(int)
We set ourselves to a high priority, that we might pre-empt everything else. If your PBX has heavy ac...
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define ast_realloc(p, len)
A wrapper for realloc()
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ast_malloc(len)
A wrapper for malloc()
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
static unsigned char * buff
General Asterisk PBX channel definitions.
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
int ast_write(struct ast_channel *chan, struct ast_frame *frame)
Write a frame to a channel This function writes the given frame to the indicated channel.
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
int ast_answer(struct ast_channel *chan)
Answer a channel.
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
ast_channel_state
ast_channel states
Asterisk architecture endianess compatibility definitions.
Generic File Format Support. Should be included by clients of the file handling routines....
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
#define AST_APP_ARG(name)
Define an application argument.
int ast_safe_fork(int stop_reaper)
Common routine to safely fork without a chance of a signal handler firing badly in the child.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
void ast_close_fds_above_n(int n)
Common routine for child processes, to close all fds prior to exec(2)
Configuration File Parser.
#define ast_config_load(filename, flags)
Load a config file.
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
#define ast_debug(level,...)
Log a DEBUG message.
Asterisk locking-related definitions:
void MD5Update(struct MD5Context *context, unsigned char const *buf, unsigned len)
void MD5Init(struct MD5Context *context)
void MD5Final(unsigned char digest[16], struct MD5Context *context)
Asterisk module definitions.
#define ASTERISK_GPL_KEY
The text the key() function should return.
int ast_unregister_application(const char *app)
Unregister an application.
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
int ast_sockaddr_resolve_first_af(struct ast_sockaddr *addr, const char *name, int flag, int family)
Return the first entry from ast_sockaddr_resolve filtered by address family.
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
#define ast_opt_high_priority
Core PBX routines and definitions.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Main Channel structure associated with a channel.
Structure used to handle boolean flags.
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
enum ast_frame_type frametype
Socket address structure.