src/main.c
changeset 0 06dd3b8d90ad
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 <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);
+}