Browse Source

Use espeak_ng_STATUS codes for the fifo API.

master
Reece H. Dunn 9 years ago
parent
commit
dfdc76e1d8
4 changed files with 69 additions and 68 deletions
  1. 1
    0
      src/include/espeak-ng/espeak_ng.h
  2. 47
    46
      src/libespeak-ng/fifo.c
  3. 4
    16
      src/libespeak-ng/fifo.h
  4. 17
    6
      src/libespeak-ng/speak_lib.c

+ 1
- 0
src/include/espeak-ng/espeak_ng.h View File

ENS_OK = 0, ENS_OK = 0,
ENS_COMPILE_ERROR = 0x100001FF, ENS_COMPILE_ERROR = 0x100001FF,
ENS_VERSION_MISMATCH = 0x100002FF, ENS_VERSION_MISMATCH = 0x100002FF,
ENS_FIFO_BUFFER_FULL = 0x100003FF,
} espeak_ng_STATUS; } espeak_ng_STATUS;


typedef enum { typedef enum {

+ 47
- 46
src/libespeak-ng/fifo.c View File

/* /*
* Copyright (C) 2007, Gilles Casse <[email protected]> * Copyright (C) 2007, Gilles Casse <[email protected]>
* Copyright (C) 2013-2015 Reece H. Dunn
* Copyright (C) 2013-2016 Reece H. Dunn
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
#include <sys/time.h> #include <sys/time.h>
#include <time.h> #include <time.h>


#include "espeak_ng.h"

#include "speech.h" #include "speech.h"
#include "fifo.h" #include "fifo.h"
#include "wave.h" #include "wave.h"


static void *say_thread(void *); static void *say_thread(void *);


static espeak_ERROR push(t_espeak_command *the_command);
static espeak_ng_STATUS push(t_espeak_command *the_command);
static t_espeak_command *pop(); static t_espeak_command *pop();
static void init(int process_parameters); static void init(int process_parameters);
static int node_counter = 0; static int node_counter = 0;
continue; // Restart when interrupted by handler continue; // Restart when interrupted by handler
} }


espeak_ERROR fifo_add_command(t_espeak_command *the_command)
espeak_ng_STATUS fifo_add_command(t_espeak_command *the_command)
{ {
int a_status = pthread_mutex_lock(&my_mutex);
espeak_ERROR a_error = EE_OK;
espeak_ng_STATUS status;
if ((status = pthread_mutex_lock(&my_mutex)) != ENS_OK)
return status;


if (!a_status) {
a_error = push(the_command);
a_status = pthread_mutex_unlock(&my_mutex);
}
if ((status = push(the_command)) != ENS_OK)
return status;

if ((status = pthread_mutex_unlock(&my_mutex)) != ENS_OK)
return status;


if (!a_status && !my_command_is_running && (a_error == EE_OK)) {
if (!my_command_is_running) {
// quit when command is actually started // quit when command is actually started
// (for possible forthcoming 'end of command' checks) // (for possible forthcoming 'end of command' checks)
sem_post(&my_sem_start_is_required); sem_post(&my_sem_start_is_required);
} }
} }


if (a_status != 0)
a_error = EE_INTERNAL_ERROR;

return a_error;
return ENS_OK;
} }


espeak_ERROR fifo_add_commands(t_espeak_command *command1, t_espeak_command *command2)
espeak_ng_STATUS fifo_add_commands(t_espeak_command *command1, t_espeak_command *command2)
{ {
int a_status = pthread_mutex_lock(&my_mutex);
espeak_ERROR a_error = EE_OK;

if (!a_status) {
if (node_counter+1 >= MAX_NODE_COUNTER)
a_error = EE_BUFFER_FULL;
else {
push(command1);
push(command2);
}
a_status = pthread_mutex_unlock(&my_mutex);
}
espeak_ng_STATUS status;
if ((status = pthread_mutex_lock(&my_mutex)) != ENS_OK)
return status;


if (!a_status && !my_command_is_running && (a_error == EE_OK)) {
if (node_counter+1 >= MAX_NODE_COUNTER)
return ENS_FIFO_BUFFER_FULL;

if ((status = push(command1)) != ENS_OK)
return status;

if ((status = push(command2)) != ENS_OK)
return status;

if ((status = pthread_mutex_unlock(&my_mutex)) != ENS_OK)
return status;

if (!my_command_is_running) {
// quit when one command is actually started // quit when one command is actually started
// (for possible forthcoming 'end of command' checks) // (for possible forthcoming 'end of command' checks)
sem_post(&my_sem_start_is_required); sem_post(&my_sem_start_is_required);
} }
} }


if (a_status != 0)
a_error = EE_INTERNAL_ERROR;

return a_error;
return ENS_OK;
} }


espeak_ERROR fifo_stop()
espeak_ng_STATUS fifo_stop()
{ {
int a_command_is_running = 0;
int a_status = pthread_mutex_lock(&my_mutex);
if (a_status != 0)
return EE_INTERNAL_ERROR;
espeak_ng_STATUS status;
if ((status = pthread_mutex_lock(&my_mutex)) != ENS_OK)
return status;


int a_command_is_running = 0;
if (my_command_is_running) { if (my_command_is_running) {
a_command_is_running = 1; a_command_is_running = 1;
my_stop_is_required = 1; my_stop_is_required = 1;
} }
a_status = pthread_mutex_unlock(&my_mutex);
if (a_status != 0)
return EE_INTERNAL_ERROR;
if ((status = pthread_mutex_unlock(&my_mutex)) != ENS_OK)
return status;


if (a_command_is_running) { if (a_command_is_running) {
while ((sem_wait(&my_sem_stop_is_acknowledged) == -1) && errno == EINTR) while ((sem_wait(&my_sem_stop_is_acknowledged) == -1) && errno == EINTR)


my_stop_is_required = 0; my_stop_is_required = 0;


return EE_OK;
return ENS_OK;
} }


int fifo_is_busy() int fifo_is_busy()
static node *head = NULL; static node *head = NULL;
static node *tail = NULL; static node *tail = NULL;


static espeak_ERROR push(t_espeak_command *the_command)
static espeak_ng_STATUS push(t_espeak_command *the_command)
{ {
assert((!head && !tail) || (head && tail)); assert((!head && !tail) || (head && tail));


if (the_command == NULL) if (the_command == NULL)
return EE_INTERNAL_ERROR;
return EINVAL;


if (node_counter >= MAX_NODE_COUNTER) if (node_counter >= MAX_NODE_COUNTER)
return EE_BUFFER_FULL;
return ENS_FIFO_BUFFER_FULL;


node *n = (node *)malloc(sizeof(node)); node *n = (node *)malloc(sizeof(node));
if (n == NULL) if (n == NULL)
return EE_INTERNAL_ERROR;
return ENOMEM;


if (head == NULL) { if (head == NULL) {
head = n; head = n;


the_command->state = CS_PENDING; the_command->state = CS_PENDING;


return EE_OK;
return ENS_OK;
} }


static t_espeak_command *pop() static t_espeak_command *pop()

+ 4
- 16
src/libespeak-ng/fifo.h View File

/* /*
* Copyright (C) 2007, Gilles Casse <[email protected]> * Copyright (C) 2007, Gilles Casse <[email protected]>
* Copyright (C) 2015 Reece H. Dunn
* Copyright (C) 2015-2016 Reece H. Dunn
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
// //
// Note: this function fails if too many commands are already buffered. // Note: this function fails if too many commands are already buffered.
// In such a case, the calling function could wait and then add again its command. // In such a case, the calling function could wait and then add again its command.
//
// Return: EE_OK: operation achieved
// EE_BUFFER_FULL: the command can not be buffered;
// you may try after a while to call the function again.
// EE_INTERNAL_ERROR.
espeak_ERROR fifo_add_command(t_espeak_command *c);
espeak_ng_STATUS fifo_add_command(t_espeak_command *c);


// Add two espeak commands in a single transaction. // Add two espeak commands in a single transaction.
// //
// Note: this function fails if too many commands are already buffered. // Note: this function fails if too many commands are already buffered.
// In such a case, the calling function could wait and then add again these commands. // In such a case, the calling function could wait and then add again these commands.
//
// Return: EE_OK: operation achieved
// EE_BUFFER_FULL: at least one command can not be buffered;
// you may try after a while to call the function again.
// EE_INTERNAL_ERROR.
espeak_ERROR fifo_add_commands(t_espeak_command *c1, t_espeak_command *c2);
espeak_ng_STATUS fifo_add_commands(t_espeak_command *c1, t_espeak_command *c2);


// The current running command must be stopped and the awaiting commands are cleared. // The current running command must be stopped and the awaiting commands are cleared.
// Return: EE_OK: operation achieved
// EE_INTERNAL_ERROR.
espeak_ERROR fifo_stop();
espeak_ng_STATUS fifo_stop();


// Is there a running command? // Is there a running command?
// Returns 1 if yes; 0 otherwise. // Returns 1 if yes; 0 otherwise.

+ 17
- 6
src/libespeak-ng/speak_lib.c View File

voice_samplerate = wvoice->samplerate; voice_samplerate = wvoice->samplerate;
} }


static espeak_ERROR status_to_espeak_error(espeak_ng_STATUS status)
{
switch (status)
{
case ENS_OK: return EE_OK;
case ENOENT: return EE_NOT_FOUND;
case ENS_FIFO_BUFFER_FULL: return EE_BUFFER_FULL;
default: return EE_INTERNAL_ERROR;
}
}

#ifdef USE_ASYNC #ifdef USE_ASYNC


static int dispatch_audio(short *outbuf, int length, espeak_EVENT *event) static int dispatch_audio(short *outbuf, int length, espeak_EVENT *event)


// Try to add these 2 commands (single transaction) // Try to add these 2 commands (single transaction)
if (c1 && c2) { if (c1 && c2) {
a_error = fifo_add_commands(c1, c2);
a_error = status_to_espeak_error(fifo_add_commands(c1, c2));
if (a_error != EE_OK) { if (a_error != EE_OK) {
delete_espeak_command(c1); delete_espeak_command(c1);
delete_espeak_command(c2); delete_espeak_command(c2);


// Try to add these 2 commands (single transaction) // Try to add these 2 commands (single transaction)
if (c1 && c2) { if (c1 && c2) {
a_error = fifo_add_commands(c1, c2);
a_error = status_to_espeak_error(fifo_add_commands(c1, c2));
if (a_error != EE_OK) { if (a_error != EE_OK) {
delete_espeak_command(c1); delete_espeak_command(c1);
delete_espeak_command(c2); delete_espeak_command(c2);


#ifdef USE_ASYNC #ifdef USE_ASYNC
t_espeak_command *c = create_espeak_key(key, NULL); t_espeak_command *c = create_espeak_key(key, NULL);
a_error = fifo_add_command(c);
a_error = status_to_espeak_error(fifo_add_command(c));
if (a_error != EE_OK) if (a_error != EE_OK)
delete_espeak_command(c); delete_espeak_command(c);
#endif #endif
} }


t_espeak_command *c = create_espeak_char(character, NULL); t_espeak_command *c = create_espeak_char(character, NULL);
a_error = fifo_add_command(c);
a_error = status_to_espeak_error(fifo_add_command(c));
if (a_error != EE_OK) if (a_error != EE_OK)
delete_espeak_command(c); delete_espeak_command(c);
return a_error; return a_error;


t_espeak_command *c = create_espeak_parameter(parameter, value, relative); t_espeak_command *c = create_espeak_parameter(parameter, value, relative);


a_error = fifo_add_command(c);
a_error = status_to_espeak_error(fifo_add_command(c));
if (a_error != EE_OK) if (a_error != EE_OK)
delete_espeak_command(c); delete_espeak_command(c);
return a_error; return a_error;
} }


t_espeak_command *c = create_espeak_punctuation_list(punctlist); t_espeak_command *c = create_espeak_punctuation_list(punctlist);
a_error = fifo_add_command(c);
a_error = status_to_espeak_error(fifo_add_command(c));
if (a_error != EE_OK) if (a_error != EE_OK)
delete_espeak_command(c); delete_espeak_command(c);
return a_error; return a_error;

Loading…
Cancel
Save