+ /* Set up output. Currently we only support L16 so there's no harm setting
+ * the format before we know what it is! */
+ uaudio_set_format(44100/*Hz*/, 2/*channels*/,
+ 16/*bits/channel*/, 1/*signed*/);
+ backend->start(playrtp_callback, NULL);
+ /* We receive and convert audio data in a background thread */
+ if((err = pthread_create(<id, 0, listen_thread, 0)))
+ fatal(err, "pthread_create listen_thread");
+ /* We have a second thread to add received packets to the queue */
+ if((err = pthread_create(<id, 0, queue_thread, 0)))
+ fatal(err, "pthread_create queue_thread");
+ pthread_mutex_lock(&lock);
+ for(;;) {
+ /* Wait for the buffer to fill up a bit */
+ playrtp_fill_buffer();
+ /* Start playing now */
+ info("Playing...");
+ next_timestamp = pheap_first(&packets)->timestamp;
+ active = 1;
+ pthread_mutex_unlock(&lock);
+ backend->activate();
+ pthread_mutex_lock(&lock);
+ /* Wait until the buffer empties out
+ *
+ * If there's a packet that we can play right now then we definitely
+ * continue.
+ *
+ * Also if there's at least minbuffer samples we carry on regardless and
+ * insert silence. The assumption is there's been a pause but more data
+ * is now available.
+ */
+ while(nsamples >= minbuffer
+ || (nsamples > 0
+ && contains(pheap_first(&packets), next_timestamp))) {
+ //fprintf(stderr, "%8u/%u (%u) PLAYING\n", nsamples, maxbuffer, minbuffer);
+ pthread_cond_wait(&cond, &lock);
+ }
+#if 0
+ if(nsamples) {
+ struct packet *p = pheap_first(&packets);
+ fprintf(stderr, "nsamples=%u (%u) next_timestamp=%"PRIx32", first packet is [%"PRIx32",%"PRIx32")\n",
+ nsamples, minbuffer, next_timestamp,p->timestamp,p->timestamp+p->nsamples);
+ }
+#endif
+ /* Stop playing for a bit until the buffer re-fills */
+ pthread_mutex_unlock(&lock);
+ backend->deactivate();
+ pthread_mutex_lock(&lock);
+ active = 0;
+ /* Go back round */
+ }