-retry:
- xgettimeofday(&now, NULL);
- if(rtp_reactivated) {
- /* We've been deactivated for some unknown interval. We need to advance
- * rtp_timestamp to account for the dead air. */
- /* On the first run through we'll set the start time. */
- if(!rtp_timeval.tv_sec)
- rtp_timeval = now;
- /* See how much time we missed.
- *
- * This will be 0 on the first run through, in which case we'll not modify
- * anything.
- *
- * It'll be negative in the (rare) situation where the deactivation
- * interval is shorter than the last packet we sent. In this case we wait
- * for that much time and then return having sent no samples, which will
- * cause uaudio_play_thread_fn() to retry.
- *
- * In the normal case it will be positive.
- */
- const int64_t delay = tvsub_us(now, rtp_timeval); /* microseconds */
- if(delay < 0) {
- usleep(-delay);
- goto retry;
- }
- /* Advance the RTP timestamp to the present. With 44.1KHz stereo this will
- * overflow the intermediate value with a delay of a bit over 6 years.
- * This seems acceptable. */
- uint64_t update = (delay * uaudio_rate * uaudio_channels) / 1000000;
- /* Don't throw off channel synchronization */
- update -= update % uaudio_channels;
- /* We log nontrivial changes */
- if(update)
- info("advancing rtp_time by %"PRIu64" samples", update);
- rtp_timestamp += update;
- rtp_timeval = now;
- rtp_reactivated = 0;
- } else {
- /* Chances are we've been called right on the heels of the previous packet.
- * If we just sent packets as fast as we got audio data we'd get way ahead
- * of the player and some buffer somewhere would fill (or at least become
- * unreasonably large).
- *
- * First find out how far ahead of the target time we are.
- */
- const int64_t ahead = tvsub_us(now, rtp_timeval); /* microseconds */
- /* Only delay at all if we are nontrivially ahead. */
- if(ahead > rtp_delay_threshold) {
- /* Don't delay by the full amount */
- usleep(ahead - rtp_delay_threshold / 2);
- /* Refetch time (so we don't get out of step with reality) */
- xgettimeofday(&now, NULL);
- }
+ const uint32_t timestamp = uaudio_schedule_sync();
+ header.timestamp = htonl(rtp_base + (uint32_t)timestamp);
+
+ /* We send ~120 packets a second with current arrangements. So if we log
+ * once every 8192 packets we log about once a minute. */
+
+ if(!(ntohs(header.seq) & 8191)
+ && config->rtp_verbose)
+ disorder_info("RTP: seq %04"PRIx16" %08"PRIx32"+%08"PRIx32"=%08"PRIx32" ns %zu%s",
+ ntohs(header.seq),
+ rtp_base,
+ timestamp,
+ header.timestamp,
+ nsamples,
+ flags & UAUDIO_PAUSED ? " [paused]" : "");
+
+ /* If we're paused don't actually end a packet, we just pretend */
+ if(flags & UAUDIO_PAUSED) {
+ uaudio_schedule_sent(nsamples);
+ return nsamples;