gnome-speech r312 - in trunk: . drivers/espeak
- From: wwalker svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-speech r312 - in trunk: . drivers/espeak
- Date: Mon, 16 Jun 2008 17:06:36 +0000 (UTC)
Author: wwalker
Date: Mon Jun 16 17:06:36 2008
New Revision: 312
URL: http://svn.gnome.org/viewvc/gnome-speech?rev=312&view=rev
Log:
Fix for bug #535493 to stop eSpeak driver from blocking on 'say' method
Modified:
trunk/ChangeLog
trunk/drivers/espeak/espeakspeaker.c
trunk/drivers/espeak/espeakspeaker.h
trunk/drivers/espeak/espeaksynthesisdriver.c
trunk/drivers/espeak/espeaksynthesisdriver.h
Modified: trunk/drivers/espeak/espeakspeaker.c
==============================================================================
--- trunk/drivers/espeak/espeakspeaker.c (original)
+++ trunk/drivers/espeak/espeakspeaker.c Mon Jun 16 17:06:36 2008
@@ -1,7 +1,7 @@
/*
* GNOME Speech - Speech services for the GNOME desktop
*
- * Copyright 2007 Sun Microsystems Inc.
+ * Copyright 2007-2008 Sun Microsystems Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -267,12 +267,11 @@
s->driver = g_object_ref (d);
/* Set the specified voice */
- espeak_VOICE a_voice;
- memset( &a_voice, 0, sizeof(espeak_VOICE));
- a_voice.name = voice_spec->name;
- a_voice.languages = NULL;
- a_voice.gender = (voice_spec->gender == GNOME_Speech_gender_male);
- espeak_SetVoiceByProperties(&a_voice);
+ memset( &speaker->voice, 0, sizeof(espeak_VOICE));
+ speaker->voice.name = g_strdup(voice_spec->name);
+ speaker->voice.languages = NULL;
+ speaker->voice.gender = (voice_spec->gender == GNOME_Speech_gender_male);
+ espeak_SetVoiceByProperties(&speaker->voice);
espeak_add_parameter (speaker,
espeakPITCH,
@@ -290,7 +289,7 @@
espeakRATE,
"rate",
80,
- 370,
+ 390,
espeak_set_rate);
espeak_add_parameter (speaker,
espeakVOLUME,
Modified: trunk/drivers/espeak/espeakspeaker.h
==============================================================================
--- trunk/drivers/espeak/espeakspeaker.h (original)
+++ trunk/drivers/espeak/espeakspeaker.h Mon Jun 16 17:06:36 2008
@@ -1,7 +1,7 @@
/*
* GNOME Speech - Speech services for the GNOME desktop
*
- * Copyright 2007 Sun Microsystems Inc.
+ * Copyright 2007-2008 Sun Microsystems Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -49,6 +49,7 @@
typedef struct {
Speaker parent;
+ espeak_VOICE voice;
} EspeakSpeaker;
typedef struct {
@@ -60,7 +61,7 @@
EspeakSpeaker *
espeak_speaker_new (GObject *d,
- const GNOME_Speech_VoiceInfo *voice_speec);
+ const GNOME_Speech_VoiceInfo *voice_spec);
#ifdef __cplusplus
}
Modified: trunk/drivers/espeak/espeaksynthesisdriver.c
==============================================================================
--- trunk/drivers/espeak/espeaksynthesisdriver.c (original)
+++ trunk/drivers/espeak/espeaksynthesisdriver.c Mon Jun 16 17:06:36 2008
@@ -1,7 +1,7 @@
/*
* GNOME Speech - Speech services for the GNOME desktop
*
- * Copyright 2007 Sun Microsystems Inc.
+ * Copyright 2007-2008 Sun Microsystems Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -27,20 +27,28 @@
#include <string.h>
#include <stdlib.h>
#include <libbonobo.h>
+#include <glib.h>
#include <glib/gmain.h>
#include <speak_lib.h>
#include <gnome-speech/gnome-speech.h>
#include "espeaksynthesisdriver.h"
#include "espeakspeaker.h"
-
#define VERSION_LENGTH 20
+static gint utterance_id = 0;
+
typedef struct {
GNOME_Speech_SpeechCallback cb;
gboolean speech_is_started;
-} t_index;
+ gint id;
+} t_user_data;
+typedef struct {
+ EspeakSpeaker *espeak_speaker;
+ char *text;
+ t_user_data *user_data;
+} t_utterance;
static GObjectClass *parent_class;
@@ -51,13 +59,6 @@
}
-static gboolean
-espeak_synthesis_driver_timeout_callback (void *data)
-{
- return TRUE;
-}
-
-
static int
espeak_synthesis_driver_index_callback (short* wav,
int numsamples,
@@ -65,8 +66,9 @@
{
if (event && event->user_data)
{
- t_index *user_data = event->user_data;
- GNOME_Speech_speech_callback_type type=GNOME_Speech_speech_callback_speech_started;
+ t_user_data *user_data = event->user_data;
+ GNOME_Speech_speech_callback_type type =
+ GNOME_Speech_speech_callback_speech_started;
gboolean a_callback_is_called = TRUE;
@@ -102,7 +104,7 @@
CORBA_exception_init (&ev);
GNOME_Speech_SpeechCallback_notify (user_data->cb,
type,
- event->unique_identifier,
+ user_data->id,
event->text_position,
&ev);
@@ -174,11 +176,7 @@
espeak_Initialize(AUDIO_OUTPUT_PLAYBACK, 200, NULL);
#endif
- /* Add a timeout callback to poke this instance of eSpeak */
-
- d->timeout_id = g_timeout_add_full (G_PRIORITY_HIGH_IDLE, 100,
- espeak_synthesis_driver_timeout_callback, d, NULL);
-
+ d->text_idle = 0;
d->initialized = TRUE;
}
return d->initialized;
@@ -383,8 +381,33 @@
{
driver->mutex = g_mutex_new ();
driver->last_speaker = NULL;
- driver->index_queue = NULL;
- driver->timeout_id = -1;
+ driver->utterance_queue = NULL;
+}
+
+
+static void
+espeak_synthesis_driver_free_utterance (t_utterance *utterance)
+{
+ g_free (utterance->text);
+ g_free (utterance);
+}
+
+
+static void
+espeak_synthesis_driver_flush_queue (EspeakSynthesisDriver *driver)
+{
+ GSList *tmp;
+
+ /* Flush the utterance queue */
+
+ g_mutex_lock (driver->mutex);
+ for (tmp = driver->utterance_queue; tmp; tmp = tmp->next) {
+ t_utterance *u = (t_utterance *) tmp->data;
+ espeak_synthesis_driver_free_utterance (u);
+ }
+ g_slist_free (driver->utterance_queue);
+ driver->utterance_queue = NULL;
+ g_mutex_unlock (driver->mutex);
}
@@ -397,10 +420,10 @@
espeak_Synchronize ();
espeak_Terminate ();
- /* Remove timeout */
+ if (d->text_idle)
+ g_source_remove (d->text_idle);
- if (d->timeout_id >= 0)
- g_source_remove (d->timeout_id);
+ espeak_synthesis_driver_flush_queue (d);
if (parent_class->finalize)
parent_class->finalize (obj);
@@ -487,59 +510,104 @@
}
+
+static gboolean
+espeak_idle(gpointer data)
+{
+ EspeakSynthesisDriver *driver = ESPEAK_SYNTHESIS_DRIVER (data);
+ gboolean rerun;
+
+ g_mutex_lock (driver->mutex);
+
+ if (driver->utterance_queue) {
+ t_utterance *utterance;
+ unsigned int unique_identifier=0;
+ espeak_ERROR a_error = EE_INTERNAL_ERROR;
+
+ utterance = (t_utterance *) driver->utterance_queue->data;
+ espeak_SetVoiceByProperties(&utterance->espeak_speaker->voice);
+ a_error = espeak_Synth((char *) utterance->text,
+ strlen((char*)utterance->text) + 1,
+ 0, POS_CHARACTER, 0, espeakCHARS_UTF8,
+ &unique_identifier,
+ utterance->user_data);
+
+ if (a_error != EE_BUFFER_FULL) {
+ driver->utterance_queue = g_slist_remove_link (
+ driver->utterance_queue,
+ driver->utterance_queue);
+ espeak_synthesis_driver_free_utterance (utterance);
+ }
+ }
+
+ if (driver->utterance_queue) {
+ rerun = TRUE;
+ } else {
+ driver->text_idle = 0;
+ rerun = FALSE;
+ }
+
+ g_mutex_unlock (driver->mutex);
+
+ return rerun;
+}
+
+
gint
-espeak_synthesis_driver_say (EspeakSynthesisDriver *d,
- EspeakSpeaker *s,
+espeak_synthesis_driver_say (EspeakSynthesisDriver *driver,
+ EspeakSpeaker *espeak_speaker,
gchar *text)
{
- Speaker *speaker = SPEAKER (s);
- espeak_ERROR a_error = EE_INTERNAL_ERROR;
- gint a_status = -1;
- unsigned int unique_identifier=0;
-
- /* If this speaker wasn't the last one to speak, reset the speech parameters */
+ t_utterance *utterance = NULL;
+ Speaker *speaker = SPEAKER (espeak_speaker);
- if (d->last_speaker != s || speaker_needs_parameter_refresh(speaker)) {
+ speaker = SPEAKER (espeak_speaker);
+ if (driver->last_speaker != espeak_speaker
+ || speaker_needs_parameter_refresh(speaker)) {
speaker_refresh_parameters (speaker);
- d->last_speaker = s;
+ driver->last_speaker = espeak_speaker;
}
-
- t_index *user_data = NULL;
- if (speaker->cb != CORBA_OBJECT_NIL)
- {
- CORBA_Environment ev;
+ utterance = g_new (t_utterance, 1);
+ utterance->espeak_speaker = espeak_speaker;
+ utterance->text = g_strdup (text);
- user_data = g_new(t_index, 1);
+ if (speaker->cb != CORBA_OBJECT_NIL) {
+ t_user_data *user_data;
+ CORBA_Environment ev;
+ user_data = g_new(t_user_data, 1);
CORBA_exception_init (&ev);
user_data->cb = CORBA_Object_duplicate (speaker->cb, &ev);
- user_data->speech_is_started = FALSE;
CORBA_exception_free (&ev);
+ user_data->speech_is_started = FALSE;
+ user_data->id = ++utterance_id;
+ utterance->user_data = user_data;
+ } else {
+ utterance->user_data = NULL;
}
- while(1)
- {
- a_error = espeak_Synth((char *) text, strlen((char*)text)+1,
- 0, POS_CHARACTER, 0, espeakCHARS_UTF8,
- &unique_identifier, user_data);
- if (a_error != EE_BUFFER_FULL)
- {
- break;
- }
- usleep(20000);
- };
-
-
- if (a_error == EE_OK)
- a_status = (gint)unique_identifier;
+ g_mutex_lock (driver->mutex);
+ driver->utterance_queue = g_slist_append (driver->utterance_queue,
+ utterance);
+ if (!driver->text_idle) {
+ driver->text_idle = g_idle_add (espeak_idle, driver);
+ }
+ g_mutex_unlock (driver->mutex);
- return a_status;
+ return utterance_id;
}
gboolean
espeak_synthesis_driver_stop (EspeakSynthesisDriver *d)
{
+ if (d->text_idle) {
+ g_source_remove (d->text_idle);
+ d->text_idle = 0;
+ }
+
+ espeak_synthesis_driver_flush_queue (d);
+
espeak_Cancel ();
return TRUE;
}
Modified: trunk/drivers/espeak/espeaksynthesisdriver.h
==============================================================================
--- trunk/drivers/espeak/espeaksynthesisdriver.h (original)
+++ trunk/drivers/espeak/espeaksynthesisdriver.h Mon Jun 16 17:06:36 2008
@@ -1,7 +1,7 @@
/*
* GNOME Speech - Speech services for the GNOME desktop
*
- * Copyright 2007 Sun Microsystems Inc.
+ * Copyright 2007-2008 Sun Microsystems Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -50,7 +50,8 @@
EspeakSpeaker *last_speaker;
guint timeout_id;
- GSList *index_queue;
+ guint text_idle;
+ GSList *utterance_queue;
gboolean initialized;
} EspeakSynthesisDriver;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]