/* This is called whenever new data may be written to the stream */ static void stream_write_callback(pa_stream *s, size_t length, void *userdata) { pa_assert(s); pa_assert(length > 0); if (raw) { pa_assert(!sndfile); if (stdio_event) mainloop_api->io_enable(stdio_event, PA_IO_EVENT_INPUT); if (!buffer) return; do_stream_write(length); } else { sf_count_t bytes; void *data; pa_assert(sndfile); for (;;) { size_t data_length = length; if (pa_stream_begin_write(s, &data, &data_length) < 0) { pa_log(_("pa_stream_begin_write() failed: %s"), pa_strerror(pa_context_errno(context))); quit(1); return; } if (readf_function) { size_t k = pa_frame_size(&sample_spec); if ((bytes = readf_function(sndfile, data, (sf_count_t) (data_length/k))) > 0) bytes *= (sf_count_t) k; } else bytes = sf_read_raw(sndfile, data, (sf_count_t) data_length); if (bytes > 0) pa_stream_write(s, data, (size_t) bytes, NULL, 0, PA_SEEK_RELATIVE); else pa_stream_cancel_write(s); /* EOF? */ if (bytes < (sf_count_t) data_length) { start_drain(); break; } /* Request fulfilled */ if ((size_t) bytes >= length) break; length -= bytes; } } }
/* New data on STDIN **/ static void stdin_callback(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) { size_t l, w = 0; ssize_t r; pa_assert(a == mainloop_api); pa_assert(e); pa_assert(stdio_event == e); if (buffer) { mainloop_api->io_enable(stdio_event, PA_IO_EVENT_NULL); return; } if (!stream || pa_stream_get_state(stream) != PA_STREAM_READY || !(l = w = pa_stream_writable_size(stream))) l = 4096; buffer = pa_xmalloc(l); if ((r = read(fd, buffer, l)) <= 0) { if (r == 0) { if (verbose) pa_log(_("Got EOF.")); start_drain(); } else { pa_log(_("read() failed: %s"), strerror(errno)); quit(1); } mainloop_api->io_free(stdio_event); stdio_event = NULL; return; } buffer_length = (uint32_t) r; buffer_index = 0; if (w) do_stream_write(w); }
/* Write some data to the stream */ static void do_stream_write(size_t length) { size_t l; assert(length); printf("do stream write: Writing %d to stream\n", length); if (!buffer || !buffer_length) { buffer = pa_xmalloc(length); buffer_length = length; buffer_index = 0; //printf(" return without writing\n"); //return; } while (buffer_length > 0) { l = read(fdin, buffer + buffer_index, buffer_length); if (l <= 0) { start_drain(); return; } if (pa_stream_write(stream, (uint8_t*) buffer + buffer_index, l, NULL, 0, PA_SEEK_RELATIVE) < 0) { printf("pa_stream_write() failed: %s", pa_strerror(pa_context_errno(context))); exit(1); return; } buffer_length -= l; buffer_index += l; if (!buffer_length) { pa_xfree(buffer); buffer = NULL; buffer_index = buffer_length = 0; } } }