- if(ready && !forceplay) {
- switch(config->speaker_backend) {
- case BACKEND_COMMAND:
- /* We send sample data to the subprocess as fast as it can accept it.
- * This isn't ideal as pause latency can be very high as a result. */
- if(cmdfd >= 0)
- cmdfd_slot = addfd(cmdfd, POLLOUT);
- break;
- case BACKEND_NETWORK: {
- struct timeval now;
- uint64_t target_us;
- uint64_t target_rtp_time;
- const int64_t samples_ahead = ((uint64_t)RTP_AHEAD_MS
- * config->sample_format.rate
- * config->sample_format.channels
- / 1000);
-#if 0
- static unsigned logit;
-#endif
-
- /* If we're starting then initialize the base time */
- if(!rtp_time)
- xgettimeofday(&rtp_time_0, 0);
- /* We send audio data whenever we get RTP_AHEAD seconds or more
- * behind */
- xgettimeofday(&now, 0);
- target_us = tvsub_us(now, rtp_time_0);
- assert(target_us <= UINT64_MAX / 88200);
- target_rtp_time = (target_us * config->sample_format.rate
- * config->sample_format.channels)
-
- / 1000000;
-#if 0
- /* TODO remove logging guff */
- if(!(logit++ & 1023))
- info("rtp_time %llu target %llu difference %lld [%lld]",
- rtp_time, target_rtp_time,
- rtp_time - target_rtp_time,
- samples_ahead);
-#endif
- if((int64_t)(rtp_time - target_rtp_time) < samples_ahead)
- bfd_slot = addfd(bfd, POLLOUT);
- break;
- }
-#if API_ALSA
- case BACKEND_ALSA: {
- /* We send sample data to ALSA as fast as it can accept it, relying on
- * the fact that it has a relatively small buffer to minimize pause
- * latency. */
- int retry = 3;
-
- alsa_slots = fdno;
- do {
- retry = 0;
- alsa_nslots = snd_pcm_poll_descriptors(pcm, &fds[fdno], NFDS - fdno);
- if((alsa_nslots <= 0
- || !(fds[alsa_slots].events & POLLOUT))
- && snd_pcm_state(pcm) == SND_PCM_STATE_XRUN) {
- error(0, "underrun detected after call to snd_pcm_poll_descriptors()");
- if((err = snd_pcm_prepare(pcm)))
- fatal(0, "error calling snd_pcm_prepare: %d", err);
- } else
- break;
- } while(retry-- > 0);
- if(alsa_nslots >= 0)
- fdno += alsa_nslots;
- break;
- }
-#endif
- default:
- assert(!"unknown backend");
- }
- }