From 8776f84e86198e120694f3259b574c2ad0140480 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Fri, 25 Sep 2015 16:47:58 +0100
Subject: [PATCH 01/39] Initial debug and exploratory code
---
player.c | 8 ++++++--
rtp.c | 2 ++
rtsp.c | 15 +++++++++++----
3 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/player.c b/player.c
index c86b9724..859e5136 100644
--- a/player.c
+++ b/player.c
@@ -299,7 +299,11 @@ void player_put_packet(seq_t seqno, uint32_t timestamp, uint8_t *data, int len)
time_of_last_audio_packet = get_absolute_time_in_fp();
if (connection_state_to_output) { // if we are supposed to be processing these packets
- if ((flush_rtp_timestamp != 0) &&
+ if (flush_rtp_timestamp != 0)
+ debug(1,"Flush_rtp_timestamp is %u",flush_rtp_timestamp);
+
+// if ((flush_rtp_timestamp != 0) &&
+ if ((0) &&
((timestamp == flush_rtp_timestamp) || seq32_order(timestamp, flush_rtp_timestamp))) {
debug(2, "Dropping flushed packet in player_put_packet, seqno %u, timestamp %u, flushing to "
"timestamp: %u.",
@@ -1243,7 +1247,7 @@ void player_volume(double f) {
}
void player_flush(uint32_t timestamp) {
- // debug(1,"Flush requested up to %u. It seems as if 0 is special.",timestamp);
+ debug(1,"Flush requested up to %u. It seems as if 0 is special.",timestamp);
pthread_mutex_lock(&flush_mutex);
flush_requested = 1;
// if (timestamp!=0)
diff --git a/rtp.c b/rtp.c
index e00a7536..2053f43c 100644
--- a/rtp.c
+++ b/rtp.c
@@ -193,6 +193,8 @@ static void *rtp_control_receiver(void *arg) {
rtp_timestamp_less_latency = ntohl(*((uint32_t *)&packet[4]));
sync_rtp_timestamp = ntohl(*((uint32_t *)&packet[16]));
+
+ debug(1,"Latency is %u frames.",sync_rtp_timestamp-rtp_timestamp_less_latency);
if (packet[0] & 0x10) {
// if it's a packet right after a flush or resume
diff --git a/rtsp.c b/rtsp.c
index cbd1fa6f..068b12f1 100644
--- a/rtsp.c
+++ b/rtsp.c
@@ -584,6 +584,12 @@ static void msg_write_response(int fd, rtsp_message *resp) {
static void handle_record(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) {
debug(1,"Handle Record");
resp->respcode = 200;
+ // I think this is for telling the client what the asbsolute minimum latency actually is,
+ // and when the client specifies a latency, it should be added to this figure.
+
+ // Thus, AirPlay's latency figure of 77175, when added to 11025 gives you exactly 88200
+ // and iTunes' latency figure of 88553, when added to 11025 gives you 99578, pretty close to the 99400 we guessed.
+
msg_add_header(resp, "Audio-Latency", "88200");
char *p;
@@ -596,13 +602,14 @@ static void handle_record(rtsp_conn_info *conn, rtsp_message *req, rtsp_message
p = strstr(hdr, "rtptime=");
if (p) {
p = strchr(p, '=') + 1;
- if (p)
+ if (p) {
rtptime = uatoi(p); // unsigned integer -- up to 2^32-1
+ rtptime--;
+ // debug(1,"RTSP Flush Requested by handle_record: %u.",rtptime);
+ player_flush(rtptime);
+ }
}
}
- rtptime--;
- debug(1,"RTSP Flush Requested by handle_record: %u.",rtptime);
- player_flush(rtptime);
}
static void handle_options(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) {
From 569154159d129ac66f90a050a3e91aaafb00bf10 Mon Sep 17 00:00:00 2001
From: Mke Brady
Date: Fri, 25 Sep 2015 18:19:00 +0100
Subject: [PATCH 02/39] Add experimental negotiated latencies setting and
associated logic.
---
common.h | 2 +-
configure.ac | 2 +-
player.c | 9 ++++-----
rtp.c | 10 ++++++++--
rtsp.c | 6 +++---
scripts/shairport-sync.conf | 1 +
shairport.c | 11 +++++++++++
7 files changed, 29 insertions(+), 12 deletions(-)
diff --git a/common.h b/common.h
index 4a6c44f0..4aa3568a 100644
--- a/common.h
+++ b/common.h
@@ -69,7 +69,7 @@ typedef struct {
uint32_t AirPlayLatency; // supplied with --AirPlayLatency option
uint32_t ForkedDaapdLatency; // supplied with --ForkedDaapdLatency option
int daemonise;
- int statistics_requested;
+ int statistics_requested,use_negotiated_latencies;
char *cmd_start, *cmd_stop;
int cmd_blocking;
int tolerance; // allow this much drift before attempting to correct it
diff --git a/configure.ac b/configure.ac
index 4d6f2983..9ac37f2e 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], [2.5.0.5], [mikebrady@eircom.net])
+AC_INIT([shairport-sync], [2.5.0.6], [mikebrady@eircom.net])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([shairport.c])
AC_CONFIG_HEADERS([config.h])
diff --git a/player.c b/player.c
index 859e5136..80fcae22 100644
--- a/player.c
+++ b/player.c
@@ -299,11 +299,10 @@ void player_put_packet(seq_t seqno, uint32_t timestamp, uint8_t *data, int len)
time_of_last_audio_packet = get_absolute_time_in_fp();
if (connection_state_to_output) { // if we are supposed to be processing these packets
- if (flush_rtp_timestamp != 0)
- debug(1,"Flush_rtp_timestamp is %u",flush_rtp_timestamp);
+// if (flush_rtp_timestamp != 0)
+// debug(1,"Flush_rtp_timestamp is %u",flush_rtp_timestamp);
-// if ((flush_rtp_timestamp != 0) &&
- if ((0) &&
+ if ((flush_rtp_timestamp != 0) &&
((timestamp == flush_rtp_timestamp) || seq32_order(timestamp, flush_rtp_timestamp))) {
debug(2, "Dropping flushed packet in player_put_packet, seqno %u, timestamp %u, flushing to "
"timestamp: %u.",
@@ -1247,7 +1246,7 @@ void player_volume(double f) {
}
void player_flush(uint32_t timestamp) {
- debug(1,"Flush requested up to %u. It seems as if 0 is special.",timestamp);
+ // debug(1,"Flush requested up to %u. It seems as if 0 is special.",timestamp);
pthread_mutex_lock(&flush_mutex);
flush_requested = 1;
// if (timestamp!=0)
diff --git a/rtp.c b/rtp.c
index 2053f43c..8ab96589 100644
--- a/rtp.c
+++ b/rtp.c
@@ -194,8 +194,14 @@ static void *rtp_control_receiver(void *arg) {
rtp_timestamp_less_latency = ntohl(*((uint32_t *)&packet[4]));
sync_rtp_timestamp = ntohl(*((uint32_t *)&packet[16]));
- debug(1,"Latency is %u frames.",sync_rtp_timestamp-rtp_timestamp_less_latency);
-
+ if (config.use_negotiated_latencies) {
+ uint32_t la = sync_rtp_timestamp-rtp_timestamp_less_latency+11025;
+ if (la!=config.latency) {
+ config.latency = la;
+ debug(1,"Using negotiated latency of %u frames.",config.latency);
+ }
+ }
+
if (packet[0] & 0x10) {
// if it's a packet right after a flush or resume
sync_rtp_timestamp += 352; // add frame_size -- can't see a reference to this anywhere,
diff --git a/rtsp.c b/rtsp.c
index 068b12f1..7e4c077c 100644
--- a/rtsp.c
+++ b/rtsp.c
@@ -582,7 +582,7 @@ static void msg_write_response(int fd, rtsp_message *resp) {
}
static void handle_record(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) {
- debug(1,"Handle Record");
+ //debug(1,"Handle Record");
resp->respcode = 200;
// I think this is for telling the client what the asbsolute minimum latency actually is,
// and when the client specifies a latency, it should be added to this figure.
@@ -590,7 +590,7 @@ static void handle_record(rtsp_conn_info *conn, rtsp_message *req, rtsp_message
// Thus, AirPlay's latency figure of 77175, when added to 11025 gives you exactly 88200
// and iTunes' latency figure of 88553, when added to 11025 gives you 99578, pretty close to the 99400 we guessed.
- msg_add_header(resp, "Audio-Latency", "88200");
+ msg_add_header(resp, "Audio-Latency", "11025");
char *p;
uint32_t rtptime = 0;
@@ -650,7 +650,7 @@ static void handle_flush(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *
}
static void handle_setup(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) {
- debug(1,"Handle Setup");
+ // debug(1,"Handle Setup");
int cport, tport;
int lsport, lcport, ltport;
uint32_t active_remote = 0;
diff --git a/scripts/shairport-sync.conf b/scripts/shairport-sync.conf
index b2ac51a5..a2975789 100644
--- a/scripts/shairport-sync.conf
+++ b/scripts/shairport-sync.conf
@@ -23,6 +23,7 @@ general =
// It's probably better to compensate for a delay in the output device using the alsa "audio_backend_latency_offset" setting -- see below.
latencies =
{
+// use_negotiated_latencies = "no"; // set this to "yes" to negotiate latencies with the client, and ignore the static settings listed below
// default = 88200; // used for unrecognised sources and for iTunes up to and including iTunes 9.X.
// itunes = 99400; // used for iTunes 10 or later
// airplay = 88200;
diff --git a/shairport.c b/shairport.c
index 2561350a..a1a37e80 100644
--- a/shairport.c
+++ b/shairport.c
@@ -399,6 +399,16 @@ int parse_options(int argc, char **argv) {
die("Invalid ignore_volume_control option choice \"%s\". It should be \"yes\" or \"no\"");
}
+ /* Get the dynamic latencies setting. */
+ if (config_lookup_string(config.cfg, "latencies.use_negotiated_latencies", &str)) {
+ if (strcasecmp(str, "no") == 0)
+ config.use_negotiated_latencies = 0;
+ else if (strcasecmp(str, "yes") == 0)
+ config.use_negotiated_latencies = 1;
+ else
+ die("Invalid use_negotiated_latencies option choice \"%s\". It should be \"yes\" or \"no\"");
+ }
+
/* Get the default latency. */
if (config_lookup_int(config.cfg, "latencies.default", &value))
config.latency = value;
@@ -850,6 +860,7 @@ int main(int argc, char **argv) {
debug(2, "audio backend desired buffer length is %d.",
config.audio_backend_buffer_desired_length);
debug(2, "audio backend latency offset is %d.", config.audio_backend_latency_offset);
+ debug(2, "use_negotiated_latencies %d.", config.use_negotiated_latencies);
char *realConfigPath = realpath(config.configfile,NULL);
if (realConfigPath) {
From 75f6fddd3f728599ceba4d80b7ef28e2fe92a8a9 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Fri, 25 Sep 2015 19:02:48 +0100
Subject: [PATCH 03/39] Update RELEASENOTES.md
---
RELEASENOTES.md | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index cb653812..9a09e4ff 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -1,8 +1,11 @@
-HEAD
+Version 2.5.0.6
----
+**New Feature**
+* Use Negotiated Latencies. The AirPlay protocol used by Shairport Sync allows the audio source to specify the exact delay or latency that should be applied to the audio stream. Until now, Shairport Sync ignored this information and used fixed preset latencies that were selected on the basis of the "User-Agent" setting. Using negotiated latencies means that Shairport Sync should be able adapt automatically to a wider range of sources. To enable it, there is a new setting in the configuration file "use_negoriated_latencies". Set this to "yes" to enable this behaviour. If it works reliably, it will become the default.
**Bug fixes**
* Fix in the `shairport.c`: the USE_CUSTOM_LOCAL_STATE_DIR macro was still being used when it should have been USE_CUSTOM_PID_DIR.
+* Fix a crashing bug -- if metadata was enabled but a pipename was not supplied, boom.
Version 2.5.0.2
----
From 43c63f04a229c1b5021830a363a42f10535493dd Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Wed, 30 Sep 2015 15:52:50 +0000
Subject: [PATCH 04/39] Allow latency variables to be negative, in preparation
for using values of -1 as a flag.
---
common.h | 14 +++++++-------
shairport.c | 4 ++--
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/common.h b/common.h
index 4aa3568a..0f51a4b3 100644
--- a/common.h
+++ b/common.h
@@ -63,11 +63,11 @@ typedef struct {
char *mdns_name;
mdns_backend *mdns;
int buffer_start_fill;
- uint32_t latency;
- uint32_t userSuppliedLatency; // overrides all other latencies -- use with caution
- uint32_t iTunesLatency; // supplied with --iTunesLatency option
- uint32_t AirPlayLatency; // supplied with --AirPlayLatency option
- uint32_t ForkedDaapdLatency; // supplied with --ForkedDaapdLatency option
+ int32_t latency;
+ int32_t userSuppliedLatency; // overrides all other latencies -- use with caution
+ int32_t iTunesLatency; // supplied with --iTunesLatency option
+ int32_t AirPlayLatency; // supplied with --AirPlayLatency option
+ int32_t ForkedDaapdLatency; // supplied with --ForkedDaapdLatency option
int daemonise;
int statistics_requested,use_negotiated_latencies;
char *cmd_start, *cmd_stop;
@@ -78,9 +78,9 @@ typedef struct {
char *logfile;
char *errfile;
char *configfile;
- uint32_t audio_backend_buffer_desired_length; // this will be the desired number of frames in the
+ int32_t audio_backend_buffer_desired_length; // this will be the desired number of frames in the
// audio backend buffer -- the DAC buffer for ALSA
- uint32_t audio_backend_latency_offset; // this will be the offset to compensate for any fixed latency
+ int32_t audio_backend_latency_offset; // this will be the offset to compensate for any fixed latency
// there might be in the audio
} shairport_cfg;
diff --git a/shairport.c b/shairport.c
index a1a37e80..cfc76622 100644
--- a/shairport.c
+++ b/shairport.c
@@ -171,10 +171,10 @@ void usage(char *progname) {
printf(" -a, --name=NAME set advertised name\n");
printf(
" -A, --AirPlayLatency=FRAMES set the latency for audio sent from an AirPlay device.\n");
- printf(" The default value is %u frames.\n", config.AirPlayLatency);
+ printf(" The default value is %d frames.\n", config.AirPlayLatency);
printf(
" -i, --iTunesLatency=FRAMES set the latency for audio sent from iTunes 10 or later.\n");
- printf(" The default value is %u frames.\n", config.iTunesLatency);
+ printf(" The default value is %d frames.\n", config.iTunesLatency);
printf(" -L, --latency=FRAMES set the latency for audio sent from an unknown device\n");
printf(" or from an old version of iTunes. Default is %d frames.\n",
config.latency);
From 440b592f640bdc09577e88fba4f28a4e0571b56a Mon Sep 17 00:00:00 2001
From: Mke Brady
Date: Thu, 1 Oct 2015 08:21:21 +0100
Subject: [PATCH 05/39] Make automatic latency selection default. Warn of
deprecation of static latencies
---
rtsp.c | 13 +++++--
scripts/shairport-sync.conf | 25 +++++++------
shairport.c | 71 +++++++++++++++++++++++++++----------
3 files changed, 77 insertions(+), 32 deletions(-)
diff --git a/rtsp.c b/rtsp.c
index 7e4c077c..4066a2db 100644
--- a/rtsp.c
+++ b/rtsp.c
@@ -674,13 +674,16 @@ static void handle_setup(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *
}
#endif
- // select latency
+ // This latency-setting mechanism is deprecated and will be removed.
+ // If no non-standard latency is chosen, automatic negotiated latency setting is permitted.
+
+ // Select a static latency
// if iTunes V10 or later is detected, use the iTunes latency setting
// if AirPlay is detected, use the AirPlay latency setting
// for everything else, use the general latency setting, if given, or
// else use the default latency setting
- config.latency = 88200;
+ config.latency = -1;
if (config.userSuppliedLatency)
config.latency = config.userSuppliedLatency;
@@ -716,6 +719,12 @@ static void handle_setup(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *
debug(2, "Unrecognised User-Agent. Using latency of %d frames.", config.latency);
}
}
+
+ if (config.latency==-1) {
+ // this means that no static latency was set, so we'll allow it to be set dynamically
+ config.latency=88200; // to be sure, to be sure
+ config.use_negotiated_latencies = 1;
+ }
char *hdr = msg_get_header(req, "Transport");
if (!hdr)
goto error;
diff --git a/scripts/shairport-sync.conf b/scripts/shairport-sync.conf
index a2975789..8a4dbf72 100644
--- a/scripts/shairport-sync.conf
+++ b/scripts/shairport-sync.conf
@@ -19,17 +19,6 @@ general =
// ignore_volume_control = "no"; // set this to "yes" if you want the volume to be at 100% no matter what the source's volume control is set to.
};
-// Latencies for different sources. These have been estimated from listening tests.
-// It's probably better to compensate for a delay in the output device using the alsa "audio_backend_latency_offset" setting -- see below.
-latencies =
-{
-// use_negotiated_latencies = "no"; // set this to "yes" to negotiate latencies with the client, and ignore the static settings listed below
-// default = 88200; // used for unrecognised sources and for iTunes up to and including iTunes 9.X.
-// itunes = 99400; // used for iTunes 10 or later
-// airplay = 88200;
-// forkedDaapd = 99400;
-};
-
// How to deal with metadata, including artwork
metadata =
{
@@ -76,3 +65,17 @@ stdout =
// audio_backend_latency_offset = 0; // Set this offset to compensate for a fixed delay in the audio back end. E.g. if the output device delays by 100 ms, set this to -4410.
// audio_backend_buffer_desired_length = 44100; // Having started to send audio at the right time, send all subsequent audio this many frames ahead of time, creating a buffer this size.
};
+
+// The following static latency settings are deprecated -- do not use them for new installations. Shairport Sync now sets latencies automatically.
+// To compensate for a delay in the output device using the alsa/stdio/pipe "audio_backend_latency_offset" setting.
+
+// Static latencies for different sources. These have been estimated from listening tests.
+latencies =
+{
+// default = 88200; // used for unrecognised sources and for iTunes up to and including iTunes 9.X.
+// itunes = 99400; // used for iTunes 10 or later
+// airplay = 88200;
+// forkedDaapd = 99400;
+};
+
+
diff --git a/shairport.c b/shairport.c
index cfc76622..beb8d21b 100644
--- a/shairport.c
+++ b/shairport.c
@@ -399,29 +399,19 @@ int parse_options(int argc, char **argv) {
die("Invalid ignore_volume_control option choice \"%s\". It should be \"yes\" or \"no\"");
}
- /* Get the dynamic latencies setting. */
- if (config_lookup_string(config.cfg, "latencies.use_negotiated_latencies", &str)) {
- if (strcasecmp(str, "no") == 0)
- config.use_negotiated_latencies = 0;
- else if (strcasecmp(str, "yes") == 0)
- config.use_negotiated_latencies = 1;
- else
- die("Invalid use_negotiated_latencies option choice \"%s\". It should be \"yes\" or \"no\"");
- }
-
- /* Get the default latency. */
+ /* Get the default latency. Deprecated! */
if (config_lookup_int(config.cfg, "latencies.default", &value))
- config.latency = value;
+ config.userSuppliedLatency = value;
- /* Get the itunes latency. */
+ /* Get the itunes latency. Deprecated! */
if (config_lookup_int(config.cfg, "latencies.itunes", &value))
config.iTunesLatency = value;
- /* Get the AirPlay latency. */
+ /* Get the AirPlay latency. Deprecated! */
if (config_lookup_int(config.cfg, "latencies.airplay", &value))
config.AirPlayLatency = value;
- /* Get the forkedDaapd latency. */
+ /* Get the forkedDaapd latency. Deprecated! */
if (config_lookup_int(config.cfg, "latencies.forkedDaapd", &value))
config.ForkedDaapdLatency = value;
@@ -648,14 +638,14 @@ int main(int argc, char **argv) {
config.configfile = configuration_file_path;
config.statistics_requested = 0; // don't print stats in the log
- config.latency = 88200; // AirPlay. Is also reset in rtsp.c when play is about to start
+ config.latency = -1; // -1 means not set. 88200 works well. This is also reset in rtsp.c when play is about to start
config.userSuppliedLatency = 0; // zero means none supplied
- config.iTunesLatency = 99400; // this seems to work pretty well for iTunes from Version 10 (?)
+ config.iTunesLatency = -1; // -1 means not supplied. 99400 seems to work pretty well for iTunes from Version 10 (?)
// upwards-- two left-ear headphones, one from the iMac jack, one
// from an NSLU2 running a cheap "3D Sound" USB Soundcard
- config.AirPlayLatency = 88200; // this seems to work pretty well for AirPlay -- Syncs sound and
+ config.AirPlayLatency = -1; // -1 means not set. 88200 seems to work well for AirPlay -- Syncs sound and
// vision on AppleTV, but also used for iPhone/iPod/iPad sources
- config.ForkedDaapdLatency = 99400; // Seems to be right
+ config.ForkedDaapdLatency = -1; // -1 means not set. 99400 seems to be right
config.resyncthreshold = 441 * 5; // this number of frames is 50 ms
config.timeout = 120; // this number of seconds to wait for [more] audio before switching to idle.
config.tolerance = 88; // this number of frames of error before attempting to correct it.
@@ -833,6 +823,49 @@ int main(int argc, char **argv) {
daemon_log(LOG_NOTICE, "startup");
+ /* Mess around with the latency options */
+ // Basically, we used to rely on static latencies -- 99400 for iTunes 10 or later and forkedDaapd, 88200 for everything else
+ // Nowadays we allow the source to set the latency, which works out at 99651 for iTunes 10 and forkedDaapd and 88220 for everything else
+ // What we want to do here is allow the source to set the latency unless the user has specified an non-standard latency.
+ // If the user has specified a standard latency, we suggest to them to stop doing it.
+ // If they specify a non-standard latency, we suggest the user to use the audio_backend_latency_offset instead.
+
+ if (config.AirPlayLatency!=-1) {
+ if (config.AirPlayLatency==88200) {
+ inform("It is not necessary to set the AirPlay latency to 88200 -- you should remove this setting or configuration option, as it is deprecated.");
+ config.AirPlayLatency= -1;
+ } else {
+ inform("The AirPlay latency setting is deprecated, as Shairport Sync can now get the correct latency from the source.");
+ inform("Please remove this setting and use the relevant audio_backend_latency_offset setting, if necessary, to compensate for delays elsewhere.");
+ }
+ }
+
+ if (config.iTunesLatency!=-1) {
+ if (config.iTunesLatency==99400) {
+ inform("It is not necessary to set the iTunes latency to 99400 -- you should remove this setting or configuration option, as it is deprecated and ignored.");
+ config.iTunesLatency= -1;
+ } else {
+ inform("The iTunes latency setting is deprecated, as Shairport Sync can now get the correct latency from the source.");
+ inform("Please remove this setting and use the relevant audio_backend_latency_offset setting, if necessary, to compensate for delays elsewhere.");
+ }
+ }
+
+ if (config.ForkedDaapdLatency!=-1) {
+ if (config.ForkedDaapdLatency==99400) {
+ inform("It is not necessary to set the forkedDaapd latency to 99400 -- you should remove this setting or configuration option, as it is deprecated and ignored.");
+ config.ForkedDaapdLatency= -1;
+ } else {
+ inform("The forkedDaapd latency setting is deprecated, as Shairport Sync can now get the correct latency from the source.");
+ inform("Please remove this setting and use the relevant audio_backend_latency_offset setting, if necessary, to compensate for delays elsewhere.");
+ }
+ }
+
+ if (config.userSuppliedLatency) {
+ inform("The default latency setting is deprecated, as Shairport Sync can now get the correct latency from the source.");
+ inform("Please remove this setting and use the relevant audio_backend_latency_offset setting, if necessary, to compensate for delays elsewhere.");
+ }
+
+
/* Print out options */
debug(2, "statistics_requester status is %d.", config.statistics_requested);
From ba02dee44322e9600c8024ddac8046811c83b90c Mon Sep 17 00:00:00 2001
From: Mke Brady
Date: Sat, 3 Oct 2015 12:49:56 +0100
Subject: [PATCH 06/39] playing with using just a linear mixer
---
audio_alsa.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++-----
player.c | 33 ++++++++++++++-------------
2 files changed, 75 insertions(+), 21 deletions(-)
diff --git a/audio_alsa.c b/audio_alsa.c
index d4e54973..309a8314 100644
--- a/audio_alsa.c
+++ b/audio_alsa.c
@@ -29,6 +29,7 @@
#include
#include
#include
+#include
#include
#include
#include "common.h"
@@ -43,9 +44,9 @@ static void stop(void);
static void flush(void);
static uint32_t delay(void);
static void volume(double vol);
+static void linear_volume(double vol);
static void parameters(audio_parameters *info);
static int has_mute = 0;
-static int has_db_vol = 0;
static double set_volume;
audio_output audio_alsa = {
@@ -209,12 +210,37 @@ static int init(int argc, char **argv) {
alsa_mix_elem = snd_mixer_find_selem(alsa_mix_handle, alsa_mix_sid);
if (!alsa_mix_elem)
die("Failed to find mixer element");
+ // Check that the output device has two playback channels
+ snd_mixer_selem_channel_id_t chn;
+
+
+ if (snd_mixer_selem_has_playback_volume(alsa_mix_elem) ||
+ snd_mixer_selem_has_playback_switch(alsa_mix_elem)) {
+ if (snd_mixer_selem_is_playback_mono(alsa_mix_elem)) {
+ debug(1,"Mono Capable Output Device Only");
+ } else {
+ for (chn = 0; chn <= SND_MIXER_SCHN_LAST; chn++){
+ if (snd_mixer_selem_has_playback_channel(alsa_mix_elem, chn)) {
+ debug(1,"Playback channel \"%s\" discovered", snd_mixer_selem_channel_name(chn));
+ // see if it's got a dB range
+ int64_t cmin,cmax;
+ if (snd_mixer_selem_get_playback_dB_range(alsa_mix_elem,&cmin,&cmax)==0)
+ debug(1,"Range in dB is from %ld to %ld",cmin,cmax);
+ else
+ debug(1,"Can't get dB volume range");
+ }
+ }
+ }
+ }
+
+
+
if (snd_mixer_selem_get_playback_volume_range(alsa_mix_elem, &alsa_mix_minv, &alsa_mix_maxv) < 0)
debug(1, "Can't read mixer's [linear] min and max volumes.");
else {
- if ((snd_mixer_selem_ask_playback_vol_dB(alsa_mix_elem, alsa_mix_minv, &alsa_mix_mindb) == 0) &&
- (snd_mixer_selem_ask_playback_vol_dB(alsa_mix_elem, alsa_mix_maxv, &alsa_mix_maxdb) == 0)) {
- has_db_vol = 1;
+ if (snd_mixer_selem_get_playback_dB_range (alsa_mix_elem, &alsa_mix_mindb, &alsa_mix_maxdb) == 0) {
+// if ((snd_mixer_selem_ask_playback_vol_dB(alsa_mix_elem, alsa_mix_minv, &alsa_mix_mindb) == 0) &&
+// (snd_mixer_selem_ask_playback_vol_dB(alsa_mix_elem, alsa_mix_maxv, &alsa_mix_maxdb) == 0)) {
audio_alsa.volume = &volume; // insert the volume function now we know it can do dB stuff
audio_alsa.parameters = ¶meters; // likewise the parameters stuff
if (alsa_mix_mindb == -9999999) {
@@ -226,8 +252,17 @@ static int init(int argc, char **argv) {
debug(1, "Hardware mixer has dB volume from %f to %f.", (1.0 * alsa_mix_mindb) / 100.0,
(1.0 * alsa_mix_maxdb) / 100.0);
} else {
+ // use the linear scale and do the db conversion ourselves
inform("note: the hardware mixer specified -- \"%s\" -- does not have dB volume, so it can not be used for volume control.",alsa_mix_ctrl);
- }
+ debug(1, "Min and max volumes are %d and %d.",alsa_mix_minv,alsa_mix_maxv);
+ alsa_mix_maxdb = 0;
+ if ((alsa_mix_maxv!=0) && (alsa_mix_minv!=0))
+ alsa_mix_mindb = -20*100*(log10(alsa_mix_maxv*1.0)-log10(alsa_mix_minv*1.0));
+ else if (alsa_mix_maxv!=0)
+ alsa_mix_mindb = -20*100*log10(alsa_mix_maxv*1.0);
+ audio_alsa.volume = &linear_volume; // insert the linear volume function
+ debug(1,"Max and min dB calculated are %d and %d.",alsa_mix_maxdb,alsa_mix_mindb);
+ }
}
if (snd_mixer_selem_has_playback_switch(alsa_mix_elem)) {
has_mute = 1;
@@ -320,7 +355,7 @@ static void play(short buf[], int samples) {
if (alsa_handle == NULL) {
ret = open_alsa_device();
if ((ret == 0) && (audio_alsa.volume))
- volume(set_volume);
+ audio_alsa.volume(set_volume);
}
if (ret == 0) {
pthread_mutex_lock(&alsa_mutex);
@@ -390,6 +425,7 @@ static void parameters(audio_parameters *info) {
}
static void volume(double vol) {
+ debug(1,"Setting volume in dB.");
set_volume = vol;
double vol_setting = vol2attn(vol, alsa_mix_maxdb, alsa_mix_mindb);
// debug(1,"Setting volume db to %f, for volume input of %f.",vol_setting/100,vol);
@@ -398,3 +434,18 @@ static void volume(double vol) {
if (has_mute)
snd_mixer_selem_set_playback_switch_all(alsa_mix_elem, (vol != -144.0));
}
+
+static void linear_volume(double vol) {
+ debug(1,"Setting linear volume for %f.",vol);
+ set_volume = vol;
+ double vol_setting = vol2attn(vol, 0, alsa_mix_mindb)/2000;
+ debug(1,"Adjusted volume is %f.",vol_setting);
+ double linear_volume = pow(10, vol_setting);
+ debug(1,"Linear volume is %f.",linear_volume);
+ long int_vol = alsa_mix_minv + (alsa_mix_maxv - alsa_mix_minv) * linear_volume;
+ debug(1,"Setting volume to %ld, for volume input of %f.",int_vol,vol);
+ if (snd_mixer_selem_set_playback_volume_all(alsa_mix_elem, int_vol) != 0)
+ die("Failed to set playback volume");
+ if (has_mute)
+ snd_mixer_selem_set_playback_switch_all(alsa_mix_elem, (vol != -144.0));
+}
diff --git a/player.c b/player.c
index 80fcae22..b7224e5e 100644
--- a/player.c
+++ b/player.c
@@ -1196,32 +1196,35 @@ void player_volume(double f) {
// The volume ranges -144.0 (mute) or -30 -- 0. See
// http://git.zx2c4.com/Airtunes2/about/#setting-volume
// By examination, the -30 -- 0 range is linear on the slider; i.e. the slider is calibrated in 30
- // equal increments
- // So, we will pass this on without any weighting if we have a hardware mixer, as we expect the
- // mixer to be calibrated in dB.
-
- // Here, we ask for an attenuation we will apply in software. The dB range of a value from 1 to
- // 65536 is about 48.1 dB (log10 of 65536 is 4.8164).
- // Thus, we ask our vol2attn function for an appropriate dB between -48.1 and 0 dB and translate
+ // equal increments. Since the human ear's response is roughly logarithmic, we imagine these to
+ // be power dB, i.e. from -30dB to 0dB.
+
+ // So, if we have a hardware mixer, we will pass this on to its dB volume settings.
+
+ // Without a hardware mixer, we have to do attenuation in software, so
+ // here, we ask for an attenuation we will apply to the signal amplitude in software.
+ // The dB range of a value from 1 to 65536 is about 96.3 dB (log10 of 65536 is 4.8164).
+ // Since the levels correspond with amplitude, they correspond to voltage, hence voltage dB,
+ // or 20 times the log of the ratio. Then multiplied by 100 for convenience.
+ // Thus, we ask our vol2attn function for an appropriate dB between -96.3 and 0 dB and translate
// it back to a number.
- double scaled_volume = vol2attn(f, 0, -4810);
- double linear_volume = pow(10, scaled_volume / 1000);
+ double scaled_volume = vol2attn(f, 0, -9630);
+ double linear_volume = pow(10, scaled_volume / 20*100);
if (f == -144.0)
linear_volume = 0.0;
if (config.output->volume) {
config.output->volume(f); // volume will be sent as metadata by the config.output device
- linear_volume =
- 1.0; // no attenuation needed -- this value is used as a flag to avoid calculations
+ linear_volume = 1.0; // no attenuation needed -- this value is used as a flag to avoid calculations
}
if (config.output->parameters)
config.output->parameters(&audio_information);
else {
audio_information.airplay_volume = f;
- audio_information.minimum_volume_dB = -4810;
+ audio_information.minimum_volume_dB = -9630;
audio_information.maximum_volume_dB = 0;
audio_information.current_volume_dB = scaled_volume;
audio_information.has_true_mute = 0;
@@ -1233,10 +1236,10 @@ void player_volume(double f) {
fix_volume = 65536.0 * software_mixer_volume;
pthread_mutex_unlock(&vol_mutex);
#ifdef CONFIG_METADATA
- char *dv = malloc(64); // will be freed in the metadata thread
+ char *dv = malloc(128); // will be freed in the metadata thread
if (dv) {
- memset(dv, 0, 64);
- snprintf(dv, 63, "%.2f,%.2f,%.2f,%.2f", audio_information.airplay_volume,
+ memset(dv, 0, 128);
+ snprintf(dv, 127, "%.2f,%.2f,%.2f,%.2f", audio_information.airplay_volume,
audio_information.current_volume_dB / 100.0,
audio_information.minimum_volume_dB / 100.0,
audio_information.maximum_volume_dB / 100.0);
From b82952dc13b86490749cf6b8d1b94759e43beaa7 Mon Sep 17 00:00:00 2001
From: Mke Brady
Date: Sat, 3 Oct 2015 20:26:06 +0100
Subject: [PATCH 07/39] Remove some scaffolding, turn off some debug messages
---
audio_alsa.c | 54 ++++++++++++++++++----------------------------------
1 file changed, 18 insertions(+), 36 deletions(-)
diff --git a/audio_alsa.c b/audio_alsa.c
index 309a8314..7a3fe45e 100644
--- a/audio_alsa.c
+++ b/audio_alsa.c
@@ -184,6 +184,8 @@ static int init(int argc, char **argv) {
if (optind < argc)
die("Invalid audio argument: %s", argv[optind]);
+
+ debug(1,"Output device name is \"%s\".",alsa_out_dev);
if (!hardware_mixer)
return 0;
@@ -192,13 +194,14 @@ static int init(int argc, char **argv) {
alsa_mix_dev = alsa_out_dev;
int ret = 0;
-
+
snd_mixer_selem_id_alloca(&alsa_mix_sid);
snd_mixer_selem_id_set_index(alsa_mix_sid, alsa_mix_index);
snd_mixer_selem_id_set_name(alsa_mix_sid, alsa_mix_ctrl);
if ((snd_mixer_open(&alsa_mix_handle, 0)) < 0)
die("Failed to open mixer");
+ debug(1,"Mixer device name is \"%s\".",alsa_mix_dev);
if ((snd_mixer_attach(alsa_mix_handle, alsa_mix_dev)) < 0)
die("Failed to attach mixer");
if ((snd_mixer_selem_register(alsa_mix_handle, NULL, NULL)) < 0)
@@ -207,44 +210,24 @@ static int init(int argc, char **argv) {
ret = snd_mixer_load(alsa_mix_handle);
if (ret < 0)
die("Failed to load mixer element");
- alsa_mix_elem = snd_mixer_find_selem(alsa_mix_handle, alsa_mix_sid);
+
+ debug(1,"Mixer Control name is \"%s\".",alsa_mix_ctrl);
+
+ alsa_mix_elem = snd_mixer_find_selem(alsa_mix_handle, alsa_mix_sid);
if (!alsa_mix_elem)
die("Failed to find mixer element");
- // Check that the output device has two playback channels
- snd_mixer_selem_channel_id_t chn;
-
-
- if (snd_mixer_selem_has_playback_volume(alsa_mix_elem) ||
- snd_mixer_selem_has_playback_switch(alsa_mix_elem)) {
- if (snd_mixer_selem_is_playback_mono(alsa_mix_elem)) {
- debug(1,"Mono Capable Output Device Only");
- } else {
- for (chn = 0; chn <= SND_MIXER_SCHN_LAST; chn++){
- if (snd_mixer_selem_has_playback_channel(alsa_mix_elem, chn)) {
- debug(1,"Playback channel \"%s\" discovered", snd_mixer_selem_channel_name(chn));
- // see if it's got a dB range
- int64_t cmin,cmax;
- if (snd_mixer_selem_get_playback_dB_range(alsa_mix_elem,&cmin,&cmax)==0)
- debug(1,"Range in dB is from %ld to %ld",cmin,cmax);
- else
- debug(1,"Can't get dB volume range");
- }
- }
- }
- }
-
-
+
if (snd_mixer_selem_get_playback_volume_range(alsa_mix_elem, &alsa_mix_minv, &alsa_mix_maxv) < 0)
debug(1, "Can't read mixer's [linear] min and max volumes.");
else {
if (snd_mixer_selem_get_playback_dB_range (alsa_mix_elem, &alsa_mix_mindb, &alsa_mix_maxdb) == 0) {
-// if ((snd_mixer_selem_ask_playback_vol_dB(alsa_mix_elem, alsa_mix_minv, &alsa_mix_mindb) == 0) &&
-// (snd_mixer_selem_ask_playback_vol_dB(alsa_mix_elem, alsa_mix_maxv, &alsa_mix_maxdb) == 0)) {
+
audio_alsa.volume = &volume; // insert the volume function now we know it can do dB stuff
audio_alsa.parameters = ¶meters; // likewise the parameters stuff
- if (alsa_mix_mindb == -9999999) {
- // trying to say that the lowest vol is mute, maybe? Raspberry Pi does this
+ if (alsa_mix_mindb == SND_CTL_TLV_DB_GAIN_MUTE) {
+ // Raspberry Pi does this
+ debug(1, "Lowest dB value is a mute.");
if (snd_mixer_selem_ask_playback_vol_dB(alsa_mix_elem, alsa_mix_minv + 1,
&alsa_mix_mindb) == 0)
debug(1, "Can't get dB value corresponding to a \"volume\" of 1.");
@@ -253,7 +236,7 @@ static int init(int argc, char **argv) {
(1.0 * alsa_mix_maxdb) / 100.0);
} else {
// use the linear scale and do the db conversion ourselves
- inform("note: the hardware mixer specified -- \"%s\" -- does not have dB volume, so it can not be used for volume control.",alsa_mix_ctrl);
+ debug(1, "note: the hardware mixer specified -- \"%s\" -- does not have dB volume -- using the [hopefully] linear settings.",alsa_mix_ctrl);
debug(1, "Min and max volumes are %d and %d.",alsa_mix_minv,alsa_mix_maxv);
alsa_mix_maxdb = 0;
if ((alsa_mix_maxv!=0) && (alsa_mix_minv!=0))
@@ -261,6 +244,7 @@ static int init(int argc, char **argv) {
else if (alsa_mix_maxv!=0)
alsa_mix_mindb = -20*100*log10(alsa_mix_maxv*1.0);
audio_alsa.volume = &linear_volume; // insert the linear volume function
+ audio_alsa.parameters = ¶meters; // likewise the parameters stuff
debug(1,"Max and min dB calculated are %d and %d.",alsa_mix_maxdb,alsa_mix_mindb);
}
}
@@ -425,7 +409,6 @@ static void parameters(audio_parameters *info) {
}
static void volume(double vol) {
- debug(1,"Setting volume in dB.");
set_volume = vol;
double vol_setting = vol2attn(vol, alsa_mix_maxdb, alsa_mix_mindb);
// debug(1,"Setting volume db to %f, for volume input of %f.",vol_setting/100,vol);
@@ -436,14 +419,13 @@ static void volume(double vol) {
}
static void linear_volume(double vol) {
- debug(1,"Setting linear volume for %f.",vol);
set_volume = vol;
double vol_setting = vol2attn(vol, 0, alsa_mix_mindb)/2000;
- debug(1,"Adjusted volume is %f.",vol_setting);
+ // debug(1,"Adjusted volume is %f.",vol_setting);
double linear_volume = pow(10, vol_setting);
- debug(1,"Linear volume is %f.",linear_volume);
+ // debug(1,"Linear volume is %f.",linear_volume);
long int_vol = alsa_mix_minv + (alsa_mix_maxv - alsa_mix_minv) * linear_volume;
- debug(1,"Setting volume to %ld, for volume input of %f.",int_vol,vol);
+ // debug(1,"Setting volume to %ld, for volume input of %f.",int_vol,vol);
if (snd_mixer_selem_set_playback_volume_all(alsa_mix_elem, int_vol) != 0)
die("Failed to set playback volume");
if (has_mute)
From 2a4f40495335f5acb3392685294bef8fd19665c5 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sat, 3 Oct 2015 21:33:10 +0100
Subject: [PATCH 08/39] Disable using linear mixer scale for the time being.
---
audio_alsa.c | 5 ++++-
player.c | 18 +++++++++++++-----
2 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/audio_alsa.c b/audio_alsa.c
index 7a3fe45e..e050e88a 100644
--- a/audio_alsa.c
+++ b/audio_alsa.c
@@ -236,7 +236,8 @@ static int init(int argc, char **argv) {
(1.0 * alsa_mix_maxdb) / 100.0);
} else {
// use the linear scale and do the db conversion ourselves
- debug(1, "note: the hardware mixer specified -- \"%s\" -- does not have dB volume -- using the [hopefully] linear settings.",alsa_mix_ctrl);
+ debug(1, "note: the hardware mixer specified -- \"%s\" -- does not have a dB volume scale, so it can't be used.",alsa_mix_ctrl);
+ /*
debug(1, "Min and max volumes are %d and %d.",alsa_mix_minv,alsa_mix_maxv);
alsa_mix_maxdb = 0;
if ((alsa_mix_maxv!=0) && (alsa_mix_minv!=0))
@@ -246,6 +247,7 @@ static int init(int argc, char **argv) {
audio_alsa.volume = &linear_volume; // insert the linear volume function
audio_alsa.parameters = ¶meters; // likewise the parameters stuff
debug(1,"Max and min dB calculated are %d and %d.",alsa_mix_maxdb,alsa_mix_mindb);
+ */
}
}
if (snd_mixer_selem_has_playback_switch(alsa_mix_elem)) {
@@ -409,6 +411,7 @@ static void parameters(audio_parameters *info) {
}
static void volume(double vol) {
+ // debug(1,"Volume called %f.",vol);
set_volume = vol;
double vol_setting = vol2attn(vol, alsa_mix_maxdb, alsa_mix_mindb);
// debug(1,"Setting volume db to %f, for volume input of %f.",vol_setting/100,vol);
diff --git a/player.c b/player.c
index b7224e5e..c28ad726 100644
--- a/player.c
+++ b/player.c
@@ -492,12 +492,12 @@ static abuf_t *buffer_get_frame(void) {
if (curframe->ready) {
if (ab_buffering) { // if we are getting packets but not yet forwarding them to the player
+ uint32_t reference_timestamp;
+ uint64_t reference_timestamp_time,remote_reference_timestamp_time;
+ get_reference_timestamp_stuff(&reference_timestamp, &reference_timestamp_time, &remote_reference_timestamp_time);
if (first_packet_timestamp == 0) { // if this is the very first packet
// debug(1,"First frame seen, time %u, with %d
// frames...",curframe->timestamp,seq_diff(ab_read, ab_write));
- uint32_t reference_timestamp;
- uint64_t reference_timestamp_time,remote_reference_timestamp_time;
- get_reference_timestamp_stuff(&reference_timestamp, &reference_timestamp_time, &remote_reference_timestamp_time);
if (reference_timestamp) { // if we have a reference time
// debug(1,"First frame seen with timestamp...");
first_packet_timestamp = curframe->timestamp; // we will keep buffering until we are
@@ -527,7 +527,6 @@ static abuf_t *buffer_get_frame(void) {
// -4410 frames.
int64_t delta = ((int64_t)first_packet_timestamp - (int64_t)reference_timestamp);
-
first_packet_time_to_play =
reference_timestamp_time +
((delta + (int64_t)config.latency + (int64_t)config.audio_backend_latency_offset)
@@ -544,6 +543,13 @@ static abuf_t *buffer_get_frame(void) {
}
if (first_packet_time_to_play != 0) {
+ // recalculate first_packet_time_to_play -- the latency might change
+ int64_t delta = ((int64_t)first_packet_timestamp - (int64_t)reference_timestamp);
+ first_packet_time_to_play =
+ reference_timestamp_time +
+ ((delta + (int64_t)config.latency + (int64_t)config.audio_backend_latency_offset)
+ << 32) /
+ 44100;
uint32_t filler_size = frame_size;
uint32_t max_dac_delay = 4410;
@@ -1210,12 +1216,13 @@ void player_volume(double f) {
// it back to a number.
double scaled_volume = vol2attn(f, 0, -9630);
- double linear_volume = pow(10, scaled_volume / 20*100);
+ double linear_volume = pow(10, scaled_volume / 2000);
if (f == -144.0)
linear_volume = 0.0;
if (config.output->volume) {
+ // debug(1,"Set volume to %f.",f);
config.output->volume(f); // volume will be sent as metadata by the config.output device
linear_volume = 1.0; // no attenuation needed -- this value is used as a flag to avoid calculations
}
@@ -1231,6 +1238,7 @@ void player_volume(double f) {
audio_information.is_muted = 0;
}
audio_information.valid = 1;
+ // debug(1,"Software volume set to %f on scale with a %f dB",f,linear_volume);
pthread_mutex_lock(&vol_mutex);
software_mixer_volume = linear_volume;
fix_volume = 65536.0 * software_mixer_volume;
From 94d3864ed8f50a1c10fcae9ba4a9b2396d3edd53 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sat, 3 Oct 2015 23:24:06 +0100
Subject: [PATCH 09/39] Add a boolean to stop the player asking for the DAC
delay before sending anything to it.
---
player.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/player.c b/player.c
index c28ad726..b98776b4 100644
--- a/player.c
+++ b/player.c
@@ -492,6 +492,7 @@ static abuf_t *buffer_get_frame(void) {
if (curframe->ready) {
if (ab_buffering) { // if we are getting packets but not yet forwarding them to the player
+ int have_sent_prefiller_silence; // set true when we have send some silent frames to the DAC
uint32_t reference_timestamp;
uint64_t reference_timestamp_time,remote_reference_timestamp_time;
get_reference_timestamp_stuff(&reference_timestamp, &reference_timestamp_time, &remote_reference_timestamp_time);
@@ -502,6 +503,7 @@ static abuf_t *buffer_get_frame(void) {
// debug(1,"First frame seen with timestamp...");
first_packet_timestamp = curframe->timestamp; // we will keep buffering until we are
// supposed to start playing this
+ have_sent_prefiller_silence = 0;
// Here, calculate when we should start playing. We need to know when to allow the
// packets to be sent to the player.
@@ -569,7 +571,7 @@ static abuf_t *buffer_get_frame(void) {
first_packet_time_to_play = 0;
time_since_play_started = 0;
} else {
- if (config.output->delay) {
+ if ((config.output->delay) && (have_sent_prefiller_silence != 0)) {
dac_delay = config.output->delay();
if (dac_delay == -1) {
debug(1, "Error getting dac_delay in buffer_get_frame.");
@@ -610,6 +612,7 @@ static abuf_t *buffer_get_frame(void) {
// with %d packets.",exact_frame_gap,fs,dac_delay,seq_diff(ab_read, ab_write));
config.output->play(silence, fs);
free(silence);
+ have_sent_prefiller_silence = 1;
if (ab_buffering == 0) {
uint64_t reference_timestamp_time; // don't need this...
get_reference_timestamp_stuff(&play_segment_reference_frame, &reference_timestamp_time, &play_segment_reference_frame_remote_time);
From 6fada5ff701e0e17802048a8fb3995d8796f27d0 Mon Sep 17 00:00:00 2001
From: Mke Brady
Date: Sun, 4 Oct 2015 21:56:12 +0100
Subject: [PATCH 10/39] Add GET_PARAMETER method and also a check for
unrecognised rtsp requests
---
rtsp.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/rtsp.c b/rtsp.c
index 4066a2db..e2eb53e9 100644
--- a/rtsp.c
+++ b/rtsp.c
@@ -1106,6 +1106,12 @@ static void handle_set_parameter_metadata(rtsp_conn_info *conn, rtsp_message *re
#endif
+static void handle_get_parameter(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) {
+ debug(1, "received GET_PARAMETER request.");
+ resp->respcode = 200;
+}
+
+
static void handle_set_parameter(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) {
// if (!req->contentlength)
// debug(1, "received empty SET_PARAMETER request.");
@@ -1247,7 +1253,7 @@ static struct method_handler {
{"FLUSH", handle_flush},
{"TEARDOWN", handle_teardown},
{"SETUP", handle_setup},
- {"GET_PARAMETER", handle_ignore},
+ {"GET_PARAMETER", handle_get_parameter},
{"SET_PARAMETER", handle_set_parameter},
{"RECORD", handle_record},
{NULL, NULL}};
@@ -1470,16 +1476,20 @@ static void *rtsp_conversation_thread_func(void *pconn) {
goto respond;
struct method_handler *mh;
+ int method_selected = 0;
for (mh = method_handlers; mh->method; mh++) {
if (!strcmp(mh->method, req->method)) {
//debug(1,"RTSP Packet received of type \"%s\":",mh->method),
//msg_print_debug_headers(req);
+ method_selected = 1;
mh->handler(conn, req, resp);
//debug(1,"RTSP Response:");
//msg_print_debug_headers(resp);
break;
}
}
+ if (method_selected==0)
+ debug(1,"Unrecognised and unhandled rtsp request \"%s\".",req->method);
respond:
msg_write_response(conn->fd, resp);
From 1377c707d0104fcb930c748c2e53cf98a0061b83 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Mon, 5 Oct 2015 10:04:03 +0100
Subject: [PATCH 11/39] Automatic latencies
---
RELEASENOTES.md | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 9a09e4ff..a45b9d56 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -1,12 +1,20 @@
-Version 2.5.0.6
+Version 2.5.0.7
----
**New Feature**
-* Use Negotiated Latencies. The AirPlay protocol used by Shairport Sync allows the audio source to specify the exact delay or latency that should be applied to the audio stream. Until now, Shairport Sync ignored this information and used fixed preset latencies that were selected on the basis of the "User-Agent" setting. Using negotiated latencies means that Shairport Sync should be able adapt automatically to a wider range of sources. To enable it, there is a new setting in the configuration file "use_negoriated_latencies". Set this to "yes" to enable this behaviour. If it works reliably, it will become the default.
+* Source-specified Latencies. The AirPlay protocol used by Shairport Sync allows the audio source to specify the exact delay or latency that should be applied to the audio stream. Until now, Shairport Sync ignored this information and used fixed preset latencies that were selected on the basis of the "User-Agent" setting. Using source-specified latencies means that Shairport Sync should be able adapt automatically to a wider range of sources.
+Using source-specified latencies is now automatic unless non-standard static latencies have been specified in the configuration file or command line. Using non-standard latencies is usually done to compensate for delays in the back end of the system. For example, if the audio amplifier being driven by Shairport Sync has an inherent delay of its own -- as happens with many home theatre and surround sound systems -- then some users have reduced the latencies used by Shairport Sync to compensate. This usage is discouraged -- the `audio_backend_latency_offset` in the appropriate backend stanza (e.g. in the "alsa" stanza) should be used for this. Static latency settings are now deprecated, and will be removed in a future version of Shairport Sync.
**Bug fixes**
* Fix in the `shairport.c`: the USE_CUSTOM_LOCAL_STATE_DIR macro was still being used when it should have been USE_CUSTOM_PID_DIR.
* Fix a crashing bug -- if metadata was enabled but a pipename was not supplied, boom.
+**Other Changes**
+* Volume ratios expressed in decibels are now consistently denominated in voltage decibels rather than power decibels. The rationale is that the levels refer to voltage levels, and power is proportional to the square of voltage.
+Thus a ratio of levels of 65535 to 1 is 96.3 dB rather than the 48.15 dB used before.
+* The latency figure returned to the source as part of the response to an rtsp request packet is 11,025, which may (?) be meant to indicate the minimum latency the device is capable of.
+* An experimental handler for a GET_PARAMETER rtsp request has been added. It does nothing except log the occurence.
+* The RTSP request dispatcher now logs an event whenever an unrecognised rtsp has been made.
+
Version 2.5.0.2
----
**Changes**
From be573dddc98e534f0a0c2453e1e45429f7810e10 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Mon, 5 Oct 2015 10:06:05 +0100
Subject: [PATCH 12/39] Update configure.ac
---
configure.ac | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index 9ac37f2e..b4febda9 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], [2.5.0.6], [mikebrady@eircom.net])
+AC_INIT([shairport-sync], [2.5.0.7], [mikebrady@eircom.net])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([shairport.c])
AC_CONFIG_HEADERS([config.h])
From 5152804738b321a69eab4c9d74bc72daf17cc713 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Mon, 5 Oct 2015 10:22:18 +0100
Subject: [PATCH 13/39] Update README.md
---
README.md | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/README.md b/README.md
index c3e40785..8d27ab6e 100644
--- a/README.md
+++ b/README.md
@@ -13,11 +13,11 @@ Shairport Sync works by using timing information and timestamps present in data
To maintain the exact latency required, if an output device is running slow relative to the source, Shairport Sync will delete frames of audio to allow the device to keep up. If the output device is running fast, Shairport Sync will insert frames to keep time. The number of frames inserted or deleted is so small as to be almost inaudible on normal audio material. Frames are inserted or deleted as necessary at pseudorandom intervals. Alternatively, with `libsoxr` support, Shairport Sync can resample the audio feed to ensure the output device can keep up. This is less obtrusive than insertion and deletion but requires a good deal of processing power — most embedded devices probably can't support it. The process of insertion/deletion or resampling is rather inelegantly called “stuffing”.
-There are four default latency settings, chosen automatically. One latency matches the latency used by recent versions of iTunes when playing audio and another matches the latency used by so-called "AirPlay" devices — iOS devices and iTunes and Quicktime Player when they are playing video. A third latency is used when the audio source is `forked-daapd`. The fourth latency is the default if no other latency is chosen and is used for older versions of iTunes.
+The exact latency to be used is specified by the source when it negotiates with Shaiport Sync. Most sources set a latency of 88,200 frames -- exactly two seconds. Recent versions of iTunes and forkedDaapd use a latency of 99,577 frames (pretty close to the 99,400 frames estimated from listening tests!).
Shairport Sync is a pretty 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 designed for Linux and ALSA. It must have direct access to the output device, which must be a real sound card capable of working with 44,100 samples per second interleaved PCM stereo (you'll get a message in the logfile if there's a problem).
+Shairport Sync is mainly designed for `alsa` and thus for Linux, though `alsa` has been ported to FreeBSD, so 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 samples per second interleaved PCM stereo (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.
@@ -27,13 +27,13 @@ What else?
* Hardware Mute — Shairport Sync will mute properly if the hardware supports it.
* Fast Response — With hardware volume control, response is instantaneous; otherwise the response time is 0.15 seconds.
* Non-Interruptible — Shairport Sync sends back a "busy" signal if it's already playing audio from another source, so other sources can't disrupt an existing Shairport Sync session. (If a source disappears without warning, the session automatically terminates after two minutes and the device becomes available again.)
-* Metadata — Shairport Sync can be configured to deliver metadata, such as Album Name, Artist Name, Cover Art, etc. through a pipe to a recipient application program — see https://github.com/mikebrady/shairport-sync-metadata-reader for a sample recipient.
+* Metadata — Shairport Sync can be configured to deliver metadata supplied by the source, such as Album Name, Artist Name, Cover Art, etc. through a pipe to a recipient application program — see https://github.com/mikebrady/shairport-sync-metadata-reader for a sample recipient. Sources that supply metadata include iTunes among others but the Music app in iOS 9 only supplies volume control metadata.
* Raw Audio — Shairport Sync can deliver raw PCM audio to standard output or to a pipe. This output is delivered synchronously with the source after the appropriate latency and is not interpolated or "stuffed" on its way through Shairport Sync.
* Autotools and Libtool Support — One important difference between Shairport Sync and other versions of Shairport is that the Shairport Sync build process uses GNU autotools and libtool to examine and configure the build environment — very important for cross compilation. Previous versions of Shairport looked at the current system to determine which packages were available, instead of looking at the target system for what packages were available.
Status
------
-Shairport Sync works on a wide variety of Linux devices. It works on standard Ubuntu laptops, on the Raspberry Pi with Raspbian, 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 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 runs well on the Raspberry Pi. It can drive the built-in sound card, though the audio out of the card is of poor quality. USB-connected sound cards work well on recent versions of Raspbian; however older versions of Raspbian appear to suffer from a problem — see http://www.raspberrypi.org/forums/viewtopic.php?t=23544, so it is wise to update. Shairport Sync works well with the IQAudIO Pi-DAC — see http://www.iqaudio.com.
@@ -41,7 +41,7 @@ At the time of writing, OpenWrt trunk does not support USB audio well on the Ras
Shairport Sync runs on Ubuntu, OpenWrt, Debian, Arch Linux and Fedora inside VMWare Fusion on a Mac, but synchronisation in inaccurate — possibly because the soundcard 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` 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.
@@ -310,13 +310,9 @@ alsa = {
Latency
-------
-Latency is the exact time from a sound signal's original timestamp until that signal actually "appears" on the output of the audio output device, usually a Digital to Audio Converter (DAC), irrespective of any internal delays, processing times, etc. in the computer. From listening tests, it seems that there are three latencies in current use:
-* If the source is iTunes 10 or later, a latency of 99,400 frames seems to bring Shairport Sync into exact synchronisation both with the speakers on the iTunes computer itself and with AirPort Express receivers.
-* If the source is an AirPlay device, the latency seems to be exactly 88,200 frames. AirPlay devices include AppleTV, iPod, iPad and iPhone and Quicktime Player on Mac.
-* If the source is a `forked-daapd`-powered device, the latency seems to be exactly 99,400 frames.
-* If the source cannot be identified as AirPlay or as iTunes 10 or later, then the default latency of 88,200 frames seems to work in general. Note that some third party programs masquerade as older versions of iTunes.
+Latency is the exact time from a sound signal's original timestamp until that signal actually "appears" on the output of the audio output device, usually a Digital to Audio Converter (DAC), irrespective of any internal delays, processing times, etc. in the computer.
-Shairport Sync uses the latencies described above as defaults. You shouldn't need to change them.
+Shairport Sync uses latencies suplied by the source, typically either 88,200 or 99,577 frames. You shouldn't need to change them. (The `latencies` stanza in the configuration file and the various latency command-line options are deprecated.)
Problems can arise when you are trying to synchronise with speaker systems — typically surround-sound home theatre systems — that have their own inherent delays. You can compensate for an inherent delay using the `alsa` group `audio_backend_latency_offset`. Set this offset (in frames) to compensate for a fixed delay in the audio back end, for example, if the output device delays by 100 ms, set this to -4410.
From f5cce61181825171a0bfc0a07857a505f6de45d1 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Mon, 5 Oct 2015 10:35:55 +0100
Subject: [PATCH 14/39] Update README.md
---
README.md | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/README.md b/README.md
index 8d27ab6e..e5c3a16d 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@ The exact latency to be used is specified by the source when it negotiates with
Shairport Sync is a pretty 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, though `alsa` has been ported to FreeBSD, so 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 samples per second interleaved PCM stereo (you'll get a message in the logfile if there's a problem).
+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 samples per second interleaved PCM stereo (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.
@@ -52,7 +52,7 @@ Building And Installing
If you wish to install Shairport Sync on OpenWrt, Arch or Fedora platforms, please follow the appropriate instructions below. Otherwise follow the General Build Instructions. Then, when the progam has been installed, refer to the section on Configuring Shairport Sync that follows.
**OpenWrt:**
-If you're interested in Shairport Sync for OpenWrt, there's an OpenWrt package at https://github.com/mikebrady/shairport-sync-for-openwrt. OpenWrt doesn't support the IQaudIO Pi-DAC.
+Thes is a Shairport Sync package in OpenWrt `trunk`. Also, there's an OpenWrt package at https://github.com/mikebrady/shairport-sync-for-openwrt, including one that builds back to `Attitude Adjustment`.
**Arch Linux:**
An Arch Linux installation package is available at [EliaCereda/shairport-sync-PKGBUILD](https://github.com/EliaCereda/shairport-sync-PKGBUILD).
@@ -156,7 +156,7 @@ use a specific sound card and mixer control, etc. — there are some examples in
*Man Page*
-You can view the man page here: http://htmlpreview.github.io/?https://github.com/mikebrady/shairport-sync/blob/master/man/shairport-sync.html
+You can view the man page here: http://htmlpreview.github.io/?https://github.com/mikebrady/shairport-sync/blob/development/man/shairport-sync.html
Configuring Shairport Sync
@@ -312,9 +312,9 @@ Latency
-------
Latency is the exact time from a sound signal's original timestamp until that signal actually "appears" on the output of the audio output device, usually a Digital to Audio Converter (DAC), irrespective of any internal delays, processing times, etc. in the computer.
-Shairport Sync uses latencies suplied by the source, typically either 88,200 or 99,577 frames. You shouldn't need to change them. (The `latencies` stanza in the configuration file and the various latency command-line options are deprecated.)
+Shairport Sync uses latencies supplied by the source, typically either 88,200 or 99,577 frames. You shouldn't need to change them. (The `latencies` stanza in the configuration file and the various latency command-line options are deprecated.)
-Problems can arise when you are trying to synchronise with speaker systems — typically surround-sound home theatre systems — that have their own inherent delays. You can compensate for an inherent delay using the `alsa` group `audio_backend_latency_offset`. Set this offset (in frames) to compensate for a fixed delay in the audio back end, for example, if the output device delays by 100 ms, set this to -4410.
+Problems can arise when you are trying to synchronise with speaker systems — typically surround-sound home theatre systems — that have their own inherent delays. You can compensate for an inherent delay using the appropriate backend (typically `alsa`) `audio_backend_latency_offset`. Set this offset (in frames) to compensate for a fixed delay in the audio back end, for example, if the output device delays by 100 ms, set this to -4410.
Resynchronisation
-------------
@@ -324,7 +324,7 @@ If synchronisation is lost — say due to a busy source or a congested network
Tolerance
---------
-Playback synchronisation is allowed to wander a small amount before attempting to correct it. The default is 88 frames, i.e. 2 ms. The smaller the tolerance, the more likely it is that overcorrection will occur. Overcorrection is when more corrections (insertions and deletions) are made than are strictly necessary to keep the stream in sync. Use the statistics setting to monitor correction levels. Corrections should not greatly exceed net corrections.
+Playback synchronisation is allowed to wander, or to "drift") a small amount before attempting to correct it. The default is 88 frames, i.e. 2 ms. The smaller the tolerance, the more likely it is that overcorrection will occur. Overcorrection is when more corrections (insertions and deletions) are made than are strictly necessary to keep the stream in sync. Use the statistics setting to monitor correction levels. Corrections should not greatly exceed net corrections.
* You can vary the tolerance with the `general` `drift` setting.
Some Statistics
@@ -333,7 +333,7 @@ If you turn on the `general` `statistics` setting, statistics like this will be
`Sync error: -35.4 (frames); net correction: 24.2 (ppm); corrections: 24.2 (ppm); missing packets 0; late packets 5; too late packets 0; resend requests 6; min DAC queue size 4430.`
-"Sync error" is the average deviation from exact synchronisation. The example above indicates that the output is on average 35.4 frames ahead of exact synchronisation. Sync is allowed to wander by the tolerance — 88 frames (± 2 milliseconds) by default — before a correction will be made.
+"Sync error" is the average deviation from exact synchronisation. The example above indicates that the output is on average 35.4 frames ahead of exact synchronisation. Sync is allowed to drift by the `general` `drift` setting — 88 frames (± 2 milliseconds) by default — before a correction will be made.
"Net correction" is actually the net sum of corrections — the number of frame insertions less the number of frame deletions — given as a moving average in parts per million. After an initial settling period, it represents the drift — the divergence between the rate at which frames are generated at the source and the rate at which the output device consumes them. The example above indicates that the output device is consuming frames 24.2 ppm faster than the source is generating them.
@@ -341,6 +341,6 @@ If you turn on the `general` `statistics` setting, statistics like this will be
For reference, a drift of one second per day is approximately 11.57 ppm. Left uncorrected, even a drift this small between two audio outputs will be audible after a short time. The above sample is from a second-generation iPod driving the Raspberry Pi which is connected over Ethernet.
-It's not unusual to have resend requests, late packets and even missing packets if some part of the connection to the Shairport Sync device is over WiFi. Sometimes late packets can be asked for and received multiple times. Sometimes late packets are sent and arrive too late, but have already been sent and received in time, so weren't needed anyway...
+It's not unusual to have resend requests, late packets and even missing packets if some part of the connection to the Shairport Sync device is over WiFi. Late packets can sometimes be asked for and received multiple times. Sometimes late packets are sent and arrive too late, but have already been sent and received in time, so weren't needed anyway...
"Min DAC queue size" is the minimum size the queue of samples in the output device's hardware buffer was measured at. It is meant to stand at 0.15 seconds = 6,615 samples, and will go low if the processor is very busy. If it goes below about 2,000 then it's a sign that the processor can't really keep up.
From b7d048644240b79a1c4e80a6dce96f416fffc338 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Tue, 6 Oct 2015 09:04:14 +0100
Subject: [PATCH 15/39] Update README.md
---
README.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/README.md b/README.md
index e5c3a16d..ab830bce 100644
--- a/README.md
+++ b/README.md
@@ -112,6 +112,10 @@ Download Shairport Sync:
`git clone https://github.com/mikebrady/shairport-sync.git`
+Select the `development` branch:
+
+`git checkout development`
+
Next, `cd` into the shairport-sync directory and execute the following commands:
```
From ac24794121397b440b904c81ccda87b6537bebbf Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Tue, 6 Oct 2015 09:28:20 +0100
Subject: [PATCH 16/39] Update README.md
---
README.md | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index ab830bce..1bd67632 100644
--- a/README.md
+++ b/README.md
@@ -137,11 +137,35 @@ Choose the appropriate `--with-*` options:
- `--with-configfile` to install a configuration file and a separate sample file at the `make install` stage. Default is to install. An existing `/etc/shairport-sync.conf` will not be overwritten.
- `--with-pkg-config` to use pkg-config to find libraries. Default is to use pkg-config — this option is for special purpose use.
+**System V and `systemd`**
+
+At the time of writing, there are two general systems for automatically starting programs automatically at startup: "System V" or `systemd`. To see if the `systemd` process is running on your system, enter the following command:
+
+`ps aux | grep systemd | grep -v grep`
+
+On a system using `systemd` (this is a Raspberry Pi running Raspbian Jessie) you'll get many lines containing `systemd`, for example:
+```
+pi@raspberrypi ~ $ ps aux | grep systemd | grep -v grep
+root 90 0.1 0.6 8088 2764 ? Ss 08:00 0:01 /lib/systemd/systemd-journald
+root 93 0.0 0.6 11816 3004 ? Ss 08:00 0:00 /lib/systemd/systemd-udevd
+root 502 0.0 0.5 3824 2436 ? Ss 08:00 0:00 /lib/systemd/systemd-logind
+message+ 528 0.0 0.7 5568 3172 ? Ss 08:00 0:01 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
+pi 983 0.0 0.7 4912 3256 ? Ss 08:00 0:00 /lib/systemd/systemd --user
+pi@raspberrypi ~ $
+```
+whereas on a system without `systemd` -- presumably using System V -- (this is a Raspberry Pi running Raspbian Wheezy) , you'll get nothing:
+```
+pi@raspberrypi ~ $ ps aux | grep systemd | grep -v grep
+pi@raspberrypi ~ $
+```
+Choose `--with-systemd` or `--with-systemv` on the basis of the outcome.
+
Here is an example, suitable for installations such as Ubuntu and Raspbian:
`$ ./configure --with-alsa --with-avahi --with-ssl=openssl --with-metadata --with-soxr --with-systemv`
-Omit the `--with-soxr` if the libsoxr library is not available. For installation into a `systemd` system, replace the `--with-systemv` with `--with-systemd`.
+* Omit the `--with-soxr` if the libsoxr library is not available.
+* For installation into a `systemd` system, replace the `--with-systemv` with `--with-systemd`.
Enter:
From 274ef1a629aa71ef24fd100ee19ddb6f847ca35a Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Tue, 6 Oct 2015 09:55:45 +0100
Subject: [PATCH 17/39] Update LIBSOXR.md
---
LIBSOXR.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/LIBSOXR.md b/LIBSOXR.md
index 20c40b9f..80a67987 100644
--- a/LIBSOXR.md
+++ b/LIBSOXR.md
@@ -14,7 +14,7 @@ git clone git://git.code.sf.net/p/soxr/code libsoxr
cd libsoxr
./go
```
-Be patient! This takes a long time on a Raspberry Pi -- it looks like it gets stuck at 47%, but it will finish if you let it.
+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:
```
From 0ad7d7962fde92c69d74e0ceccc9bc1e0e328794 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Tue, 6 Oct 2015 10:36:07 +0100
Subject: [PATCH 18/39] =?UTF-8?q?Edit=20for=20a=20system=20installation=20?=
=?UTF-8?q?=E2=80=93=20unfinished?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 43 ++++++++++++++++++++++++++++++++-----------
1 file changed, 32 insertions(+), 11 deletions(-)
diff --git a/README.md b/README.md
index 1bd67632..5e67dda5 100644
--- a/README.md
+++ b/README.md
@@ -106,19 +106,16 @@ Assuming the usual build essentials and git, Debian, Ubuntu and Raspbian users c
- `apt-get install avahi-daemon libavahi-client-dev` if you want to use Avahi (recommended).
- `apt-get install libssl-dev` if you want to use OpenSSL and libcrypto, or use PolarSSL otherwise.
- `apt-get install libpolarssl-dev` if you want to use PolarSSL, or use OpenSSL/libcrypto otherwise.
-- `apt-get install libsoxr-dev` if you want support for libsoxr-based resampling. This library is not yet part of Raspbian; instructions for how to build it from source are available at [LIBSOXR.md](https://github.com/mikebrady/shairport-sync/blob/2.3/LIBSOXR.md).
+- `apt-get install libsoxr-dev` if you want support for libsoxr-based resampling. This library is not yet part of Raspbian; instructions for how to build it from source are available at [LIBSOXR.md](https://github.com/mikebrady/shairport-sync/blob/development/LIBSOXR.md).
Download Shairport Sync:
`git clone https://github.com/mikebrady/shairport-sync.git`
-Select the `development` branch:
-
-`git checkout development`
-
Next, `cd` into the shairport-sync directory and execute the following commands:
```
+$ git checkout development #select the development branch
$ autoreconf -i -f
```
@@ -171,22 +168,46 @@ Enter:
`$ make`
-to build the application. Next, run:
+to build the application.
+
+**Installation to a System V system**
+If you are installing onto a System V system:
```
$sudo make install
-$sudo update-rc.d shairport-sync defaults 90 10
```
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.
-The settings are the most basic defaults, so you will want to edit the configuration — the file is `/etc/shairport-sync.conf` — to give the service a name,
-use a specific sound card and mixer control, etc. — there are some examples in the sample configuration file.
-*Man Page*
+To complete the installation, enter:
+```
+$sudo update-rc.d shairport-sync defaults 90 10
+```
+
+**Installation 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 priviliges. 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:
+
+```
+$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
+```
+
+Next, enter:
+
+```
+$sudo make install
+```
+
+to install `shairport-sync` along with a `man` page, a default configuration file and some `systemd` startup configuration files to launch it automatically at system startup.
+
+To enable Shairport Sync to start automatically at system startup, enter:
+
+`$sudo systemctl enable shairport-sync`
+
+**Man Page**
You can view the man page here: http://htmlpreview.github.io/?https://github.com/mikebrady/shairport-sync/blob/development/man/shairport-sync.html
-
Configuring Shairport Sync
--------
There are two logically distinct parts to getting Shairport Sync to run properly on your machine — (1) starting and stopping it and (2) ensuring it has the right settings.
From a89da7fded202a36bdaaa5e2008d4ec5246a6500 Mon Sep 17 00:00:00 2001
From: Mke Brady
Date: Tue, 6 Oct 2015 13:39:05 +0100
Subject: [PATCH 19/39] Fix a bug whereby it would not start to play the stream
-- visible when used as system sound. Improperly initialised
first_packet_timestamp
---
configure.ac | 2 +-
player.c | 1 +
rtsp.c | 2 +-
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac
index b4febda9..f6f0f70f 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], [2.5.0.7], [mikebrady@eircom.net])
+AC_INIT([shairport-sync], [2.5.0.8], [mikebrady@eircom.net])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([shairport.c])
AC_CONFIG_HEADERS([config.h])
diff --git a/player.c b/player.c
index b98776b4..557eb52a 100644
--- a/player.c
+++ b/player.c
@@ -911,6 +911,7 @@ static void *player_thread_func(void *arg) {
silence = malloc(OUTFRAME_BYTES(frame_size));
memset(silence, 0, OUTFRAME_BYTES(frame_size));
late_packet_message_sent = 0;
+ first_packet_timestamp = 0;
missing_packets = late_packets = too_late_packets = resend_requests = 0;
flush_rtp_timestamp = 0; // it seems this number has a special significance -- it seems to be used
// as a null operand, so we'll use it like that too
diff --git a/rtsp.c b/rtsp.c
index e2eb53e9..c03bb72f 100644
--- a/rtsp.c
+++ b/rtsp.c
@@ -722,7 +722,7 @@ static void handle_setup(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *
if (config.latency==-1) {
// this means that no static latency was set, so we'll allow it to be set dynamically
- config.latency=88200; // to be sure, to be sure
+ config.latency=88198; // to be sure, to be sure -- make it slighty different from the default to ensure we get a debug message when set to 88200
config.use_negotiated_latencies = 1;
}
char *hdr = msg_get_header(req, "Transport");
From c566c6860e6fd894d8262be4c295a983268e97cc Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Tue, 6 Oct 2015 13:43:36 +0100
Subject: [PATCH 20/39] Update RELEASENOTES.md
---
RELEASENOTES.md | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index a45b9d56..a0dc9ae8 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -1,3 +1,8 @@
+Version 2.5.0.8
+----
+**Bug fix**
+* Sometimes, especially when using Shairport Sync as a system output, it would not play the audio stream. This was caused by an improperly initialised variable. Fixed.
+
Version 2.5.0.7
----
**New Feature**
From ddd76b10af0a21e5c0d08d3101538adcb418551c Mon Sep 17 00:00:00 2001
From: Mke Brady
Date: Wed, 7 Oct 2015 08:40:10 +0100
Subject: [PATCH 21/39] Add, untested, stuff to capture and remember a
volume_range_db setting.
---
common.h | 1 +
configure.ac | 2 +-
scripts/shairport-sync.conf | 1 +
scripts/shairport-sync.conf~ | 81 ++++++++++++++++++++++++++++++++++++
shairport.c | 13 +++++-
5 files changed, 95 insertions(+), 3 deletions(-)
create mode 100644 scripts/shairport-sync.conf~
diff --git a/common.h b/common.h
index 0f51a4b3..ef3f84b3 100644
--- a/common.h
+++ b/common.h
@@ -81,6 +81,7 @@ typedef struct {
int32_t audio_backend_buffer_desired_length; // this will be the desired number of frames in the
// audio backend buffer -- the DAC buffer for ALSA
int32_t audio_backend_latency_offset; // this will be the offset to compensate for any fixed latency
+ uint32_t volume_range_db; // the range, in dB, from max dB to min dB. Zero means use the mixer's native range.
// there might be in the audio
} shairport_cfg;
diff --git a/configure.ac b/configure.ac
index f6f0f70f..6b15fef9 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], [2.5.0.8], [mikebrady@eircom.net])
+AC_INIT([shairport-sync], [2.5.0.9], [mikebrady@eircom.net])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([shairport.c])
AC_CONFIG_HEADERS([config.h])
diff --git a/scripts/shairport-sync.conf b/scripts/shairport-sync.conf
index 8a4dbf72..0a9be12a 100644
--- a/scripts/shairport-sync.conf
+++ b/scripts/shairport-sync.conf
@@ -17,6 +17,7 @@ general =
// resync_threshold = 2205; // a synchronisation error greater than this will cause resynchronisation; 0 disables it
// log_verbosity = 0; // "0" means no debug verbosity, "3" is most verbose.
// ignore_volume_control = "no"; // set this to "yes" if you want the volume to be at 100% no matter what the source's volume control is set to.
+// volume_range_db = 0; // set this to the range, in dB, you want between the maximum volume and the minimum volume. Zero means use the mixer's native range. Default is 0.
};
// How to deal with metadata, including artwork
diff --git a/scripts/shairport-sync.conf~ b/scripts/shairport-sync.conf~
new file mode 100644
index 00000000..8a4dbf72
--- /dev/null
+++ b/scripts/shairport-sync.conf~
@@ -0,0 +1,81 @@
+// Sample Configuration File for Shairport Sync
+// Commented out settings are generally the defaults, except where noted.
+
+// General Settings
+general =
+{
+// name = "Shairport Sync Player"; // This is the name the service will advertise to iTunes. The default is "Shairport Sync on "
+// password = "secret"; // comment out this line if you want to have no password
+// interpolation = "basic"; // aka "stuffing". Default is "basic", alternative is "soxr". Use "soxr" only if you have a reasonably fast processor.
+// output_backend = "alsa"; // Run "shairport-sync -h" to get a list of all output_backends, e.g. "alsa", "pipe", "stdout". The default is the first one.
+// 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).
+// statistics = "no"; // set to "yes" to print statistics in the log
+// drift = 88; // allow this number of frames of drift away from exact synchronisation before attempting to correct it
+// resync_threshold = 2205; // a synchronisation error greater than this will cause resynchronisation; 0 disables it
+// log_verbosity = 0; // "0" means no debug verbosity, "3" is most verbose.
+// ignore_volume_control = "no"; // set this to "yes" if you want the volume to be at 100% no matter what the source's volume control is set to.
+};
+
+// How to deal with metadata, including artwork
+metadata =
+{
+// enabled = "no"; // et to yes to get Shairport Sync to solicit metadata from the source and to pass it on via a pipe
+// include_cover_art = "no"; // set to "yes" to get Shairport Sync to solicit cover art from the source and pass it via the pipe. You must also set "enabled" to "yes".
+// pipe_name = "/tmp/shairport-sync-metadata";
+};
+
+// Advanced parameters for controlling how a Shairport Sync runs
+sessioncontrol =
+{
+// run_this_before_play_begins = "/full/path/to/application and args"; // make sure the application has executable permission. It it's a script, include the #!... stuff on the first line
+// run_this_after_play_ends = "/full/path/to/application and args"; // make sure the application has executable permission. It it's a script, include the #!... stuff on the first line
+// wait_for_completion = "no"; // set to "yes" to get Shairport Sync to wait until the "run_this..." applications have terminated before continuing
+// allow_session_interruption = "no"; // set to "yes" to allow another device to interrupt Shairport Sync while it's playing from an existing audio source
+// session_timeout = 120; // wait for this number of seconds after a source disappears before terminating the session and becoming available again.
+};
+
+//
+// Back End Settings
+//
+
+// These are parameters for the "alsa" audio back end, the only back end that supports synchronised audio.
+alsa =
+{
+// output_device = "default"; // the name of the alsa output device. Use "alsamixer" or "aplay" to find out the names of devices, mixers, etc.
+// mixer_control_name = "PCM"; // the name of the mixer to use to adjust output volume. If not specified, volume in adjusted in software.
+// mixer_device = "default"; // the mixer_device default is whatever the output_device is. Normally you wouldn't have to use this.
+// audio_backend_latency_offset = 0; // Set this offset to compensate for a fixed delay in the audio back end. E.g. if the output device delays by 100 ms, set this to -4410.
+// audio_backend_buffer_desired_length = 6615; // If set too small, buffer underflow occurs on low-powered machines. Too long and the response times with software mixer become annoying.
+};
+
+// 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.
+pipe =
+{
+// name = "/path/to/pipe"; // there is no default pipe name for the output
+// audio_backend_latency_offset = 0; // Set this offset to compensate for a fixed delay in the audio back end. E.g. if the output device delays by 100 ms, set this to -4410.
+// audio_backend_buffer_desired_length = 44100; // Having started to send audio at the right time, send all subsequent audio this many frames ahead of time, creating a buffer this size.
+};
+
+// These are parameters for the "stdout" audio back end, a back end that directs raw CD-style audio output to stdout. No interpolation is done.
+stdout =
+{
+// audio_backend_latency_offset = 0; // Set this offset to compensate for a fixed delay in the audio back end. E.g. if the output device delays by 100 ms, set this to -4410.
+// audio_backend_buffer_desired_length = 44100; // Having started to send audio at the right time, send all subsequent audio this many frames ahead of time, creating a buffer this size.
+};
+
+// The following static latency settings are deprecated -- do not use them for new installations. Shairport Sync now sets latencies automatically.
+// To compensate for a delay in the output device using the alsa/stdio/pipe "audio_backend_latency_offset" setting.
+
+// Static latencies for different sources. These have been estimated from listening tests.
+latencies =
+{
+// default = 88200; // used for unrecognised sources and for iTunes up to and including iTunes 9.X.
+// itunes = 99400; // used for iTunes 10 or later
+// airplay = 88200;
+// forkedDaapd = 99400;
+};
+
+
diff --git a/shairport.c b/shairport.c
index beb8d21b..a17fa86b 100644
--- a/shairport.c
+++ b/shairport.c
@@ -399,7 +399,16 @@ int parse_options(int argc, char **argv) {
die("Invalid ignore_volume_control option choice \"%s\". It should be \"yes\" or \"no\"");
}
- /* Get the default latency. Deprecated! */
+ /* Get the volume range, in dB, that should be used If not set, it means you just use the range set by the mixer. */
+ if (config_lookup_int(config.cfg, "general.volume_range", &value)) {
+ if ((value < 0) || (value > 200))
+ die("Invalid volume range \"%sd\". It should be between 0 and 200. Zero means use the mixer's native range",
+ value);
+ else
+ config.volume_range_db = value;
+ }
+
+/* Get the default latency. Deprecated! */
if (config_lookup_int(config.cfg, "latencies.default", &value))
config.userSuppliedLatency = value;
@@ -893,7 +902,7 @@ int main(int argc, char **argv) {
debug(2, "audio backend desired buffer length is %d.",
config.audio_backend_buffer_desired_length);
debug(2, "audio backend latency offset is %d.", config.audio_backend_latency_offset);
- debug(2, "use_negotiated_latencies %d.", config.use_negotiated_latencies);
+ debug(2, "volume range in dB (zero means use the range specified by the mixer): %u.", config.volume_range_db);
char *realConfigPath = realpath(config.configfile,NULL);
if (realConfigPath) {
From 97a83c810a0b09f94272b9c1bee8bf904138a2f9 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Wed, 7 Oct 2015 14:31:20 +0100
Subject: [PATCH 22/39] Delete shairport-sync.conf~
Included by mhistake!
---
scripts/shairport-sync.conf~ | 81 ------------------------------------
1 file changed, 81 deletions(-)
delete mode 100644 scripts/shairport-sync.conf~
diff --git a/scripts/shairport-sync.conf~ b/scripts/shairport-sync.conf~
deleted file mode 100644
index 8a4dbf72..00000000
--- a/scripts/shairport-sync.conf~
+++ /dev/null
@@ -1,81 +0,0 @@
-// Sample Configuration File for Shairport Sync
-// Commented out settings are generally the defaults, except where noted.
-
-// General Settings
-general =
-{
-// name = "Shairport Sync Player"; // This is the name the service will advertise to iTunes. The default is "Shairport Sync on "
-// password = "secret"; // comment out this line if you want to have no password
-// interpolation = "basic"; // aka "stuffing". Default is "basic", alternative is "soxr". Use "soxr" only if you have a reasonably fast processor.
-// output_backend = "alsa"; // Run "shairport-sync -h" to get a list of all output_backends, e.g. "alsa", "pipe", "stdout". The default is the first one.
-// 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).
-// statistics = "no"; // set to "yes" to print statistics in the log
-// drift = 88; // allow this number of frames of drift away from exact synchronisation before attempting to correct it
-// resync_threshold = 2205; // a synchronisation error greater than this will cause resynchronisation; 0 disables it
-// log_verbosity = 0; // "0" means no debug verbosity, "3" is most verbose.
-// ignore_volume_control = "no"; // set this to "yes" if you want the volume to be at 100% no matter what the source's volume control is set to.
-};
-
-// How to deal with metadata, including artwork
-metadata =
-{
-// enabled = "no"; // et to yes to get Shairport Sync to solicit metadata from the source and to pass it on via a pipe
-// include_cover_art = "no"; // set to "yes" to get Shairport Sync to solicit cover art from the source and pass it via the pipe. You must also set "enabled" to "yes".
-// pipe_name = "/tmp/shairport-sync-metadata";
-};
-
-// Advanced parameters for controlling how a Shairport Sync runs
-sessioncontrol =
-{
-// run_this_before_play_begins = "/full/path/to/application and args"; // make sure the application has executable permission. It it's a script, include the #!... stuff on the first line
-// run_this_after_play_ends = "/full/path/to/application and args"; // make sure the application has executable permission. It it's a script, include the #!... stuff on the first line
-// wait_for_completion = "no"; // set to "yes" to get Shairport Sync to wait until the "run_this..." applications have terminated before continuing
-// allow_session_interruption = "no"; // set to "yes" to allow another device to interrupt Shairport Sync while it's playing from an existing audio source
-// session_timeout = 120; // wait for this number of seconds after a source disappears before terminating the session and becoming available again.
-};
-
-//
-// Back End Settings
-//
-
-// These are parameters for the "alsa" audio back end, the only back end that supports synchronised audio.
-alsa =
-{
-// output_device = "default"; // the name of the alsa output device. Use "alsamixer" or "aplay" to find out the names of devices, mixers, etc.
-// mixer_control_name = "PCM"; // the name of the mixer to use to adjust output volume. If not specified, volume in adjusted in software.
-// mixer_device = "default"; // the mixer_device default is whatever the output_device is. Normally you wouldn't have to use this.
-// audio_backend_latency_offset = 0; // Set this offset to compensate for a fixed delay in the audio back end. E.g. if the output device delays by 100 ms, set this to -4410.
-// audio_backend_buffer_desired_length = 6615; // If set too small, buffer underflow occurs on low-powered machines. Too long and the response times with software mixer become annoying.
-};
-
-// 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.
-pipe =
-{
-// name = "/path/to/pipe"; // there is no default pipe name for the output
-// audio_backend_latency_offset = 0; // Set this offset to compensate for a fixed delay in the audio back end. E.g. if the output device delays by 100 ms, set this to -4410.
-// audio_backend_buffer_desired_length = 44100; // Having started to send audio at the right time, send all subsequent audio this many frames ahead of time, creating a buffer this size.
-};
-
-// These are parameters for the "stdout" audio back end, a back end that directs raw CD-style audio output to stdout. No interpolation is done.
-stdout =
-{
-// audio_backend_latency_offset = 0; // Set this offset to compensate for a fixed delay in the audio back end. E.g. if the output device delays by 100 ms, set this to -4410.
-// audio_backend_buffer_desired_length = 44100; // Having started to send audio at the right time, send all subsequent audio this many frames ahead of time, creating a buffer this size.
-};
-
-// The following static latency settings are deprecated -- do not use them for new installations. Shairport Sync now sets latencies automatically.
-// To compensate for a delay in the output device using the alsa/stdio/pipe "audio_backend_latency_offset" setting.
-
-// Static latencies for different sources. These have been estimated from listening tests.
-latencies =
-{
-// default = 88200; // used for unrecognised sources and for iTunes up to and including iTunes 9.X.
-// itunes = 99400; // used for iTunes 10 or later
-// airplay = 88200;
-// forkedDaapd = 99400;
-};
-
-
From ea250113941d4ea80bd2e93e95feb68b03e5717a Mon Sep 17 00:00:00 2001
From: Mke Brady
Date: Wed, 7 Oct 2015 22:33:20 +0100
Subject: [PATCH 23/39] Functional volume_range_db setting in the general
stanza
---
audio_alsa.c | 7 +++++++
player.c | 19 +++++++++++++------
scripts/shairport-sync.conf | 2 +-
shairport.c | 6 +++---
4 files changed, 24 insertions(+), 10 deletions(-)
diff --git a/audio_alsa.c b/audio_alsa.c
index e050e88a..3cfacea1 100644
--- a/audio_alsa.c
+++ b/audio_alsa.c
@@ -234,6 +234,13 @@ static int init(int argc, char **argv) {
}
debug(1, "Hardware mixer has dB volume from %f to %f.", (1.0 * alsa_mix_mindb) / 100.0,
(1.0 * alsa_mix_maxdb) / 100.0);
+ if (config.volume_range_db) {
+ long suggested_alsa_min_db = alsa_mix_maxdb - (long)trunc(config.volume_range_db*100);
+ if (suggested_alsa_min_db > alsa_mix_mindb)
+ alsa_mix_mindb = suggested_alsa_min_db;
+ else
+ inform("The volume_range_db setting, %f is greater than the native range of the mixer %f, so it is ignored.",config.volume_range_db,(alsa_mix_maxdb-alsa_mix_mindb)/100.0);
+ }
} else {
// use the linear scale and do the db conversion ourselves
debug(1, "note: the hardware mixer specified -- \"%s\" -- does not have a dB volume scale, so it can't be used.",alsa_mix_ctrl);
diff --git a/player.c b/player.c
index 557eb52a..52a93f5f 100644
--- a/player.c
+++ b/player.c
@@ -1219,11 +1219,7 @@ void player_volume(double f) {
// Thus, we ask our vol2attn function for an appropriate dB between -96.3 and 0 dB and translate
// it back to a number.
- double scaled_volume = vol2attn(f, 0, -9630);
- double linear_volume = pow(10, scaled_volume / 2000);
-
- if (f == -144.0)
- linear_volume = 0.0;
+ double linear_volume = 0.0;
if (config.output->volume) {
// debug(1,"Set volume to %f.",f);
@@ -1234,12 +1230,23 @@ void player_volume(double f) {
if (config.output->parameters)
config.output->parameters(&audio_information);
else {
+ long mindb = -9630;
+ if (config.volume_range_db) {
+ long suggested_alsa_min_db = -(long)trunc(config.volume_range_db*100);
+ if (suggested_alsa_min_db > mindb)
+ mindb = suggested_alsa_min_db;
+ else
+ inform("The volume_range_db setting, %f is greater than the native range of the mixer %f, so it is ignored.",config.volume_range_db,mindb/100.0);
+ }
+ double scaled_volume = vol2attn(f, 0, mindb);
+ linear_volume = pow(10, scaled_volume / 2000);
audio_information.airplay_volume = f;
- audio_information.minimum_volume_dB = -9630;
+ audio_information.minimum_volume_dB = mindb;
audio_information.maximum_volume_dB = 0;
audio_information.current_volume_dB = scaled_volume;
audio_information.has_true_mute = 0;
audio_information.is_muted = 0;
+ // debug(1,"Minimum software volume set to %d centi-dB",f,mindb);
}
audio_information.valid = 1;
// debug(1,"Software volume set to %f on scale with a %f dB",f,linear_volume);
diff --git a/scripts/shairport-sync.conf b/scripts/shairport-sync.conf
index 0a9be12a..28eca89e 100644
--- a/scripts/shairport-sync.conf
+++ b/scripts/shairport-sync.conf
@@ -17,7 +17,7 @@ general =
// resync_threshold = 2205; // a synchronisation error greater than this will cause resynchronisation; 0 disables it
// log_verbosity = 0; // "0" means no debug verbosity, "3" is most verbose.
// ignore_volume_control = "no"; // set this to "yes" if you want the volume to be at 100% no matter what the source's volume control is set to.
-// volume_range_db = 0; // set this to the range, in dB, you want between the maximum volume and the minimum volume. Zero means use the mixer's native range. Default is 0.
+// volume_range_db = 60 ; // use this to set the range, in dB, you want between the maximum volume and the minimum volume. Range is 30 to 150 dB. Omit to use mixer's native range.
};
// How to deal with metadata, including artwork
diff --git a/shairport.c b/shairport.c
index a17fa86b..91f2fb85 100644
--- a/shairport.c
+++ b/shairport.c
@@ -400,9 +400,9 @@ int parse_options(int argc, char **argv) {
}
/* Get the volume range, in dB, that should be used If not set, it means you just use the range set by the mixer. */
- if (config_lookup_int(config.cfg, "general.volume_range", &value)) {
- if ((value < 0) || (value > 200))
- die("Invalid volume range \"%sd\". It should be between 0 and 200. Zero means use the mixer's native range",
+ if (config_lookup_int(config.cfg, "general.volume_range_db", &value)) {
+ if ((value < 30) || (value > 150))
+ die("Invalid volume range \"%sd\". It should be between 30 and 150 dB. Zero means use the mixer's native range",
value);
else
config.volume_range_db = value;
From b3c2d97be75e7603caec4eb71214f0c464ba7865 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Fri, 9 Oct 2015 13:39:11 +0100
Subject: [PATCH 24/39] Update RELEASENOTES.md
---
RELEASENOTES.md | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index a0dc9ae8..9ae73eb4 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -1,3 +1,8 @@
+Version 2.5.0.9
+----
+**New Feature**
+* Set Volume Range. This is a new setting that allows you to use just a portion of the full range of attenuation offered by a mixer. For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available. This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting. Or it might be because the range specified by the mixer does not match the capabilities of the device. For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB. The new `general` setting `volume_range_db` allows you to specify the maximum range from highest to lowest. Many domestic Hi Fi systems have a range of 60 to 80 dB. The range suggested for the Raspberry Pi's built-in audio DAC, whcih feeds the headphone jack, is 35. Using it in this case gives the volume control a much more useful range of volumes.
+
Version 2.5.0.8
----
**Bug fix**
From df99489b185ee406da83a093d7d9b606aba77750 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Fri, 9 Oct 2015 13:40:13 +0100
Subject: [PATCH 25/39] Update RELEASENOTES.md
---
RELEASENOTES.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 9ae73eb4..4f9336b3 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -1,7 +1,7 @@
Version 2.5.0.9
----
**New Feature**
-* Set Volume Range. This is a new setting that allows you to use just a portion of the full range of attenuation offered by a mixer. For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available. This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting. Or it might be because the range specified by the mixer does not match the capabilities of the device. For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB. The new `general` setting `volume_range_db` allows you to specify the maximum range from highest to lowest. Many domestic Hi Fi systems have a range of 60 to 80 dB. The range suggested for the Raspberry Pi's built-in audio DAC, whcih feeds the headphone jack, is 35. Using it in this case gives the volume control a much more useful range of volumes.
+* Set Volume Range. This is a new setting that allows you to use just a portion of the full range of attenuation offered by a mixer. For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available. This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting. Or it might be because the range specified by the mixer does not match the capabilities of the device. For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB. The new `general` setting `volume_range_db` allows you to specify the maximum range from highest to lowest. Many domestic Hi Fi systems have a range of 60 to 80 dB. The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 35. Using it in this case gives the volume control a much more useful range of volumes.
Version 2.5.0.8
----
From 71ccee32fd5fb81214d705a9f31f77ba6f620d57 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Fri, 9 Oct 2015 13:59:35 +0100
Subject: [PATCH 26/39] Update RELEASENOTES.md
---
RELEASENOTES.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 4f9336b3..7ad0bfe2 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -1,7 +1,7 @@
Version 2.5.0.9
----
**New Feature**
-* Set Volume Range. This is a new setting that allows you to use just a portion of the full range of attenuation offered by a mixer. For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available. This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting. Or it might be because the range specified by the mixer does not match the capabilities of the device. For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB. The new `general` setting `volume_range_db` allows you to specify the maximum range from highest to lowest. Many domestic Hi Fi systems have a range of 60 to 80 dB. The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 35. Using it in this case gives the volume control a much more useful range of volumes.
+* Set Volume Range. This is a new setting that allows you to use just a portion of the full range of attenuation offered by a mixer. For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available. This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting. Or it might be because the range specified by the mixer does not match the capabilities of the device. For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB. The new `volume_range_db` setting in the `general` stanza allows you to specify the maximum range from highest to lowest. Many domestic Hi Fi systems have a range of 60 to 80 dB. The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 35. Using it in this case gives the volume control a much more useful range of volumes.
Version 2.5.0.8
----
From c57295bdce76c9bb0eb6b7a7703ee518dcdf2387 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Fri, 9 Oct 2015 14:24:30 +0100
Subject: [PATCH 27/39] Update RELEASENOTES.md
---
RELEASENOTES.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 7ad0bfe2..ca77a159 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -1,7 +1,7 @@
Version 2.5.0.9
----
**New Feature**
-* Set Volume Range. This is a new setting that allows you to use just a portion of the full range of attenuation offered by a mixer. For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available. This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting. Or it might be because the range specified by the mixer does not match the capabilities of the device. For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB. The new `volume_range_db` setting in the `general` stanza allows you to specify the maximum range from highest to lowest. Many domestic Hi Fi systems have a range of 60 to 80 dB. The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 35. Using it in this case gives the volume control a much more useful range of volumes.
+* Set Volume Range. This is a new setting that allows you to use just a portion of the full range of attenuation offered by a mixer. For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available. This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting. Or it might be because the range specified by the mixer does not match the capabilities of the device. For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB. The new `volume_range_db` setting in the `general` stanza allows you to specify the maximum range from highest to lowest. Many domestic Hi Fi systems have a range of 60 to 80 dB. The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 35. Using it in this case gives the volume control a much more useful range of settings.
Version 2.5.0.8
----
From 9002212eea63f3cd9d1e408d807b52bfb6be8c3b Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Fri, 16 Oct 2015 13:21:25 +0100
Subject: [PATCH 28/39] Update for automated latencies and volume range setting
---
RELEASENOTES.md | 3 +
man/shairport-sync.7 | 117 +++++++++++++----------
man/shairport-sync.7.xml | 186 ++++++++++++++++++++----------------
man/shairport-sync.html | 186 ++++++++++++++++++++----------------
scripts/shairport-sync.conf | 8 +-
5 files changed, 276 insertions(+), 224 deletions(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index ca77a159..4fecb56a 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -3,6 +3,9 @@ Version 2.5.0.9
**New Feature**
* Set Volume Range. This is a new setting that allows you to use just a portion of the full range of attenuation offered by a mixer. For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available. This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting. Or it might be because the range specified by the mixer does not match the capabilities of the device. For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB. The new `volume_range_db` setting in the `general` stanza allows you to specify the maximum range from highest to lowest. Many domestic Hi Fi systems have a range of 60 to 80 dB. The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 35. Using it in this case gives the volume control a much more useful range of settings.
+**Other Changes**
+* Initial timing accuracy improved. The estimate of when to play the starting frame of the audio sequence has improved significantly.
+
Version 2.5.0.8
----
**Bug fix**
diff --git a/man/shairport-sync.7 b/man/shairport-sync.7
index 1449c43d..e5a64ba4 100644
--- a/man/shairport-sync.7
+++ b/man/shairport-sync.7
@@ -99,54 +99,8 @@ Use this to specify how much debugging information should be output or logged. "
\fBignore_volume_control=\f1\fI"choice"\f1\fB;\f1
Set this \fIchoice\f1 to "yes" if you want the volume to be at 100% no matter what the source's volume control is set to. This might be useful if you want to set the volume on the output device, independently of the setting at the source. The default is "no".
.TP
-\fB"LATENCIES" SETTINGS\f1
-There are four default latency settings, chosen automatically. One latency matches the latency used by recent versions of iTunes when playing audio and another matches the latency used by so-called "AirPlay" devices, including iOS devices and iTunes and Quicktime Player when they are playing video. A third latency is used when the audio source is forked-daapd. The fourth latency is the default if no other latency is chosen and is used for older versions of iTunes.
-
-If you want to change latencies to compensate for a delay in the audio output device (which will have the same effect on all sources), instead of changing these individual latencies, consider using the \fBaudio_backend_latency_offset\f1 setting in the \fBalsa\f1 group (or the appropriate other group if you're not outputing through the alsa backend).
-.TP
-\fBitunes=\f1\fIlatency\f1\fB;\f1
-This is the \fIlatency\f1, in frames, used for iTunes 10 or later. Default is 99,400.
-.TP
-\fBairplay=\f1\fIlatency\f1\fB;\f1
-This is the \fIlatency\f1, in frames, used for AirPlay devices, including iOS devices and iTunes and Quicktime Player when they are playing video. Default is 88,200.
-.TP
-\fBforkedDaapd=\f1\fIlatency\f1\fB;\f1
-This is the \fIlatency\f1, in frames, used for forkedDaapd sources. Default is 99,400.
-.TP
-\fBdefault=\f1\fIlatency\f1\fB;\f1
-This is the \fIlatency\f1, in frames, used when the source is unrecognised. Default is 88,200.
-.TP
-\fB"METADATA" SETTINGS\f1
-shairport-sync can process metadata provided by the source, such as Track Number, Album Name, cover art, etc. and can provide additional metadata such as volume level, pause/resume, etc. It provides the metadata to a pipe, by default \fI/tmp/shairport-sync-metadata\f1. To process metadata, shairport-sync must have been compiled with metadata support included. You can check that this is so by running \fBshairport-sync -V\f1; the identification string will contain the word \fBmetadata\f1.
-
-The \fBmetadata\f1 group of settings allow you to enable metadata handling and to control certain aspects of it:
-.TP
-\fBenabled=\f1\fI"choice"\f1\fB;\f1
-Set the \fIchoice\f1 to "yes" to enable shairport-sync to look for metadata from the audio source and to forward it, along with metadata generated by shairport-sync itself, to the metadata pipe. The default is "no".
-.TP
-\fBinclude_cover_art=\f1\fI"choice"\f1\fB;\f1
-Set the \fIchoice\f1 to "yes" to enable shairport-sync to look for cover art from the audio source and to include it in the feed to the metadata pipe. You must also enable metadata (see above). One reason for not including cover art is that the images can sometimes be very large and may delay transmission of subsequent metadata through the pipe. The default is "no".
-.TP
-\fBpipe_name=\f1\fI"filepathname"\f1\fB;\f1
-Specify the absolute path name of the pipe through which metadata should be sent The default is \fI/tmp/shairport-sync-metadata\f1".
-.TP
-\fB"SESSIONCONTROL" SETTINGS\f1
-shairport-sync can run programs just before it starts to play an audio stream and just after it finishes. You specify them using the sessioncontrol group settings run_this_before_play_begins and run_this_after_play_ends.
-.TP
-\fBrun_this_before_play_begins=\f1\fI"/path/to/application and args"\f1\fB;\f1
-Here you can specify a program and its arguments that will be run just before a play session begins. Be careful to include the full path to the application. The application must be marked as executable and, if it is a script, its first line must begin with the standard \fI#!/bin/...\f1 as appropriate.
-.TP
-\fBrun_this_after_play_ends=\f1\fI"/path/to/application and args"\f1\fB;\f1
-Here you can specify a program and its arguments that will be run just after a play session ends. Be careful to include the full path to the application. The application must be marked as executable and, if it is a script, its first line must begin with the standard \fI#!/bin/...\f1 as appropriate.
-.TP
-\fBwait_for_completion=\f1\fI"choice"\f1\fB;\f1
-Set \fIchoice\f1 to "yes" to make shairport-sync wait until the programs specified in the \fBrun_this_before_play_begins\f1 and \fBrun_this_after_play_ends\f1 have completed execution before continuing. The default is "no".
-.TP
-\fBallow_session_interruption=\f1\fI"choice"\f1\fB;\f1
-If \fBchoice\f1 is set to "yes", then another source will be able to interrupt an existing play session and start a new one. When set to "no" (the default), other devices attempting to interrupt a session will fail, receiving a busy signal.
-.TP
-\fBsession_timeout=\f1\fIseconds\f1\fB;\f1
-If a play session has been established and the source disappears without warning (such as a device going out of range of a network) then wait for \fIseconds\f1 seconds before ending the session. Once the session has terminated, other devices can use it. The default is 120 seconds.
+\fBvolume_range_db=\f1\fIdBvalue\f1\fB;\f1
+Set this \fIdBvalue\f1 to use just a portion of the full range of attenuation offered by a mixer. For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available. This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting. Or it might be because the range specified by the mixer does not match the capabilities of the device. For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB. The setting allows you to specify the maximum range from highest to lowest. Many domestic HiFi systems have a range of 60 to 80 dB. The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 35. Using it in this case gives the volume control a much more useful range of settings. If you omit this setting, the full "native" range of the output device is used.
.TP
\fB"ALSA" SETTINGS\f1
These settings are for the ALSA back end, used to communicate with audio output devices in the ALSA system. (By the way, you can use tools such as \fBalsamixer\f1 or \fBaplay\f1 to discover what devices are available.) Use these settings to select the output device and the mixer control to be used to control the output volume. You can additionally set the desired size of the output buffer and you can adjust overall latency. Here are the \fBalsa\f1 group settings:
@@ -157,7 +111,7 @@ Use the output device called \fIoutput_device\f1. The default is the device call
.TP
\fBmixer_control_name=\f1\fI"name"\f1\fB;\f1
Specify the \fIname\f1 of the mixer control to be used by shairport-sync to control the volume. The mixer control must be on the mixer device, which by default is the output device. If you do not specify a mixer control name, shairport-sync will adjust the volume in software. \fBmixer_type=\f1\fI"mixer_type"\f1\fB;\f1
-This setting is deprecated and will be removed soon. If you wish to use a mixer control to control the volume, then set \fImixer_type\f1 to "hardware". The default is "software".
+This setting is deprecated and ignored and will be removed soon.
.TP
\fBmixer_device=\f1\fI"mixer_device"\f1\fB;\f1
By default, the mixer is assumed to be output_device. Use this setting to specify a device other than the output device.
@@ -198,8 +152,65 @@ Packets of audio frames are written to stdout synchronously -- that is, they are
.TP
\fBaudio_backend_buffer_desired_length=\f1\fIbuffer_length_in_frames\f1\fB;\f1
Use this setting, in frames, to set the size of the output buffer. It works by determining how soon the second and subsequent packets of audio frames are sent to stdout. For example, if you send the first packet of audio exactly when it is due and, using a \fIaudio_backend_buffer_desired_length\f1 setting of 44100, send subsequent packets of audio a second before they are due to be played, they will be buffered in the stdout reader's buffer, giving it a nominal buffer size of 44,100 frames. Note that if the stdout reader consumes audio packets faster or slower than they are supplied, the buffer will eventually empty or overflow -- shairport-sync performs no stuffing or interpolation when writing to stdout. Default setting is 44,100 frames.
+.TP
+\fB"METADATA" SETTINGS\f1
+shairport-sync can process metadata provided by the source, such as Track Number, Album Name, cover art, etc. and can provide additional metadata such as volume level, pause/resume, etc. It sends the metadata to a pipe, by default \fI/tmp/shairport-sync-metadata\f1. To process metadata, shairport-sync must have been compiled with metadata support included. You can check that this is so by running \fBshairport-sync -V\f1; the identification string will contain the word \fBmetadata\f1.
+
+Please note that different sources provide different levels of metadata. Some provide a lot; some provide almost none.
+
+The \fBmetadata\f1 group of settings allow you to enable metadata handling and to control certain aspects of it:
+.TP
+\fBenabled=\f1\fI"choice"\f1\fB;\f1
+Set the \fIchoice\f1 to "yes" to enable shairport-sync to look for metadata from the audio source and to forward it, along with metadata generated by shairport-sync itself, to the metadata pipe. The default is "no".
+.TP
+\fBinclude_cover_art=\f1\fI"choice"\f1\fB;\f1
+Set the \fIchoice\f1 to "yes" to enable shairport-sync to look for cover art from the audio source and to include it in the feed to the metadata pipe. You must also enable metadata (see above). One reason for not including cover art is that the images can sometimes be very large and may delay transmission of subsequent metadata through the pipe. The default is "no".
+.TP
+\fBpipe_name=\f1\fI"filepathname"\f1\fB;\f1
+Specify the absolute path name of the pipe through which metadata should be sent The default is \fI/tmp/shairport-sync-metadata\f1".
+.TP
+\fB"SESSIONCONTROL" SETTINGS\f1
+shairport-sync can run programs just before it starts to play an audio stream and just after it finishes. You specify them using the sessioncontrol group settings run_this_before_play_begins and run_this_after_play_ends.
+.TP
+\fBrun_this_before_play_begins=\f1\fI"/path/to/application and args"\f1\fB;\f1
+Here you can specify a program and its arguments that will be run just before a play session begins. Be careful to include the full path to the application. The application must be marked as executable and, if it is a script, its first line must begin with the standard \fI#!/bin/...\f1 as appropriate.
+.TP
+\fBrun_this_after_play_ends=\f1\fI"/path/to/application and args"\f1\fB;\f1
+Here you can specify a program and its arguments that will be run just after a play session ends. Be careful to include the full path to the application. The application must be marked as executable and, if it is a script, its first line must begin with the standard \fI#!/bin/...\f1 as appropriate.
+.TP
+\fBwait_for_completion=\f1\fI"choice"\f1\fB;\f1
+Set \fIchoice\f1 to "yes" to make shairport-sync wait until the programs specified in the \fBrun_this_before_play_begins\f1 and \fBrun_this_after_play_ends\f1 have completed execution before continuing. The default is "no".
+.TP
+\fBallow_session_interruption=\f1\fI"choice"\f1\fB;\f1
+If \fBchoice\f1 is set to "yes", then another source will be able to interrupt an existing play session and start a new one. When set to "no" (the default), other devices attempting to interrupt a session will fail, receiving a busy signal.
+.TP
+\fBsession_timeout=\f1\fIseconds\f1\fB;\f1
+If a play session has been established and the source disappears without warning (such as a device going out of range of a network) then wait for \fIseconds\f1 seconds before ending the session. Once the session has terminated, other devices can use it. The default is 120 seconds.
+.TP
+\fB"LATENCIES" SETTINGS\f1
+The latencies settings are now deprecated. Do not use them for new installations. They will be removed from a future version of Shairport Sync.
+
+Latency is the exact time from a sound signal's original timestamp until that signal actually "appears" on the output of the audio output device, usually a Digital to Audio Converter (DAC), irrespective of any internal delays, processing times, etc. in the computer.
+
+Shairport Sync now sets latencies automatically using information supplied by the source, typically either 88,200 or 99,577 frames.
+
+The following relates to the old scheme of using fixed latencies, which ignores the latency information supplied by the source. There are four default latency settings. One latency matches the latency used by recent versions of iTunes when playing audio and another matches the latency used by so-called "AirPlay" devices, including iOS devices and iTunes and Quicktime Player when they are playing video. A third latency is used when the audio source is forked-daapd. The fourth latency is the default if no other latency is chosen and is used for older versions of iTunes.
+
+Note: If you are thinking of changing latencies to compensate for a delay in the audio output device, then instead of changing these individual latencies, consider using the \fBaudio_backend_latency_offset\f1 setting in the \fBalsa\f1 group (or the appropriate other group if you're not outputing through the alsa backend).
+.TP
+\fBitunes=\f1\fIlatency\f1\fB;\f1
+This is the \fIlatency\f1, in frames, used for iTunes 10 or later. Default is 99,400.
+.TP
+\fBairplay=\f1\fIlatency\f1\fB;\f1
+This is the \fIlatency\f1, in frames, used for AirPlay devices, including iOS devices and iTunes and Quicktime Player when they are playing video. Default is 88,200.
+.TP
+\fBforkedDaapd=\f1\fIlatency\f1\fB;\f1
+This is the \fIlatency\f1, in frames, used for forkedDaapd sources. Default is 99,400.
+.TP
+\fBdefault=\f1\fIlatency\f1\fB;\f1
+This is the \fIlatency\f1, in frames, used when the source is unrecognised. Default is 88,200.
.SH OPTIONS
-Note: if you are setting up shairport-sync for the first time or are updating an existing installation, you are encouraged to use the configuration file settings described above. Most of the options described below simply replicate the configuration settings and are retained to provide backward compatability with older installations of shairport-sync.
+Note: if you are setting up Shairport Sync for the first time or are updating an existing installation, you are encouraged to use the configuration file settings described above. Most of the options described below simply replicate the configuration settings and are retained to provide backward compatability with older installations of Shairport Sync.
Many of the options take sensible default values, so you can normally ignore most of them. See the EXAMPLES section for typical usages.
@@ -322,10 +333,10 @@ The example above is slightly contrived in order to show the use of the \fB-m\f1
shairport-sync \fB-d\f1 \fB-a "Joe's Stereo"\f1 \fB-S soxr\f1 \fB--\f1 \fB-d hw:1\f1 \fB-c PCM\f1
.SH CREDITS
-Mike Brady developed shairport-sync from the original shairport by James Laird.
+Mike Brady developed Shairport Sync from the original Shairport by James Laird.
-shairport-sync can be found at \fBhttps://github.com/mikebrady/shairport-sync.\f1
+Shairport Sync can be found at \fBhttps://github.com/mikebrady/shairport-sync.\f1
-shairport can be found at \fBhttps://github.com/abrasive/shairport.\f1
+Shairport can be found at \fBhttps://github.com/abrasive/shairport.\f1
.SH COMMENTS
This man page was written using \fBxml2man(1)\f1 by Oliver Kurth.
diff --git a/man/shairport-sync.7.xml b/man/shairport-sync.7.xml
index 14c8be65..965f5700 100644
--- a/man/shairport-sync.7.xml
+++ b/man/shairport-sync.7.xml
@@ -192,84 +192,12 @@
Set this choice to "yes" if you want the volume to be at 100% no matter what the source's volume control is set to. This might be useful if you want to set the volume on the output device, independently of the setting at the source. The default is "no".
-
-
There are four default latency settings, chosen automatically. One latency matches the latency used by recent versions of iTunes when playing audio and another matches the latency used by so-called "AirPlay" devices, including iOS devices and iTunes and Quicktime Player when they are playing video. A third latency is used when the audio source is forked-daapd. The fourth latency is the default if no other latency is chosen and is used for older versions of iTunes.
-
If you want to change latencies to compensate for a delay in the audio output device (which will have the same effect on all sources), instead of changing these individual latencies, consider using the audio_backend_latency_offset setting in the alsa group (or the appropriate other group if you're not outputing through the alsa backend).
+
-
-
-
-
-
-
-
shairport-sync can process metadata provided by the source, such as Track Number, Album Name, cover art, etc. and can provide additional metadata such as volume level,
- pause/resume, etc. It provides the metadata to a pipe, by default /tmp/shairport-sync-metadata.
- To process metadata, shairport-sync must have been compiled with metadata support included.
- You can check that this is so by running shairport-sync -V; the identification string will contain the word metadata.
-
The metadata group of settings allow you to enable metadata handling and to control certain aspects of it:
-
-
-
-
-
-
-
-
shairport-sync can run programs just before it starts to play an audio stream and just after it finishes.
- You specify them using the sessioncontrol group settings run_this_before_play_begins and run_this_after_play_ends.
-
-
-
-
-
-
-
These settings are for the ALSA back end, used to communicate with audio output devices in the ALSA system.
@@ -289,8 +217,7 @@
If you do not specify a mixer control name, shairport-sync will adjust the volume in software.
mixer_type="mixer_type";
- This setting is deprecated and will be removed soon. If you wish to use a mixer control to control the volume, then set mixer_type to "hardware".
- The default is "software".
+ This setting is deprecated and ignored and will be removed soon.
+
+
+
shairport-sync can process metadata provided by the source, such as Track Number, Album Name, cover art, etc. and can provide additional metadata such as volume level,
+ pause/resume, etc. It sends the metadata to a pipe, by default /tmp/shairport-sync-metadata.
+ To process metadata, shairport-sync must have been compiled with metadata support included.
+ You can check that this is so by running shairport-sync -V; the identification string will contain the word metadata.
+
Please note that different sources provide different levels of metadata. Some provide a lot; some provide almost none.
+
The metadata group of settings allow you to enable metadata handling and to control certain aspects of it:
+
+
+
+
+
+
+
+
shairport-sync can run programs just before it starts to play an audio stream and just after it finishes.
+ You specify them using the sessioncontrol group settings run_this_before_play_begins and run_this_after_play_ends.
+
+
+
+
+
+
+
+
+
+
The latencies settings are now deprecated. Do not use them for new installations. They will be removed from a future version of Shairport Sync.
+
Latency is the exact time from a sound signal's original timestamp until that signal actually "appears" on the output of the audio output device,
+ usually a Digital to Audio Converter (DAC), irrespective of any internal delays, processing times, etc. in the computer.
+
+
Shairport Sync now sets latencies automatically using information supplied by the source, typically either 88,200 or 99,577 frames.
+
+
The following relates to the old scheme of using fixed latencies, which ignores the latency information supplied by the source.
+ There are four default latency settings. One latency matches the latency used by recent versions of
+ iTunes when playing audio and another matches the latency
+ used by so-called "AirPlay" devices, including iOS devices and iTunes and Quicktime Player when they are playing video.
+ A third latency is used when the audio source is forked-daapd. The fourth latency is the default if no other latency is chosen and is used for older versions of iTunes.
+
Note: If you are thinking of changing latencies to compensate for a delay in the audio output device, then
+ instead of changing these individual latencies, consider using the audio_backend_latency_offset setting in the alsa group
+ (or the appropriate other group if you're not outputing through the alsa backend).
+
+
+
+
+
+
+
-
Note: if you are setting up shairport-sync for the first time or are updating an existing installation,
+
Note: if you are setting up Shairport Sync for the first time or are updating an existing installation,
you are encouraged to use the configuration file settings described above. Most of the options described below
- simply replicate the configuration settings and are retained to provide backward compatability with older installations of shairport-sync.
+ simply replicate the configuration settings and are retained to provide backward compatability with older installations of Shairport Sync.
Many of the options take sensible default values, so you can normally
ignore most of them. See the EXAMPLES section for typical usages.
@@ -745,9 +765,9 @@
-
Mike Brady developed shairport-sync from the original shairport by James Laird.
-
shairport-sync can be found at
-
shairport can be found at
+
Mike Brady developed Shairport Sync from the original Shairport by James Laird.
+
Shairport Sync can be found at
+
Shairport can be found at
diff --git a/man/shairport-sync.html b/man/shairport-sync.html
index c587b03e..0930dc1d 100644
--- a/man/shairport-sync.html
+++ b/man/shairport-sync.html
@@ -174,85 +174,13 @@
Set this choice to "yes" if you want the volume to be at 100% no matter what the source's volume control is set to. This might be useful if you want to set the volume on the output device, independently of the setting at the source. The default is "no".
-
"LATENCIES" SETTINGS
-
There are four default latency settings, chosen automatically. One latency matches the latency used by recent versions of iTunes when playing audio and another matches the latency used by so-called "AirPlay" devices, including iOS devices and iTunes and Quicktime Player when they are playing video. A third latency is used when the audio source is forked-daapd. The fourth latency is the default if no other latency is chosen and is used for older versions of iTunes.
-
If you want to change latencies to compensate for a delay in the audio output device (which will have the same effect on all sources), instead of changing these individual latencies, consider using the audio_backend_latency_offset setting in the alsa group (or the appropriate other group if you're not outputing through the alsa backend).
+
+
volume_range_db=dBvalue;
+ Set this dBvalue to use just a portion of the full range of attenuation offered by a mixer. For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available. This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting. Or it might be because the range specified by the mixer does not match the capabilities of the device. For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB. The setting allows you to specify the maximum range from highest to lowest. Many domestic HiFi systems have a range of 60 to 80 dB. The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 35. Using it in this case gives the volume control a much more useful range of settings. If you omit this setting, the full "native" range of the output device is used.
+
-
itunes=latency;
- This is the latency, in frames, used for iTunes 10 or later. Default is 99,400.
-
-
-
airplay=latency;
- This is the latency, in frames, used for AirPlay devices, including iOS devices and iTunes and Quicktime Player when they are playing video. Default is 88,200.
-
-
-
forkedDaapd=latency;
- This is the latency, in frames, used for forkedDaapd sources. Default is 99,400.
-
-
-
default=latency;
- This is the latency, in frames, used when the source is unrecognised. Default is 88,200.
-
-
-
"METADATA" SETTINGS
-
shairport-sync can process metadata provided by the source, such as Track Number, Album Name, cover art, etc. and can provide additional metadata such as volume level,
- pause/resume, etc. It provides the metadata to a pipe, by default /tmp/shairport-sync-metadata.
- To process metadata, shairport-sync must have been compiled with metadata support included.
- You can check that this is so by running shairport-sync -V; the identification string will contain the word metadata.
-
The metadata group of settings allow you to enable metadata handling and to control certain aspects of it:
-
-
-
-
enabled="choice";
- Set the choice to "yes" to enable shairport-sync to look for metadata from the audio source and to forward it,
- along with metadata generated by shairport-sync itself, to the metadata pipe. The default is "no".
-
-
-
include_cover_art="choice";
- Set the choice to "yes" to enable shairport-sync to look for cover art from the audio source and to include it in the feed to the metadata pipe.
- You must also enable metadata (see above).
- One reason for not including cover art is that the images can sometimes be very large and may delay transmission of subsequent metadata through the pipe.
- The default is "no".
-
-
-
pipe_name="filepathname";
- Specify the absolute path name of the pipe through which metadata should be sent The default is /tmp/shairport-sync-metadata".
-
-
-
"SESSIONCONTROL" SETTINGS
-
shairport-sync can run programs just before it starts to play an audio stream and just after it finishes.
- You specify them using the sessioncontrol group settings run_this_before_play_begins and run_this_after_play_ends.
-
-
-
-
run_this_before_play_begins="/path/to/application and args";
- Here you can specify a program and its arguments that will be run just before a play session begins. Be careful to include the full path to the application.
- The application must be marked as executable and, if it is a script, its first line must begin with the standard #!/bin/... as appropriate.
-
-
-
run_this_after_play_ends="/path/to/application and args";
- Here you can specify a program and its arguments that will be run just after a play session ends. Be careful to include the full path to the application.
- The application must be marked as executable and, if it is a script, its first line must begin with the standard #!/bin/... as appropriate.
-
-
-
wait_for_completion="choice";
- Set choice to "yes" to make shairport-sync wait until the programs specified in the run_this_before_play_begins
- and run_this_after_play_ends have completed execution before continuing. The default is "no".
-
-
-
allow_session_interruption="choice";
- If choice is set to "yes", then another source will be able to interrupt an existing play session and start a new one.
- When set to "no" (the default), other devices attempting to interrupt a session will fail, receiving a busy signal.
-
-
-
session_timeout=seconds;
- If a play session has been established and the source disappears without warning (such as a device going out of range of a network)
- then wait for seconds seconds before ending the session. Once the session has terminated, other devices can use it.
- The default is 120 seconds.
-
-
"ALSA" SETTINGS
These settings are for the ALSA back end, used to communicate with audio output devices in the ALSA system.
(By the way, you can use tools such as alsamixer or aplay to discover what devices are available.)
@@ -271,8 +199,7 @@
If you do not specify a mixer control name, shairport-sync will adjust the volume in software.
mixer_type="mixer_type";
- This setting is deprecated and will be removed soon. If you wish to use a mixer control to control the volume, then set mixer_type to "hardware".
- The default is "software".
+ This setting is deprecated and ignored and will be removed soon.
mixer_device="mixer_device";
@@ -353,6 +280,99 @@
shairport-sync performs no stuffing or interpolation when writing to stdout. Default setting is 44,100 frames.
+
+
"METADATA" SETTINGS
+
shairport-sync can process metadata provided by the source, such as Track Number, Album Name, cover art, etc. and can provide additional metadata such as volume level,
+ pause/resume, etc. It sends the metadata to a pipe, by default /tmp/shairport-sync-metadata.
+ To process metadata, shairport-sync must have been compiled with metadata support included.
+ You can check that this is so by running shairport-sync -V; the identification string will contain the word metadata.
+
Please note that different sources provide different levels of metadata. Some provide a lot; some provide almost none.
+
The metadata group of settings allow you to enable metadata handling and to control certain aspects of it:
+
+
+
+
enabled="choice";
+ Set the choice to "yes" to enable shairport-sync to look for metadata from the audio source and to forward it,
+ along with metadata generated by shairport-sync itself, to the metadata pipe. The default is "no".
+
+
+
include_cover_art="choice";
+ Set the choice to "yes" to enable shairport-sync to look for cover art from the audio source and to include it in the feed to the metadata pipe.
+ You must also enable metadata (see above).
+ One reason for not including cover art is that the images can sometimes be very large and may delay transmission of subsequent metadata through the pipe.
+ The default is "no".
+
+
+
pipe_name="filepathname";
+ Specify the absolute path name of the pipe through which metadata should be sent The default is /tmp/shairport-sync-metadata".
+
+
+
"SESSIONCONTROL" SETTINGS
+
shairport-sync can run programs just before it starts to play an audio stream and just after it finishes.
+ You specify them using the sessioncontrol group settings run_this_before_play_begins and run_this_after_play_ends.
+
+
+
+
run_this_before_play_begins="/path/to/application and args";
+ Here you can specify a program and its arguments that will be run just before a play session begins. Be careful to include the full path to the application.
+ The application must be marked as executable and, if it is a script, its first line must begin with the standard #!/bin/... as appropriate.
+
+
+
run_this_after_play_ends="/path/to/application and args";
+ Here you can specify a program and its arguments that will be run just after a play session ends. Be careful to include the full path to the application.
+ The application must be marked as executable and, if it is a script, its first line must begin with the standard #!/bin/... as appropriate.
+
+
+
wait_for_completion="choice";
+ Set choice to "yes" to make shairport-sync wait until the programs specified in the run_this_before_play_begins
+ and run_this_after_play_ends have completed execution before continuing. The default is "no".
+
+
+
allow_session_interruption="choice";
+ If choice is set to "yes", then another source will be able to interrupt an existing play session and start a new one.
+ When set to "no" (the default), other devices attempting to interrupt a session will fail, receiving a busy signal.
+
+
+
session_timeout=seconds;
+ If a play session has been established and the source disappears without warning (such as a device going out of range of a network)
+ then wait for seconds seconds before ending the session. Once the session has terminated, other devices can use it.
+ The default is 120 seconds.
+
+
+
"LATENCIES" SETTINGS
+
The latencies settings are now deprecated. Do not use them for new installations. They will be removed from a future version of Shairport Sync.
+
Latency is the exact time from a sound signal's original timestamp until that signal actually "appears" on the output of the audio output device,
+ usually a Digital to Audio Converter (DAC), irrespective of any internal delays, processing times, etc. in the computer.
+
+
Shairport Sync now sets latencies automatically using information supplied by the source, typically either 88,200 or 99,577 frames.
+
+
The following relates to the old scheme of using fixed latencies, which ignores the latency information supplied by the source.
+ There are four default latency settings. One latency matches the latency used by recent versions of
+ iTunes when playing audio and another matches the latency
+ used by so-called "AirPlay" devices, including iOS devices and iTunes and Quicktime Player when they are playing video.
+ A third latency is used when the audio source is forked-daapd. The fourth latency is the default if no other latency is chosen and is used for older versions of iTunes.
+
Note: If you are thinking of changing latencies to compensate for a delay in the audio output device, then
+ instead of changing these individual latencies, consider using the audio_backend_latency_offset setting in the alsa group
+ (or the appropriate other group if you're not outputing through the alsa backend).
+
+
+
+
itunes=latency;
+ This is the latency, in frames, used for iTunes 10 or later. Default is 99,400.
+
+
+
airplay=latency;
+ This is the latency, in frames, used for AirPlay devices, including iOS devices and iTunes and Quicktime Player when they are playing video. Default is 88,200.
+
+
+
forkedDaapd=latency;
+ This is the latency, in frames, used for forkedDaapd sources. Default is 99,400.
+
+
+
default=latency;
+ This is the latency, in frames, used when the source is unrecognised. Default is 88,200.
+
+
@@ -360,9 +380,9 @@
Options
-
Note: if you are setting up shairport-sync for the first time or are updating an existing installation,
+
Note: if you are setting up Shairport Sync for the first time or are updating an existing installation,
you are encouraged to use the configuration file settings described above. Most of the options described below
- simply replicate the configuration settings and are retained to provide backward compatability with older installations of shairport-sync.
+ simply replicate the configuration settings and are retained to provide backward compatability with older installations of Shairport Sync.
Many of the options take sensible default values, so you can normally
ignore most of them. See the EXAMPLES section for typical usages.
@@ -738,9 +758,9 @@
Credits
-
Mike Brady developed shairport-sync from the original shairport by James Laird.
diff --git a/scripts/shairport-sync.conf b/scripts/shairport-sync.conf
index 28eca89e..ff2651aa 100644
--- a/scripts/shairport-sync.conf
+++ b/scripts/shairport-sync.conf
@@ -5,7 +5,7 @@
general =
{
// name = "Shairport Sync Player"; // This is the name the service will advertise to iTunes. The default is "Shairport Sync on "
-// password = "secret"; // comment out this line if you want to have no password
+// password = "secret"; // leave this commented out if you don't want to require a password
// interpolation = "basic"; // aka "stuffing". Default is "basic", alternative is "soxr". Use "soxr" only if you have a reasonably fast processor.
// output_backend = "alsa"; // Run "shairport-sync -h" to get a list of all output_backends, e.g. "alsa", "pipe", "stdout". The default is the first one.
// mdns_backend = "avahi"; // Run "shairport-sync -h" to get a list of all mdns_backends. The default is the first one.
@@ -17,7 +17,7 @@ general =
// resync_threshold = 2205; // a synchronisation error greater than this will cause resynchronisation; 0 disables it
// log_verbosity = 0; // "0" means no debug verbosity, "3" is most verbose.
// ignore_volume_control = "no"; // set this to "yes" if you want the volume to be at 100% no matter what the source's volume control is set to.
-// volume_range_db = 60 ; // use this to set the range, in dB, you want between the maximum volume and the minimum volume. Range is 30 to 150 dB. Omit to use mixer's native range.
+// volume_range_db = 60 ; // use this to set the range, in dB, you want between the maximum volume and the minimum volume. Range is 30 to 150 dB. Leave it commented out to use mixer's native range.
};
// How to deal with metadata, including artwork
@@ -38,9 +38,7 @@ sessioncontrol =
// session_timeout = 120; // wait for this number of seconds after a source disappears before terminating the session and becoming available again.
};
-//
// Back End Settings
-//
// These are parameters for the "alsa" audio back end, the only back end that supports synchronised audio.
alsa =
@@ -68,7 +66,7 @@ stdout =
};
// The following static latency settings are deprecated -- do not use them for new installations. Shairport Sync now sets latencies automatically.
-// To compensate for a delay in the output device using the alsa/stdio/pipe "audio_backend_latency_offset" setting.
+// To compensate for a delay in the output device please use the alsa/stdio/pipe "audio_backend_latency_offset" setting.
// Static latencies for different sources. These have been estimated from listening tests.
latencies =
From 03ea4544a0398f22f625cf8d48e02fcabf63da97 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Fri, 16 Oct 2015 15:27:52 +0100
Subject: [PATCH 29/39] Update RELEASENOTES.md
---
RELEASENOTES.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 4fecb56a..b76041f1 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -1,7 +1,8 @@
Version 2.5.0.9
----
**New Feature**
-* Set Volume Range. This is a new setting that allows you to use just a portion of the full range of attenuation offered by a mixer. For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available. This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting. Or it might be because the range specified by the mixer does not match the capabilities of the device. For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB. The new `volume_range_db` setting in the `general` stanza allows you to specify the maximum range from highest to lowest. Many domestic Hi Fi systems have a range of 60 to 80 dB. The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 35. Using it in this case gives the volume control a much more useful range of settings.
+* Set Volume Range. This is a new setting that allows you to use just a portion of the full range of attenuation offered by a mixer. For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available. This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting -- for this reason, many domestic HiFi systems have a volume control range of only 60 to 80 dB.
+Another possible reason might be because the range specified by the mixer does not match the capabilities of the device. For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB. The new `volume_range_db` setting in the `general` stanza allows you to specify the maximum range from highest to lowest. The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 35. Using it in this case gives the volume control a much more useful range of settings.
**Other Changes**
* Initial timing accuracy improved. The estimate of when to play the starting frame of the audio sequence has improved significantly.
From b8dcd95ef67c6895c3f7adf1157907d78ae5e010 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Fri, 16 Oct 2015 14:34:12 +0000
Subject: [PATCH 30/39] Minor wording changes.
---
man/shairport-sync.7.xml | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/man/shairport-sync.7.xml b/man/shairport-sync.7.xml
index 965f5700..4b0845d1 100644
--- a/man/shairport-sync.7.xml
+++ b/man/shairport-sync.7.xml
@@ -194,10 +194,14 @@
-
-
These settings are for the ALSA back end, used to communicate with audio output devices in the ALSA system.
From ca60150fd32f5653223aadcdc3bb0f3bf171215a Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Fri, 16 Oct 2015 17:24:49 +0100
Subject: [PATCH 31/39] Add note about Raspberry Pi DAC
---
README.md | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index 5e67dda5..f26ce54b 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
Shairport Sync
=============
-Shairport Sync emulates an AirPort Express for the purpose of streaming audio from iTunes, iPods, iPhones, iPads and AppleTVs.
+Shairport Sync is an AirPlay audio player -- it plays audio streamed from iTunes, iOS devices and third-party AirPlay sources such as ForkedDaapd and 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.
@@ -35,7 +35,7 @@ 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 runs well on the Raspberry Pi. It can drive the built-in sound card, though the audio out of the card is of poor quality. USB-connected sound cards work well on recent versions of Raspbian; however older versions of Raspbian appear to suffer from a problem — see http://www.raspberrypi.org/forums/viewtopic.php?t=23544, so it is wise to update. Shairport Sync works well with the IQAudIO Pi-DAC — see http://www.iqaudio.com.
+Shairport Sync runs well on the Raspberry Pi. 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). USB-connected sound cards work well on recent versions of Raspbian; however older versions of Raspbian appear to suffer from a problem — see http://www.raspberrypi.org/forums/viewtopic.php?t=23544, so it is wise to update. Shairport Sync works well with the IQAudIO Pi-DAC — see http://www.iqaudio.com.
At the time of writing, OpenWrt trunk does not support USB audio well on the Raspberry Pi.
@@ -212,7 +212,7 @@ Configuring Shairport Sync
--------
There are two logically distinct parts to getting Shairport Sync to run properly on your machine — (1) starting and stopping it and (2) ensuring it has the right settings.
-Starting and stopping automatically is taken care of differently in different versions of Linux. In the example above, when you run `$sudo make install`, a System V startup script is placed at `/etc/init.d/shairport-sync`. This will not be appropriate in Linuxes that use `systemd` such as Arch Linux, so please look at the separate installation scripts for those.
+Starting and stopping automatically is taken care of differently in different versions of Linux -- see the previous section for an example of installing into a System V or a `systemd` based system.
To get the best from Shairport Sync, you’ll need to (1) give Shairport Sync a service name by which it will be seen in iTunes etc., (2) specify the output device to use and (3) specify the name of the mixer volume control to use to control the output level. To get values for (2) and (3) you might need to explore the ALSA output devices with a program like `alsamixer` or similar.
@@ -251,6 +251,13 @@ Shairport Sync can run programs just before it starts to play an audio stream an
Please note that the full path to the programs must be specified, and script files will not be executed unless they are marked as executable and have the standard `#!/bin/...` first line. (This behaviour may be different from other Shairports.)
+**Raspberry Pi**
+The Raspberry Pi has a built-in audio DAC that is connected to the device's headphone jack. This provides a low-quality output that is nevertheless useful for testing purposes and may indeed by quite adequate for [very] casual listening. It is not HiFi: it is noisy and can't play anything above about 15kHz. A further problem is that it declares itself to have a very large mixer volume control range -- all the way from -102.38dB up to +4dB, a range of 106.38 dB. In reality, only the top 35dB of it is in any way usable.
+
+Accordingly, Shairport Sync has a `volume_range_db` setting in the `general` stanza which allows you to tell Shairport Sync to use a subrange of the declared range. For example, if you set the `volume_range_db` figure to 35, the top 35 dB of the range will the used. With this setting on the Raspberry Pi, maximum volume will be +4dB and minimum volume will be -31dB, below which muting will occur.
+
+From a user's point of view, the effect of using this setting is to move the minimum usable volume all the way down to the bottom of the user's volume control, rather than have the minimum usable volume concentrated very close to the maximum volume.
+
*Command Line Arguments*
You can use command line arguments to provide settings to Shairport Sync as before. For full information, please read the Shairport Sync `man` page, also available at http://htmlpreview.github.io/?https://github.com/mikebrady/shairport-sync/blob/development/man/shairport-sync.html.
@@ -282,7 +289,7 @@ alsa = {
This gives the service a particular name — "Joe's Stereo" and specifies that audio device hw:0 be used.
-For best results — including getting true mute and instant response to volume control and pause commands — you should access the hardware volume controls. Use `amixer` or `alsamixer` or similar to discover the name of the volume controller to be used after the `-c` option.
+For best results — including getting true mute and instant response to volume control and pause commands — you should access the hardware volume controls. Use `amixer` or `alsamixer` or similar to discover the name of the mixer control to be used as the `mixer_control_name`.
Here is an example for for a Raspberry Pi using its internal soundcard — device hw:0 — that drives the headphone jack:
```
From 83be2ad1249b69c9a9762205e1eeb386dba5a660 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Fri, 16 Oct 2015 17:31:40 +0100
Subject: [PATCH 32/39] Update RELEASENOTES.md
---
RELEASENOTES.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index b76041f1..dd7a5549 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -5,7 +5,7 @@ Version 2.5.0.9
Another possible reason might be because the range specified by the mixer does not match the capabilities of the device. For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB. The new `volume_range_db` setting in the `general` stanza allows you to specify the maximum range from highest to lowest. The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 35. Using it in this case gives the volume control a much more useful range of settings.
**Other Changes**
-* Initial timing accuracy improved. The estimate of when to play the starting frame of the audio sequence has improved significantly.
+* Initial timing accuracy improved. The estimate of when to play the starting frame of the audio sequence has improved significantly. This leads to fewer corrections being needed at the start.
Version 2.5.0.8
----
From 20c2b8a38cca6d39682c630f23743ed6a6995c37 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Fri, 16 Oct 2015 17:33:23 +0100
Subject: [PATCH 33/39] Update RELEASENOTES.md
---
RELEASENOTES.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index dd7a5549..3f288af0 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -9,8 +9,8 @@ Another possible reason might be because the range specified by the mixer does n
Version 2.5.0.8
----
-**Bug fix**
-* Sometimes, especially when using Shairport Sync as a system output, it would not play the audio stream. This was caused by an improperly initialised variable. Fixed.
+**Important Bug fix**
+* Sometimes, especially when using Shairport Sync as a system output, it would not play the audio stream. This was caused by an improperly initialised variable. Fixed. It may also be implcated in the continuing issue with Synology devices being unable to play to Shairport Sync.
Version 2.5.0.7
----
From e1e24e6059d16e4e19e14ae29c538a1ae8fe0da7 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Fri, 16 Oct 2015 17:35:20 +0100
Subject: [PATCH 34/39] Update RELEASENOTES.md
---
RELEASENOTES.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 3f288af0..91bcce92 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -1,7 +1,7 @@
Version 2.5.0.9
----
**New Feature**
-* Set Volume Range. This is a new setting that allows you to use just a portion of the full range of attenuation offered by a mixer. For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available. This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting -- for this reason, many domestic HiFi systems have a volume control range of only 60 to 80 dB.
+* Set Volume Range. This is a new setting that allows you to use just a portion of the full range of attenuation offered by a mixer. For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available. This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting -- (for this reason, many domestic HiFi systems have a volume control range of only 60 to 80 dB).
Another possible reason might be because the range specified by the mixer does not match the capabilities of the device. For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB. The new `volume_range_db` setting in the `general` stanza allows you to specify the maximum range from highest to lowest. The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 35. Using it in this case gives the volume control a much more useful range of settings.
**Other Changes**
From 50fd1799f0e7cafe7e49678f64769b351e2a3f56 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Fri, 16 Oct 2015 17:37:38 +0100
Subject: [PATCH 35/39] Update RELEASENOTES.md
---
RELEASENOTES.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 91bcce92..904481f0 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -10,7 +10,7 @@ Another possible reason might be because the range specified by the mixer does n
Version 2.5.0.8
----
**Important Bug fix**
-* Sometimes, especially when using Shairport Sync as a system output, it would not play the audio stream. This was caused by an improperly initialised variable. Fixed. It may also be implcated in the continuing issue with Synology devices being unable to play to Shairport Sync.
+* Sometimes, especially when using Shairport Sync as a system output, it would not play the audio stream. This was caused by an improperly initialised variable. Fixed. It may also be implicated in the continuing issue with Synology devices being unable to play to Shairport Sync.
Version 2.5.0.7
----
From 529e81bb2b749c1c4c21d60022ec803ea35afc81 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Fri, 16 Oct 2015 17:39:03 +0100
Subject: [PATCH 36/39] Update RELEASENOTES.md
---
RELEASENOTES.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 904481f0..56468497 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -1,7 +1,8 @@
Version 2.5.0.9
----
**New Feature**
-* Set Volume Range. This is a new setting that allows you to use just a portion of the full range of attenuation offered by a mixer. For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available. This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting -- (for this reason, many domestic HiFi systems have a volume control range of only 60 to 80 dB).
+* Set Volume Range. This is a new setting that allows you to use just a portion of the full range of attenuation offered by a mixer. For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available. This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting. It is for this reason that many domestic HiFi systems have a volume control range of only 60 to 80 dB.
+
Another possible reason might be because the range specified by the mixer does not match the capabilities of the device. For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB. The new `volume_range_db` setting in the `general` stanza allows you to specify the maximum range from highest to lowest. The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 35. Using it in this case gives the volume control a much more useful range of settings.
**Other Changes**
From f30d2249870ca2f18357892be1e6eee0b38afb9e Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Fri, 16 Oct 2015 17:40:10 +0100
Subject: [PATCH 37/39] Update RELEASENOTES.md
---
RELEASENOTES.md | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 56468497..cac3bb0c 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -2,8 +2,7 @@ Version 2.5.0.9
----
**New Feature**
* Set Volume Range. This is a new setting that allows you to use just a portion of the full range of attenuation offered by a mixer. For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available. This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting. It is for this reason that many domestic HiFi systems have a volume control range of only 60 to 80 dB.
-
-Another possible reason might be because the range specified by the mixer does not match the capabilities of the device. For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB. The new `volume_range_db` setting in the `general` stanza allows you to specify the maximum range from highest to lowest. The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 35. Using it in this case gives the volume control a much more useful range of settings.
+ Another possible reason might be because the range specified by the mixer does not match the capabilities of the device. For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB. The new `volume_range_db` setting in the `general` stanza allows you to specify the maximum range from highest to lowest. The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 35. Using it in this case gives the volume control a much more useful range of settings.
**Other Changes**
* Initial timing accuracy improved. The estimate of when to play the starting frame of the audio sequence has improved significantly. This leads to fewer corrections being needed at the start.
From 7266dacd0dae67d38ed70b8721ce6079a8097ad6 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sat, 17 Oct 2015 11:05:19 +0100
Subject: [PATCH 38/39] Minor changes to man pages.
---
man/shairport-sync.7 | 2 +-
man/shairport-sync.html | 10 +++++++---
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/man/shairport-sync.7 b/man/shairport-sync.7
index e5a64ba4..df42352d 100644
--- a/man/shairport-sync.7
+++ b/man/shairport-sync.7
@@ -100,7 +100,7 @@ Use this to specify how much debugging information should be output or logged. "
Set this \fIchoice\f1 to "yes" if you want the volume to be at 100% no matter what the source's volume control is set to. This might be useful if you want to set the volume on the output device, independently of the setting at the source. The default is "no".
.TP
\fBvolume_range_db=\f1\fIdBvalue\f1\fB;\f1
-Set this \fIdBvalue\f1 to use just a portion of the full range of attenuation offered by a mixer. For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available. This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting. Or it might be because the range specified by the mixer does not match the capabilities of the device. For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB. The setting allows you to specify the maximum range from highest to lowest. Many domestic HiFi systems have a range of 60 to 80 dB. The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 35. Using it in this case gives the volume control a much more useful range of settings. If you omit this setting, the full "native" range of the output device is used.
+Set this \fIdBvalue\f1 to use just a portion of the full range of attenuation offered by a mixer. For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available. This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting -- indeed, many domestic HiFi systmes have a volume copntrol range of just 60 to 80dB. Another potential use might be where the range specified by the mixer does not match the capabilities of the device. For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB. The setting allows you to specify the maximum range from highest to lowest. The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 35. Using it in this case gives the volume control a much more useful range of settings. If you omit this setting, the full "native" range of the mixer is used.
.TP
\fB"ALSA" SETTINGS\f1
These settings are for the ALSA back end, used to communicate with audio output devices in the ALSA system. (By the way, you can use tools such as \fBalsamixer\f1 or \fBaplay\f1 to discover what devices are available.) Use these settings to select the output device and the mixer control to be used to control the output volume. You can additionally set the desired size of the output buffer and you can adjust overall latency. Here are the \fBalsa\f1 group settings:
diff --git a/man/shairport-sync.html b/man/shairport-sync.html
index 0930dc1d..0fe6a88d 100644
--- a/man/shairport-sync.html
+++ b/man/shairport-sync.html
@@ -176,10 +176,14 @@
volume_range_db=dBvalue;
- Set this dBvalue to use just a portion of the full range of attenuation offered by a mixer. For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available. This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting. Or it might be because the range specified by the mixer does not match the capabilities of the device. For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB. The setting allows you to specify the maximum range from highest to lowest. Many domestic HiFi systems have a range of 60 to 80 dB. The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 35. Using it in this case gives the volume control a much more useful range of settings. If you omit this setting, the full "native" range of the output device is used.
+ Set this dBvalue to use just a portion of the full range of attenuation offered by a mixer.
+For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available.
+This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting -- indeed, many domestic HiFi systmes have a volume copntrol range of just 60 to 80dB.
+Another potential use might be where the range specified by the mixer does not match the capabilities of the device.
+For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB.
+The setting allows you to specify the maximum range from highest to lowest. The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 35.
+Using it in this case gives the volume control a much more useful range of settings. If you omit this setting, the full "native" range of the mixer is used.
-
-
"ALSA" SETTINGS
These settings are for the ALSA back end, used to communicate with audio output devices in the ALSA system.
From 2a6071e9ce6047a56a6507a0a3ccbd31251b7e91 Mon Sep 17 00:00:00 2001
From: Mike Brady
Date: Sat, 17 Oct 2015 11:11:57 +0100
Subject: [PATCH 39/39] Fix a misspelling and quieten a debug message.
---
rtp.c | 2 +-
rtsp.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/rtp.c b/rtp.c
index 8ab96589..fcffd860 100644
--- a/rtp.c
+++ b/rtp.c
@@ -198,7 +198,7 @@ static void *rtp_control_receiver(void *arg) {
uint32_t la = sync_rtp_timestamp-rtp_timestamp_less_latency+11025;
if (la!=config.latency) {
config.latency = la;
- debug(1,"Using negotiated latency of %u frames.",config.latency);
+ // debug(1,"Using negotiated latency of %u frames.",config.latency);
}
}
diff --git a/rtsp.c b/rtsp.c
index c03bb72f..1085de15 100644
--- a/rtsp.c
+++ b/rtsp.c
@@ -584,7 +584,7 @@ static void msg_write_response(int fd, rtsp_message *resp) {
static void handle_record(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) {
//debug(1,"Handle Record");
resp->respcode = 200;
- // I think this is for telling the client what the asbsolute minimum latency actually is,
+ // I think this is for telling the client what the absolute minimum latency actually is,
// and when the client specifies a latency, it should be added to this figure.
// Thus, AirPlay's latency figure of 77175, when added to 11025 gives you exactly 88200