+ break;
+ case BACKEND_NETWORK:
+ /* We transmit using RTP (RFC3550) and attempt to conform to the internet
+ * AVT profile (RFC3551). */
+ if(rtp_time_real.tv_sec == 0)
+ xgettimeofday(&rtp_time_real, 0);
+ if(idled) {
+ struct timeval now;
+ xgettimeofday(&now, 0);
+ /* There's been a gap. Fix up the RTP time accordingly. */
+ const long offset = (((now.tv_sec + now.tv_usec /1000000.0)
+ - (rtp_time_real.tv_sec + rtp_time_real.tv_usec / 1000000.0))
+ * playing->format.rate * playing->format.channels);
+ if(offset >= 0) {
+ info("offset RTP timestamp by %ld", offset);
+ rtp_time += offset;
+ }
+ rtp_time_real = now;
+ }
+ header.vpxcc = 2 << 6; /* V=2, P=0, X=0, CC=0 */
+ header.seq = htons(rtp_seq++);
+ header.timestamp = htonl(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;
+ 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.)"
+ */
+ 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;
+#if 0
+ {
+ char buffer[3 * sizeof header + 1];
+ size_t n;
+ const uint8_t *ptr = (void *)&header;
+
+ for(n = 0; n < sizeof header; ++n)
+ sprintf(&buffer[3 * n], "%02x ", *ptr++);
+ info(buffer);
+ }
+#endif
+ 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;
+ }
+ 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;
+ /* Advance the corresponding real time */
+ assert(NETWORK_BYTES <= 2000); /* else risk overflowing 32 bits */
+ rtp_time_real.tv_usec += written_frames * 1000000 / playing->format.rate;
+ if(rtp_time_real.tv_usec >= 1000000) {
+ ++rtp_time_real.tv_sec;
+ rtp_time_real.tv_usec -= 1000000;
+ }
+ assert(rtp_time_real.tv_usec < 1000000);
+ break;
+ default:
+ assert(!"reached");