45 #include <sys/socket.h> 47 #include <netinet/in.h> 48 #include <arpa/inet.h> 66 #define FESTIVAL_CONFIG "festival.conf" 68 #define MAXFESTLEN 2048 87 static 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;
284 struct hostent *serverhost;
289 const char *cachedir;
291 const char *festivalcommand;
300 unsigned char MD5Res[16];
301 char MD5Hex[33] =
"";
312 char *newfestivalcommand;
354 const char *startcmd =
"(tts_textasterisk \"";
355 const char *endcmd =
"\" 'file)(quit)\n";
357 strln = strlen(startcmd) + strlen(
args.text) + strlen(endcmd) + 1;
359 snprintf(newfestivalcommand, strln,
"%s%s%s", startcmd,
args.text, endcmd);
360 festivalcommand = newfestivalcommand;
363 newfestivalcommand =
ast_alloca(strlen(festivalcommand) + strlen(
args.text) + 1);
365 for (x = 0, j = 0; x < strlen(festivalcommand); x++) {
366 if (festivalcommand[x] ==
'\\' && festivalcommand[x + 1] ==
'n') {
367 newfestivalcommand[j++] =
'\n';
369 }
else if (festivalcommand[x] ==
'\\') {
370 newfestivalcommand[j++] = festivalcommand[x + 1];
372 }
else if (festivalcommand[x] ==
'%' && festivalcommand[x + 1] ==
's') {
373 sprintf(&newfestivalcommand[j],
"%s",
args.text);
374 j += strlen(
args.text);
377 newfestivalcommand[j++] = festivalcommand[x];
379 newfestivalcommand[j] =
'\0';
380 festivalcommand = newfestivalcommand;
383 if (
args.interrupt && !strcasecmp(
args.interrupt,
"any"))
386 ast_debug(1,
"Text passed to festival server : %s\n",
args.text);
389 fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
397 memset(&serv_addr, 0,
sizeof(serv_addr));
399 if ((serv_addr.sin_addr.s_addr = inet_addr(host)) == -1) {
403 if (serverhost ==
NULL) {
409 memmove(&serv_addr.sin_addr, serverhost->h_addr, serverhost->h_length);
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) + strlen(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 unload_module(void)
Main Channel structure associated with a channel.
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
#define ast_realloc(p, len)
A wrapper for realloc()
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
static int festival_exec(struct ast_channel *chan, const char *vdata)
#define CONFIG_STATUS_FILEINVALID
void ast_close_fds_above_n(int n)
Common routine for child processes, to close all fds prior to exec(2)
void MD5Final(unsigned char digest[16], struct MD5Context *context)
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
ast_channel_state
ast_channel states
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
int ast_unregister_application(const char *app)
Unregister an application.
static int send_waveform_to_channel(struct ast_channel *chan, char *waveform, int length, char *intkeys)
void MD5Init(struct MD5Context *context)
struct ast_frame_subclass subclass
#define ast_strlen_zero(foo)
Configuration File Parser.
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_config_load(filename, flags)
Load a config file.
General Asterisk PBX channel definitions.
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
Asterisk architecture endianess compatibility definitions.
void ast_config_destroy(struct ast_config *config)
Destroys a config.
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ast_malloc(len)
A wrapper for malloc()
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Core PBX routines and definitions.
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
void MD5Update(struct MD5Context *context, unsigned char const *buf, unsigned len)
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
int ast_safe_fork(int stop_reaper)
Common routine to safely fork without a chance of a signal handler firing badly in the child...
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.
Module has failed to load, may be in an inconsistent state.
Structure used to handle boolean flags.
AST_MODULE_INFO_STANDARD_EXTENDED(ASTERISK_GPL_KEY, "Simple Festival Interface")
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
struct hostent * ast_gethostbyname(const char *host, struct ast_hostent *hp)
Thread-safe gethostbyname function to use in Asterisk.
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
static unsigned char * buff
int ast_answer(struct ast_channel *chan)
Answer a channel.
Data structure associated with a single frame of data.
enum ast_frame_type frametype
static int load_module(void)
Load the module.
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
int ast_stopstream(struct ast_channel *c)
Stops a stream.
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
#define ast_opt_high_priority
static char * socket_receive_file_to_buff(int fd, int *size)
static int send_waveform_to_fd(char *waveform, int length, int fd)
#define AST_APP_ARG(name)
Define an application argument.