initial import

This commit is contained in:
William Hubbs 2008-07-28 01:23:43 -05:00
commit 4e3bbdb0b0
4 changed files with 246 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
espeakup

12
Makefile Normal file
View file

@ -0,0 +1,12 @@
LDLIBS = -lespeak
PROGRAM = espeakup
all: $(PROGRAM)
clean:
rm $(PROGRAM)
install: $(PROGRAM)
install -m 0755 $(PROGRAM) $(DESTDIR)/usr/bin

42
README Normal file
View file

@ -0,0 +1,42 @@
espeakup connector
=======================
This is very early alpha software, so please keep that in mind if you
use this program.
espeakup is a program which makes it possible for speakup to use
the espeak software synthesizer. It does this by reading speakup's
softsynth device and passing the text to espeak which actually speaks.
Requirements
============
This program works with the speakup screen reader, which can be obtained
from http://linux-speakup.org, and the espeak software speech
synthesizer which can be obtained from http://espeak.sourceforge.net.
You must have both of these installed and operational. Setting them up
is beyond the scope of this document.
Installation
============
To install espeakup, first cd into the directory where you
unpacked the tarball, then issue make to compile the program. Once this
is done, as root, issue make install. This will install espeakup in /usr/bin.
Starting up
===========
This program should be run after speakup is set up to communicate with a
software synthesizer and after /dev/softsynth exists. Currently it does
not accept any command line options, so invoke it as follows:
/usr/sbin/espeakup
Questions
=========
You can contact me with questions, bugs, patches, etc, at
w.d.hubbs@gmail.com or on the speakup mailing list.
Thanks, and I hope you find this useful.

191
espeakup.c Normal file
View file

@ -0,0 +1,191 @@
/*
* espeakup - connector so that speakup can use espeak.
*
* Copyright (C) 2008 William Hubbs
*
* 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <espeak/speak_lib.h>
/* multipliers and offsets */
const int pitchMultiplier = 10;
const int rateMultiplier = 32;
const int rateOffset = 80;
struct synth_t {
int fd;
int pitch;
int rate;
char buf[1025];
};
int SynthCallback(short *wav, int numsamples, espeak_EVENT *events)
{
return 0;
}
static void set_pitch (struct synth_t *s)
{
espeak_SetParameter(espeakPITCH, s->pitch * pitchMultiplier, 0);
}
static void set_rate (struct synth_t *s)
{
espeak_SetParameter(espeakRATE, s->rate * rateMultiplier + rateOffset, 0);
}
static void stop_speech(void)
{
espeak_Cancel();
}
static void speak_text(struct synth_t *s)
{
if (! strlen(s->buf))
return;
espeak_Synth(s->buf, strlen(s->buf), 0, POS_CHARACTER, 0, 0, NULL, s);
strcpy(s->buf, "");
}
static int process_command(struct synth_t *s, char *buf, int start)
{
char value;
char param;
switch (buf[start]) {
case 1:
if (buf[start+1] == '+' || buf[start+1] == '-') {
value = buf[start+2]-'0';
param = buf[start+3];
if (buf[start+1] == '-')
value = -value;
switch (param) {
case 'p':
s->pitch += value;
set_pitch (s);
break;
case 's':
s->rate += value;
set_rate (s);
break;
}
return 4;
} else if (buf[start+1] >= '0' && buf[start+1] <= '9') {
value = buf[start+1]-'0';
param = buf[start+2];
switch (param) {
case 'p':
s->pitch = value;
set_pitch (s);
break;
case 's':
s->rate = value;
set_rate (s);
break;
}
}
return 3;
case 24:
stop_speech();
return 1;
}
return 1;
}
static void process_data (struct synth_t *s)
{
int length;
int start;
int end;
char buf[1025];
char tmp_buf[1025];
length = read (s->fd, buf, 1024);
start = 0;
end = 0;
while (start < length) {
while (buf[end] >= 32 && end < length)
end++;
if (end != start) {
strncpy (tmp_buf, buf + start, end-start);
tmp_buf[end-start] = 0;
strcat(s->buf, tmp_buf);
}
if (end < length)
start = end = end+process_command (s, buf, end);
else
start = length;
}
speak_text (s);
}
static void main_loop (struct synth_t *s)
{
fd_set set;
struct timeval tv;
struct timeval timeout = {0, 20000};
int i;
while (1) {
FD_ZERO (&set);
FD_SET (s->fd, &set);
tv = timeout;
i = select (s->fd+1, &set, NULL, NULL, &tv);
if (i)
process_data (s);
}
}
int main ()
{
struct synth_t s;
/* become a daemon */
daemon(0, 1);
/* open the softsynth. */
s.fd = open ("/dev/softsynth", O_RDWR | O_NONBLOCK);
if (s.fd < 0) {
printf("Unable to open the softsynth device.\n");
return -1;
}
/* initialize espeak */
espeak_Initialize(AUDIO_OUTPUT_PLAYBACK, 0, NULL, 0);
espeak_SetSynthCallback(SynthCallback);
/* Setup initial voice parameters */
s.pitch = 5;
s.rate = 5;
strcpy(s.buf,"");
set_pitch (&s);
set_rate (&s);
/* run the main loop */
main_loop (&s);
/* shutdown espeak and close the softsynth */
espeak_Terminate();
close(s.fd);
return 0;
}