X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/disorder/blobdiff_plain/de37b64085838de48894200ae2b9d49417668a76..34fb8c61ac9d00d64a82facbfc16113cc5b6cfd1:/server/speaker.c diff --git a/server/speaker.c b/server/speaker.c index 1db3658..a55b074 100644 --- a/server/speaker.c +++ b/server/speaker.c @@ -1,6 +1,6 @@ /* * This file is part of DisOrder - * Copyright (C) 2005-2010 Richard Kettlewell + * Copyright (C) 2005-2013 Richard Kettlewell * Portions (C) 2007 Mark Wooding * * This program is free software: you can redistribute it and/or modify @@ -386,7 +386,7 @@ static void report(void) { return; memset(&sm, 0, sizeof sm); sm.type = paused ? SM_PAUSED : SM_PLAYING; - strcpy(sm.id, playing->id); + strcpy(sm.u.id, playing->id); sm.data = playing->played / (uaudio_rate * uaudio_channels); speaker_send(1, &sm); xtime(&last_report); @@ -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; @@ -557,7 +563,7 @@ static void mainloop(void) { } /* Notify the server that the connection arrived */ sm.type = SM_ARRIVED; - strcpy(sm.id, id); + strcpy(sm.u.id, id); speaker_send(1, &sm); } } else @@ -587,7 +593,7 @@ static void mainloop(void) { if(pending_playing) disorder_fatal(0, "got SM_PLAY but have a pending playing track"); } - t = findtrack(sm.id, 1); + t = findtrack(sm.u.id, 1); D(("SM_PLAY %s fd %d", t->id, t->fd)); if(t->fd == -1) disorder_error(0, @@ -616,8 +622,8 @@ static void mainloop(void) { force_report = 1; break; case SM_CANCEL: - D(("SM_CANCEL %s", sm.id)); - t = removetrack(sm.id); + D(("SM_CANCEL %s", sm.u.id)); + t = removetrack(sm.u.id); if(t) { if(t == playing || t == pending_playing) { /* Scratching the track that the server believes is playing, @@ -634,16 +640,16 @@ static void mainloop(void) { * log more because there's been a bug here recently than because * it's particularly interesting; the log message will be removed * if no further problems show up. */ - disorder_info("SM_CANCEL for nonplaying track %s", sm.id); + disorder_info("SM_CANCEL for nonplaying track %s", sm.u.id); sm.type = SM_STILLBORN; } - strcpy(sm.id, t->id); + strcpy(sm.u.id, t->id); destroy(t); } else { /* Probably scratching the playing track well before it's got * going, but could indicate a bug, so we log this as an error. */ sm.type = SM_UNKNOWN; - disorder_error(0, "SM_CANCEL for unknown track %s", sm.id); + disorder_error(0, "SM_CANCEL for unknown track %s", sm.u.id); } speaker_send(1, &sm); force_report = 1; @@ -654,6 +660,15 @@ static void mainloop(void) { disorder_error(0, "cannot read configuration"); disorder_info("reloaded configuration"); break; + case SM_RTP_REQUEST: + /* TODO the error behavior here is really unhelpful */ + if(rtp_add_recipient(&sm.u.address)) + disorder_error(0, "unacceptable RTP destination"); + break; + case SM_RTP_CANCEL: + if(rtp_remove_recipient(&sm.u.address)) + disorder_error(0, "unacceptable RTP destination for removal"); + break; default: disorder_error(0, "unknown message type %d", sm.type); } @@ -683,7 +698,7 @@ static void mainloop(void) { && playing->used <= early_finish) { memset(&sm, 0, sizeof sm); sm.type = SM_FINISHED; - strcpy(sm.id, playing->id); + strcpy(sm.u.id, playing->id); speaker_send(1, &sm); playing->finished = 1; } @@ -795,6 +810,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 +830,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;