]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - play.c
introduce struct writer and struct writer_node
[paraslash.git] / play.c
diff --git a/play.c b/play.c
index a7bea9fa1ef7e195a247da6a5c76ad1d9adaa83a..c9cc56abb5374831979cb510bcc89ed337425257 100644 (file)
--- a/play.c
+++ b/play.c
@@ -38,6 +38,24 @@ struct private_alsa_data {
        size_t bytes_per_frame;
 };
 
+struct writer_node {
+       struct writer *writer;
+       void *private_data;
+};
+
+struct writer {
+       int (*open)(struct writer_node **);
+       int (*write)(char *data, size_t nbytes, struct writer_node *);
+       void (*close)(struct writer_node *);
+       void (*shutdown)(struct writer_node *);
+};
+
+#define NUM_WRITERS 1
+static struct writer writers[NUM_WRITERS];
+#define FOR_EACH_WRITER(i) for (i = 0; i < NUM_WRITERS, i++)
+static struct writer_node **writer_nodes;
+
+
 static unsigned char *audiobuf;
 static struct timeval *start_time;
 static struct gengetopt_args_info conf;
@@ -77,7 +95,7 @@ static int read_wav_header(void)
  *
  * Install PCM software and hardware configuration. Exit on errors.
  */
-static int alsa_init(void **private_data)
+static int alsa_open(void **private_data)
 {
        snd_pcm_hw_params_t *hwparams;
        snd_pcm_sw_params_t *swparams;
@@ -163,15 +181,16 @@ static int alsa_init(void **private_data)
  *
  * \return Number of bytes written, -E_ALSA_WRITE on errors.
  */
-static int alsa_write(u_char *data, size_t nbytes, void *private_data)
+static int alsa_write(char *data, size_t nbytes, void *private_data)
 {
        struct private_alsa_data *pad = private_data;
        size_t frames = nbytes / pad->bytes_per_frame;
+       unsigned char *d = data;
        snd_pcm_sframes_t r, result = 0;
 
        while (frames > 0) {
                /* write interleaved frames */
-               r = snd_pcm_writei(pad->handle, data, frames);
+               r = snd_pcm_writei(pad->handle, d, frames);
                if (r < 0)
                        PARA_ERROR_LOG("write error: %s\n", snd_strerror(r));
                if (r == -EAGAIN || (r >= 0 && r < frames))
@@ -183,13 +202,13 @@ static int alsa_write(u_char *data, size_t nbytes, void *private_data)
                if (r > 0) {
                        result += r;
                        frames -= r;
-                       data += r * pad->bytes_per_frame;
+                       d += r * pad->bytes_per_frame;
                }
        }
        return result * pad->bytes_per_frame;
 }
 
-static void alsa_shutdown(void *private_data)
+static void alsa_close(void *private_data)
 {
        struct private_alsa_data *pad = private_data;
        snd_pcm_drain(pad->handle);
@@ -198,6 +217,15 @@ static void alsa_shutdown(void *private_data)
        free(pad);
 }
 
+void alsa_writer_init(struct writer *w)
+{
+       w->open = alsa_open;
+       w->write = alsa_write;
+       w->close = alsa_close;
+       w->shutdown = NULL; /* nothing to do */
+}
+
+
 /**
  * check if current time is later than start_time
  * \param diff pointer to write remaining time to
@@ -249,7 +277,7 @@ static int play_pcm(size_t loaded)
        unsigned char *p;
        struct timeval delay;
        void *private_data;
-       int chunk_bytes, ret = alsa_init(&private_data);
+       int chunk_bytes, ret = alsa_open(&private_data);
 
        if (ret < 0)
                goto out;
@@ -289,7 +317,7 @@ read:
        }
        ret = 1;
 out:
-       alsa_shutdown(private_data);
+       alsa_close(private_data);
        return ret;
 }
 
@@ -322,6 +350,11 @@ int main(int argc, char *argv[])
                        goto out;
                start_time = &tv;
        }
+       /* call init for each supported writer */
+       alsa_writer_init(&writers[0]);
+       /* one for each given writer */
+       writer_nodes = para_calloc(2 * sizeof(struct writer_node));
+
        audiobuf = para_malloc(WAV_HEADER_LEN);
        ret = read_wav_header();
        if (ret < 0)