static size_t speaker_callback(void *buffer,
size_t max_samples,
void attribute((unused)) *userdata) {
- const size_t max_bytes = max_samples * uaudio_sample_size;
+ size_t max_bytes = max_samples * uaudio_sample_size;
size_t provided_samples = 0;
+ /* Be sure to keep the amount of data in a buffer a whole number of frames:
+ * otherwise the playing threads can become stuck. */
+ max_bytes -= max_bytes % (uaudio_sample_size * uaudio_channels);
+
pthread_mutex_lock(&lock);
/* TODO perhaps we should immediately go silent if we've been asked to pause
* or cancel the playing track (maybe block in the cancel case and see what
/* Limit to what we were asked for */
if(bytes > max_bytes)
bytes = max_bytes;
+ /* And truncate to a whole number of frames. */
+ bytes -= bytes % (uaudio_sample_size * uaudio_channels);
/* Provide it */
memcpy(buffer, playing->buffer + playing->start, bytes);
playing->start += bytes;
/* backend-specific initialization */
if(backend->configure)
backend->configure();
+ uaudio_set("application", "disorder-speaker");
backend->start(speaker_callback, NULL);
/* create the private socket directory */
byte_xasprintf(&dir, "%s/private", config->home);
disorder_fatal(errno, "error binding socket to %s", addr.sun_path);
xlisten(listenfd, 128);
nonblock(listenfd);
+ disorder_info("version "VERSION" process ID %lu",
+ (unsigned long)getpid());
disorder_info("listening on %s", addr.sun_path);
memset(&sm, 0, sizeof sm);
sm.type = SM_READY;