+#endif
+ case BACKEND_COMMAND:
+ if(avail_bytes > frames * bpf)
+ avail_bytes = frames * bpf;
+ written_bytes = write(cmdfd, playing->buffer + playing->start,
+ avail_bytes);
+ D(("actually play %zu bytes, wrote %d",
+ avail_bytes, (int)written_bytes));
+ if(written_bytes < 0) {
+ switch(errno) {
+ case EPIPE:
+ error(0, "hmm, command died; trying another");
+ fork_cmd();
+ return;
+ case EAGAIN:
+ return;
+ }
+ }
+ written_frames = written_bytes / bpf; /* good enough */
+ break;
+ case BACKEND_NETWORK:
+ /* We transmit using RTP (RFC3550) and attempt to conform to the internet
+ * AVT profile (RFC3551). */
+
+ if(idled) {
+ /* There's been a gap. Fix up the RTP time accordingly. */
+ struct timeval now;
+ uint64_t delta;
+ uint64_t target_rtp_time;
+
+ /* Find the current time */
+ xgettimeofday(&now, 0);
+ /* Find the number of microseconds elapsed since rtp_time=0 */
+ delta = tvsub_us(now, rtp_time_0);
+ assert(delta <= UINT64_MAX / 88200);
+ target_rtp_time = (delta * playing->format.rate
+ * playing->format.channels) / 1000000;
+ /* Overflows at ~6 years uptime with 44100Hz stereo */
+ if(target_rtp_time > rtp_time)
+ info("advancing rtp_time by %"PRIu64" samples",
+ target_rtp_time - rtp_time);
+ else if(target_rtp_time < rtp_time)
+ info("reversing rtp_time by %"PRIu64" samples",
+ rtp_time - target_rtp_time);
+ rtp_time = target_rtp_time;
+ }
+ header.vpxcc = 2 << 6; /* V=2, P=0, X=0, CC=0 */
+ header.seq = htons(rtp_seq++);
+ header.timestamp = htonl((uint32_t)rtp_time);
+ header.ssrc = rtp_id;
+ header.mpt = (idled ? 0x80 : 0x00) | 10;
+ /* 10 = L16 = 16-bit x 2 x 44100KHz. We ought to deduce this value from
+ * the sample rate (in a library somewhere so that configuration.c can rule
+ * out invalid rates).
+ */
+ idled = 0;
+ if(avail_bytes > NETWORK_BYTES - sizeof header) {
+ avail_bytes = NETWORK_BYTES - sizeof header;
+ /* Always send a whole number of frames */
+ avail_bytes -= avail_bytes % bpf;
+ }
+ /* "The RTP clock rate used for generating the RTP timestamp is independent
+ * of the number of channels and the encoding; it equals the number of
+ * sampling periods per second. For N-channel encodings, each sampling
+ * period (say, 1/8000 of a second) generates N samples. (This terminology
+ * is standard, but somewhat confusing, as the total number of samples
+ * generated per second is then the sampling rate times the channel
+ * count.)"
+ */
+ write_bytes = avail_bytes;
+ if(write_bytes) {
+ vec[0].iov_base = (void *)&header;
+ vec[0].iov_len = sizeof header;
+ vec[1].iov_base = playing->buffer + playing->start;
+ vec[1].iov_len = avail_bytes;
+ do {
+ written_bytes = writev(bfd,
+ vec,
+ 2);
+ } while(written_bytes < 0 && errno == EINTR);
+ if(written_bytes < 0) {
+ error(errno, "error transmitting audio data");
+ ++audio_errors;
+ if(audio_errors == 10)
+ fatal(0, "too many audio errors");
+ return;
+ }
+ } else
+ audio_errors /= 2;
+ written_bytes = avail_bytes;
+ written_frames = written_bytes / bpf;
+ /* Advance RTP's notion of the time */
+ rtp_time += written_frames * playing->format.channels;
+ break;
+ default:
+ assert(!"reached");
+ }
+ /* written_bytes and written_frames had better both be set and correct by
+ * this point */