diff --git a/man/shairport-sync.html b/man/shairport-sync.html
index 5c1455f7..b1c543fb 100644
--- a/man/shairport-sync.html
+++ b/man/shairport-sync.html
@@ -13,6 +13,7 @@
[-c configurationfile]
[-E command]
[--get-cover-art]
+ [--logOutputLevel=]
[-L latency]
[-m backend]
[--meta-dir=directory]
@@ -583,6 +584,15 @@
+
--logOutputLevel
+
+ Use this to log the volume level when the volume is changed. It may be useful if you are trying to
+ determine a suitable value for the maximum volume level. Not available as a configuration file setting.
+
+
+
+
+
-L | --latency=latency
Use this to set the default latency, in frames, for audio coming from an unidentified source or from an iTunes Version 9 or earlier source. The standard value for the default latency is 88,200 frames, where there are 44,100
From c0abd82ad8f0c2b49b00a7e75bc081c24e592b81 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Fri, 7 Apr 2017 20:32:53 +0100
Subject: [PATCH 066/239] Bug fixes, improved error messaging, stability
improvements, new --logOutputLevel option.
---
configure.ac | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index 63e8347b..a900949b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.50])
-AC_INIT([shairport-sync], [3.1s4], [mikebrady@eircom.net])
+AC_INIT([shairport-sync], [3.1s5], [mikebrady@eircom.net])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([shairport.c])
AC_CONFIG_HEADERS([config.h])
From a27c2b8daee450c9ea02a0a00e80b2b5508c7fd1 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Fri, 7 Apr 2017 20:40:47 +0100
Subject: [PATCH 067/239] Update RELEASENOTES.md
---
RELEASENOTES.md | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 9ee87457..e95ec70c 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -1,7 +1,22 @@
+Version 3.1s5
+====
+Generally, more extensive changes have been to make all relevant operations reentrant.
+
+Your stability reports would be welcome.
+
+**New Feature**
+* A new command line option **--logOutputLevel** that logs the output level whenever the volume is changed. It's meant to be ueful if you have to to determine the right level to set in volume_max_db.
+
+**Bug fix**
+* Sometimes when you stop a play and quickly start another, a short piece of audio from the end of the old session will play before the new session starts. Fixed by improving the flush command and by ignoring the first few frames after a play starts.
+
+**Enchancements**
+* Better reporting when a pipe can't be written to or can't be opened.
+
Version 3.1s4
====
**Bug fix**
-* If Shairport Sync tried to change a mixer level and failed, it would terminate. Now is just logs a debug report.
+* If Shairport Sync tried to change a mixer level and failed, it would terminate. Now it just logs a debug report.
Version 3.1s3
====
@@ -16,7 +31,7 @@ Other minor fixes will be detailed later.
Version 3.1d1
====
-This is a stability update. Some users have reported occasional crashes particularly when a play session ends and another begins immediately. The thread that plays a session was not reentrant, and this _may_ have been causing those stability problems. The player thread is now fully re-entrant, so those stability problems should be gone. The changes made were quite extensive, so more bugs may have been reintroduced. Your stability reports would be welcome.
+This is a stability update. Some users have reported occasional crashes particularly when a play session ends and another begins immediately. The thread that plays a session was not reentrant, and this _may_ have been causing those stability problems. The player thread is now fully re-entrant, so those stability problems should be gone. The changes made were quite extensive, so more bugs may have been reintroduced.
Please note that there are still problems with SoundCloud. Soundcloud seems to have problems with AirPlay in general -- the problems are not specific to Shairport Sync.
From eaf8ffb0cab0d74a1d06c31f1eb9bd6136a23233 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Fri, 7 Apr 2017 20:41:42 +0100
Subject: [PATCH 068/239] Update RELEASENOTES.md
---
RELEASENOTES.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index e95ec70c..a3ff0431 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -10,7 +10,7 @@ Your stability reports would be welcome.
**Bug fix**
* Sometimes when you stop a play and quickly start another, a short piece of audio from the end of the old session will play before the new session starts. Fixed by improving the flush command and by ignoring the first few frames after a play starts.
-**Enchancements**
+**Enhancements**
* Better reporting when a pipe can't be written to or can't be opened.
Version 3.1s4
From e3dab142cfecc80f9cde9c1483a4a7895d75560c Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Fri, 7 Apr 2017 20:42:20 +0100
Subject: [PATCH 069/239] Update RELEASENOTES.md
---
RELEASENOTES.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index a3ff0431..2f226314 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -5,7 +5,7 @@ Generally, more extensive changes have been to make all relevant operations reen
Your stability reports would be welcome.
**New Feature**
-* A new command line option **--logOutputLevel** that logs the output level whenever the volume is changed. It's meant to be ueful if you have to to determine the right level to set in volume_max_db.
+* A new command line option **--logOutputLevel** that logs the output level whenever the volume is changed. It's meant to be useful if you have to to determine the right level to set in volume_max_db.
**Bug fix**
* Sometimes when you stop a play and quickly start another, a short piece of audio from the end of the old session will play before the new session starts. Fixed by improving the flush command and by ignoring the first few frames after a play starts.
From da12c4497881fabcfe72ecdb032d98bc6162d2e9 Mon Sep 17 00:00:00 2001
From: Tobias Kortkamp
Date: Wed, 12 Apr 2017 15:15:57 +0200
Subject: [PATCH 070/239] Rewrite and unbreak sndio backend
---
audio_sndio.c | 263 +++++++++++++++++++++++++++++-------
configure.ac | 4 +-
scripts/shairport-sync.conf | 10 ++
3 files changed, 224 insertions(+), 53 deletions(-)
diff --git a/audio_sndio.c b/audio_sndio.c
index e8f14807..8aa1d8ab 100644
--- a/audio_sndio.c
+++ b/audio_sndio.c
@@ -1,6 +1,7 @@
/*
* sndio output driver. This file is part of Shairport.
* Copyright (c) 2013 Dimitri Sokolyuk
+ * Copyright (c) 2017 Tobias Kortkamp
*
* Modifications for audio synchronisation
* and related work, copyright (c) Mike Brady 2014
@@ -20,58 +21,23 @@
*/
#include "audio.h"
+#include "common.h"
+#include
#include
#include
+#include
#include
-static struct sio_hdl *sio;
-static struct sio_par par;
-
-static int init(int argc, char **argv) {
- sio = sio_open(SIO_DEVANY, SIO_PLAY, 0);
- if (!sio)
- die("sndio: cannot connect to sound server");
-
- sio_initpar(&par);
-
- par.bits = 16;
- par.rate = 44100;
- par.pchan = 2;
- par.le = SIO_LE_NATIVE;
- par.sig = 1;
-
- if (!sio_setpar(sio, &par))
- die("sndio: failed to set audio parameters");
- if (!sio_getpar(sio, &par))
- die("sndio: failed to get audio parameters");
-
- config.audio_backend_buffer_desired_length = 44100; // one second.
- config.audio_backend_latency_offset = 0;
-
- return 0;
-}
-
-static void deinit(void) { sio_close(sio); }
-
-static void start(int sample_rate) {
- sio_start(sio);
-}
-
-static void play(short buf[], int samples) {
- sio_write(sio, (char *)buf, samples * par.bps * par.pchan);
-}
-
-static void stop(void) { sio_stop(sio); }
-
-static void help(void) {
- printf(" There are no options for sndio audio.\n");
- printf(" Use AUDIODEVICE environment variable.\n");
-}
-
-static void volume(double vol) {
- unsigned int v = vol * SIO_MAXVOL;
- sio_setvol(sio, v);
-}
+static void help(void);
+static int init(int, char **);
+static void onmove_cb(void *, int);
+static void deinit(void);
+static void start(int, int);
+static void play(short[], int);
+static void stop(void);
+static void onmove_cb(void *, int);
+static int delay(long *);
+static void flush(void);
audio_output audio_sndio = {.name = "sndio",
.help = &help,
@@ -79,9 +45,204 @@ audio_output audio_sndio = {.name = "sndio",
.deinit = &deinit,
.start = &start,
.stop = &stop,
- .flush = NULL,
- .delay = NULL,
+ .flush = &flush,
+ .delay = &delay,
.play = &play,
- .volume = &volume,
+ .volume = NULL,
.parameters = NULL,
.mute = NULL};
+
+static pthread_mutex_t sndio_mutex = PTHREAD_MUTEX_INITIALIZER;
+static struct sio_hdl *hdl;
+static int framesize;
+static size_t played;
+static size_t written;
+
+struct sndio_formats {
+ const char *name;
+ enum sps_format_t fmt;
+
+ unsigned int bits;
+ unsigned int bps;
+ unsigned int sig;
+ unsigned int le;
+};
+
+static struct sndio_formats formats[] = {
+ {"s8", SPS_FORMAT_S8, 8, 1, 1, SIO_LE_NATIVE},
+ {"u8", SPS_FORMAT_U8, 8, 1, 0, SIO_LE_NATIVE},
+ {"s16", SPS_FORMAT_S16, 16, 2, 1, SIO_LE_NATIVE},
+ {"s24", SPS_FORMAT_S24, 24, 4, 1, SIO_LE_NATIVE},
+ {"s24le3", SPS_FORMAT_S24_3LE, 24, 3, 1, 1},
+ {"s24be3", SPS_FORMAT_S24_3BE, 24, 3, 1, 0},
+ {"s32", SPS_FORMAT_S32, 24, 4, 1, SIO_LE_NATIVE}};
+
+static void help() {
+ printf(" -d output-device set the output device [default*|...]\n");
+}
+
+static int init(int argc, char **argv) {
+ struct sio_par par;
+ int i, found, opt, round, rate, bufsz;
+ const char *devname, *tmp;
+
+ sio_initpar(&par);
+ par.rate = 44100;
+ par.pchan = 2;
+ par.bits = 16;
+ par.bps = SIO_BPS(par.bits);
+ par.le = 1;
+ par.sig = 1;
+
+ if (!config_lookup_string(config.cfg, "sndio.device", &devname))
+ devname = SIO_DEVANY;
+ if (config_lookup_int(config.cfg, "sndio.rate", &rate)) {
+ if (rate % 44100 == 0 && rate >= 44100 && rate <= 352800) {
+ par.rate = rate;
+ } else {
+ die("sndio: output rate must be a multiple of 44100 and 44100 <= rate <= "
+ "352800");
+ }
+ }
+ if (config_lookup_int(config.cfg, "sndio.bufsz", &bufsz)) {
+ if (bufsz > 0) {
+ par.appbufsz = bufsz;
+ } else {
+ die("sndio: bufsz must be > 0");
+ }
+ }
+ if (config_lookup_int(config.cfg, "sndio.round", &round)) {
+ if (round > 0) {
+ par.round = round;
+ } else {
+ die("sndio: round must be > 0");
+ }
+ }
+ if (config_lookup_string(config.cfg, "sndio.format", &tmp)) {
+ for (i = 0, found = 0; i < sizeof(formats) / sizeof(formats[0]); i++) {
+ if (strcmp(formats[i].name, tmp) == 0) {
+ config.output_format = formats[i].fmt;
+ found = 1;
+ break;
+ }
+ }
+ if (!found)
+ die("Invalid output format \"%s\". Should be one of: s8, u8, s16, s24, "
+ "s24le3, s24be3, s32",
+ tmp);
+ }
+
+ optind = 1; // optind=0 is equivalent to optind=1 plus special behaviour
+ argv--; // so we shift the arguments to satisfy getopt()
+ argc++;
+ while ((opt = getopt(argc, argv, "d:")) > 0) {
+ switch (opt) {
+ case 'd':
+ devname = optarg;
+ break;
+ default:
+ help();
+ die("Invalid audio option -%c specified", opt);
+ }
+ }
+ if (optind < argc)
+ die("Invalid audio argument: %s", argv[optind]);
+
+ pthread_mutex_lock(&sndio_mutex);
+ debug(1, "Output device name is \"%s\".", devname);
+ hdl = sio_open(devname, SIO_PLAY, 0);
+ if (!hdl)
+ die("sndio: cannot open audio device");
+
+ written = played = 0;
+
+ for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++) {
+ if (formats[i].fmt == config.output_format) {
+ par.bits = formats[i].bits;
+ par.bps = formats[i].bps;
+ par.sig = formats[i].sig;
+ par.le = formats[i].le;
+ break;
+ }
+ }
+
+ if (!sio_setpar(hdl, &par) || !sio_getpar(hdl, &par))
+ die("sndio: failed to set audio parameters");
+ for (i = 0, found = 0; i < sizeof(formats) / sizeof(formats[0]); i++) {
+ if (formats[i].bits == par.bits && formats[i].bps == par.bps &&
+ formats[i].sig == par.sig && formats[i].le == par.le) {
+ config.output_format = formats[i].fmt;
+ found = 1;
+ break;
+ }
+ }
+ if (!found)
+ die("sndio: failed to negotiate audio parameters");
+
+ framesize = par.bps * par.pchan;
+ config.output_rate = par.rate;
+ config.audio_backend_buffer_desired_length = 1.0 * par.bufsz / par.rate;
+ config.audio_backend_latency_offset = 0;
+
+ sio_onmove(hdl, onmove_cb, NULL);
+
+ pthread_mutex_unlock(&sndio_mutex);
+
+ return 0;
+}
+
+static void deinit() {
+ pthread_mutex_lock(&sndio_mutex);
+ sio_close(hdl);
+ pthread_mutex_unlock(&sndio_mutex);
+}
+
+static void start(int sample_rate, int sample_format) {
+ pthread_mutex_lock(&sndio_mutex);
+ if (!sio_start(hdl))
+ die("sndio: unable to start");
+ written = played = 0;
+ pthread_mutex_unlock(&sndio_mutex);
+}
+
+static void play(short buf[], int frames) {
+ if (frames > 0) {
+ pthread_mutex_lock(&sndio_mutex);
+ written += sio_write(hdl, buf, frames * framesize);
+ pthread_mutex_unlock(&sndio_mutex);
+ }
+}
+
+static void stop() {
+ pthread_mutex_lock(&sndio_mutex);
+ if (!sio_stop(hdl))
+ die("sndio: unable to stop");
+ written = played = 0;
+ pthread_mutex_unlock(&sndio_mutex);
+}
+
+static void onmove_cb(void *arg, int delta) {
+ pthread_mutex_lock(&sndio_mutex);
+ played += delta;
+ pthread_mutex_unlock(&sndio_mutex);
+}
+
+static int delay(long *_delay) {
+ pthread_mutex_lock(&sndio_mutex);
+ if (played > (written / framesize)) {
+ /* _delay is in frames */
+ *_delay = (written / framesize) - played;
+ } else {
+ *_delay = 0;
+ }
+ pthread_mutex_unlock(&sndio_mutex);
+ return 0;
+}
+
+static void flush() {
+ pthread_mutex_lock(&sndio_mutex);
+ if (!sio_stop(hdl) || !sio_start(hdl))
+ die("sndio: unable to flush");
+ written = played = 0;
+ pthread_mutex_unlock(&sndio_mutex);
+}
diff --git a/configure.ac b/configure.ac
index a900949b..816858b6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -206,8 +206,8 @@ AC_ARG_WITH(alsa, [ --with-alsa = choose ALSA API support (GNU/Linux only)],
AM_CONDITIONAL([USE_ALSA], [test "x$HAS_ALSA" = "x1"])
# Look for SNDIO flag
-AC_ARG_WITH(sndio, [ --with-sndio = choose SNDIO API support (FreeBSD) -- probably broken], [
- AC_MSG_RESULT(>>Including a SNDIO back end -- N.B. this is probably broken!)
+AC_ARG_WITH(sndio, [ --with-sndio = choose SNDIO API support], [
+ AC_MSG_RESULT(>>Including a SNDIO back end)
HAS_SNDIO=1
AC_DEFINE([CONFIG_SNDIO], 1, [Needed by the compiler.])
AC_CHECK_LIB([sndio], [sio_open], , AC_MSG_ERROR(SNDIO support requires the sndio library!))], )
diff --git a/scripts/shairport-sync.conf b/scripts/shairport-sync.conf
index 0ebe7021..9af4460f 100644
--- a/scripts/shairport-sync.conf
+++ b/scripts/shairport-sync.conf
@@ -127,6 +127,16 @@ ao =
// audio_backend_buffer_desired_length = 1.0; // Having started to send audio at the right time, send all subsequent audio this much ahead of time, creating a buffer this length.
};
+// These are parameters for the "sndio" audio back end. All are optional.
+sndio =
+{
+// device = "snd/0"; // the name of the output device
+// rate = 44100; // can be 44100, 88200, 176400 or 352800, but the device must have the capability.
+// format = "s16le"; // set output format. can be "u8", "s8", "s16le", "s24le", "s24le3", "s24be3", "s32"
+// round = ; // set the period size near to this value
+// bufsz = ; // set the buffer size near to this value
+};
+
// Static latency settings are deprecated and the settings have been removed.
From c9e378f515e5dcce7c143f6a68cb441075e57959 Mon Sep 17 00:00:00 2001
From: Tobias Kortkamp
Date: Wed, 12 Apr 2017 15:18:39 +0200
Subject: [PATCH 071/239] FreeBSD doesn't have ETIME but both FreeBSD and Linux
know ETIMEDOUT
---
common.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/common.c b/common.c
index 0a60a1af..48df934a 100644
--- a/common.c
+++ b/common.c
@@ -648,7 +648,7 @@ ssize_t non_blocking_write(int fd, const void *buf, size_t count) {
} else if (rc == 0) {
// warn("non-blocking write timeout waiting for pipe to become ready for writing");
rc = -1;
- errno = -ETIME;
+ errno = -ETIMEDOUT;
} else { // rc > 0, implying it might be ready
ssize_t bytes_written = write(fd, ibuf, bytes_remaining);
if (bytes_written == -1) {
From bfd22f18254f5106233d232b955746a18e625ed4 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 14:36:56 +0100
Subject: [PATCH 072/239] Create FREEBSD.md
---
FREEBSD.md | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
create mode 100644 FREEBSD.md
diff --git a/FREEBSD.md b/FREEBSD.md
new file mode 100644
index 00000000..4af46c3a
--- /dev/null
+++ b/FREEBSD.md
@@ -0,0 +1,58 @@
+This is a very quick initial note about installing Shairport Sync on FreeBSD. Some manual installation is required.
+
+The build instrctions here install back ends of SNDIO (native to *BSD, AFAIK) and ALSA. ALSA is, or course, the Advanced Linux Sound Architecture, so it is not "native" to FreeBSD. It has, however, been ported, so it should work pretty well.
+
+This build was done on a default build of `FreeBSD 11.0-RELEASE-p9`.
+
+First, update everything:
+```
+# freebsd-update fetch
+# freebsd-update install
+```
+Next, install the `pkg` package manager and update its lists:
+
+```
+# pkg
+# pkg update
+```
+
+Now, install the ALSA and Avahi subsystems. Note: `avahi-app` is chosen because it doesn’t require X11 and `nss_mdns` allows FreeBSD
+to resolve mDNS-originated addresses. Thanks to [reidransom](https://gist.github.com/reidransom/6033227) for this:
+
+```
+# pkg install alsa-utils avahi-app nss_mdns
+```
+To enable these services to load automatically at startup, add these lines to `/etc/rc.conf`:
+```
+dbus_enable="YES"
+avahi_daemon_enable="YES"
+```
+Next, change the `hosts:` line in `/etc/nsswitch.conf` to
+```
+hosts: files dns mdns
+```
+Reboot for these changes to take effect.
+
+Next, install the packages that are needed for Shairport Sync to be downloaded and build successfully:
+```
+# pkg install git autotools pkgconf popt libconfig openssl sndio
+```
+
+Now, download Shairport Sync from GitHub and check out the `development` branch.
+```
+$ git clone https://github.com/mikebrady/shairport-sync.git
+$ cd shairport-sync
+$ git checkout development
+```
+Next, configure the build and compile it:
+
+```
+$ autoreconf -i -f
+$ CPPFLAGS="-I/usr/local/include" ./configure --with-alsa --with-avahi --with-ssl=openssl --with-metadata
+$ make
+```
+
+After this, you're on your own – the `$ sudo make install` step does not work for FreeBSD. Maybe some day...
+
+To continue, you should create a configuration file at `/usr/local/etc/shairport-sync.conf`. Please see the sample configuration file for more details.
+
From 963a363c7c8f06a9783f77355c76ac26bf3612bd Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 14:45:43 +0100
Subject: [PATCH 073/239] Update RELEASENOTES.md
---
RELEASENOTES.md | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 2f226314..86aef74b 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -1,3 +1,10 @@
+Version 3.1d6
+====
+**New Feature**
+An extensively enhanced and updated backend for SNDIO thanks to the work of [t6](https://github.com/t6).
+
+SNDIO is *"the software layer of the OpenBSD operating system that manages the use of sound cards and MIDI ports."* Additionally, SNDIO *"... pays special attention to synchronization mechanisms and reliability required by music applications"*, hopefully opening up the possibility of synchronisation native to \*BSD.
+
Version 3.1s5
====
Generally, more extensive changes have been to make all relevant operations reentrant.
From 553726ac618ac63f1528e6c6e28bbd53cd70032f Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 14:46:07 +0100
Subject: [PATCH 074/239] Update RELEASENOTES.md
---
RELEASENOTES.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 86aef74b..9add24de 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -1,6 +1,7 @@
Version 3.1d6
====
**New Feature**
+
An extensively enhanced and updated backend for SNDIO thanks to the work of [t6](https://github.com/t6).
SNDIO is *"the software layer of the OpenBSD operating system that manages the use of sound cards and MIDI ports."* Additionally, SNDIO *"... pays special attention to synchronization mechanisms and reliability required by music applications"*, hopefully opening up the possibility of synchronisation native to \*BSD.
From b505c21a9e4aa57b92f82eab3857967d04667f9b Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 14:50:31 +0100
Subject: [PATCH 075/239] Update README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 577683ba..45923d79 100644
--- a/README.md
+++ b/README.md
@@ -38,7 +38,7 @@ What else?
Status
------
-Shairport Sync works on a wide variety of Linux devices. It works on standard Ubuntu laptops, on the Raspberry Pi with Raspbian Wheezy and Jessie, Arch Linux and OpenWrt, and it runs on a Linksys NSLU2 and a TP-Link 710N using OpenWrt. It works with built-in audio and with a variety of USB-connected audio amplifiers and DACs, including a cheapo USB "3D Sound" dongle, a first generation iMic and a Topping TP30 amplifier with a USB DAC input. It will not work properly — if at all — with a PulseAudio (pseudo-)output device. Using a port of the `alsa` system, Shairport Sync runs rather well on FreeBSD.
+Shairport Sync works on a wide variety of Linux devices. It works on standard Ubuntu laptops, on the Raspberry Pi with Raspbian Wheezy and Jessie, Arch Linux and OpenWrt, and it runs on a Linksys NSLU2 and a TP-Link 710N using OpenWrt. It works with built-in audio and with a variety of USB-connected audio amplifiers and DACs, including a cheapo USB "3D Sound" dongle, a first generation iMic and a Topping TP30 amplifier with a USB DAC input. It will not work properly — if at all — with a PulseAudio (pseudo-)output device. Shairport Sync runs rather well on FreeBSD using either the ALSA or `sndio` sound systems – see [FREEBSD.md](https://github.com/mikebrady/shairport-sync/blob/development/FREEBSD.md) for a note on bulding for FreeBSD.
Shairport Sync runs well on the Raspberry Pi on USB and I2S cards. It can drive the built-in sound card, though the audio out of the card is of poor quality – see the note below on configuring the Raspberry Pi to make best use of it.
From 29f077c27f3e4f565246ddc79c63227ceb4b4345 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 14:54:26 +0100
Subject: [PATCH 076/239] Update README.md
---
README.md | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 45923d79..0f64e499 100644
--- a/README.md
+++ b/README.md
@@ -38,13 +38,15 @@ What else?
Status
------
-Shairport Sync works on a wide variety of Linux devices. It works on standard Ubuntu laptops, on the Raspberry Pi with Raspbian Wheezy and Jessie, Arch Linux and OpenWrt, and it runs on a Linksys NSLU2 and a TP-Link 710N using OpenWrt. It works with built-in audio and with a variety of USB-connected audio amplifiers and DACs, including a cheapo USB "3D Sound" dongle, a first generation iMic and a Topping TP30 amplifier with a USB DAC input. It will not work properly — if at all — with a PulseAudio (pseudo-)output device. Shairport Sync runs rather well on FreeBSD using either the ALSA or `sndio` sound systems – see [FREEBSD.md](https://github.com/mikebrady/shairport-sync/blob/development/FREEBSD.md) for a note on bulding for FreeBSD.
+Shairport Sync works on a wide variety of Linux devices and FreeBSD. It works on standard Ubuntu laptops, on the Raspberry Pi with Raspbian Wheezy and Jessie, Arch Linux and OpenWrt, and it runs on a Linksys NSLU2 and a TP-Link 710N using OpenWrt. It works with built-in audio and with a variety of USB-connected audio amplifiers and DACs, including a cheapo USB "3D Sound" dongle, a first generation iMic and a Topping TP30 amplifier with a USB DAC input. It will not work properly — if at all — with a PulseAudio (pseudo-)output device.
Shairport Sync runs well on the Raspberry Pi on USB and I2S cards. It can drive the built-in sound card, though the audio out of the card is of poor quality – see the note below on configuring the Raspberry Pi to make best use of it.
At the time of writing, OpenWrt trunk does not support USB audio well on the Raspberry Pi.
-Shairport Sync runs on Ubuntu, OpenWrt, Debian, Arch Linux and Fedora inside VMWare Fusion on a Mac, but synchronisation in inaccurate — possibly because the sound card is being emulated.
+Shairport Sync runs rather well on FreeBSD using either the ALSA or `sndio` sound systems.
+
+Shairport Sync runs on Ubuntu, OpenWrt, Debian, Arch Linux, Fedora and FreeBSD inside VMWare Fusion on a Mac, but synchronisation in inaccurate — possibly because the sound card is being emulated.
Shairport Sync will output to `alsa` cards, to standard output and to pipes using appropriate backends. You can try compiling additional backends in as you wish, but it definitely will not work properly with them. Maybe someday...
@@ -56,6 +58,8 @@ Building And Installing the Development Version
---------------------
The following procedures will install the shairport-sync application into your system. Before continuing, you should check to see if shairport-sync is already installed – you can use the command `$ which shairport-sync` to find where it is located, if installed. If it is installed you should delete it – you may need superuser privileges. After deleting, check again in case further copies are installed elsewhere.
+To build Shairport Sync from sources on FreeBSD please refer to [FREEBSD.md](https://github.com/mikebrady/shairport-sync/blob/development/FREEBSD.md).
+
To build Shairport Sync from sources on Debian, Ubuntu, Raspbian, etc. follow these instructions.
The following libraries are required:
From a55b224140ceadffd4e1456b2f3b6e2115a9b63d Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 14:56:33 +0100
Subject: [PATCH 077/239] Update FREEBSD.md
---
FREEBSD.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/FREEBSD.md b/FREEBSD.md
index 4af46c3a..99cddb55 100644
--- a/FREEBSD.md
+++ b/FREEBSD.md
@@ -1,6 +1,6 @@
This is a very quick initial note about installing Shairport Sync on FreeBSD. Some manual installation is required.
-The build instrctions here install back ends of SNDIO (native to *BSD, AFAIK) and ALSA. ALSA is, or course, the Advanced Linux Sound Architecture, so it is not "native" to FreeBSD. It has, however, been ported, so it should work pretty well.
+The build instrctions here install back ends of `sndio` (native to OpenBSD) and ALSA. ALSA is, or course, the Advanced Linux Sound Architecture, so it is not "native" to FreeBSD. It has, however, been ported, so it should work pretty well.
This build was done on a default build of `FreeBSD 11.0-RELEASE-p9`.
From dcd283428d13601b896ff56b3196349a0dea64e5 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 14:58:10 +0100
Subject: [PATCH 078/239] Update FREEBSD.md
---
FREEBSD.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/FREEBSD.md b/FREEBSD.md
index 99cddb55..94960f83 100644
--- a/FREEBSD.md
+++ b/FREEBSD.md
@@ -48,7 +48,7 @@ Next, configure the build and compile it:
```
$ autoreconf -i -f
-$ CPPFLAGS="-I/usr/local/include" ./configure --with-alsa --with-avahi --with-ssl=openssl --with-metadata
+$ CPPFLAGS="-I/usr/local/include" ./configure --with-alsa --with-avahi --with-sndio --with-ssl=openssl --with-metadata
$ make
```
From 455bf28a9ec6cd2afd64233d64f3b589a730ed65 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 15:58:15 +0100
Subject: [PATCH 079/239] Update RELEASENOTES.md
---
RELEASENOTES.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 9add24de..eb819fef 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -6,6 +6,9 @@ An extensively enhanced and updated backend for SNDIO thanks to the work of [t6]
SNDIO is *"the software layer of the OpenBSD operating system that manages the use of sound cards and MIDI ports."* Additionally, SNDIO *"... pays special attention to synchronization mechanisms and reliability required by music applications"*, hopefully opening up the possibility of synchronisation native to \*BSD.
+**Enhancements**
+* Fixed some warnings detected by `clang` on FreeBSD.
+
Version 3.1s5
====
Generally, more extensive changes have been to make all relevant operations reentrant.
From 45f2e1658678dc09b81d444c455faeb64d562aa4 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 15:59:02 +0100
Subject: [PATCH 080/239] Update RELEASENOTES.md
---
RELEASENOTES.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index eb819fef..e22600a6 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -7,7 +7,7 @@ An extensively enhanced and updated backend for SNDIO thanks to the work of [t6]
SNDIO is *"the software layer of the OpenBSD operating system that manages the use of sound cards and MIDI ports."* Additionally, SNDIO *"... pays special attention to synchronization mechanisms and reliability required by music applications"*, hopefully opening up the possibility of synchronisation native to \*BSD.
**Enhancements**
-* Fixed some warnings detected by `clang` on FreeBSD.
+* Fixed some warnings detected by `clang` on FreeBSD. One was potentially a significant error.
Version 3.1s5
====
From a53b4c5c36a2850959a93b9fea05f5c189fe0bd2 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 16:52:43 +0100
Subject: [PATCH 081/239] Fix some warnings from clang on FreeBSD. One was
significant -- the randarray stuff didn't look right.
---
audio_alsa.c | 4 +++-
common.c | 6 ++++--
player.c | 15 ++++++++++++---
3 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/audio_alsa.c b/audio_alsa.c
index f843d0d9..43542ec5 100644
--- a/audio_alsa.c
+++ b/audio_alsa.c
@@ -66,7 +66,7 @@ audio_output audio_alsa = {.name = "alsa",
static pthread_mutex_t alsa_mutex = PTHREAD_MUTEX_INITIALIZER;
static unsigned int desired_sample_rate;
-static snd_pcm_format_t sample_format;
+static enum sps_format_t sample_format;
static snd_pcm_t *alsa_handle = NULL;
static snd_pcm_hw_params_t *alsa_params = NULL;
@@ -517,6 +517,8 @@ int open_alsa_device(void) {
case SPS_FORMAT_S32:
sf = SND_PCM_FORMAT_S32;
break;
+ default:
+ die("Unsupported output format at audio_alsa.c");
}
ret = snd_pcm_hw_params_set_format(alsa_handle, alsa_params, sf);
if (ret < 0) {
diff --git a/common.c b/common.c
index 48df934a..5c10c918 100644
--- a/common.c
+++ b/common.c
@@ -755,11 +755,13 @@ void ranarrayinit() {
uint64_t ranarrayval() {
uint64_t v = ranarray[ranarraynext];
- ranarraynext = (ranarraynext++) % ranarraylength;
+ ranarraynext++;
+ ranarraynext = ranarraynext % ranarraylength;
+ return v;
}
void r64arrayinit() { ranarrayinit(); }
uint64_t ranarray64u() { return (ranarrayval()); }
-int64_t ranarray64i() { return (ranarrayval(&rx) >> 1); }
+int64_t ranarray64i() { return (ranarrayval() >> 1); }
diff --git a/player.c b/player.c
index 6012d01a..9f57e1c4 100644
--- a/player.c
+++ b/player.c
@@ -599,6 +599,8 @@ static inline void process_sample(int32_t sample, char **outp, enum sps_format_t
case SPS_FORMAT_U8:
dither_mask = (int64_t)1 << (64 + 1 - 8);
break;
+ case SPS_FORMAT_UNKNOWN:
+ die("Unexpected SPS_FORMAT_UNKNOWN while calculating dither mask.");
}
dither_mask -= 1;
// int64_t r = r64i();
@@ -673,6 +675,8 @@ static inline void process_sample(int32_t sample, char **outp, enum sps_format_t
*op = hyper_sample;
result = 1;
break;
+ case SPS_FORMAT_UNKNOWN:
+ die("Unexpected SPS_FORMAT_UNKNOWN while outputting samples");
}
*outp += result;
@@ -1321,7 +1325,6 @@ static void *player_thread_func(void *arg) {
// rate, multiply it by the frame ratio.
// but, on some occasions, more than one frame could be added
- conn->output_bytes_per_frame = 4;
switch (config.output_format) {
case SPS_FORMAT_S24_3LE:
case SPS_FORMAT_S24_3BE:
@@ -1333,6 +1336,8 @@ static void *player_thread_func(void *arg) {
case SPS_FORMAT_S32:
conn->output_bytes_per_frame = 8;
break;
+ default:
+ conn->output_bytes_per_frame = 4;
}
debug(1, "Output frame bytes is %d.", conn->output_bytes_per_frame);
@@ -1415,6 +1420,8 @@ static void *player_thread_func(void *arg) {
case SPS_FORMAT_S32:
output_bit_depth = 32;
break;
+ case SPS_FORMAT_UNKNOWN:
+ die("Unknown format choosing output bit depth");
}
debug(1, "Output bit depth is %d.", output_bit_depth);
@@ -1570,6 +1577,8 @@ static void *player_thread_func(void *arg) {
case ST_right_only:
ls = rs;
break;
+ case ST_stereo:
+ break; // nothing extra to do
}
// here, replicate the samples if you're upsampling
@@ -1817,14 +1826,14 @@ static void *player_thread_func(void *arg) {
stuff_buffer_basic_32((int32_t *)tbuf, inbuflength, config.output_format,
outbuf, amount_to_stuff, enable_dither, conn);
break;
-#ifdef HAVE_LIBSOXR
case ST_soxr:
+#ifdef HAVE_LIBSOXR
// if (amount_to_stuff) debug(1,"Soxr stuff...");
play_samples = stuff_buffer_soxr_32((int32_t *)tbuf, (int32_t *)sbuf, inbuflength,
config.output_format, outbuf, amount_to_stuff,
enable_dither,conn);
- break;
#endif
+ break;
}
/*
From 555c0c738be4441867f1f5f1c0e4983bc553af35 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 17:09:59 +0100
Subject: [PATCH 082/239] Fix off-by-one error in enumatering UDP ports in the
port_range. Make the error message a little more useful.
---
rtp.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/rtp.c b/rtp.c
index 921da780..af98b349 100644
--- a/rtp.c
+++ b/rtp.c
@@ -562,13 +562,13 @@ static int bind_port(int ip_family, const char *self_ip_address, uint32_t scope_
#endif
} while ((ret < 0) && (errno == EADDRINUSE) && (desired_port != 0) &&
- (desired_port++ < config.udp_port_base + config.udp_port_range));
+ (++desired_port < config.udp_port_base + config.udp_port_range));
// debug(1,"UDP port chosen: %d.",desired_port);
if (ret < 0) {
close(local_socket);
- die("error: could not bind a UDP port!");
+ die("error: could not bind a UDP port! Check the udp_port_range is large enough (>= 10) or check for restrictive firewall settings or a bad router!");
}
int sport;
From f73f26755c7cb3c7d8754ac727a13ca4fbbd4fa7 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 16:15:08 +0100
Subject: [PATCH 083/239] Update FREEBSD.md
---
FREEBSD.md | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/FREEBSD.md b/FREEBSD.md
index 94960f83..bf5fae14 100644
--- a/FREEBSD.md
+++ b/FREEBSD.md
@@ -56,3 +56,10 @@ After this, you're on your own – the `$ sudo make install` step does not work
To continue, you should create a configuration file at `/usr/local/etc/shairport-sync.conf`. Please see the sample configuration file for more details.
+Note, the `mixer` command is useful for setting the output device's overall volume settings. With the default settings for the `sndio` back end, the `pcm` mixer controls its maximum output:
+
+```
+$ mixer vol 100 # sets overall volume
+$ mixer pcm 100 # sets maximum volume level for the default sndio device used by Shairport Sync
+```
+
From 782726248bdbffe3cb954d687ba5bbdeaac81ed5 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 16:21:11 +0100
Subject: [PATCH 084/239] Update shairport-sync.conf
---
scripts/shairport-sync.conf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/shairport-sync.conf b/scripts/shairport-sync.conf
index 9af4460f..57821361 100644
--- a/scripts/shairport-sync.conf
+++ b/scripts/shairport-sync.conf
@@ -18,7 +18,7 @@ general =
// mdns_backend = "avahi"; // Run "shairport-sync -h" to get a list of all mdns_backends. The default is the first one.
// port = 5000; // Listen for service requests on this port
// udp_port_base = 6001; // start allocating UDP ports from this port number when needed
-// udp_port_range = 100; // look for free ports in this number of places, starting at the UDP port base (only three are needed).
+// udp_port_range = 100; // look for free ports in this number of places, starting at the UDP port base. Allow at least 10, though only three are needed in a steady state.
// statistics = "no"; // set to "yes" to print statistics in the log
// drift_tolerance_in_seconds = 0.002; // allow a timing error of this number of seconds of drift away from exact synchronisation before attempting to correct it
// resync_threshold_in_seconds = 0.050; // a synchronisation error greater than this number of seconds will cause resynchronisation; 0 disables it
From 843af022e0d672c28e830ca6d66565f59d710541 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 16:25:49 +0100
Subject: [PATCH 085/239] Update RELEASENOTES.md
---
RELEASENOTES.md | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index e22600a6..c71972c4 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -2,9 +2,12 @@ Version 3.1d6
====
**New Feature**
-An extensively enhanced and updated backend for SNDIO thanks to the work of [t6](https://github.com/t6).
+An extensively enhanced and updated backend for `sndio` thanks to the work of [t6](https://github.com/t6).
-SNDIO is *"the software layer of the OpenBSD operating system that manages the use of sound cards and MIDI ports."* Additionally, SNDIO *"... pays special attention to synchronization mechanisms and reliability required by music applications"*, hopefully opening up the possibility of synchronisation native to \*BSD.
+`sndio` is *"the software layer of the OpenBSD operating system that manages the use of sound cards and MIDI ports."* Additionally, `sndio` *"... pays special attention to synchronization mechanisms and reliability required by music applications"*, hopefully opening up the possibility of synchronisation native to \*BSD.
+
+**Bug fix**
+* Fixed an off-by-one bug which allowed one more port than specified in the `udp_port_range` setting. Thanks to [kingosticks](https://github.com/kingosticks) for the alert.
**Enhancements**
* Fixed some warnings detected by `clang` on FreeBSD. One was potentially a significant error.
From 273b622c5f2cbf729ac79e8e8f5e3d31c45ab43b Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 16:29:27 +0100
Subject: [PATCH 086/239] Update configure.ac
Better `snide` back end, some enhancements and bug fixes
---
configure.ac | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index 816858b6..4a5efa56 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.50])
-AC_INIT([shairport-sync], [3.1s5], [mikebrady@eircom.net])
+AC_INIT([shairport-sync], [3.1d6], [mikebrady@eircom.net])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([shairport.c])
AC_CONFIG_HEADERS([config.h])
From 15a4f702e95b5a3cb8f1bba8d1c3f6dd007259ee Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 17:55:47 +0100
Subject: [PATCH 087/239] Update FREEBSD.md
---
FREEBSD.md | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/FREEBSD.md b/FREEBSD.md
index bf5fae14..286cad08 100644
--- a/FREEBSD.md
+++ b/FREEBSD.md
@@ -1,4 +1,4 @@
-This is a very quick initial note about installing Shairport Sync on FreeBSD. Some manual installation is required.
+This is a very quick initial note about installing Shairport Sync on FreeBSD. Some manual installation is required. Please see important notes at the end about using the `sndio` back end.
The build instrctions here install back ends of `sndio` (native to OpenBSD) and ALSA. ALSA is, or course, the Advanced Linux Sound Architecture, so it is not "native" to FreeBSD. It has, however, been ported, so it should work pretty well.
@@ -63,3 +63,13 @@ $ mixer vol 100 # sets overall volume
$ mixer pcm 100 # sets maximum volume level for the default sndio device used by Shairport Sync
```
+Using the `sndio` back end.
+The `sndio` back end does synchronisation, using informatin supplied by the `sndio` subsystem. The format of the information is not the same as that coming from the ALSA subsystem, so Shairport Sync cannot yet use it properly. As a workaround, use the following settings:
+
+In the `general` stanza, make the following settings:
+```
+drift_tolerance_in_seconds = 0.005; // allow some more tolerance before attempting to correct
+resync_threshold_in_seconds = 0.0; // ignore a large error in the initial estimation of synchrnoisation time...
+```
+Note that there are workarounds -- it is hoped that they won't be necessary for too long.
+
From 0763185859b23d307aa747869824116c95d0df38 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 18:00:25 +0100
Subject: [PATCH 088/239] Update FREEBSD.md
---
FREEBSD.md | 34 +++++++++++++++++++++++++---------
1 file changed, 25 insertions(+), 9 deletions(-)
diff --git a/FREEBSD.md b/FREEBSD.md
index 286cad08..037f804e 100644
--- a/FREEBSD.md
+++ b/FREEBSD.md
@@ -1,7 +1,13 @@
-This is a very quick initial note about installing Shairport Sync on FreeBSD. Some manual installation is required. Please see important notes at the end about using the `sndio` back end.
+Introduction
+----
+This is a very quick initial note about installing Shairport Sync on FreeBSD. Some manual installation is required.
+
+Please see important notes at the end about using the `sndio` back end -- some workarounds are needed for the present.
The build instrctions here install back ends of `sndio` (native to OpenBSD) and ALSA. ALSA is, or course, the Advanced Linux Sound Architecture, so it is not "native" to FreeBSD. It has, however, been ported, so it should work pretty well.
+General
+----
This build was done on a default build of `FreeBSD 11.0-RELEASE-p9`.
First, update everything:
@@ -16,6 +22,8 @@ Next, install the `pkg` package manager and update its lists:
# pkg update
```
+Subsystems
+----
Now, install the ALSA and Avahi subsystems. Note: `avahi-app` is chosen because it doesn’t require X11 and `nss_mdns` allows FreeBSD
to resolve mDNS-originated addresses. Thanks to [reidransom](https://gist.github.com/reidransom/6033227) for this:
@@ -33,6 +41,9 @@ hosts: files dns mdns
```
Reboot for these changes to take effect.
+Building
+----
+
Next, install the packages that are needed for Shairport Sync to be downloaded and build successfully:
```
# pkg install git autotools pkgconf popt libconfig openssl sndio
@@ -52,19 +63,16 @@ $ CPPFLAGS="-I/usr/local/include" ./configure --with-alsa --with-avahi --with-s
$ make
```
+What's Next
+----
After this, you're on your own – the `$ sudo make install` step does not work for FreeBSD. Maybe some day...
To continue, you should create a configuration file at `/usr/local/etc/shairport-sync.conf`. Please see the sample configuration file for more details.
-Note, the `mixer` command is useful for setting the output device's overall volume settings. With the default settings for the `sndio` back end, the `pcm` mixer controls its maximum output:
+Using the `sndio` backend
+----
-```
-$ mixer vol 100 # sets overall volume
-$ mixer pcm 100 # sets maximum volume level for the default sndio device used by Shairport Sync
-```
-
-Using the `sndio` back end.
-The `sndio` back end does synchronisation, using informatin supplied by the `sndio` subsystem. The format of the information is not the same as that coming from the ALSA subsystem, so Shairport Sync cannot yet use it properly. As a workaround, use the following settings:
+The `sndio` back end does synchronisation, using information from the `sndio` subsystem. The format of the information is not the same as that coming from the ALSA subsystem, so Shairport Sync cannot yet use it properly. As a workaround, please use the following settings:
In the `general` stanza, make the following settings:
```
@@ -73,3 +81,11 @@ resync_threshold_in_seconds = 0.0; // ignore a large error in the initial estima
```
Note that there are workarounds -- it is hoped that they won't be necessary for too long.
+Setting Overall Volume
+----
+Note, the `mixer` command is useful for setting the output device's overall volume settings. With the default settings for the `sndio` back end, the `pcm` mixer controls its maximum output:
+
+```
+$ mixer vol 100 # sets overall volume
+$ mixer pcm 100 # sets maximum volume level for the default sndio device used by Shairport Sync
+```
From e8fc368f017914fecf9ca5099ff108e903606410 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 18:03:20 +0100
Subject: [PATCH 089/239] Update FREEBSD.md
---
FREEBSD.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/FREEBSD.md b/FREEBSD.md
index 037f804e..3484c077 100644
--- a/FREEBSD.md
+++ b/FREEBSD.md
@@ -4,7 +4,7 @@ This is a very quick initial note about installing Shairport Sync on FreeBSD. So
Please see important notes at the end about using the `sndio` back end -- some workarounds are needed for the present.
-The build instrctions here install back ends of `sndio` (native to OpenBSD) and ALSA. ALSA is, or course, the Advanced Linux Sound Architecture, so it is not "native" to FreeBSD. It has, however, been ported, so it should work pretty well.
+The build instrctions here install back ends for `sndio` (native to OpenBSD) and ALSA. ALSA is, or course, the Advanced Linux Sound Architecture, so it is not "native" to FreeBSD. It has, however, been ported, so it should work pretty well.
General
----
@@ -63,7 +63,7 @@ $ CPPFLAGS="-I/usr/local/include" ./configure --with-alsa --with-avahi --with-s
$ make
```
-What's Next
+Manual Installation
----
After this, you're on your own – the `$ sudo make install` step does not work for FreeBSD. Maybe some day...
From d09f125b7db30a8caf35a049aabfac97cb0a58c1 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 18:14:22 +0100
Subject: [PATCH 090/239] Update FREEBSD.md
---
FREEBSD.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/FREEBSD.md b/FREEBSD.md
index 3484c077..5b62a435 100644
--- a/FREEBSD.md
+++ b/FREEBSD.md
@@ -72,12 +72,12 @@ To continue, you should create a configuration file at `/usr/local/etc/shairport
Using the `sndio` backend
----
-The `sndio` back end does synchronisation, using information from the `sndio` subsystem. The format of the information is not the same as that coming from the ALSA subsystem, so Shairport Sync cannot yet use it properly. As a workaround, please use the following settings:
+The `sndio` back end does synchronisation, thanks to the work of [t6](https://github.com/t6), using information from the `sndio` subsystem. The format of the information is not the same as that coming from the ALSA subsystem, so Shairport Sync cannot yet use it properly. As a workaround, please use the following settings:
-In the `general` stanza, make the following settings:
+In the `general` stanza of the configuration file at `/usr/local/etc/shairport-sync.conf`, make the following settings:
```
drift_tolerance_in_seconds = 0.005; // allow some more tolerance before attempting to correct
-resync_threshold_in_seconds = 0.0; // ignore a large error in the initial estimation of synchrnoisation time...
+resync_threshold_in_seconds = 0.0; // ignore a large error in the initial estimation of synchronisation time...
```
Note that there are workarounds -- it is hoped that they won't be necessary for too long.
From 5ab3c3b99870413a22234009e69f02724a94959c Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 18:15:08 +0100
Subject: [PATCH 091/239] Update FREEBSD.md
---
FREEBSD.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/FREEBSD.md b/FREEBSD.md
index 5b62a435..241e3dfc 100644
--- a/FREEBSD.md
+++ b/FREEBSD.md
@@ -4,7 +4,7 @@ This is a very quick initial note about installing Shairport Sync on FreeBSD. So
Please see important notes at the end about using the `sndio` back end -- some workarounds are needed for the present.
-The build instrctions here install back ends for `sndio` (native to OpenBSD) and ALSA. ALSA is, or course, the Advanced Linux Sound Architecture, so it is not "native" to FreeBSD. It has, however, been ported, so it should work pretty well.
+The build instructions here install back ends for `sndio` (native to OpenBSD) and ALSA. ALSA is, or course, the Advanced Linux Sound Architecture, so it is not "native" to FreeBSD. It has, however, been ported, so it should work pretty well.
General
----
From 225efa127aee78e4033fd9741ee4ebd7a9f2f738 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 18:40:05 +0100
Subject: [PATCH 092/239] Improve debug messages a little
---
audio_sndio.c | 10 ++++++----
player.c | 4 ++--
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/audio_sndio.c b/audio_sndio.c
index 8aa1d8ab..c10077c2 100644
--- a/audio_sndio.c
+++ b/audio_sndio.c
@@ -229,12 +229,14 @@ static void onmove_cb(void *arg, int delta) {
static int delay(long *_delay) {
pthread_mutex_lock(&sndio_mutex);
- if (played > (written / framesize)) {
+ // debug(1,"Frames written %u, played %u.",written/framesize,played);
+
+ //if (played > (written / framesize)) {
/* _delay is in frames */
*_delay = (written / framesize) - played;
- } else {
- *_delay = 0;
- }
+ // } else {
+ // *_delay = 0;
+ // }
pthread_mutex_unlock(&sndio_mutex);
return 0;
}
diff --git a/player.c b/player.c
index 9f57e1c4..5dbce717 100644
--- a/player.c
+++ b/player.c
@@ -1685,7 +1685,7 @@ static void *player_thread_func(void *arg) {
current_delay = l_delay;
if (resp == 0) { // no error
if (current_delay < 0) {
- debug(1, "Underrun of %d frames reported, but ignored.", current_delay);
+ debug(1, "Underrun of %lld frames reported, but ignored.", current_delay);
current_delay =
0; // could get a negative value if there was underrun, but ignore it.
}
@@ -1728,7 +1728,7 @@ static void *player_thread_func(void *arg) {
// only allow stuffing if there is enough time to do it -- check DAC buffer...
if (current_delay < DAC_BUFFER_QUEUE_MINIMUM_LENGTH) {
- // debug(1,"DAC buffer too short to allow stuffing.");
+ // debug(2,"DAC buffer too short(at %lld frames) to allow stuffing.",current_delay);
amount_to_stuff = 0;
}
From 2caeeb35819e45f5b535416e2e4976d932c9a7c6 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 18:43:11 +0100
Subject: [PATCH 093/239] Fix an error that prevented it from reporting delay
correctly.
---
audio_sndio.c | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/audio_sndio.c b/audio_sndio.c
index c10077c2..52e127dd 100644
--- a/audio_sndio.c
+++ b/audio_sndio.c
@@ -229,14 +229,7 @@ static void onmove_cb(void *arg, int delta) {
static int delay(long *_delay) {
pthread_mutex_lock(&sndio_mutex);
- // debug(1,"Frames written %u, played %u.",written/framesize,played);
-
- //if (played > (written / framesize)) {
- /* _delay is in frames */
- *_delay = (written / framesize) - played;
- // } else {
- // *_delay = 0;
- // }
+ *_delay = (written / framesize) - played;
pthread_mutex_unlock(&sndio_mutex);
return 0;
}
From bcdd2408a5619d01fc186a36a69e7ce00e49b047 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 20:04:37 +0100
Subject: [PATCH 094/239] Update LIBSOXR.md
---
LIBSOXR.md | 30 +++++++++++++++++++++---------
1 file changed, 21 insertions(+), 9 deletions(-)
diff --git a/LIBSOXR.md b/LIBSOXR.md
index 2c703ab6..8a81cfdd 100644
--- a/LIBSOXR.md
+++ b/LIBSOXR.md
@@ -3,28 +3,40 @@ The Raspbian image at the time of writing is the `May 2016` version, with the re
Alternatively, `libsoxr` is very easy to compile. Here are very brief instructions to download, compile and install it:
-* Install `cmake`. This is used in the building of libsoxr:
+* Install `cmake`. This is used in the building of libsoxr. On Linuxes such as Debian/Ubuntu/Raspbian:
```
-sudo apt-get install cmake
+# apt-get install cmake
```
+On FreeBSD:
+```
+# pkg install cmake
+```
+
* Download the `libsoxr source`:
```
-git clone git://git.code.sf.net/p/soxr/code libsoxr
+$ git clone git://git.code.sf.net/p/soxr/code libsoxr
```
* `cd` into the `libsoxr` directory and start the build process:
```
-cd libsoxr
-./go
+$ cd libsoxr
+$ ./go
```
Be patient! This takes a long time on a Raspberry Pi -- it looks like it gets stuck around 40% or 50%, but it will finish if you let it.
Having compiled `libsoxr`, it must now must be installed:
```
-cd Release
-sudo make install
+$ cd Release
+# make install
```
-Finally, for Shairport Sync to be able to locate `libsoxr-dev` during compilation, you need to tell `ld` to catalogue it:
+Finally, for Shairport Sync to be able to locate `libsoxr` during compilation, you need to tell `ld` about it. Be careful here if you are on FreeBSD -- the following instructions for Linux would mess up your FreeBSD system.
+
+On Linuxes such as Debian/Ubuntu/Raspbian:
```
-sudo ldconfig -v
+# ldconfig -v
+```
+On FreeBSD you must add the location of the `soxr.pc` file to the `PKG_CONFIG_PATH`, if it exists, and define it otherwise. Here is what you do if it doesn't already exist:
+```
+$ PKG_CONFIG_PATH="/usr/local/lib/pkgconfig"
+$ export PKG_CONFIG_PATH
```
That's it. Now you can select the `--with-soxr` option when you're building Shairport Sync.
From 637072858f2b5643411965a73de113885e4fe747 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 20:47:55 +0100
Subject: [PATCH 095/239] Fix an inconsequential warning showing up in clang
---
apple_alac.cpp | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/apple_alac.cpp b/apple_alac.cpp
index 0ee30290..6d543b2e 100644
--- a/apple_alac.cpp
+++ b/apple_alac.cpp
@@ -52,4 +52,7 @@ extern "C" int apple_alac_decode_frame(unsigned char *sampleBuffer, uint32_t buf
return 0;
}
-extern "C" int apple_alac_terminate() { delete (theDecoder); }
+extern "C" int apple_alac_terminate() {
+ delete (theDecoder);
+ return 0;
+}
From 67aed3a3590beb9e6f16eadb8bf191ff4305f94e Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 22:12:17 +0100
Subject: [PATCH 096/239] Fix a few crashing bugs if there was no configuration
file at all
---
audio_sndio.c | 77 ++++++++++++++++++++++++++-------------------------
1 file changed, 39 insertions(+), 38 deletions(-)
diff --git a/audio_sndio.c b/audio_sndio.c
index 52e127dd..7ea0a89e 100644
--- a/audio_sndio.c
+++ b/audio_sndio.c
@@ -85,6 +85,7 @@ static int init(int argc, char **argv) {
struct sio_par par;
int i, found, opt, round, rate, bufsz;
const char *devname, *tmp;
+
sio_initpar(&par);
par.rate = 44100;
@@ -93,45 +94,47 @@ static int init(int argc, char **argv) {
par.bps = SIO_BPS(par.bits);
par.le = 1;
par.sig = 1;
-
- if (!config_lookup_string(config.cfg, "sndio.device", &devname))
- devname = SIO_DEVANY;
- if (config_lookup_int(config.cfg, "sndio.rate", &rate)) {
- if (rate % 44100 == 0 && rate >= 44100 && rate <= 352800) {
- par.rate = rate;
- } else {
- die("sndio: output rate must be a multiple of 44100 and 44100 <= rate <= "
- "352800");
- }
- }
- if (config_lookup_int(config.cfg, "sndio.bufsz", &bufsz)) {
- if (bufsz > 0) {
- par.appbufsz = bufsz;
- } else {
- die("sndio: bufsz must be > 0");
- }
- }
- if (config_lookup_int(config.cfg, "sndio.round", &round)) {
- if (round > 0) {
- par.round = round;
- } else {
- die("sndio: round must be > 0");
- }
- }
- if (config_lookup_string(config.cfg, "sndio.format", &tmp)) {
- for (i = 0, found = 0; i < sizeof(formats) / sizeof(formats[0]); i++) {
- if (strcmp(formats[i].name, tmp) == 0) {
- config.output_format = formats[i].fmt;
- found = 1;
- break;
+ devname = SIO_DEVANY;
+
+ if (config.cfg != NULL) {
+ if (!config_lookup_string(config.cfg, "sndio.device", &devname))
+ devname = SIO_DEVANY;
+ if (config_lookup_int(config.cfg, "sndio.rate", &rate)) {
+ if (rate % 44100 == 0 && rate >= 44100 && rate <= 352800) {
+ par.rate = rate;
+ } else {
+ die("sndio: output rate must be a multiple of 44100 and 44100 <= rate <= "
+ "352800");
}
}
- if (!found)
- die("Invalid output format \"%s\". Should be one of: s8, u8, s16, s24, "
- "s24le3, s24be3, s32",
- tmp);
+ if (config_lookup_int(config.cfg, "sndio.bufsz", &bufsz)) {
+ if (bufsz > 0) {
+ par.appbufsz = bufsz;
+ } else {
+ die("sndio: bufsz must be > 0");
+ }
+ }
+ if (config_lookup_int(config.cfg, "sndio.round", &round)) {
+ if (round > 0) {
+ par.round = round;
+ } else {
+ die("sndio: round must be > 0");
+ }
+ }
+ if (config_lookup_string(config.cfg, "sndio.format", &tmp)) {
+ for (i = 0, found = 0; i < sizeof(formats) / sizeof(formats[0]); i++) {
+ if (strcmp(formats[i].name, tmp) == 0) {
+ config.output_format = formats[i].fmt;
+ found = 1;
+ break;
+ }
+ }
+ if (!found)
+ die("Invalid output format \"%s\". Should be one of: s8, u8, s16, s24, "
+ "s24le3, s24be3, s32",
+ tmp);
+ }
}
-
optind = 1; // optind=0 is equivalent to optind=1 plus special behaviour
argv--; // so we shift the arguments to satisfy getopt()
argc++;
@@ -147,7 +150,6 @@ static int init(int argc, char **argv) {
}
if (optind < argc)
die("Invalid audio argument: %s", argv[optind]);
-
pthread_mutex_lock(&sndio_mutex);
debug(1, "Output device name is \"%s\".", devname);
hdl = sio_open(devname, SIO_PLAY, 0);
@@ -187,7 +189,6 @@ static int init(int argc, char **argv) {
sio_onmove(hdl, onmove_cb, NULL);
pthread_mutex_unlock(&sndio_mutex);
-
return 0;
}
From f8d8f98f30909f75776c87e75f780965376a9337 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 16 Apr 2017 21:18:42 +0100
Subject: [PATCH 097/239] Update RELEASENOTES.md
---
RELEASENOTES.md | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index c71972c4..3f4f0aaf 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -4,10 +4,13 @@ Version 3.1d6
An extensively enhanced and updated backend for `sndio` thanks to the work of [t6](https://github.com/t6).
-`sndio` is *"the software layer of the OpenBSD operating system that manages the use of sound cards and MIDI ports."* Additionally, `sndio` *"... pays special attention to synchronization mechanisms and reliability required by music applications"*, hopefully opening up the possibility of synchronisation native to \*BSD.
+`sndio` is *"the software layer of the OpenBSD operating system that manages the use of sound cards and MIDI ports."* Additionally, `sndio` *"... pays special attention to synchronization mechanisms and reliability required by music applications"*.
+
+Using `sndio` brings the possibility of "native" synchronisation to \*BSD. In fact, it already works but with some workarounds. The synchronization may not be exact, but it doesn't overrun or underrun. More exploration necessary.
**Bug fix**
* Fixed an off-by-one bug which allowed one more port than specified in the `udp_port_range` setting. Thanks to [kingosticks](https://github.com/kingosticks) for the alert.
+* Various small bugfixes to the `sndio` backend.
**Enhancements**
* Fixed some warnings detected by `clang` on FreeBSD. One was potentially a significant error.
From 4d169d7b3be9fddcc7c705e2805850f3b0104f4a Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Mon, 17 Apr 2017 17:00:18 +0100
Subject: [PATCH 098/239] Improve the delay function by estimating the number
of frames played during the interval
---
audio_sndio.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/audio_sndio.c b/audio_sndio.c
index 7ea0a89e..3434324f 100644
--- a/audio_sndio.c
+++ b/audio_sndio.c
@@ -57,6 +57,8 @@ static struct sio_hdl *hdl;
static int framesize;
static size_t played;
static size_t written;
+int64_t time_of_last_onmove_cb;
+int at_least_one_onmove_cb_seen;
struct sndio_formats {
const char *name;
@@ -157,6 +159,8 @@ static int init(int argc, char **argv) {
die("sndio: cannot open audio device");
written = played = 0;
+ time_of_last_onmove_cb = 0;
+ at_least_one_onmove_cb_seen = 0;
for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++) {
if (formats[i].fmt == config.output_format) {
@@ -203,6 +207,8 @@ static void start(int sample_rate, int sample_format) {
if (!sio_start(hdl))
die("sndio: unable to start");
written = played = 0;
+ time_of_last_onmove_cb = 0;
+ at_least_one_onmove_cb_seen = 0;
pthread_mutex_unlock(&sndio_mutex);
}
@@ -224,13 +230,25 @@ static void stop() {
static void onmove_cb(void *arg, int delta) {
pthread_mutex_lock(&sndio_mutex);
+ time_of_last_onmove_cb = get_absolute_time_in_fp();
+ at_least_one_onmove_cb_seen = 1;
played += delta;
pthread_mutex_unlock(&sndio_mutex);
}
static int delay(long *_delay) {
pthread_mutex_lock(&sndio_mutex);
- *_delay = (written / framesize) - played;
+ size_t estimated_extra_frames_output = 0;
+ if (at_least_one_onmove_cb_seen) { // when output starts, the onmove_cb callback will be made
+ // calculate the difference in time between now and when the last callback occoured,
+ // and use it to estimate the frames that would have been output
+ uint64_t time_difference = get_absolute_time_in_fp() - time_of_last_onmove_cb;
+ uint64_t frame_difference = time_difference * 44100;
+ uint64_t frame_difference_big_integer = frame_difference>>32;
+ estimated_extra_frames_output = frame_difference_big_integer;
+ // debug(1,"Frames played to last cb: %d, estimated to current time: %d.",played,estimated_extra_frames_output);
+ }
+ *_delay = (written / framesize) - (played+estimated_extra_frames_output);
pthread_mutex_unlock(&sndio_mutex);
return 0;
}
From 9654783879733de3de5d8f5e383fe22e111c86f1 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Mon, 17 Apr 2017 19:47:58 +0100
Subject: [PATCH 099/239] Update FREEBSD.md
---
FREEBSD.md | 13 ++-----------
1 file changed, 2 insertions(+), 11 deletions(-)
diff --git a/FREEBSD.md b/FREEBSD.md
index 241e3dfc..67b6af14 100644
--- a/FREEBSD.md
+++ b/FREEBSD.md
@@ -2,9 +2,7 @@ Introduction
----
This is a very quick initial note about installing Shairport Sync on FreeBSD. Some manual installation is required.
-Please see important notes at the end about using the `sndio` back end -- some workarounds are needed for the present.
-
-The build instructions here install back ends for `sndio` (native to OpenBSD) and ALSA. ALSA is, or course, the Advanced Linux Sound Architecture, so it is not "native" to FreeBSD. It has, however, been ported, so it should work pretty well.
+The build instructions here install back ends for `sndio` (native to OpenBSD) and ALSA. ALSA is, or course, the Advanced Linux Sound Architecture, so it is not "native" to FreeBSD. It has, however, been ported to some architectures (not to the ARM, unfortunately), so it should work pretty well on those.
General
----
@@ -72,14 +70,7 @@ To continue, you should create a configuration file at `/usr/local/etc/shairport
Using the `sndio` backend
----
-The `sndio` back end does synchronisation, thanks to the work of [t6](https://github.com/t6), using information from the `sndio` subsystem. The format of the information is not the same as that coming from the ALSA subsystem, so Shairport Sync cannot yet use it properly. As a workaround, please use the following settings:
-
-In the `general` stanza of the configuration file at `/usr/local/etc/shairport-sync.conf`, make the following settings:
-```
-drift_tolerance_in_seconds = 0.005; // allow some more tolerance before attempting to correct
-resync_threshold_in_seconds = 0.0; // ignore a large error in the initial estimation of synchronisation time...
-```
-Note that there are workarounds -- it is hoped that they won't be necessary for too long.
+The `sndio` back end does synchronisation and is still under development. Right now, it seems to work very well. It does not have a mixer control facility, however. You should set the volume to maximum before use, using, for example, the `mixer` command described below.
Setting Overall Volume
----
From d52d7b87d2b30e7065e60b874d3ed545419a52e4 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Mon, 17 Apr 2017 19:50:25 +0100
Subject: [PATCH 100/239] Update RELEASENOTES.md
---
RELEASENOTES.md | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 3f4f0aaf..581722cc 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -1,3 +1,9 @@
+Version 3.1d7
+====
+**Improvements**
+
+Synchronisation is now working reasonably well in the `sndio` back end. Further work is necessary, but it looks pretty solid and the workarounds are no longer needed.
+
Version 3.1d6
====
**New Feature**
From 0744691051dc26351a1829b14f6c06881eee0bc2 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Mon, 17 Apr 2017 19:51:06 +0100
Subject: [PATCH 101/239] Update configure.ac
---
configure.ac | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index 4a5efa56..465141ff 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.50])
-AC_INIT([shairport-sync], [3.1d6], [mikebrady@eircom.net])
+AC_INIT([shairport-sync], [3.1d7], [mikebrady@eircom.net])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([shairport.c])
AC_CONFIG_HEADERS([config.h])
From 0a3efc4e72896ae51922600c570161500be6dbe4 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Wed, 19 Apr 2017 19:29:46 +0100
Subject: [PATCH 102/239] Update FREEBSD.md
---
FREEBSD.md | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/FREEBSD.md b/FREEBSD.md
index 67b6af14..16f210cf 100644
--- a/FREEBSD.md
+++ b/FREEBSD.md
@@ -2,7 +2,7 @@ Introduction
----
This is a very quick initial note about installing Shairport Sync on FreeBSD. Some manual installation is required.
-The build instructions here install back ends for `sndio` (native to OpenBSD) and ALSA. ALSA is, or course, the Advanced Linux Sound Architecture, so it is not "native" to FreeBSD. It has, however, been ported to some architectures (not to the ARM, unfortunately), so it should work pretty well on those.
+The build instructions here install back ends for `sndio` (native to OpenBSD) and ALSA. ALSA is, or course, the Advanced Linux Sound Architecture, so it is not "native" to FreeBSD, but has been ported to some architectures under FreeBSB.
General
----
@@ -22,13 +22,12 @@ Next, install the `pkg` package manager and update its lists:
Subsystems
----
-Now, install the ALSA and Avahi subsystems. Note: `avahi-app` is chosen because it doesn’t require X11 and `nss_mdns` allows FreeBSD
-to resolve mDNS-originated addresses. Thanks to [reidransom](https://gist.github.com/reidransom/6033227) for this:
+Now, install the Avahi subsystem. FYI, `avahi-app` is chosen because it doesn’t require X11 and `nss_mdns` is included to allow FreeBSD to resolve mDNS-originated addresses -- it's not needed by Shairport Sync. Thanks to [reidransom](https://gist.github.com/reidransom/6033227) for this.
```
-# pkg install alsa-utils avahi-app nss_mdns
+# pkg install avahi-app nss_mdns
```
-To enable these services to load automatically at startup, add these lines to `/etc/rc.conf`:
+Add these lines to `/etc/rc.conf`:
```
dbus_enable="YES"
avahi_daemon_enable="YES"
@@ -44,8 +43,9 @@ Building
Next, install the packages that are needed for Shairport Sync to be downloaded and build successfully:
```
-# pkg install git autotools pkgconf popt libconfig openssl sndio
+# pkg install git autotools pkgconf popt libconfig openssl sndio alsa-utils
```
+Omit `alsa-utils` if you're not using ALSA. Likewsie, omit `sndio` if you don't intend to use the `sndio` subsystem.
Now, download Shairport Sync from GitHub and check out the `development` branch.
```
@@ -57,9 +57,10 @@ Next, configure the build and compile it:
```
$ autoreconf -i -f
-$ CPPFLAGS="-I/usr/local/include" ./configure --with-alsa --with-avahi --with-sndio --with-ssl=openssl --with-metadata
+$ CPPFLAGS="-I/usr/local/include" ./configure --with-avahi --with-ssl=openssl --with-alsa --with-sndio
$ make
```
+Omit `--with-alsa` if you don;t want ot include the ALSA back end and omit the `--with-sndio` if you don't want the `sndio` back end.
Manual Installation
----
@@ -74,9 +75,8 @@ The `sndio` back end does synchronisation and is still under development. Right
Setting Overall Volume
----
-Note, the `mixer` command is useful for setting the output device's overall volume settings. With the default settings for the `sndio` back end, the `pcm` mixer controls its maximum output:
+Note, the `mixer` command can be used for setting the output device's volume settings. You may hae to experiment to figure out which settings are appropriate.
```
$ mixer vol 100 # sets overall volume
-$ mixer pcm 100 # sets maximum volume level for the default sndio device used by Shairport Sync
```
From 160043cd96fb030212befdaa65ccf3f9ab536a2b Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Wed, 19 Apr 2017 19:31:32 +0100
Subject: [PATCH 103/239] Update FREEBSD.md
---
FREEBSD.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/FREEBSD.md b/FREEBSD.md
index 16f210cf..dab9168d 100644
--- a/FREEBSD.md
+++ b/FREEBSD.md
@@ -60,7 +60,7 @@ $ autoreconf -i -f
$ CPPFLAGS="-I/usr/local/include" ./configure --with-avahi --with-ssl=openssl --with-alsa --with-sndio
$ make
```
-Omit `--with-alsa` if you don;t want ot include the ALSA back end and omit the `--with-sndio` if you don't want the `sndio` back end.
+Omit `--with-alsa` if you don't want to include the ALSA back end. Omit the `--with-sndio` if you don't want the `sndio` back end.
Manual Installation
----
From b77241c1fa1e660130608dd994612cc91b57db82 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Wed, 19 Apr 2017 19:32:26 +0100
Subject: [PATCH 104/239] Update FREEBSD.md
---
FREEBSD.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/FREEBSD.md b/FREEBSD.md
index dab9168d..3805bf7a 100644
--- a/FREEBSD.md
+++ b/FREEBSD.md
@@ -22,7 +22,7 @@ Next, install the `pkg` package manager and update its lists:
Subsystems
----
-Now, install the Avahi subsystem. FYI, `avahi-app` is chosen because it doesn’t require X11 and `nss_mdns` is included to allow FreeBSD to resolve mDNS-originated addresses -- it's not needed by Shairport Sync. Thanks to [reidransom](https://gist.github.com/reidransom/6033227) for this.
+Install the Avahi subsystem. FYI, `avahi-app` is chosen because it doesn’t require X11. `nss_mdns` is included to allow FreeBSD to resolve mDNS-originated addresses – it's not actually needed by Shairport Sync. Thanks to [reidransom](https://gist.github.com/reidransom/6033227) for this.
```
# pkg install avahi-app nss_mdns
From 7a6c6d3f0453af404a92afd59a8d61f3aa0b392a Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Wed, 19 Apr 2017 19:33:48 +0100
Subject: [PATCH 105/239] Update FREEBSD.md
---
FREEBSD.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/FREEBSD.md b/FREEBSD.md
index 3805bf7a..b2a06720 100644
--- a/FREEBSD.md
+++ b/FREEBSD.md
@@ -75,8 +75,9 @@ The `sndio` back end does synchronisation and is still under development. Right
Setting Overall Volume
----
-Note, the `mixer` command can be used for setting the output device's volume settings. You may hae to experiment to figure out which settings are appropriate.
+The `mixer` command can be used for setting the output device's volume settings. You may hae to experiment to figure out which settings are appropriate.
```
$ mixer vol 100 # sets overall volume
```
+If you've installed `alsa-utils`, then `alsamixer` and friends will also be available.
From bb8597e37c06f8c4543b86ef49d5edaa2cfd7674 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Wed, 19 Apr 2017 19:36:22 +0100
Subject: [PATCH 106/239] Update FREEBSD.md
---
FREEBSD.md | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/FREEBSD.md b/FREEBSD.md
index b2a06720..a5a6dab7 100644
--- a/FREEBSD.md
+++ b/FREEBSD.md
@@ -1,8 +1,10 @@
-Introduction
+Shairport Sync on FreeBSD
----
+Shairport Sync now runs "natively" on FreeBSD using the \*BSD-specific `sndio` back end.
+
This is a very quick initial note about installing Shairport Sync on FreeBSD. Some manual installation is required.
-The build instructions here install back ends for `sndio` (native to OpenBSD) and ALSA. ALSA is, or course, the Advanced Linux Sound Architecture, so it is not "native" to FreeBSD, but has been ported to some architectures under FreeBSB.
+The build instructions here install back ends for `sndio` (originally developed got OpenBSD) and ALSA. ALSA is, or course, the Advanced Linux Sound Architecture, so it is not "native" to FreeBSD, but has been ported to some architectures under FreeBSD.
General
----
From 1f5d81c22d06d7f2ac1e6025a5271b4519172ecd Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Wed, 19 Apr 2017 19:37:10 +0100
Subject: [PATCH 107/239] Update FREEBSD.md
---
FREEBSD.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/FREEBSD.md b/FREEBSD.md
index a5a6dab7..2f906b00 100644
--- a/FREEBSD.md
+++ b/FREEBSD.md
@@ -43,7 +43,7 @@ Reboot for these changes to take effect.
Building
----
-Next, install the packages that are needed for Shairport Sync to be downloaded and build successfully:
+Install the packages that are needed for Shairport Sync to be downloaded and build successfully:
```
# pkg install git autotools pkgconf popt libconfig openssl sndio alsa-utils
```
From f90fb9b2edd1a482c8765524d08d13d72a385219 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Wed, 19 Apr 2017 19:37:32 +0100
Subject: [PATCH 108/239] Update FREEBSD.md
---
FREEBSD.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/FREEBSD.md b/FREEBSD.md
index 2f906b00..c21d1588 100644
--- a/FREEBSD.md
+++ b/FREEBSD.md
@@ -4,7 +4,7 @@ Shairport Sync now runs "natively" on FreeBSD using the \*BSD-specific `sndio` b
This is a very quick initial note about installing Shairport Sync on FreeBSD. Some manual installation is required.
-The build instructions here install back ends for `sndio` (originally developed got OpenBSD) and ALSA. ALSA is, or course, the Advanced Linux Sound Architecture, so it is not "native" to FreeBSD, but has been ported to some architectures under FreeBSD.
+The build instructions here install back ends for `sndio` (originally developed for OpenBSD) and ALSA. ALSA is, or course, the Advanced Linux Sound Architecture, so it is not "native" to FreeBSD, but has been ported to some architectures under FreeBSD.
General
----
From 0df8bf31055bbdb6fbd1806ae0c41c696358bef7 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sat, 22 Apr 2017 15:00:22 +0100
Subject: [PATCH 109/239] Add FreeBSD service and installation. Change default
PID file directory. SystemV and SystemD scripts should be updated.
---
Makefile.am | 18 +++++++++++++++---
configure.ac | 8 ++++----
scripts/shairport-sync.freebsd | 26 ++++++++++++++++++++++++++
shairport.c | 21 ++++++++++++++-------
4 files changed, 59 insertions(+), 14 deletions(-)
create mode 100644 scripts/shairport-sync.freebsd
diff --git a/Makefile.am b/Makefile.am
index 3dfae1d3..91b64cd3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,7 +4,11 @@ bin_PROGRAMS = shairport-sync
shairport_sync_SOURCES = shairport.c rtsp.c mdns.c mdns_external.c common.c rtp.c player.c alac.c audio.c loudness.c
AM_CFLAGS = -Wno-multichar -DSYSCONFDIR=\"$(sysconfdir)\" -O2
-AM_CPPFLAGS = -Wno-multichar -DSYSCONFDIR=\"$(sysconfdir)\" -O2
+if BUILD_FOR_FREEBSD
+ AM_CPPFLAGS = -I/usr/local/include -Wno-multichar -DSYSCONFDIR=\"$(sysconfdir)\" -O2
+else
+ AM_CPPFLAGS = -Wno-multichar -DSYSCONFDIR=\"$(sysconfdir)\" -O2
+endif
if USE_APPLE_ALAC
shairport_sync_SOURCES += apple_alac.cpp
@@ -70,11 +74,19 @@ if INSTALL_CONFIG_FILES
cp scripts/shairport-sync.conf $(DESTDIR)$(sysconfdir)/shairport-sync.conf.sample
[ -f $(DESTDIR)$(sysconfdir)/shairport-sync.conf ] || cp scripts/shairport-sync.conf $(DESTDIR)$(sysconfdir)/shairport-sync.conf
endif
-if INSTALL_SYSTEMV
+if BUILD_FOR_SYSTEMV
[ -e $(DESTDIR)$(sysconfdir)/init.d ] || mkdir -p $(DESTDIR)$(sysconfdir)/init.d
[ -f $(DESTDIR)$(sysconfdir)/init.d/shairport-sync ] || cp scripts/shairport-sync $(DESTDIR)$(sysconfdir)/init.d/
endif
-if INSTALL_SYSTEMD
+if BUILD_FOR_SYSTEMD
[ -e $(DESTDIR)$(systemdsystemunitdir) ] || mkdir -p $(DESTDIR)$(systemdsystemunitdir)
[ -f $(DESTDIR)$(systemdsystemunitdir)/shairport-sync.service ] || cp scripts/shairport-sync.service $(DESTDIR)$(systemdsystemunitdir)
endif
+if BUILD_FOR_FREEBSD
+ pw showgroup shairport-sync > /dev/null 2>&1 || pw addgroup shairport-sync > /dev/null 2>&1
+ pw showuser shairport-sync > /dev/null 2>&1 || pw adduser shairport-sync > /dev/null 2>&1
+ [ -e /var/run/shairport-sync ] || mkdir -p /var/run/shairport-sync
+ chown shairport-sync:shairport-sync /var/run/shairport-sync
+ [ -f /usr/local/etc/rc.d/shairport-sync ] || cp scripts/shairport-sync.freebsd /usr/local/etc/rc.d/shairport-sync
+ chmod 555 /usr/local/etc/rc.d/shairport-sync
+endif
diff --git a/configure.ac b/configure.ac
index 465141ff..d35eb2fb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -8,8 +8,6 @@ AC_CONFIG_SRCDIR([shairport.c])
AC_CONFIG_HEADERS([config.h])
# Derived from the Avahi configure.ac file
-#
-#
# Specifying the OS type, defaulting to linux.
#
AC_ARG_WITH(os_type, AS_HELP_STRING([--with-os-type=OSType],[Specify the distribution to target: One of linux freebsd or darwin]))
@@ -30,6 +28,8 @@ if test "x${with_os_type}" = xlinux -o "x${with_os_type}" = xfreebsd ; then
AC_CHECK_LIB([rt],[clock_gettime], , AC_MSG_ERROR(librt needed))
fi
+AM_CONDITIONAL([BUILD_FOR_FREEBSD], [test "x${with_os_type}" = xfreebsd ])
+
##### Some build systems are not fully using pkg-config, so we can use the flag ${with_pkg_config} on a case-by-case basis
##### to control how to deal with them
@@ -73,13 +73,13 @@ AM_CONDITIONAL([USE_PIPE], [test "x$with_pipe" = "xyes" ])
AC_ARG_WITH([systemv],
[ --with-systemv = install a System V startup script during a make install], , )
-AM_CONDITIONAL([INSTALL_SYSTEMV], [test "x$with_systemv" = "xyes"])
+AM_CONDITIONAL([BUILD_FOR_SYSTEMV], [test "x$with_systemv" = "xyes"])
# Check to see if we should include the systemd stuff to define it as a service
AC_ARG_WITH([systemd],
[ --with-systemd = install a systemd service description file during a make install], , )
-AM_CONDITIONAL([INSTALL_SYSTEMD], [test "x$with_systemd" = "xyes"])
+AM_CONDITIONAL([BUILD_FOR_SYSTEMD], [test "x$with_systemd" = "xyes"])
# Add the libconfig package
if test "x${with_pkg_config}" = xyes ; then
diff --git a/scripts/shairport-sync.freebsd b/scripts/shairport-sync.freebsd
new file mode 100644
index 00000000..779a1eb2
--- /dev/null
+++ b/scripts/shairport-sync.freebsd
@@ -0,0 +1,26 @@
+#!/bin/sh
+#
+# $FreeBSD: releng/11.0/etc/rc.d/motd 298514 2016-04-23 16:10:54Z lme $
+#
+
+# PROVIDE: shairport-sync
+# REQUIRE: FILESYSTEMS DAEMON hostname
+
+. /etc/rc.subr
+
+name="shairport-sync"
+start_cmd="${name}_start"
+stop_cmd="${name}_stop"
+
+shairport-sync_start()
+{
+ su -m shairport-sync -c "/usr/local/bin/shairport-sync -d"
+}
+
+shairport-sync_stop()
+{
+ su -m shairport-sync -c "/usr/local/bin/shairport-sync -k"
+}
+
+load_rc_config $name
+run_rc_command "$1"
diff --git a/shairport.c b/shairport.c
index 3e34d60c..3dfdb7f1 100644
--- a/shairport.c
+++ b/shairport.c
@@ -873,9 +873,9 @@ void shairport_startup_complete(void) {
}
}
-#ifdef USE_CUSTOM_PID_DIR
const char *pid_file_proc(void) {
+#ifdef USE_CUSTOM_PID_DIR
#ifdef HAVE_ASPRINTF
static char *fn = NULL;
asprintf(&fn, "%s/%s.pid", PIDDIR, daemon_pid_file_ident ? daemon_pid_file_ident : "unknown");
@@ -884,10 +884,18 @@ const char *pid_file_proc(void) {
snprintf(fn, sizeof(fn), "%s/%s.pid", PIDDIR,
daemon_pid_file_ident ? daemon_pid_file_ident : "unknown");
#endif
-
+#else
+#ifdef HAVE_ASPRINTF
+ static char *fn = NULL;
+ asprintf(&fn, "/var/run/shairport-sync/%s.pid", daemon_pid_file_ident ? daemon_pid_file_ident : "unknown");
+#else
+ static char fn[8192];
+ snprintf(fn, sizeof(fn), "/var/run/shairport-sync/%s.pid",
+ daemon_pid_file_ident ? daemon_pid_file_ident : "unknown");
+#endif
+#endif
return fn;
}
-#endif
void exit_function() {
if (config.cfg)
@@ -1005,11 +1013,10 @@ int main(int argc, char **argv) {
return 1;
}
-#if USE_CUSTOM_PID_DIR
- debug(1, "Locating custom pid dir at \"%s\"", PIDDIR);
- /* Point to a function to help locate where the PID file will go */
+ // Point to a function to help locate where the PID file will go
+ // We always use this function because the default location
+ // is unsatisfactory. By default we want to use /var/run/shairport-sync/.
daemon_pid_file_proc = pid_file_proc;
-#endif
/* Set indentification string for the daemon for both syslog and PID file */
daemon_pid_file_ident = daemon_log_ident = daemon_ident_from_argv0(argv[0]);
From f6eca4ca6eef53b67057b06300fd45662f7ffd12 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sat, 22 Apr 2017 18:09:56 +0100
Subject: [PATCH 110/239] Improve startup script and make it optional
---
Makefile.am | 10 +++++-----
configure.ac | 22 +++++++++++++---------
scripts/shairport-sync.freebsd | 20 +++++++++++---------
3 files changed, 29 insertions(+), 23 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 91b64cd3..908b34cc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -74,19 +74,19 @@ if INSTALL_CONFIG_FILES
cp scripts/shairport-sync.conf $(DESTDIR)$(sysconfdir)/shairport-sync.conf.sample
[ -f $(DESTDIR)$(sysconfdir)/shairport-sync.conf ] || cp scripts/shairport-sync.conf $(DESTDIR)$(sysconfdir)/shairport-sync.conf
endif
-if BUILD_FOR_SYSTEMV
+if INSTALL_SYSTEMV
[ -e $(DESTDIR)$(sysconfdir)/init.d ] || mkdir -p $(DESTDIR)$(sysconfdir)/init.d
[ -f $(DESTDIR)$(sysconfdir)/init.d/shairport-sync ] || cp scripts/shairport-sync $(DESTDIR)$(sysconfdir)/init.d/
endif
-if BUILD_FOR_SYSTEMD
+if INSTALL_SYSTEMD
[ -e $(DESTDIR)$(systemdsystemunitdir) ] || mkdir -p $(DESTDIR)$(systemdsystemunitdir)
[ -f $(DESTDIR)$(systemdsystemunitdir)/shairport-sync.service ] || cp scripts/shairport-sync.service $(DESTDIR)$(systemdsystemunitdir)
endif
-if BUILD_FOR_FREEBSD
+if INSTALL_FREEBSD_SERVICE
pw showgroup shairport-sync > /dev/null 2>&1 || pw addgroup shairport-sync > /dev/null 2>&1
pw showuser shairport-sync > /dev/null 2>&1 || pw adduser shairport-sync > /dev/null 2>&1
[ -e /var/run/shairport-sync ] || mkdir -p /var/run/shairport-sync
chown shairport-sync:shairport-sync /var/run/shairport-sync
- [ -f /usr/local/etc/rc.d/shairport-sync ] || cp scripts/shairport-sync.freebsd /usr/local/etc/rc.d/shairport-sync
- chmod 555 /usr/local/etc/rc.d/shairport-sync
+ [ -f /usr/local/etc/rc.d/shairport_sync ] || cp scripts/shairport-sync.freebsd /usr/local/etc/rc.d/shairport_sync
+ chmod 555 /usr/local/etc/rc.d/shairport_sync
endif
diff --git a/configure.ac b/configure.ac
index d35eb2fb..93b0f4aa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -10,11 +10,11 @@ AC_CONFIG_HEADERS([config.h])
# Derived from the Avahi configure.ac file
# Specifying the OS type, defaulting to linux.
#
-AC_ARG_WITH(os_type, AS_HELP_STRING([--with-os-type=OSType],[Specify the distribution to target: One of linux freebsd or darwin]))
-if test "z$with_os_type" = "z"; then
- with_os_type="linux"
+AC_ARG_WITH(os, AS_HELP_STRING([--with-os=OSType],[Specify the distribution to target: One of linux freebsd or darwin]))
+if test "z$with_os" = "z"; then
+ with_os="linux"
fi
-with_os_type=`echo ${with_os_type} | tr '[[:upper:]]' '[[:lower:]]' `
+with_os=`echo ${with_os} | tr '[[:upper:]]' '[[:lower:]]' `
# Checks for programs.
AC_PROG_CC
@@ -24,11 +24,11 @@ AC_PROG_INSTALL
PKG_PROG_PKG_CONFIG([0.9.0])
# Checks for libraries.
-if test "x${with_os_type}" = xlinux -o "x${with_os_type}" = xfreebsd ; then
+if test "x${with_os}" = xlinux -o "x${with_os}" = xfreebsd ; then
AC_CHECK_LIB([rt],[clock_gettime], , AC_MSG_ERROR(librt needed))
fi
-AM_CONDITIONAL([BUILD_FOR_FREEBSD], [test "x${with_os_type}" = xfreebsd ])
+AM_CONDITIONAL([BUILD_FOR_FREEBSD], [test "x${with_os}" = xfreebsd ])
##### Some build systems are not fully using pkg-config, so we can use the flag ${with_pkg_config} on a case-by-case basis
##### to control how to deal with them
@@ -73,13 +73,17 @@ AM_CONDITIONAL([USE_PIPE], [test "x$with_pipe" = "xyes" ])
AC_ARG_WITH([systemv],
[ --with-systemv = install a System V startup script during a make install], , )
-AM_CONDITIONAL([BUILD_FOR_SYSTEMV], [test "x$with_systemv" = "xyes"])
+AM_CONDITIONAL([INSTALL_SYSTEMV], [test "x$with_systemv" = "xyes"])
# Check to see if we should include the systemd stuff to define it as a service
AC_ARG_WITH([systemd],
-[ --with-systemd = install a systemd service description file during a make install], , )
-AM_CONDITIONAL([BUILD_FOR_SYSTEMD], [test "x$with_systemd" = "xyes"])
+[ --with-systemd = install a systemd startup script during a make install], , )
+AM_CONDITIONAL([INSTALL_SYSTEMD], [test "x$with_systemd" = "xyes"])
+
+AC_ARG_WITH([freebsd-service],
+[ --with-freebsd-service = install a FreeBSD startup script during a make install], , )
+AM_CONDITIONAL([INSTALL_FREEBSD_SERVICE], [test "x$with_freebsd_service" = "xyes"])
# Add the libconfig package
if test "x${with_pkg_config}" = xyes ; then
diff --git a/scripts/shairport-sync.freebsd b/scripts/shairport-sync.freebsd
index 779a1eb2..9088bd82 100644
--- a/scripts/shairport-sync.freebsd
+++ b/scripts/shairport-sync.freebsd
@@ -1,25 +1,27 @@
#!/bin/sh
#
-# $FreeBSD: releng/11.0/etc/rc.d/motd 298514 2016-04-23 16:10:54Z lme $
-#
-# PROVIDE: shairport-sync
-# REQUIRE: FILESYSTEMS DAEMON hostname
+# PROVIDE: shairport_sync
+# REQUIRE: FILESYSTEMS DAEMON hostname avahi_daemon
. /etc/rc.subr
-name="shairport-sync"
+name="shairport_sync"
+rcvar="shairport_sync_enable"
+
start_cmd="${name}_start"
stop_cmd="${name}_stop"
-shairport-sync_start()
+shairport_sync_start()
{
- su -m shairport-sync -c "/usr/local/bin/shairport-sync -d"
+ checkyesno shairport_sync_enable && echo "Starting shairport-sync." && \
+ su -m shairport-sync -c "/usr/local/bin/shairport-sync -d"
}
-shairport-sync_stop()
+shairport_sync_stop()
{
- su -m shairport-sync -c "/usr/local/bin/shairport-sync -k"
+ checkyesno shairport_sync_enable && echo "Stopping shairport-sync." && \
+ /usr/local/bin/shairport-sync -k
}
load_rc_config $name
From 15c376ad57629dad16f1120dbf4c080f7de48475 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sat, 22 Apr 2017 18:51:28 +0100
Subject: [PATCH 111/239] Update System V and System D installers to define
user, group and runtime directory as necessary
---
Makefile.am | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/Makefile.am b/Makefile.am
index 908b34cc..1727ba85 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -75,10 +75,16 @@ if INSTALL_CONFIG_FILES
[ -f $(DESTDIR)$(sysconfdir)/shairport-sync.conf ] || cp scripts/shairport-sync.conf $(DESTDIR)$(sysconfdir)/shairport-sync.conf
endif
if INSTALL_SYSTEMV
+ getent group shairport-sync &>/dev/null || groupadd -r shairport-sync >/dev/null
+ getent passwd shairport-sync &> /dev/null || useradd -r -M -g shairport-sync -s /usr/bin/nologin -G audio shairport-sync >/dev/null
+ [ -e /var/run/shairport-sync ] || mkdir -p /var/run/shairport-sync
+ chown shairport-sync:shairport-sync /var/run/shairport-sync
[ -e $(DESTDIR)$(sysconfdir)/init.d ] || mkdir -p $(DESTDIR)$(sysconfdir)/init.d
[ -f $(DESTDIR)$(sysconfdir)/init.d/shairport-sync ] || cp scripts/shairport-sync $(DESTDIR)$(sysconfdir)/init.d/
endif
if INSTALL_SYSTEMD
+ getent group shairport-sync &>/dev/null || groupadd -r shairport-sync >/dev/null
+ getent passwd shairport-sync &> /dev/null || useradd -r -M -g shairport-sync -s /usr/bin/nologin -G audio shairport-sync >/dev/null
[ -e $(DESTDIR)$(systemdsystemunitdir) ] || mkdir -p $(DESTDIR)$(systemdsystemunitdir)
[ -f $(DESTDIR)$(systemdsystemunitdir)/shairport-sync.service ] || cp scripts/shairport-sync.service $(DESTDIR)$(systemdsystemunitdir)
endif
From 1ec5c64a59894146d18eee21fa94045d14b2221f Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sat, 22 Apr 2017 19:08:10 +0100
Subject: [PATCH 112/239] Update RELEASENOTES.md
---
RELEASENOTES.md | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 581722cc..80a702da 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -1,3 +1,18 @@
+Version 3.1d8
+====
+**Pesky Changes You Can't Ignore**
+
+If you are using a System V (aka `systemv`) installation, please note that the default location for PID file has moved -- it is now stored at `/var/run/shairport-sync/shairport-sync.pid`. This change is needed to improve security a little and to improve compatability across platforms. If you're not doing anythoing strange, this should make no difference.
+
+**New Features**
+* A FreeBSD installer and startup script is now available. Use the `./configure` option `--with-os=freebsd` to get the right compilation flags, and used the `./configure` option `--with-freebsd-installer` to have a startup script installed and to have a user, group and runtime directory created.
+* The standard linux System V and `systemd` installers have been enhanced to create the user and
+group `shairport-sync` if necessary.
+* The standard linux System V installer creates a special runtime directory at `/var/run/shairport-sync` owned by the user `shairport-sync` and used to store its PID file.
+
+**Improvements**
+* The FreeBSD installation based on the `sndio` back end works well.
+
Version 3.1d7
====
**Improvements**
From f3b556841b88200616dcf9651a6b857ffbef4147 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sat, 22 Apr 2017 19:24:22 +0100
Subject: [PATCH 113/239] Update FREEBSD.md
---
FREEBSD.md | 27 ++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/FREEBSD.md b/FREEBSD.md
index c21d1588..43b96dd1 100644
--- a/FREEBSD.md
+++ b/FREEBSD.md
@@ -2,7 +2,7 @@ Shairport Sync on FreeBSD
----
Shairport Sync now runs "natively" on FreeBSD using the \*BSD-specific `sndio` back end.
-This is a very quick initial note about installing Shairport Sync on FreeBSD. Some manual installation is required.
+This is an initial note about installing Shairport Sync on FreeBSD.
The build instructions here install back ends for `sndio` (originally developed for OpenBSD) and ALSA. ALSA is, or course, the Advanced Linux Sound Architecture, so it is not "native" to FreeBSD, but has been ported to some architectures under FreeBSD.
@@ -59,21 +59,34 @@ Next, configure the build and compile it:
```
$ autoreconf -i -f
-$ CPPFLAGS="-I/usr/local/include" ./configure --with-avahi --with-ssl=openssl --with-alsa --with-sndio
+./configure --with-avahi --with-ssl=openssl --with-alsa --with-sndio --with-os=freebsd --with-freebsd-service
$ make
```
-Omit `--with-alsa` if you don't want to include the ALSA back end. Omit the `--with-sndio` if you don't want the `sndio` back end.
+Omit `--with-alsa` if you don't want to include the ALSA back end. Omit the `--with-sndio` if you don't want the `sndio` back end. Omit the `--with-freebsd-service` if you don't want to install a FreeBSD startup script, runtime folder and user and group -- see below for more details.
-Manual Installation
+Installation
----
-After this, you're on your own – the `$ sudo make install` step does not work for FreeBSD. Maybe some day...
-To continue, you should create a configuration file at `/usr/local/etc/shairport-sync.conf`. Please see the sample configuration file for more details.
+Enter the superuser mode and do a make install.
+
+```
+$ su
+# make install
+```
+
+This will install the `shairport-sync` program along with a sample configuration file at `/usr/local/etc/shairport-sync.conf` and a service startup script to run Shairport Sync as a daemon. In addition, it will define a `shairport-sync` user and group and will create a folder at `/var/run/shairport-sync` to be owned by the user `shairport-sync`. This will be used to hold the daemon's PID file.
+
+Finally, edit `/usr/local/etc/shairport-sync.conf` to customise your installation, e.g. service name, etc. To make the `shairport-sync` daemon load at startup, add the following line to `/etc/rc.conf`:
+
+```
+shairport_sync_enable="YES"
+```
+You can launch the service as superuser, or simply reboot the machine.
Using the `sndio` backend
----
-The `sndio` back end does synchronisation and is still under development. Right now, it seems to work very well. It does not have a mixer control facility, however. You should set the volume to maximum before use, using, for example, the `mixer` command described below.
+The `sndio` back end does not have a hardware volume control facility. You should set the volume to maximum before use, using, for example, the `mixer` command described below.
Setting Overall Volume
----
From a0a44655ca24fe47417d8a07d4127ef3764ee947 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sat, 22 Apr 2017 19:28:16 +0100
Subject: [PATCH 114/239] Update FREEBSD.md
---
FREEBSD.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/FREEBSD.md b/FREEBSD.md
index 43b96dd1..4c741ff8 100644
--- a/FREEBSD.md
+++ b/FREEBSD.md
@@ -43,11 +43,11 @@ Reboot for these changes to take effect.
Building
----
-Install the packages that are needed for Shairport Sync to be downloaded and build successfully:
+Install the packages that are needed for Shairport Sync to be downloaded and built successfully:
```
# pkg install git autotools pkgconf popt libconfig openssl sndio alsa-utils
```
-Omit `alsa-utils` if you're not using ALSA. Likewsie, omit `sndio` if you don't intend to use the `sndio` subsystem.
+Omit `alsa-utils` if you're not using ALSA. Likewise, omit `sndio` if you don't intend to use the `sndio` subsystem.
Now, download Shairport Sync from GitHub and check out the `development` branch.
```
@@ -74,7 +74,7 @@ $ su
# make install
```
-This will install the `shairport-sync` program along with a sample configuration file at `/usr/local/etc/shairport-sync.conf` and a service startup script to run Shairport Sync as a daemon. In addition, it will define a `shairport-sync` user and group and will create a folder at `/var/run/shairport-sync` to be owned by the user `shairport-sync`. This will be used to hold the daemon's PID file.
+With the `./configure` options shown above, this will install the `shairport-sync` program along with a sample configuration file at `/usr/local/etc/shairport-sync.conf`. A service startup script will also be installed to launch Shairport Sync as a daemon. In addition, a `shairport-sync` user and group will be added and a directory will be created at `/var/run/shairport-sync` owned by the user `shairport-sync`. This will be used to hold the daemon's PID file.
Finally, edit `/usr/local/etc/shairport-sync.conf` to customise your installation, e.g. service name, etc. To make the `shairport-sync` daemon load at startup, add the following line to `/etc/rc.conf`:
From b8dffa4e9b38ad71436b8f4df4be8d301bf93088 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sat, 22 Apr 2017 19:55:56 +0100
Subject: [PATCH 115/239] Update FREEBSD.md
---
FREEBSD.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/FREEBSD.md b/FREEBSD.md
index 4c741ff8..459fc34e 100644
--- a/FREEBSD.md
+++ b/FREEBSD.md
@@ -90,7 +90,7 @@ The `sndio` back end does not have a hardware volume control facility. You shoul
Setting Overall Volume
----
-The `mixer` command can be used for setting the output device's volume settings. You may hae to experiment to figure out which settings are appropriate.
+The `mixer` command can be used for setting the output device's volume settings. You may have to experiment to figure out which settings are appropriate.
```
$ mixer vol 100 # sets overall volume
From 32bf3d7985c5e8702259e957ff4df8195c9ca541 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 23 Apr 2017 09:04:39 +0100
Subject: [PATCH 116/239] Update FREEBSD.md
---
FREEBSD.md | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/FREEBSD.md b/FREEBSD.md
index 459fc34e..3d29e082 100644
--- a/FREEBSD.md
+++ b/FREEBSD.md
@@ -1,10 +1,10 @@
Shairport Sync on FreeBSD
----
-Shairport Sync now runs "natively" on FreeBSD using the \*BSD-specific `sndio` back end.
+Shairport Sync runs natively on FreeBSD using the [`sndio`](http://www.sndio.org) back end, thanks to the work of Tobias Kortkamp [t6](https://github.com/t6).
This is an initial note about installing Shairport Sync on FreeBSD.
-The build instructions here install back ends for `sndio` (originally developed for OpenBSD) and ALSA. ALSA is, or course, the Advanced Linux Sound Architecture, so it is not "native" to FreeBSD, but has been ported to some architectures under FreeBSD.
+The build instructions here install back ends both for `sndio` (originally developed for OpenBSD) and ALSA. ALSA is, or course, the Advanced Linux Sound Architecture, so it is not "native" to FreeBSD, but has been ported to some architectures under FreeBSD. Intriguingly, `sndio` has also been ported to Linux.
General
----
@@ -67,7 +67,7 @@ Omit `--with-alsa` if you don't want to include the ALSA back end. Omit the `--w
Installation
----
-Enter the superuser mode and do a make install.
+Enter the superuser mode and do a `make install`:
```
$ su
@@ -86,7 +86,7 @@ You can launch the service as superuser, or simply reboot the machine.
Using the `sndio` backend
----
-The `sndio` back end does not have a hardware volume control facility. You should set the volume to maximum before use, using, for example, the `mixer` command described below.
+The `sndio` back end does not yet have a hardware volume control facility. You should set the volume to maximum before use, using, for example, the `mixer` command described below.
Setting Overall Volume
----
From 9e3d6a1fb48f21e163cfae4bcc3bde63d023fe11 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 23 Apr 2017 09:27:34 +0100
Subject: [PATCH 117/239] Update FREEBSD.md
---
FREEBSD.md | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/FREEBSD.md b/FREEBSD.md
index 3d29e082..74f4ea14 100644
--- a/FREEBSD.md
+++ b/FREEBSD.md
@@ -1,10 +1,12 @@
-Shairport Sync on FreeBSD
+Shairport Sync on FreeBSD using `sndio`
----
-Shairport Sync runs natively on FreeBSD using the [`sndio`](http://www.sndio.org) back end, thanks to the work of Tobias Kortkamp [t6](https://github.com/t6).
+Shairport Sync runs natively on FreeBSD using the `sndio` back end, thanks to the work of [Tobias Kortkamp (t6)](https://github.com/t6).
+
+[`sndio`](http://www.sndio.org) is *"a small audio and MIDI framework part of the OpenBSD project and ported to FreeBSD, Linux and NetBSD"* developed by Alexandre Ratchov (see also [this paper](http://www.openbsd.org/papers/asiabsdcon2010_sndio.pdf) for more details).
This is an initial note about installing Shairport Sync on FreeBSD.
-The build instructions here install back ends both for `sndio` (originally developed for OpenBSD) and ALSA. ALSA is, or course, the Advanced Linux Sound Architecture, so it is not "native" to FreeBSD, but has been ported to some architectures under FreeBSD. Intriguingly, `sndio` has also been ported to Linux.
+The build instructions here install back ends both for `sndio` and ALSA. ALSA is, or course, the Advanced Linux Sound Architecture, so it is not "native" to FreeBSD, but has been ported to some architectures under FreeBSD.
General
----
From e37c277b0a754a5a8f61ec70536008198e38c127 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 23 Apr 2017 12:37:11 +0100
Subject: [PATCH 118/239] Add a "run_this_when_volume_is_set" facility to call
a program when the volume is set. The AirPlay volume is passed.
---
common.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
common.h | 3 ++-
player.c | 2 ++
shairport.c | 4 ++++
4 files changed, 56 insertions(+), 1 deletion(-)
diff --git a/common.c b/common.c
index 5c10c918..c13f1857 100644
--- a/common.c
+++ b/common.c
@@ -32,6 +32,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -454,6 +455,53 @@ uint8_t *rsa_apply(uint8_t *input, int inlen, int *outlen, int mode) {
}
#endif
+void command_set_volume(double volume) {
+ if (config.cmd_set_volume) {
+ /*Spawn a child to run the program.*/
+ pid_t pid = fork();
+ if (pid == 0) { /* child process */
+ size_t command_buffer_size = strlen(config.cmd_set_volume)+32;
+ char* command_buffer = (char*)malloc(command_buffer_size);
+ if (command_buffer==NULL) {
+ inform("Couldn't allocate memory for set_volume argument string");
+ } else {
+ memset(command_buffer,0,command_buffer_size);
+ sprintf(command_buffer, "%s%f", config.cmd_set_volume,volume);
+ // debug(1,"command_buffer is \"%s\".",command_buffer);
+ int argC;
+ char **argV;
+ // debug(1,"set_volume command found.");
+ if (poptParseArgvString(command_buffer, &argC, (const char ***)&argV) !=
+ 0) {
+ // note that argV should be free()'d after use, but we expect this fork to exit
+ // eventually.
+ warn("Can't decipher on-set-volume command arguments \"%s\".",command_buffer);
+ free(argV);
+ free(command_buffer);
+ } else {
+ free(command_buffer);
+ // debug(1,"Executing on-set-volume command %s with %d arguments.",argV[0],argC);
+ execv(argV[0], argV);
+ warn("Execution of on-set-volume command \"%s\" failed to start", config.cmd_set_volume);
+ // debug(1, "Error executing on-set-volume command %s", config.cmd_set_volume);
+ exit(127); /* only if execv fails */
+ }
+ }
+
+ } else {
+ if (config.cmd_blocking) { /* pid!=0 means parent process and if blocking is true, wait for
+ process to finish */
+ pid_t rc = waitpid(pid, 0, 0); /* wait for child to exit */
+ if (rc != pid) {
+ warn("Execution of on-set-volume command returned an error.");
+ debug(1, "on-set-volume command %s finished with error %d", config.cmd_set_volume,errno);
+ }
+ }
+ // debug(1,"Continue after on-set-volume command");
+ }
+ }
+}
+
void command_start(void) {
if (config.cmd_start) {
/*Spawn a child to run the program.*/
diff --git a/common.h b/common.h
index 89f2901a..cb4b4b02 100644
--- a/common.h
+++ b/common.h
@@ -113,7 +113,7 @@ typedef struct {
int logOutputLevel; // log output level
int statistics_requested, use_negotiated_latencies;
enum playback_mode_type playback_mode;
- char *cmd_start, *cmd_stop;
+ char *cmd_start, *cmd_stop, *cmd_set_volume;
int cmd_blocking;
double tolerance; // allow this much drift before attempting to correct it
enum stuffing_type packet_stuffing;
@@ -203,6 +203,7 @@ config_t config_file_stuff;
void command_start(void);
void command_stop(void);
+void command_set_volume(double volume);
void shairport_shutdown();
// void shairport_startup_complete(void);
diff --git a/player.c b/player.c
index 5dbce717..459b2cc8 100644
--- a/player.c
+++ b/player.c
@@ -2109,6 +2109,8 @@ void player_volume(double airplay_volume, rtsp_conn_info* conn) {
// Thus, we ask our vol2attn function for an appropriate dB between -96.3 and 0 dB and translate
// it back to a number.
+ command_set_volume(airplay_volume);
+
int32_t hw_min_db, hw_max_db, hw_range_db, range_to_use, min_db,
max_db; // hw_range_db is a flag; if 0 means no mixer
diff --git a/shairport.c b/shairport.c
index 3dfdb7f1..356de378 100644
--- a/shairport.c
+++ b/shairport.c
@@ -499,6 +499,10 @@ int parse_options(int argc, char **argv) {
config.volume_max_db_set = 1;
}
+ if (config_lookup_string(config.cfg, "general.run_this_when_volume_is_set", &str)) {
+ config.cmd_set_volume = (char *)str;
+ }
+
/* Get the playback_mode setting */
if (config_lookup_string(config.cfg, "general.playback_mode", &str)) {
if (strcasecmp(str, "stereo") == 0)
From 47cf19620c7e96b36316744ce13c18eaac165b7d Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 23 Apr 2017 12:37:31 +0100
Subject: [PATCH 119/239] Add a "run_this_when_volume_is_set" facility to call
a program when the volume is set. The AirPlay volume is passed.
---
configure.ac | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index 93b0f4aa..acbea7cd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.50])
-AC_INIT([shairport-sync], [3.1d7], [mikebrady@eircom.net])
+AC_INIT([shairport-sync], [3.1d8], [mikebrady@eircom.net])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([shairport.c])
AC_CONFIG_HEADERS([config.h])
From c9f9b2efb389c1408a8cbd99325485fe427a482d Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 23 Apr 2017 12:54:44 +0100
Subject: [PATCH 120/239] Update RELEASENOTES.md
---
RELEASENOTES.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 80a702da..5daeb3ea 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -2,9 +2,10 @@ Version 3.1d8
====
**Pesky Changes You Can't Ignore**
-If you are using a System V (aka `systemv`) installation, please note that the default location for PID file has moved -- it is now stored at `/var/run/shairport-sync/shairport-sync.pid`. This change is needed to improve security a little and to improve compatability across platforms. If you're not doing anythoing strange, this should make no difference.
+If you are using a System V (aka `systemv`) installation, please note that the default location for PID file has moved -- it is now stored at `/var/run/shairport-sync/shairport-sync.pid`. This change is needed to improve security a little and to improve compatability across platforms. If you're not doing anything strange, this should make no difference.
**New Features**
+* A volume-changed program hook has been added – a program can now be run whenever the volume control is set or changed. Similar to the `run_this_before_play_begins` and `run_this_after_play_ends` program hooks, you can specify a command line in the `general` `run_this_when_volume_is_set` setting. The AirPlay volume is simply appended to the end of the command line – leave a space if you want it treated as an extra argument. AirPlay volume goes from 0 to -30 and -144 means "mute".
* A FreeBSD installer and startup script is now available. Use the `./configure` option `--with-os=freebsd` to get the right compilation flags, and used the `./configure` option `--with-freebsd-installer` to have a startup script installed and to have a user, group and runtime directory created.
* The standard linux System V and `systemd` installers have been enhanced to create the user and
group `shairport-sync` if necessary.
From 961b45a0ccfa81b8970965e1c59a867c04900ecf Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 23 Apr 2017 13:00:27 +0100
Subject: [PATCH 121/239] Update shairport-sync.conf
---
scripts/shairport-sync.conf | 3 +++
1 file changed, 3 insertions(+)
diff --git a/scripts/shairport-sync.conf b/scripts/shairport-sync.conf
index 57821361..bf3878e9 100644
--- a/scripts/shairport-sync.conf
+++ b/scripts/shairport-sync.conf
@@ -28,6 +28,9 @@ general =
// volume_max_db = 0.0 ; // use this advanced setting, which must have a decimal point in it, to set the maximum volume, in dB, you wish to use.
// The setting is for the hardware mixer, if chosen, or the software mixer otherwise. The value must be in the mixer's range (0.0 to -96.2 for the software mixer).
// Leave it commented out to use mixer's maximum volume.
+// run_this_when_volume_is_set = "/full/path/to/application/and/args"; // Run the specified application whenever the volume control is set or changed.
+// The desired AirPlay volume is appended to the end of the command line – leave a space if you want it treated as an extra argument.
+// AirPlay volume goes from 0 to -30 and -144 means "mute".
// regtype = "_raop._tcp"; // Use this advanced setting to set the service type and transport to be advertised by Zeroconf/Bonjour. Default is "_raop._tcp".
// playback_mode = "stereo"; // This can be "stereo", "mono", "reverse stereo", "both left" or "both right". Default is "stereo".
// alac_decoder = "hammerton"; // This can be "hammerton" or "apple". This advanced setting allows you to choose
From c2bcb1cf3fee7d9488c0a05cacbb937114656b5c Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 23 Apr 2017 13:24:25 +0100
Subject: [PATCH 122/239] Update README.md
---
README.md | 40 +++++++++++++---------------------------
1 file changed, 13 insertions(+), 27 deletions(-)
diff --git a/README.md b/README.md
index 0f64e499..6519b848 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@ Shairport Sync
Shairport Sync is an AirPlay audio player – it plays audio streamed from iTunes, iOS devices and other AirPlay sources such as Quicktime Player and ForkedDaapd, among others.
Audio played by a Shairport Sync-powered device stays synchronised with the source and hence with similar devices playing the same source. In this way, synchronised multi-room audio is possible without difficulty. (Hence the name Shairport Sync, BTW.)
-Shairport Sync does not support AirPlay video or photo streaming.
+Shairport Sync runs on Linux and FreeBSD. It does not support AirPlay video or photo streaming.
This is the unstable "development" branch. Changes and updates are incorporated into this branch quickly. To access the stable version, where changes are made after due time, please switch to the "master" branch.
@@ -20,7 +20,7 @@ To maintain the exact latency required, if an output device is running slow rela
Shairport Sync is a substantial rewrite of the fantastic work done in Shairport 1.0 by James Laird and others — please see https://github.com/abrasive/shairport/blob/master/README.md#contributors-to-version-1x for a list of the contributors to Shairport 1.x and Shairport 0.x. From a "heritage" point of view, Shairport Sync is a fork of Shairport 1.0.
-Shairport Sync is mainly designed for `alsa` and thus for Linux, although since `alsa` has been ported to FreeBSD, Shairport Sync runs in FreeBSD too. It must have direct access to the output device, which must be a real sound card capable of working with 44,100, 88,200 or 176,400 samples per second, interleaved PCM stereo of 8, 16, 24 or 32 bits. The default is 44,100 samples per second / 16 bits (you'll get a message in the logfile if there's a problem).
+Shairport Sync is designed for audio back ends that offer accurate timing and synchronisation information, including `alsa` on Linux and `sndio` on FreeBSD. It must have direct access to the output device, which must be a real sound card capable of working with 44,100, 88,200 or 176,400 samples per second, interleaved PCM stereo of 8, 16, 24 or 32 bits. The default is 44,100 samples per second / 16 bits (you'll get a message in the logfile if there's a problem).
For more about the motivation behind Shairport Sync, please see the wiki at https://github.com/mikebrady/shairport-sync/wiki.
@@ -44,11 +44,11 @@ Shairport Sync runs well on the Raspberry Pi on USB and I2S cards. It can drive
At the time of writing, OpenWrt trunk does not support USB audio well on the Raspberry Pi.
-Shairport Sync runs rather well on FreeBSD using either the ALSA or `sndio` sound systems.
+Shairport Sync runs natively on FreeBSD using the `sndio` sound system.
Shairport Sync runs on Ubuntu, OpenWrt, Debian, Arch Linux, Fedora and FreeBSD inside VMWare Fusion on a Mac, but synchronisation in inaccurate — possibly because the sound card is being emulated.
-Shairport Sync will output to `alsa` cards, to standard output and to pipes using appropriate backends. You can try compiling additional backends in as you wish, but it definitely will not work properly with them. Maybe someday...
+Shairport Sync will output to `alsa` and `sndio` cards, to standard output and to pipes using appropriate backends. You can try compiling additional backends in as you wish, but it definitely will not work properly with them. Maybe someday...
For information about changes and updates, please refer to the RELEASENOTES.md file in the distribution.
@@ -155,7 +155,7 @@ Here is an example, suitable for Linux installations that use `systemd`, such as
* Omit the `--with-soxr` if the libsoxr library is not available.
* For installation into a System V system, replace the `--with-systemd` with `--with-systemv`.
-**Build the application:**
+**Build and Install the Application:**
Enter:
@@ -163,36 +163,22 @@ Enter:
to build the application.
-**Install into to a `systemd` system**
-To complete the installation, you need to define a `shairport-sync` group and user. This is a security measure – the user and group are relatively unprivileged, and the user does not have login privileges. The user must be a member of the `audio` group to be able to access the audio hardware. The following commands define the group and user correctly if they do not already exist (note the use of `sudo` – omit this if you already have superuser privileges:
+Assuming you have used the `./configure` settings suggested above, you can now install the application:
```
-$getent group shairport-sync &>/dev/null || sudo groupadd -r shairport-sync >/dev/null
-$getent passwd shairport-sync &> /dev/null || sudo useradd -r -M -g shairport-sync -s /usr/bin/nologin -G audio shairport-sync >/dev/null
+$ sudo make install
```
+The user and group `shairport-sync` will be created if necessary, and a runtime folder will be created at `/var/run/shairport-sync` in SystemV installations. In addition, a `man` page, a default configuration file and automatic power-on startup script will be installed.
-Next, enter:
-```
-$sudo make install
-```
-
-to install `shairport-sync` along with a `man` page, a default configuration file and a `systemd` configuration file called `shairport-sync.service` to launch it automatically at system startup.
+**Complete installation into to a `systemd` system**
To enable Shairport Sync to start automatically at system startup, enter:
`$sudo systemctl enable shairport-sync`
-**Install into a System V system**
+**Complete installation into a System V system**
If you are installing onto a System V system, enter:
-
-```
-$sudo make install
-```
-
-to install `shairport-sync` along with a `man` page, a default configuration file and a System V startup script to launch it automatically at system startup.
-
-To complete the installation, enter:
```
$sudo update-rc.d shairport-sync defaults 90 10
```
@@ -211,7 +197,7 @@ Starting and stopping Shairport Sync automatically is taken care of differently
**(2) Settings:**
To get the best from Shairport Sync, you’ll need to (a) give Shairport Sync a service name by which it will be seen in iTunes etc., (b) specify the output device to use and (c) specify the name of the mixer volume control to use to control the output level. To get values for (b) and (c) you might need to explore the ALSA output devices with a program like `alsamixer` or similar.
-Shairport Sync reads settings from a configuration file at `/etc/shairport-sync.conf`. When you run `$sudo make install`, a sample configuration file is installed (or updated) at `/etc/shairport-sync.conf.sample`. This contains all the setting groups and all the settings available, but they all are commented out (comments begin with `//`) so that default values are used. The file contains explanations of the settings, useful hints and suggestions. In addition, if the file doesn't already exist, a default configuration is installed at `/etc/shairport-sync.conf`, which should work in almost any system with a sound card.
+Shairport Sync reads settings from a configuration file at `/etc/shairport-sync.conf` (note that in FreeBSD it will be at `/usr/local/etc/shairport-sync.conf`). When you run `$sudo make install`, a sample configuration file is installed or updated at `/etc/shairport-sync.conf.sample` (`/usr/local/etc/shairport-sync.conf.sample` in FreeBSD). This contains all the setting groups and all the settings available, but they all are commented out (comments begin with `//`) so that default values are used. The file contains explanations of the settings, useful hints and suggestions. In addition, if the file doesn't already exist, a default configuration is installed, which should work in almost any system with a sound card.
Settings in the configuration file are grouped. For instance, there is a `general` group within which you can use the `name` tag to set the service name. Suppose you wanted to set the name of the service to `Front Room`, give the service the password `secret` and used `libsoxr` interpolation, then you should do the following:
@@ -261,13 +247,13 @@ As previously mentioned, you can use command line arguments to provide settings
Apart from the following options, all command line options can be replaced by settings in the configuration file. Here is a brief description of command line options that are not replicated by settings in the settings file.
-* The `-c` option allows you to specify the location of the configuration file — default is `/etc/shairport-sync.conf`.
+* The `-c` option allows you to specify the location of the configuration file.
* The `-V` option gives you version information about Shairport Sync and then quits.
* The `-d` option causes Shairport Sync to properly daemonise itself, that is, to run in the background. You may need sudo privileges for this.
* The `-k` option causes Shairport Sync to kill an existing Shairport Sync daemon. You may need to have sudo privileges for this.
The System V init script at `/etc/init.d/shairport-sync` has a bare minimum :
-`-d`. Basically all it does is put the program in daemon mode. The program will read its settings from the configuration file, normally `/etc/shairport-sync.conf`.
+`-d`. Basically all it does is put the program in daemon mode. The program will read its settings from the configuration file.
Examples
--------
From 9b617bb7b28ca94ce14387d52a3a59b4cd704dd7 Mon Sep 17 00:00:00 2001
From: habbbe
Date: Wed, 26 Apr 2017 09:32:37 +0200
Subject: [PATCH 123/239] Fixed desired buffer length for Pulseaudio
---
audio_pulse.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/audio_pulse.c b/audio_pulse.c
index 282263cb..7d117980 100644
--- a/audio_pulse.c
+++ b/audio_pulse.c
@@ -60,7 +60,7 @@ static int init(int argc, char **argv) {
pulse_options.service_name = config.service_name;
- config.audio_backend_buffer_desired_length = 44100; // one second.
+ config.audio_backend_buffer_desired_length = 1; // one second.
config.audio_backend_latency_offset = 0;
optind = 1; // optind=0 is equivalent to optind=1 plus special behaviour
From 74bbb9a3f210f60c0d2bec1dcc232be84b45b3c4 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 30 Apr 2017 15:29:02 +0100
Subject: [PATCH 124/239] Only set volume if it has been asked for externally.
Clean up mute. Add ability do disable hardware mute
---
player.c | 4 ++--
rtsp.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/player.c b/player.c
index 459b2cc8..064594b5 100644
--- a/player.c
+++ b/player.c
@@ -820,7 +820,7 @@ static abuf_t *buffer_get_frame(rtsp_conn_info* conn) {
// if would be in sync. To do this, we would give it a latency offset of -100 ms, i.e.
// -4410 frames.
- debug(1, "Output sample ratio is %d", conn->output_sample_ratio);
+ // debug(1, "Output sample ratio is %d", conn->output_sample_ratio);
int64_t delta = (conn->first_packet_timestamp - reference_timestamp) +
config.latency * conn->output_sample_ratio +
@@ -1319,7 +1319,7 @@ static void *player_thread_func(void *arg) {
conn->output_sample_ratio = config.output_rate / conn->input_rate;
- debug(1, "Output sample ratio is %d.", conn->output_sample_ratio);
+ // debug(1, "Output sample ratio is %d.", conn->output_sample_ratio);
conn->max_frame_size_change = 500 * conn->output_sample_ratio; // we add or subtract one frame at the nominal
// rate, multiply it by the frame ratio.
diff --git a/rtsp.c b/rtsp.c
index 5cb65328..6b74b566 100644
--- a/rtsp.c
+++ b/rtsp.c
@@ -854,7 +854,7 @@ static void handle_set_parameter_parameter(rtsp_conn_info *conn, rtsp_message *r
if (!strncmp(cp, "volume: ", 8)) {
float volume = atof(cp + 8);
- debug(3, "volume: %f\n", volume);
+ debug(1, "AirPlay request to set volume to: %f\n", volume);
player_volume(volume,conn);
} else
#ifdef CONFIG_METADATA
@@ -1351,7 +1351,7 @@ static void handle_announce(rtsp_conn_info *conn, rtsp_message *req, rtsp_messag
if (playing_conn) {
debug(1,"Playing connection asked to stop");
if (playing_conn==conn) {
- debug(1,"ANNOuNCE asking to stop itself.");
+ debug(1,"ANNOUNCE asking to stop itself.");
} else {
playing_conn->stop = 1;
memory_barrier();
From fc492bea3a4e14a93d33848cc62ca2216d733160 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 30 Apr 2017 15:29:22 +0100
Subject: [PATCH 125/239] Only set volume if it has been asked for externally.
Clean up mute. Add ability do disable hardware mute
---
audio_alsa.c | 89 ++++++++++++++++++++++++++++++++++++----------------
1 file changed, 62 insertions(+), 27 deletions(-)
diff --git a/audio_alsa.c b/audio_alsa.c
index 43542ec5..297ea7ea 100644
--- a/audio_alsa.c
+++ b/audio_alsa.c
@@ -44,6 +44,9 @@ static void stop(void);
static void flush(void);
int delay(long *the_delay);
static void volume(double vol);
+void do_volume(double vol);
+void do_mute(int request);
+
static void linear_volume(double vol);
static void parameters(audio_parameters *info);
static void mute(int do_mute);
@@ -84,6 +87,10 @@ static char *alsa_mix_ctrl = "Master";
static int alsa_mix_index = 0;
static int hardware_mixer = 0;
static int has_softvol = 0;
+static int volume_set_request = 0; // set when an external request is made to set the volume.
+int mute_request_pending = 0; // set when an external request is made to mute or unmute.
+int mute_request_state = 0; // 1 = mute; 0 = unmute requested
+int use_playback_switch_for_mute = 1; // set to 0 for some cards, e.g. VMWare Fusion's emulated sound card
static snd_pcm_sframes_t (*alsa_pcm_write)(snd_pcm_t *, const void *,
snd_pcm_uframes_t) = snd_pcm_writei;
@@ -138,6 +145,7 @@ static int init(int argc, char **argv) {
set_period_size_request = 0;
set_buffer_size_request = 0;
+ use_playback_switch_for_mute = 1;
config.audio_backend_latency_offset = 0;
config.audio_backend_buffer_desired_length = 0.15;
@@ -235,7 +243,17 @@ static int init(int argc, char **argv) {
else
die("Invalid disable_synchronization option choice \"%s\". It should be \"yes\" or \"no\"");
}
-
+
+ /* Get the mute_using_playback_switch setting. */
+ if (config_lookup_string(config.cfg, "alsa.mute_using_playback_switch", &str)) {
+ if (strcasecmp(str, "no") == 0)
+ use_playback_switch_for_mute = 0;
+ else if (strcasecmp(str, "yes") == 0)
+ use_playback_switch_for_mute = 1;
+ else
+ die("Invalid mute_use_playback_switch option choice \"%s\". It should be \"yes\" or \"no\"");
+ }
+
/* Get the output format, using the same names as aplay does*/
if (config_lookup_string(config.cfg, "alsa.output_format", &str)) {
if (strcasecmp(str, "S16") == 0)
@@ -411,9 +429,9 @@ static int init(int argc, char **argv) {
*/
}
}
- if (snd_mixer_selem_has_playback_switch(alsa_mix_elem)) {
+ if ((use_playback_switch_for_mute==1) && (snd_mixer_selem_has_playback_switch(alsa_mix_elem))) {
audio_alsa.mute = &mute; // insert the mute function now we know it can do muting stuff
- debug(1, "Has mute ability.");
+ debug(1, "Has mute ability we will use.");
}
snd_mixer_close(alsa_mix_handle);
@@ -806,16 +824,11 @@ static void play(short buf[], int samples) {
ret = open_alsa_device();
if (hardware_mixer)
open_mixer();
- pthread_mutex_unlock(&alsa_mutex);
- // the mutex must be unlocked for the following call to proceed
if ((hardware_mixer) && (ret == 0) && (audio_alsa.volume))
- audio_alsa.volume(set_volume);
-
- pthread_mutex_lock(&alsa_mutex);
- int derr;
- if (hardware_mixer && alsa_mix_handle) {
- // debug(1,"unmute");
- snd_mixer_selem_set_playback_switch_all(alsa_mix_elem, 1);
+ do_volume(set_volume);
+ if ((hardware_mixer) && (audio_alsa.mute)) {
+ // debug(1,"Play unmute");
+ do_mute(0);
}
pthread_mutex_unlock(&alsa_mutex);
}
@@ -854,8 +867,8 @@ static void flush(void) {
pthread_mutex_lock(&alsa_mutex);
int derr;
if (hardware_mixer && alsa_mix_handle) {
- // debug(1,"Mute");
- snd_mixer_selem_set_playback_switch_all(alsa_mix_elem, 0);
+ // debug(1,"Flush mute");
+ do_mute(1);
snd_mixer_close(alsa_mix_handle);
alsa_mix_handle = NULL;
}
@@ -918,8 +931,7 @@ static void parameters(audio_parameters *info) {
info->maximum_volume_dB = alsa_mix_maxdb;
}
-static void volume(double vol) {
- pthread_mutex_lock(&alsa_mutex);
+void do_volume(double vol) { // caller is assumed to have the alsa_mutex when using this function
debug(3, "Setting volume db to %f.", vol);
set_volume = vol;
if (hardware_mixer && alsa_mix_handle) {
@@ -948,7 +960,15 @@ static void volume(double vol) {
debug(1,"Could not set playback dB volume on the mixer.");
}
}
+ volume_set_request = 0; // any external request that has been made is now satisfied
+ // debug(1,"Alsa volume actually set.");
}
+}
+
+void volume(double vol) {
+ pthread_mutex_lock(&alsa_mutex);
+ volume_set_request = 1; // an external request has been made to set the volume
+ do_volume(vol);
pthread_mutex_unlock(&alsa_mutex);
}
@@ -967,17 +987,32 @@ static void linear_volume(double vol) {
}
}
-static void mute(int do_mute) {
+static void mute(int mute_state_requested) {
+ // debug(1,"External Mute Request");
pthread_mutex_lock(&alsa_mutex);
- // debug(2,"audio_alsa mute called.");
- if (hardware_mixer && alsa_mix_handle) {
- if (do_mute) {
- // debug(1,"Mute");
- snd_mixer_selem_set_playback_switch_all(alsa_mix_elem, 0);
- } else {
- // debug(1,"Unmute");
- snd_mixer_selem_set_playback_switch_all(alsa_mix_elem, 1);
- }
- }
+ mute_request_pending = 1;
+ mute_request_state = mute_state_requested;
+ do_mute(mute_state_requested);
pthread_mutex_unlock(&alsa_mutex);
}
+
+void do_mute(int mute_state_requested) {
+ // The mute state requested will be actioned unless mute_request_pending is set
+ // If it is set, then that will be actioned.
+ // If the hardware isn't there, or we are not allowed to use it, nothing will be done
+ // The caller must have the alsa mutex
+ if (hardware_mixer && alsa_mix_handle) {
+ if (use_playback_switch_for_mute==1) {
+ if (mute_request_pending==0)
+ mute_request_state = mute_state_requested;
+ if (mute_request_state) {
+ // debug(1,"Playback Switch mute actually done");
+ snd_mixer_selem_set_playback_switch_all(alsa_mix_elem, 0);
+ } else {
+ // debug(1,"Playback Switch unmute actually done");
+ snd_mixer_selem_set_playback_switch_all(alsa_mix_elem, 1);
+ }
+ }
+ mute_request_pending = 0;
+ }
+}
From a705a3d7097f88a6f2c12b3106bd7c1e3572f7ac Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 30 Apr 2017 15:29:44 +0100
Subject: [PATCH 126/239] Modify a debug message
---
rtsp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rtsp.c b/rtsp.c
index 6b74b566..0e9ef965 100644
--- a/rtsp.c
+++ b/rtsp.c
@@ -854,7 +854,7 @@ static void handle_set_parameter_parameter(rtsp_conn_info *conn, rtsp_message *r
if (!strncmp(cp, "volume: ", 8)) {
float volume = atof(cp + 8);
- debug(1, "AirPlay request to set volume to: %f\n", volume);
+ // debug(1, "AirPlay request to set volume to: %f\n", volume);
player_volume(volume,conn);
} else
#ifdef CONFIG_METADATA
From 62d644b1524c75f245e6d65158edc902e9156abf Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 30 Apr 2017 15:30:18 +0100
Subject: [PATCH 127/239] Only set volume if it has been asked for externally.
Clean up mute. Add ability do disable hardware mute
---
configure.ac | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index acbea7cd..2d28dfea 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.50])
-AC_INIT([shairport-sync], [3.1d8], [mikebrady@eircom.net])
+AC_INIT([shairport-sync], [3.1d9], [mikebrady@eircom.net])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([shairport.c])
AC_CONFIG_HEADERS([config.h])
From 2225a46da41169192100c2daac5946c6b2501aac Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 30 Apr 2017 18:37:29 +0100
Subject: [PATCH 128/239] Add ability do disable hardware mute
---
scripts/shairport-sync.conf | 1 +
1 file changed, 1 insertion(+)
diff --git a/scripts/shairport-sync.conf b/scripts/shairport-sync.conf
index bf3878e9..94c8aa0b 100644
--- a/scripts/shairport-sync.conf
+++ b/scripts/shairport-sync.conf
@@ -106,6 +106,7 @@ alsa =
// period_size = ; // Use this optional advanced setting to set the alsa period size near to this value
// buffer_size = ; // Use this optional advanced setting to set the alsa buffer size near to this value
// use_mmap_if_available = "yes"; // Use this optional advanced setting to control whether MMAP-based output is used to communicate with the DAC. Default is "yes"
+// mute_using_playback_switch = "yes"; // Use this optional advanced setting to control whether the snd_mixer_selem_set_playback_switch_all call can be used for muting. Default is yes.
};
// These are parameters for the "pipe" audio back end, a back end that directs raw CD-style audio output to a pipe. No interpolation is done.
From 2dea79fa417df202937b0099a119a50880348b2c Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 30 Apr 2017 18:56:56 +0100
Subject: [PATCH 129/239] Add alsa_use_playback_switch_for_mute to the
configuration data structure, so visible for debug summary.
---
audio_alsa.c | 11 +++++------
common.h | 1 +
shairport.c | 1 +
3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/audio_alsa.c b/audio_alsa.c
index 297ea7ea..b173ccc1 100644
--- a/audio_alsa.c
+++ b/audio_alsa.c
@@ -90,7 +90,6 @@ static int has_softvol = 0;
static int volume_set_request = 0; // set when an external request is made to set the volume.
int mute_request_pending = 0; // set when an external request is made to mute or unmute.
int mute_request_state = 0; // 1 = mute; 0 = unmute requested
-int use_playback_switch_for_mute = 1; // set to 0 for some cards, e.g. VMWare Fusion's emulated sound card
static snd_pcm_sframes_t (*alsa_pcm_write)(snd_pcm_t *, const void *,
snd_pcm_uframes_t) = snd_pcm_writei;
@@ -145,7 +144,7 @@ static int init(int argc, char **argv) {
set_period_size_request = 0;
set_buffer_size_request = 0;
- use_playback_switch_for_mute = 1;
+ config.alsa_use_playback_switch_for_mute = 1;
config.audio_backend_latency_offset = 0;
config.audio_backend_buffer_desired_length = 0.15;
@@ -247,9 +246,9 @@ static int init(int argc, char **argv) {
/* Get the mute_using_playback_switch setting. */
if (config_lookup_string(config.cfg, "alsa.mute_using_playback_switch", &str)) {
if (strcasecmp(str, "no") == 0)
- use_playback_switch_for_mute = 0;
+ config.alsa_use_playback_switch_for_mute = 0;
else if (strcasecmp(str, "yes") == 0)
- use_playback_switch_for_mute = 1;
+ config.alsa_use_playback_switch_for_mute = 1;
else
die("Invalid mute_use_playback_switch option choice \"%s\". It should be \"yes\" or \"no\"");
}
@@ -429,7 +428,7 @@ static int init(int argc, char **argv) {
*/
}
}
- if ((use_playback_switch_for_mute==1) && (snd_mixer_selem_has_playback_switch(alsa_mix_elem))) {
+ if ((config.alsa_use_playback_switch_for_mute==1) && (snd_mixer_selem_has_playback_switch(alsa_mix_elem))) {
audio_alsa.mute = &mute; // insert the mute function now we know it can do muting stuff
debug(1, "Has mute ability we will use.");
}
@@ -1002,7 +1001,7 @@ void do_mute(int mute_state_requested) {
// If the hardware isn't there, or we are not allowed to use it, nothing will be done
// The caller must have the alsa mutex
if (hardware_mixer && alsa_mix_handle) {
- if (use_playback_switch_for_mute==1) {
+ if (config.alsa_use_playback_switch_for_mute==1) {
if (mute_request_pending==0)
mute_request_state = mute_state_requested;
if (mute_request_state) {
diff --git a/common.h b/common.h
index cb4b4b02..4dd62b19 100644
--- a/common.h
+++ b/common.h
@@ -146,6 +146,7 @@ typedef struct {
int loudness;
float loudness_reference_volume_db;
+ int alsa_use_playback_switch_for_mute;
} shairport_cfg;
diff --git a/shairport.c b/shairport.c
index 356de378..4320f659 100644
--- a/shairport.c
+++ b/shairport.c
@@ -1277,6 +1277,7 @@ int main(int argc, char **argv) {
debug(1, "zeroconf regtype is \"%s\".", config.regtype);
debug(1, "decoders_supported field is %d.", config.decoders_supported);
debug(1, "use_apple_decoder is %d.", config.use_apple_decoder);
+ debug(1, "alsa_use_playback_switch_for_mute is %d.", config.alsa_use_playback_switch_for_mute);
if (config.interface)
debug(1, "mdns service interface \"%s\" requested.", config.interface);
else
From f527af7504eb7b98eebeae4d64e315611f89d569 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sun, 30 Apr 2017 19:08:49 +0100
Subject: [PATCH 130/239] Update RELEASENOTES.md
---
RELEASENOTES.md | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 5daeb3ea..82582c89 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -1,9 +1,17 @@
-Version 3.1d8
+Version 3.1d9
====
**Pesky Changes You Can't Ignore**
If you are using a System V (aka `systemv`) installation, please note that the default location for PID file has moved -- it is now stored at `/var/run/shairport-sync/shairport-sync.pid`. This change is needed to improve security a little and to improve compatability across platforms. If you're not doing anything strange, this should make no difference.
+**New Features**
+
+* Shairport Sync has changes the way it deals with pauses and resumes, caused either by using the controls of the source program, e.g. iTunes, or those caused by resynchronisations. Specifically, it does not reset the output volume of the hardware mixer. This is so that any changes made by external controls are not needlessly reset by occasional glitches.
+* A new advanced setting for the `alsa` stanza is added: `alsa_use_playback_switch_for_mute`. The default is `"yes"`, which means that hardware mute will be used where available. Set it to `"no"` to prevent it being used. The motivation for this is to avoid using the call `snd_mixer_selem_set_playback_switch_all` which is incorrectly implemented on certain soundcards.
+
+Version 3.1d8
+====
+
**New Features**
* A volume-changed program hook has been added – a program can now be run whenever the volume control is set or changed. Similar to the `run_this_before_play_begins` and `run_this_after_play_ends` program hooks, you can specify a command line in the `general` `run_this_when_volume_is_set` setting. The AirPlay volume is simply appended to the end of the command line – leave a space if you want it treated as an extra argument. AirPlay volume goes from 0 to -30 and -144 means "mute".
* A FreeBSD installer and startup script is now available. Use the `./configure` option `--with-os=freebsd` to get the right compilation flags, and used the `./configure` option `--with-freebsd-installer` to have a startup script installed and to have a user, group and runtime directory created.
From a0c8186b4d3940cf3078ef8ef2ea88b938eb2fcd Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Mon, 1 May 2017 08:35:56 +0100
Subject: [PATCH 131/239] Fix silly bug in volume adjust code
---
audio_alsa.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/audio_alsa.c b/audio_alsa.c
index b173ccc1..7353a4e3 100644
--- a/audio_alsa.c
+++ b/audio_alsa.c
@@ -933,7 +933,7 @@ static void parameters(audio_parameters *info) {
void do_volume(double vol) { // caller is assumed to have the alsa_mutex when using this function
debug(3, "Setting volume db to %f.", vol);
set_volume = vol;
- if (hardware_mixer && alsa_mix_handle) {
+ if (hardware_mixer && alsa_mix_handle && volume_set_request) {
if (has_softvol) {
if (ctl && elem_id) {
snd_ctl_elem_value_t *value;
From 13873170e4eb511fcd61b59d10aa007a65ee7024 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Mon, 1 May 2017 08:36:04 +0100
Subject: [PATCH 132/239] Fix silly bug in volume adjust code
---
configure.ac | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index 2d28dfea..b4fee5f2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.50])
-AC_INIT([shairport-sync], [3.1d9], [mikebrady@eircom.net])
+AC_INIT([shairport-sync], [3.1d10], [mikebrady@eircom.net])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([shairport.c])
AC_CONFIG_HEADERS([config.h])
From 5188b12cf5fb1766b591a3139212966360284545 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Mon, 1 May 2017 08:57:48 +0100
Subject: [PATCH 133/239] Update RELEASENOTES.md
---
RELEASENOTES.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 82582c89..cbddd623 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -1,4 +1,4 @@
-Version 3.1d9
+Version 3.1d10
====
**Pesky Changes You Can't Ignore**
@@ -6,8 +6,8 @@ If you are using a System V (aka `systemv`) installation, please note that the d
**New Features**
-* Shairport Sync has changes the way it deals with pauses and resumes, caused either by using the controls of the source program, e.g. iTunes, or those caused by resynchronisations. Specifically, it does not reset the output volume of the hardware mixer. This is so that any changes made by external controls are not needlessly reset by occasional glitches.
-* A new advanced setting for the `alsa` stanza is added: `alsa_use_playback_switch_for_mute`. The default is `"yes"`, which means that hardware mute will be used where available. Set it to `"no"` to prevent it being used. The motivation for this is to avoid using the call `snd_mixer_selem_set_playback_switch_all` which is incorrectly implemented on certain soundcards.
+* Shairport Sync has changes the way it deals with pauses and resumes, caused either by using the controls of the source program, e.g. iTunes, or those caused by resynchronisations. Specifically, from now on, it does not reset the output volume of the hardware mixer. This is so that any changes made by external controls are not needlessly reset by occasional glitches.
+* A new advanced setting for the `alsa` stanza is added: `alsa_use_playback_switch_for_mute`. The default is `"yes"`, which means that hardware mute will be used where available. Set it to `"no"` to prevent it being used. The motivation for this is to avoid using the call `snd_mixer_selem_set_playback_switch_all` which is incorrectly implemented on certain soundcards, including the emulated card in VMWare Fusion 8.5.
Version 3.1d8
====
From b3953a0efd45cceeee825d99c276b54adac84bfc Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Mon, 1 May 2017 09:00:00 +0100
Subject: [PATCH 134/239] Update RELEASENOTES.md
---
RELEASENOTES.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index cbddd623..c0396a5a 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -6,7 +6,7 @@ If you are using a System V (aka `systemv`) installation, please note that the d
**New Features**
-* Shairport Sync has changes the way it deals with pauses and resumes, caused either by using the controls of the source program, e.g. iTunes, or those caused by resynchronisations. Specifically, from now on, it does not reset the output volume of the hardware mixer. This is so that any changes made by external controls are not needlessly reset by occasional glitches.
+* Shairport Sync has changes the way it deals with pauses and resumes, caused either by using the controls of the source program, e.g. iTunes, or those caused by resynchronisations. Specifically, from now on, on resumption after a short pause or glitch, it does not reset the output volume of the hardware mixer. This is so that any changes made by external controls are not needlessly reset by occasional network outages.
* A new advanced setting for the `alsa` stanza is added: `alsa_use_playback_switch_for_mute`. The default is `"yes"`, which means that hardware mute will be used where available. Set it to `"no"` to prevent it being used. The motivation for this is to avoid using the call `snd_mixer_selem_set_playback_switch_all` which is incorrectly implemented on certain soundcards, including the emulated card in VMWare Fusion 8.5.
Version 3.1d8
From cfd258f6b446da0691219711db972167ccc7ee36 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Mon, 1 May 2017 09:01:27 +0100
Subject: [PATCH 135/239] Update RELEASENOTES.md
---
RELEASENOTES.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index c0396a5a..98f1bbf9 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -14,7 +14,7 @@ Version 3.1d8
**New Features**
* A volume-changed program hook has been added – a program can now be run whenever the volume control is set or changed. Similar to the `run_this_before_play_begins` and `run_this_after_play_ends` program hooks, you can specify a command line in the `general` `run_this_when_volume_is_set` setting. The AirPlay volume is simply appended to the end of the command line – leave a space if you want it treated as an extra argument. AirPlay volume goes from 0 to -30 and -144 means "mute".
-* A FreeBSD installer and startup script is now available. Use the `./configure` option `--with-os=freebsd` to get the right compilation flags, and used the `./configure` option `--with-freebsd-installer` to have a startup script installed and to have a user, group and runtime directory created.
+* A FreeBSD installer and startup script is now available. Use the `./configure` option `--with-os=freebsd` to get the right compilation flags, and use the `./configure` option `--with-freebsd-installer` to have a startup script installed and to have a user, group and runtime directory created.
* The standard linux System V and `systemd` installers have been enhanced to create the user and
group `shairport-sync` if necessary.
* The standard linux System V installer creates a special runtime directory at `/var/run/shairport-sync` owned by the user `shairport-sync` and used to store its PID file.
From cfbce17f87d3bfbdc3276357bba9480e1adaaf2a Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Mon, 1 May 2017 09:02:30 +0100
Subject: [PATCH 136/239] Update RELEASENOTES.md
---
RELEASENOTES.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 98f1bbf9..e4e9cf4a 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -13,7 +13,7 @@ Version 3.1d8
====
**New Features**
-* A volume-changed program hook has been added – a program can now be run whenever the volume control is set or changed. Similar to the `run_this_before_play_begins` and `run_this_after_play_ends` program hooks, you can specify a command line in the `general` `run_this_when_volume_is_set` setting. The AirPlay volume is simply appended to the end of the command line – leave a space if you want it treated as an extra argument. AirPlay volume goes from 0 to -30 and -144 means "mute".
+* A volume-changed program hook has been added – a program can now be run whenever the volume control is set or changed. Similar to the `run_this_before_play_begins` and `run_this_after_play_ends` program hooks, you can specify a command line in the `general` `run_this_when_volume_is_set` setting. The AirPlay volume is simply appended to the end of the command line – leave a space if you want it treated as an extra argument. AirPlay volume goes from 0.0 to -30.0 and -144.0 means "mute".
* A FreeBSD installer and startup script is now available. Use the `./configure` option `--with-os=freebsd` to get the right compilation flags, and use the `./configure` option `--with-freebsd-installer` to have a startup script installed and to have a user, group and runtime directory created.
* The standard linux System V and `systemd` installers have been enhanced to create the user and
group `shairport-sync` if necessary.
From dc35995ca1b10c32f05fdf31d66f0d4a6a64667b Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Mon, 1 May 2017 09:06:32 +0100
Subject: [PATCH 137/239] Update RELEASENOTES.md
---
RELEASENOTES.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index e4e9cf4a..a21e0a61 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -7,7 +7,7 @@ If you are using a System V (aka `systemv`) installation, please note that the d
**New Features**
* Shairport Sync has changes the way it deals with pauses and resumes, caused either by using the controls of the source program, e.g. iTunes, or those caused by resynchronisations. Specifically, from now on, on resumption after a short pause or glitch, it does not reset the output volume of the hardware mixer. This is so that any changes made by external controls are not needlessly reset by occasional network outages.
-* A new advanced setting for the `alsa` stanza is added: `alsa_use_playback_switch_for_mute`. The default is `"yes"`, which means that hardware mute will be used where available. Set it to `"no"` to prevent it being used. The motivation for this is to avoid using the call `snd_mixer_selem_set_playback_switch_all` which is incorrectly implemented on certain soundcards, including the emulated card in VMWare Fusion 8.5.
+* A new advanced setting for the `alsa` stanza is added: `mute_using_playback_switch`. The default is `"yes"`, which means that hardware mute will be used where available. Set it to `"no"` to prevent it being used. The motivation for this is to avoid using the alsa function call: `snd_mixer_selem_set_playback_switch_all`, which is incorrectly implemented on certain soundcards, including the emulated card in VMWare Fusion 8.5.
Version 3.1d8
====
From eb1b7c3779d28c862537b406efbb9497fd8656e1 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Tue, 2 May 2017 12:29:57 +0100
Subject: [PATCH 138/239] Open and close the hardware mixer when needed --
don't keep it open throughout the play session. This allows it to respond to
external volume changes
---
audio_alsa.c | 70 ++++++++++++++++++++++++++++------------------------
1 file changed, 38 insertions(+), 32 deletions(-)
diff --git a/audio_alsa.c b/audio_alsa.c
index 7353a4e3..dc5a225b 100644
--- a/audio_alsa.c
+++ b/audio_alsa.c
@@ -109,7 +109,7 @@ static void help(void) {
" *) default option\n");
}
-void open_mixer() {
+int open_mixer() {
if (hardware_mixer) {
debug(2, "Open Mixer");
int ret = 0;
@@ -132,9 +132,19 @@ void open_mixer() {
alsa_mix_elem = snd_mixer_find_selem(alsa_mix_handle, alsa_mix_sid);
if (!alsa_mix_elem)
die("Failed to find mixer element");
+ return 1;
+ } else {
+ return 0;
}
}
+void close_mixer() {
+ if (alsa_mix_handle) {
+ snd_mixer_close(alsa_mix_handle);
+ alsa_mix_handle=NULL;
+ }
+}
+
static int init(int argc, char **argv) {
pthread_mutex_lock(&alsa_mutex);
// debug(2,"audio_alsa init called.");
@@ -433,7 +443,7 @@ static int init(int argc, char **argv) {
debug(1, "Has mute ability we will use.");
}
- snd_mixer_close(alsa_mix_handle);
+ close_mixer();
}
alsa_mix_handle = NULL;
@@ -444,9 +454,6 @@ static int init(int argc, char **argv) {
static void deinit(void) {
// debug(2,"audio_alsa deinit called.");
stop();
- if (hardware_mixer && alsa_mix_handle) {
- snd_mixer_close(alsa_mix_handle);
- }
}
int open_alsa_device(void) {
@@ -821,12 +828,10 @@ static void play(short buf[], int samples) {
if (alsa_handle == NULL) {
pthread_mutex_lock(&alsa_mutex);
ret = open_alsa_device();
- if (hardware_mixer)
- open_mixer();
- if ((hardware_mixer) && (ret == 0) && (audio_alsa.volume))
+ if (ret == 0) {
+ if (audio_alsa.volume)
do_volume(set_volume);
- if ((hardware_mixer) && (audio_alsa.mute)) {
- // debug(1,"Play unmute");
+ if (audio_alsa.mute)
do_mute(0);
}
pthread_mutex_unlock(&alsa_mutex);
@@ -865,12 +870,7 @@ static void flush(void) {
// debug(2,"audio_alsa flush called.");
pthread_mutex_lock(&alsa_mutex);
int derr;
- if (hardware_mixer && alsa_mix_handle) {
- // debug(1,"Flush mute");
- do_mute(1);
- snd_mixer_close(alsa_mix_handle);
- alsa_mix_handle = NULL;
- }
+ do_mute(1);
if (alsa_handle) {
// debug(1,"Dropping frames for flush...");
/*
@@ -933,7 +933,7 @@ static void parameters(audio_parameters *info) {
void do_volume(double vol) { // caller is assumed to have the alsa_mutex when using this function
debug(3, "Setting volume db to %f.", vol);
set_volume = vol;
- if (hardware_mixer && alsa_mix_handle && volume_set_request) {
+ if (volume_set_request && open_mixer()) {
if (has_softvol) {
if (ctl && elem_id) {
snd_ctl_elem_value_t *value;
@@ -961,6 +961,7 @@ void do_volume(double vol) { // caller is assumed to have the alsa_mutex when us
}
volume_set_request = 0; // any external request that has been made is now satisfied
// debug(1,"Alsa volume actually set.");
+ close_mixer();
}
}
@@ -971,6 +972,7 @@ void volume(double vol) {
pthread_mutex_unlock(&alsa_mutex);
}
+/*
static void linear_volume(double vol) {
debug(2, "Setting linear volume to %f.", vol);
set_volume = vol;
@@ -982,9 +984,11 @@ static void linear_volume(double vol) {
if (alsa_mix_handle) {
if (snd_mixer_selem_set_playback_volume_all(alsa_mix_elem, int_vol) != 0)
die("Failed to set playback volume");
+
}
}
}
+*/
static void mute(int mute_state_requested) {
// debug(1,"External Mute Request");
@@ -997,21 +1001,23 @@ static void mute(int mute_state_requested) {
void do_mute(int mute_state_requested) {
// The mute state requested will be actioned unless mute_request_pending is set
- // If it is set, then that will be actioned.
+ // If it is set, then that the pending request will be actioned.
// If the hardware isn't there, or we are not allowed to use it, nothing will be done
// The caller must have the alsa mutex
- if (hardware_mixer && alsa_mix_handle) {
- if (config.alsa_use_playback_switch_for_mute==1) {
- if (mute_request_pending==0)
- mute_request_state = mute_state_requested;
- if (mute_request_state) {
- // debug(1,"Playback Switch mute actually done");
- snd_mixer_selem_set_playback_switch_all(alsa_mix_elem, 0);
- } else {
- // debug(1,"Playback Switch unmute actually done");
- snd_mixer_selem_set_playback_switch_all(alsa_mix_elem, 1);
- }
- }
- mute_request_pending = 0;
- }
+
+ if (config.alsa_use_playback_switch_for_mute==1) {
+ if (mute_request_pending==0)
+ mute_request_state = mute_state_requested;
+ if (open_mixer()) {
+ if (mute_request_state) {
+ // debug(1,"Playback Switch mute actually done");
+ snd_mixer_selem_set_playback_switch_all(alsa_mix_elem, 0);
+ } else {
+ // debug(1,"Playback Switch unmute actually done");
+ snd_mixer_selem_set_playback_switch_all(alsa_mix_elem, 1);
+ }
+ close_mixer();
+ }
+ }
+ mute_request_pending = 0;
}
From b28b856e462d41eefd8723c0929285370306cd2f Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Tue, 2 May 2017 12:30:53 +0100
Subject: [PATCH 139/239] Open and close the hardware mixer only when needed --
don't keep it open throughout the play session. This allows it to respond to
external volume changes
---
configure.ac | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index b4fee5f2..9c3f24f1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.50])
-AC_INIT([shairport-sync], [3.1d10], [mikebrady@eircom.net])
+AC_INIT([shairport-sync], [3.1d11], [mikebrady@eircom.net])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([shairport.c])
AC_CONFIG_HEADERS([config.h])
From 6b49577b658a74265656a463be832af27be07410 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Tue, 2 May 2017 17:55:55 +0100
Subject: [PATCH 140/239] Update RELEASENOTES.md
---
RELEASENOTES.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index a21e0a61..6c7198f0 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -1,4 +1,4 @@
-Version 3.1d10
+Version 3.1d11
====
**Pesky Changes You Can't Ignore**
From 0182cac749f0d1c0aa2e2698e273e9079d8c3daf Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Wed, 3 May 2017 21:48:48 +0100
Subject: [PATCH 141/239] Don't turn the software volume down to zero when
muting
---
player.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/player.c b/player.c
index 064594b5..98e3f34b 100644
--- a/player.c
+++ b/player.c
@@ -2222,7 +2222,10 @@ void player_volume(double airplay_volume, rtsp_conn_info* conn) {
// do a mute
// needed even with hardware mute, as when sound is unmuted it might otherwise be very loud.
hardware_attenuation = hw_min_db;
- software_attenuation = sw_min_db;
+// software_attenuation = sw_min_db;
+ software_attenuation = sw_max_db - (max_db - hw_max_db); // e.g. if the hw_max_db is +4 and
+ // the max is +40, this will be -36
+ // (all by 100, of course)
if (config.output->mute)
config.output->mute(1); // use real mute if it's there
From 0f759b3e338d96b7ec437bf408dedce310974462 Mon Sep 17 00:00:00 2001
From: Mike Brady