chiark / gitweb /
uaudio: pulseaudio support
[disorder] / server / speaker.c
index 212ffb9a59ef045afca74da1b06abce898167258..fcfcf361a316beb8ec433c765f8c2f1370090024 100644 (file)
@@ -418,9 +418,13 @@ static int addfd(int fd, int events) {
 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
@@ -437,6 +441,8 @@ static size_t speaker_callback(void *buffer,
       /* 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;
@@ -795,6 +801,7 @@ int main(int argc, char **argv) {
   /* 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);
@@ -814,6 +821,8 @@ int main(int argc, char **argv) {
     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;