Troubleshooting:
* See http://de.gentoo-wiki.com/Mbrola
* txt2pho needs a config file
-> ~/.txt2phorc or /etc/txt2pho
committer: Markus Bröker <mbroeker@largo.homelinux.org>
/**
* $Id: main.c 53 2008-01-10 00:19:41Z mbroeker $
* $URL: http://localhost/svn/c/VirtualReader/trunk/src/main.c $
*/
#include <sentence.h>
#include <keyboard.h>
#include <thread.h>
#include <audioplayer.h>
#include <interface.h>
#define STARTWRITER 0
#define WRITER 1
#define READER 2
#define STEP 2 // jump back n-steps
void find_next (ThreadData * data)
{
long tm = (long)audioplayer_gettime ();
long position;
int i, max;
max = words (data->sentences[data->satz]);
for (i = 0; i < max; i++) {
if (data->timings[data->satz][i] > tm)
break;
}
position = data->timings[data->satz][i];
audioplayer_settime (position);
}
void find_prev (ThreadData * data)
{
long tm = (long)audioplayer_gettime ();
long position;
int i, max;
max = words (data->sentences[data->satz]);
for (i = STEP; i < max; i++) {
if (data->timings[data->satz][i] > tm)
break;
}
position = data->timings[data->satz][i - STEP];
audioplayer_settime (position);
}
int main (int argc, char **argv)
{
char **sentences = NULL; // to store an array of strings
char *Text = NULL; // to store the content of a textfile
long **timings = NULL; // to store the timings
int i, count; // sentence counter
int verbose = 0;
pthread_t p_thread, w_thread;
ThreadData *data[3]; // independent thread data
tts_options ttsopt = interface_get_cl_opts (argc, argv);
ttshandles ttsh = interface_init (ttsopt);
if ((Text = readbuffer (ttsopt.TextFile)) != NULL) {
sentences = getstrings (Text, &count);
free (Text);
} else {
printf ("ERROR: Textfile %s is corrupt.\n", ttsopt.TextFile);
free (ttsopt.TextFile);
free (ttsopt.AudioFile);
free (ttsopt.Voice);
free (ttsopt.Path);
return EXIT_SUCCESS;
}
// Timinganalyse des Textes
if ((timings = calloc ((size_t) count, sizeof (long *) + 1)) == NULL) {
free (ttsopt.TextFile);
free (ttsopt.AudioFile);
free (ttsopt.Voice);
free (ttsopt.Path);
return EXIT_SUCCESS;
}
for (i = 0; i < count; i++) {
timings[i] = interface_get_timing (ttsh, sentences[i]);
}
/*
* Initialize Sound
*/
if (audio_init ())
fprintf (stderr, "AUDIO ERROR\n");
for (i = 0; i < 3; i++) {
data[i] = malloc (sizeof (ThreadData) + 1);
if (data[i] == NULL)
exit (0);
data[i]->ttsopt = ttsopt;
data[i]->ttsh = ttsh;
data[i]->fname = ttsopt.TextFile;
data[i]->sentences = sentences;
data[i]->timings = timings;
}
/*
* write sentences from 0-1 :)
*/
data[STARTWRITER]->satz = 0;
data[STARTWRITER]->items = 1;
pthread_create (&w_thread, NULL, (void *)writewav, data[STARTWRITER]);
pthread_join (w_thread, NULL);
/*
* write sentences from 1-count :)
*/
data[WRITER]->satz = 1;
data[WRITER]->items = count;
pthread_create (&w_thread, NULL, (void *)writewav, data[WRITER]);
data[READER]->satz = 0;
data[READER]->items = count;
pthread_create (&p_thread, NULL, (void *)readtext, data[READER]);
while (data[READER]->satz < data[READER]->items) {
switch (getSingleKey ()) {
case 'i':
// next word
if (data[READER]->satz < data[READER]->items)
find_next (data[READER]);
else
printf ("ERROR: Cannot seek anymore\n");
break;
case 'j':
// previous sentence
if (data[READER]->satz > 0) {
data[READER]->satz--;
p_thread_restart (p_thread, readtext, data[READER]);
}
break;
case 'k':
// previous word
find_prev (data[READER]);
break;
case 'l':
// next sentence
if (data[READER]->satz < data[READER]->items) {
data[READER]->satz++;
p_thread_restart (p_thread, readtext, data[READER]);
}
break;
case 'p':
// print useful informations
printf ("Current Position: [%5d/%5d]ms = #%d\n",
audioplayer_gettime (), audioplayer_getwavelength (NULL), audioplayer_getposition ());
break;
case 'q':
// quit
pthread_cancel (w_thread);
pthread_cancel (p_thread);
data[READER]->satz = data[READER]->items;
break;
case 'r':
// reset player
pthread_cancel (p_thread);
if (!pthread_join (p_thread, NULL))
printf ("RESET\n");
break;
case 's':
printf ("S[%d]: %s\n", data[READER]->satz, sentences[data[READER]->satz]);
break;
case 'v':
verbose ^= 1;
audioplayer_setverbose (verbose);
break;
default:
/*
* unknown command
*/
break;
}
}
if (!pthread_join (p_thread, NULL))
printf ("The last thread exited\n");
// cleanup memory
for (i = 0; i < count; i++) {
if (sentences[i] != NULL)
free (sentences[i]);
if (timings[i] != NULL)
free (timings[i]);
}
if (sentences != NULL)
free (sentences);
if (timings != NULL)
free (timings);
for (i = 0; i < 3; i++)
if (data[i] != NULL)
free (data[i]);
/*
* Cleanup sound
*/
audio_shutdown ();
pthread_exit (NULL);
}