}
static void play(size_t frames) {
- size_t avail_bytes, written_frames;
+ size_t avail_bytes, write_bytes, written_frames;
ssize_t written_bytes;
- struct rtp header;
+ struct rtp_header header;
struct iovec vec[2];
if(activate()) {
struct timeval now;
xgettimeofday(&now, 0);
/* There's been a gap. Fix up the RTP time accordingly. */
- rtp_time += (((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);
+ 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++);
* 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;
+ write_bytes = 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);
- }
+ while(write_bytes > 0 && (uint32_t)(playing->buffer + playing->start + write_bytes - 4) == 0)
+ write_bytes -= 4;
#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");
+ 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;
+#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;
- }
+ }
+ } else
audio_errors /= 2;
written_bytes = avail_bytes;
written_frames = written_bytes / bpf;
++rtp_time_real.tv_sec;
rtp_time_real.tv_usec -= 1000000;
}
+ assert(rtp_time_real.tv_usec < 1000000);
break;
default:
assert(!"reached");