X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/disorder/blobdiff_plain/e9b635a3223a51d0c30867e42ec4f9b54b62e591..28f1495aaaf9ba4f1412aa006a5d48b7cf0d71db:/clients/playrtp.c
diff --git a/clients/playrtp.c b/clients/playrtp.c
index 1263d7a..aca1532 100644
--- a/clients/playrtp.c
+++ b/clients/playrtp.c
@@ -1,21 +1,19 @@
/*
* This file is part of DisOrder.
- * Copyright (C) 2007 Richard Kettlewell
+ * Copyright (C) 2007, 2008 Richard Kettlewell
*
- * This program is free software; you can redistribute it and/or modify
+ * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
+ * along with this program. If not, see .
*/
/** @file clients/playrtp.c
* @brief RTP player
@@ -49,12 +47,9 @@
* - it is safe to read uint32_t values without a lock protecting them
*/
-#include
-#include "types.h"
+#include "common.h"
#include
-#include
-#include
#include
#include
#include
@@ -62,8 +57,6 @@
#include
#include
#include
-#include
-#include
#include
#include
#include
@@ -85,6 +78,7 @@
#include "client.h"
#include "playrtp.h"
#include "inputline.h"
+#include "version.h"
#define readahead linux_headers_are_borked
@@ -174,27 +168,42 @@ pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
/** @brief Condition variable signalled whenever @ref packets is changed */
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
-#if HAVE_ALSA_ASOUNDLIB_H
-# define DEFAULT_BACKEND playrtp_alsa
-#elif HAVE_SYS_SOUNDCARD_H || EMPEG_HOST
-# define DEFAULT_BACKEND playrtp_oss
-#elif HAVE_COREAUDIO_AUDIOHARDWARE_H
-# define DEFAULT_BACKEND playrtp_coreaudio
-#else
-# error No known backend
+#if DEFAULT_BACKEND == BACKEND_ALSA
+# define DEFAULT_PLAYRTP_BACKEND playrtp_alsa
+#elif DEFAULT_BACKEND == BACKEND_OSS
+# define DEFAULT_PLAYRTP_BACKEND playrtp_oss
+#elif DEFAULT_BACKEND == BACKEND_COREAUDIO
+# define DEFAULT_PLAYRTP_BACKEND playrtp_coreaudio
#endif
/** @brief Backend to play with */
-static void (*backend)(void) = &DEFAULT_BACKEND;
+static void (*backend)(void) = DEFAULT_PLAYRTP_BACKEND;
HEAP_DEFINE(pheap, struct packet *, lt_packet);
/** @brief Control socket or NULL */
const char *control_socket;
+/** @brief Buffer for debugging dump
+ *
+ * The debug dump is enabled by the @c --dump option. It records the last 20s
+ * of audio to the specified file (which will be about 3.5Mbytes). The file is
+ * written as as ring buffer, so the start point will progress through it.
+ *
+ * Use clients/dump2wav to convert this to a WAV file, which can then be loaded
+ * into (e.g.) Audacity for further inspection.
+ *
+ * All three backends (ALSA, OSS, Core Audio) now support this option.
+ *
+ * The idea is to allow the user a few seconds to react to an audible artefact.
+ */
int16_t *dump_buffer;
+
+/** @brief Current index within debugging dump */
size_t dump_index;
-size_t dump_size = 44100 * 2 * 20; /* 20s */
+
+/** @brief Size of debugging dump in samples */
+size_t dump_size = 44100/*Hz*/ * 2/*channels*/ * 20/*seconds*/;
static const struct option options[] = {
{ "help", no_argument, 0, 'h' },
@@ -312,8 +321,9 @@ static void *queue_thread(void attribute((unused)) *arg) {
for(;;) {
/* Get the next packet */
pthread_mutex_lock(&receive_lock);
- while(!received_packets)
+ while(!received_packets) {
pthread_cond_wait(&receive_cond, &receive_lock);
+ }
p = received_packets;
received_packets = p->next;
if(!received_packets)
@@ -387,6 +397,9 @@ static void *listen_thread(void attribute((unused)) *arg) {
timestamp, next_timestamp);
continue;
}
+ /* Ignore packets with the extension bit set. */
+ if(header.vpxcc & 0x10)
+ continue;
p->next = 0;
p->flags = 0;
p->timestamp = timestamp;
@@ -411,8 +424,9 @@ static void *listen_thread(void attribute((unused)) *arg) {
* out of order then we guarantee dropouts. But for now... */
if(nsamples >= maxbuffer) {
pthread_mutex_lock(&lock);
- while(nsamples >= maxbuffer)
+ while(nsamples >= maxbuffer) {
pthread_cond_wait(&cond, &lock);
+ }
pthread_mutex_unlock(&lock);
}
/* Add the packet to the receive queue */
@@ -435,8 +449,9 @@ void playrtp_fill_buffer(void) {
while(nsamples)
drop_first_packet();
info("Buffering...");
- while(nsamples < readahead)
+ while(nsamples < readahead) {
pthread_cond_wait(&cond, &lock);
+ }
next_timestamp = pheap_first(&packets)->timestamp;
active = 1;
}
@@ -514,13 +529,6 @@ static void help(void) {
exit(0);
}
-/* display version number and terminate */
-static void version(void) {
- xprintf("disorder-playrtp version %s\n", disorder_version_string);
- xfclose(stdout);
- exit(0);
-}
-
int main(int argc, char **argv) {
int n, err;
struct addrinfo *res;
@@ -542,14 +550,10 @@ int main(int argc, char **argv) {
const char *dumpfile = 0;
static const struct addrinfo prefs = {
- AI_PASSIVE,
- PF_INET,
- SOCK_DGRAM,
- IPPROTO_UDP,
- 0,
- 0,
- 0,
- 0
+ .ai_flags = AI_PASSIVE,
+ .ai_family = PF_INET,
+ .ai_socktype = SOCK_DGRAM,
+ .ai_protocol = IPPROTO_UDP
};
mem_init();
@@ -557,7 +561,7 @@ int main(int argc, char **argv) {
while((n = getopt_long(argc, argv, "hVdD:m:b:x:L:R:M:aocC:r", options, 0)) >= 0) {
switch(n) {
case 'h': help();
- case 'V': version();
+ case 'V': version("disorder-playrtp");
case 'd': debugging = 1; break;
case 'D': device = optarg; break;
case 'm': minbuffer = 2 * atol(optarg); break;