diff --git a/src/main.c b/src/main.c new file mode 100644 --- /dev/null +++ b/src/main.c @@ -0,0 +1,223 @@ +/** + * $Id: main.c 53 2008-01-10 00:19:41Z mbroeker $ + * $URL: http://localhost/svn/c/VirtualReader/trunk/src/main.c $ + */ + +#include +#include +#include +#include +#include + +#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); +}