para_play: simplify play_pcm(), add E_PLAY_OVERRUN, E_PREMATURE_END
authorAndre <maan@p133.(none)>
Tue, 18 Apr 2006 01:34:48 +0000 (03:34 +0200)
committerAndre <maan@p133.(none)>
Tue, 18 Apr 2006 01:34:48 +0000 (03:34 +0200)
error.h
play.c

diff --git a/error.h b/error.h
index 583d2ce..880df55 100644 (file)
--- a/error.h
+++ b/error.h
@@ -301,6 +301,8 @@ extern const char **para_errlist[];
        PARA_ERROR(READ_HDR, "failed to read audio file header"), \
        PARA_ERROR(READ_STDIN, "failed to read from stdin"), \
        PARA_ERROR(PLAY_SYNTAX, "syntax error"), \
+       PARA_ERROR(PLAY_OVERRUN, "buffer overrun"), \
+       PARA_ERROR(PREMATURE_END, "premature end of audio file"), \
        PARA_ERROR(BROKEN_CONF, "Broken alsa configuration"), \
        PARA_ERROR(ACCESS_TYPE, "alsa access type not available"), \
        PARA_ERROR(SAMPLE_FORMAT, "sample format not available"), \
diff --git a/play.c b/play.c
index 5d32df7..d98a4ba 100644 (file)
--- a/play.c
+++ b/play.c
@@ -295,7 +295,7 @@ static int play_pcm(size_t loaded)
 {
        size_t bufsize, min_written = 0, prebuf_size, bytes_to_load;
        struct timeval delay;
-       int i, max_chunk_bytes = 0, ret, not_yet_started = 1, need_more_writes;
+       int eof = 0, i, max_chunk_bytes = 0, ret, not_yet_started = 1, need_more_writes;
        struct writer_node *wn;
        size_t *written = para_calloc(1 * sizeof(size_t));
 
@@ -327,52 +327,46 @@ again:
                need_more_writes = 0;
                for (i = 0; i < 1; i++) {
                        unsigned char *p = audiobuf + written[i];
+                       int bytes_to_write;
                        wn = &writer_nodes[i];
                        if (!i)
                                min_written = written[i];
                        else
                                min_written = PARA_MIN(min_written, written[i]);
-                       if (loaded < wn->chunk_bytes + written[i])
+                       if (loaded == written[i])
                                continue;
-                       ret = wn->writer->write(p, wn->chunk_bytes, wn);
+                       if (!eof && (loaded < wn->chunk_bytes + written[i]))
+                               continue;
+                       bytes_to_write = PARA_MIN(wn->chunk_bytes,
+                               loaded - written[i]);
+                       ret = wn->writer->write(p, bytes_to_write, wn);
                        if (ret < 0)
                                goto out;
-                       if (ret != wn->chunk_bytes)
-                               PARA_WARNING_LOG("short write: %d/%d", ret,
-                                       wn->chunk_bytes);
+                       if (ret != bytes_to_write)
+                               PARA_WARNING_LOG("short write: %d/%d\n", ret,
+                                       bytes_to_write);
                        written[i] += ret;
                        need_more_writes = 1;
                }
        }
        loaded -= min_written;
-       if (loaded > 0) {
-               if (loaded >= bufsize) {
-                       ret = -E_PLAY_OVERRUN;
-                       goto out;
-               }
-               memmove(audiobuf, audiobuf + min_written, loaded);
+       ret = 0;
+       if (eof)
+               goto out;
+       if (loaded >= bufsize) {
+               ret = -E_PLAY_OVERRUN;
+               goto out;
        }
+       memmove(audiobuf, audiobuf + min_written, loaded);
        for (i = 0; i < 1; i++)
                written[i] -= min_written;
        bytes_to_load = PARA_MIN(max_chunk_bytes, bufsize);
        ret = read_stdin(audiobuf, bytes_to_load, &loaded);
        if (ret < 0)
                goto out;
-       if (ret)
-               goto again;
-       for (i = 0; i < 1; i++) {
-               unsigned char *p = audiobuf + written[i];
-               wn = &writer_nodes[i];
-               int bytes_to_write;
-               if (written[i] >= loaded)
-                       continue;
-               bytes_to_write = PARA_MIN(wn->chunk_bytes, loaded - written[i]);
-               ret = wn->writer->write(p, bytes_to_write, wn);
-               if (ret < 0)
-                       goto out;
-               written[i] += ret;
-       }
-       ret = 0;
+       if (!ret)
+               eof = 1;
+       goto again;
 out:
        free(written);
        for (i = 0; i < 1; i++) {