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"), \
{
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));
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++) {