diff options
Diffstat (limited to 'navit/support/espeak/fifo.c')
-rw-r--r-- | navit/support/espeak/fifo.c | 166 |
1 files changed, 91 insertions, 75 deletions
diff --git a/navit/support/espeak/fifo.c b/navit/support/espeak/fifo.c index 95d5ab1ed..97c0fb9cc 100644 --- a/navit/support/espeak/fifo.c +++ b/navit/support/espeak/fifo.c @@ -24,7 +24,9 @@ //<includes +#ifndef PLATFORM_WINDOWS #include <unistd.h> +#endif #include <assert.h> #include <string.h> #include <stdlib.h> @@ -43,7 +45,7 @@ //> //<decls and function prototypes -// my_mutex: protects my_thread_is_talking, +// my_mutex: protects my_thread_is_talking, // my_stop_is_required, and the command fifo static pthread_mutex_t my_mutex; static int my_command_is_running = 0; @@ -51,7 +53,7 @@ static int my_stop_is_required = 0; // + fifo // -// my_thread: reads commands from the fifo, and runs them. +// my_thread: reads commands from the fifo, and runs them. static pthread_t my_thread; static sem_t my_sem_start_is_required; static sem_t my_sem_stop_is_acknowledged; @@ -60,7 +62,7 @@ static void* say_thread(void*); static espeak_ERROR push(t_espeak_command* the_command); static t_espeak_command* pop(); -static void init(); +static void init(int process_parameters); static int node_counter=0; enum {MAX_NODE_COUNTER=400, INACTIVITY_TIMEOUT=50, // in ms, check that the stream is inactive @@ -75,17 +77,17 @@ void fifo_init() // security pthread_mutex_init( &my_mutex, (const pthread_mutexattr_t *)NULL); - init(); + init(0); assert(-1 != sem_init(&my_sem_start_is_required, 0, 0)); assert(-1 != sem_init(&my_sem_stop_is_acknowledged, 0, 0)); - pthread_attr_t a_attrib; + pthread_attr_t a_attrib; if (pthread_attr_init (& a_attrib) || pthread_attr_setdetachstate(&a_attrib, PTHREAD_CREATE_JOINABLE) - || pthread_create( &my_thread, - & a_attrib, - say_thread, + || pthread_create( &my_thread, + & a_attrib, + say_thread, (void*)NULL)) { assert(0); @@ -107,8 +109,8 @@ void fifo_init() espeak_ERROR fifo_add_command (t_espeak_command* the_command) { ENTER("fifo_add_command"); - - int a_status = pthread_mutex_lock(&my_mutex); + + int a_status = pthread_mutex_lock(&my_mutex); espeak_ERROR a_error = EE_OK; if (!a_status) @@ -121,12 +123,12 @@ espeak_ERROR fifo_add_command (t_espeak_command* the_command) if (!a_status && !my_command_is_running && (a_error == EE_OK)) { - // quit when command is actually started + // quit when command is actually started // (for possible forthcoming 'end of command' checks) SHOW_TIME("fifo_add_command > post my_sem_start_is_required\n"); sem_post(&my_sem_start_is_required); int val=1; - while (val) + while (val > 0) { usleep(50000); // TBD: event? sem_getvalue(&my_sem_start_is_required, &val); @@ -148,8 +150,8 @@ espeak_ERROR fifo_add_command (t_espeak_command* the_command) espeak_ERROR fifo_add_commands (t_espeak_command* command1, t_espeak_command* command2) { ENTER("fifo_add_command"); - - int a_status = pthread_mutex_lock(&my_mutex); + + int a_status = pthread_mutex_lock(&my_mutex); espeak_ERROR a_error = EE_OK; if (!a_status) @@ -172,12 +174,12 @@ espeak_ERROR fifo_add_commands (t_espeak_command* command1, t_espeak_command* co if (!a_status && !my_command_is_running && (a_error == EE_OK)) { - // quit when one command is actually started + // quit when one command is actually started // (for possible forthcoming 'end of command' checks) SHOW_TIME("fifo_add_command > post my_sem_start_is_required\n"); sem_post(&my_sem_start_is_required); int val=1; - while (val) + while (val > 0) { usleep(50000); // TBD: event? sem_getvalue(&my_sem_start_is_required, &val); @@ -275,54 +277,58 @@ static int sleep_until_start_request_or_inactivity() int a_start_is_required=0; // Wait for the start request (my_sem_start_is_required). - // Besides this, if the audio stream is still busy, - // check from time to time its end. - // The end of the stream is confirmed by several checks + // Besides this, if the audio stream is still busy, + // check from time to time its end. + // The end of the stream is confirmed by several checks // for filtering underflow. // int i=0; - while((i<= MAX_INACTIVITY_CHECK) && !a_start_is_required) - { - if (wave_is_busy( NULL) ) + while((i<= MAX_INACTIVITY_CHECK) && !a_start_is_required) { - i = 0; - } + if (wave_is_busy( NULL) ) + { + i = 0; + } else - { - i++; - } + { + i++; + } - int err=0; - struct timespec ts, to; - struct timeval tv; - - clock_gettime2( &ts); - to.tv_sec = ts.tv_sec; - to.tv_nsec = ts.tv_nsec; - - add_time_in_ms( &ts, INACTIVITY_TIMEOUT); - - SHOW("fifo > sleep_until_start_request_or_inactivity > start sem_timedwait (start_is_required) from %d.%09lu to %d.%09lu \n", - to.tv_sec, to.tv_nsec, - ts.tv_sec, ts.tv_nsec); - - while ((err = sem_timedwait(&my_sem_start_is_required, &ts)) == -1 - && errno == EINTR) - { - continue; - } - - assert (gettimeofday(&tv, NULL) != -1); - SHOW("fifo > sleep_until_start_request_or_inactivity > stop sem_timedwait (start_is_required, err=%d) %d.%09lu \n", err, - tv.tv_sec, tv.tv_usec*1000); - - if (err==0) - { - a_start_is_required = 1; + int err=0; + struct timespec ts; + struct timeval tv; + + clock_gettime2( &ts); + +#ifdef DEBUG_ENABLED + struct timespec to; + to.tv_sec = ts.tv_sec; + to.tv_nsec = ts.tv_nsec; +#endif + + add_time_in_ms( &ts, INACTIVITY_TIMEOUT); + + SHOW("fifo > sleep_until_start_request_or_inactivity > start sem_timedwait (start_is_required) from %d.%09lu to %d.%09lu \n", + to.tv_sec, to.tv_nsec, + ts.tv_sec, ts.tv_nsec); + + while ((err = sem_timedwait(&my_sem_start_is_required, &ts)) == -1 + && errno == EINTR) + { + continue; + } + + assert (gettimeofday(&tv, NULL) != -1); + SHOW("fifo > sleep_until_start_request_or_inactivity > stop sem_timedwait (start_is_required, err=%d) %d.%09lu \n", err, + tv.tv_sec, tv.tv_usec*1000); + + if (err==0) + { + a_start_is_required = 1; + } } - } - SHOW_TIME("fifo > sleep_until_start_request_or_inactivity > LEAVE"); - return a_start_is_required; + SHOW_TIME("fifo > sleep_until_start_request_or_inactivity > LEAVE"); + return a_start_is_required; } //> @@ -332,8 +338,8 @@ static void close_stream() { SHOW_TIME("fifo > close_stream > ENTER\n"); - // Warning: a wave_close can be already required by - // an external command (espeak_Cancel + fifo_stop), if so: + // Warning: a wave_close can be already required by + // an external command (espeak_Cancel + fifo_stop), if so: // my_stop_is_required = 1; int a_status = pthread_mutex_lock(&my_mutex); @@ -355,7 +361,7 @@ static void close_stream() a_stop_is_required = my_stop_is_required; a_status = pthread_mutex_unlock(&my_mutex); - + if (a_stop_is_required) { // acknowledge the stop request @@ -434,7 +440,7 @@ static void* say_thread(void*) }; if (my_stop_is_required) - { + { SHOW_TIME("say_thread > my_command_is_running = 0\n"); my_command_is_running = 0; } @@ -450,26 +456,26 @@ static void* say_thread(void*) } if (my_stop_is_required) - { + { // no mutex required since the stop command is synchronous // and waiting for my_sem_stop_is_acknowledged - init(); + init(1); // purge start semaphore SHOW_TIME("say_thread > purge my_sem_start_is_required\n"); while(0==sem_trywait(&my_sem_start_is_required)) { }; - + // acknowledge the stop request SHOW_TIME("say_thread > post my_sem_stop_is_acknowledged\n"); int a_status = sem_post(&my_sem_stop_is_acknowledged); assert( a_status != -1); } // and wait for the next start - SHOW_TIME("say_thread > wait for my_sem_start_is_required\n"); + SHOW_TIME("say_thread > wait for my_sem_start_is_required\n"); } - + return NULL; } @@ -513,7 +519,7 @@ static espeak_ERROR push(t_espeak_command* the_command) { return EE_INTERNAL_ERROR; } - + if (head == NULL) { head = n; @@ -524,7 +530,7 @@ static espeak_ERROR push(t_espeak_command* the_command) tail->next = n; tail = n; } - + tail->next = NULL; tail->data = the_command; @@ -560,19 +566,29 @@ static t_espeak_command* pop() } display_espeak_command(the_command); - + return the_command; } -static void init() +static void init(int process_parameters) { - ENTER("fifo > init"); - while (delete_espeak_command( pop() )) - {} - node_counter = 0; + // Changed by Tyler Spivey 30.Nov.2011 + t_espeak_command *c = NULL; + ENTER("fifo > init"); + c = pop(); + while (c != NULL) { + if (process_parameters && (c->type == ET_PARAMETER || c->type == ET_VOICE_NAME || c->type == ET_VOICE_SPEC)) + { + process_espeak_command(c); + } + delete_espeak_command(c); + c = pop(); + } + node_counter = 0; } + //> //<fifo_init void fifo_terminate() @@ -585,7 +601,7 @@ void fifo_terminate() sem_destroy(&my_sem_start_is_required); sem_destroy(&my_sem_stop_is_acknowledged); - init(); // purge fifo + init(0); // purge fifo } #endif |