Squashed commit of the following:

commit 85fae473bb
Merge: bf91d35 854942d
Author: Mike Brady <mikebrady@eircom.net>
Date:   Tue Jun 4 22:15:37 2019 +0100

    Merge pull request #860 from joerg-krause/patch-2

    Debug requested period size value

commit 854942df92
Author: Jörg Krause <joerg.krause@embedded.rocks>
Date:   Tue Jun 4 20:47:43 2019 +0200

    Debug requested period size value

commit bf91d35bfb
Author: Mike Brady <mikebrady@eircom.net>
Date:   Tue Jun 4 15:33:30 2019 +0100

    Update RELEASENOTES-DEVELOPMENT.md

commit 3ca3408255
Author: Mike Brady <mikebrady@eircom.net>
Date:   Tue Jun 4 15:32:10 2019 +0100

    Fix error message for invalid standby mode choice

commit 4bafe1c982
Author: Mike Brady <mikebrady@eircom.net>
Date:   Mon Jun 3 10:03:54 2019 +0100

    quieten a compilation warning

commit 9d96906402
Author: Mike Brady <mikebrady@eircom.net>
Date:   Sun Jun 2 18:05:40 2019 +0100

    Update configure.ac

commit 0c5c4bfe3f
Author: Mike Brady <mikebrady@eircom.net>
Date:   Sun Jun 2 18:04:51 2019 +0100

    Update RELEASENOTES-DEVELOPMENT.md

commit 85cc1bdd97
Author: Mike Brady <mikebrady@eircom.net>
Date:   Sun Jun 2 17:56:47 2019 +0100

    Fix the dither calculation -- it was 12 dB too high, really noticable on the U8 setting.

commit 25f0fbc24d
Author: Mike Brady <mikebrady@eircom.net>
Date:   Sun Jun 2 13:42:19 2019 +0100

    Update INSTALL.md

commit d91e41d976
Author: Mike Brady <mikebrady@eircom.net>
Date:   Wed May 29 17:26:44 2019 +0100

    Add missing support for S32_LE, S32_BE, S24_LE and S24_LE formats.

commit 7f2e6b1aac
Author: Mike Brady <mikebrady@eircom.net>
Date:   Wed May 29 16:18:51 2019 +0100

    Add support for S32_LE, S32_BE, S24_LE and S24_BE wqhen generating frames of dithered silence

commit 76ad4e6a73
Author: Mike Brady <mikebrady@eircom.net>
Date:   Wed May 29 16:00:47 2019 +0100

    enable specification of specific formats and/or speeds to turn off automatic format/speed selection, fixing a bug. Clarify some of the warnings. Fix a few typos in the configuration file sample.

commit a8222e3f85
Merge: c677006 19fbede
Author: Mike Brady <mikebrady@eircom.net>
Date:   Mon May 27 09:30:57 2019 +0100

    Merge pull request #855 from idcrook/conf_mqtt_port

    mqtt port config changes – fix error in the configuration file and check port number for sanity.
    Many thanks, David. It'll find it's easy into the next release.

commit 19fbededcf
Author: David Crook <idcrook@users.noreply.github.com>
Date:   Sat May 25 13:01:22 2019 -0600

    mqtt port config changes

    1. update example shairport-sync.conf file
    2. update config file mqtt port parsing

    Signed-off-by: David Crook <idcrook@users.noreply.github.com>

commit c677006541
Merge: 744c595 3c4a878
Author: Mike Brady <mikebrady@eircom.net>
Date:   Fri May 24 17:37:26 2019 +0100

    Bring into line with master 3.3
This commit is contained in:
Mike Brady
2019-06-05 15:02:26 +01:00
parent 3c4a878ad9
commit 1704916a47
6 changed files with 120 additions and 50 deletions
-1
View File
@@ -9,7 +9,6 @@ Do the usual update and upgrade:
```
# apt-get update
# apt-get upgrade
# rpi-update
```
(Separately, if you haven't done so already, consider using the `raspi-config` tool to expand the file system to use the entire card.)
+41 -26
View File
@@ -192,7 +192,9 @@ static void help(void) {
" -c mixer-control set the mixer control name, default is to use no mixer.\n"
" -m mixer-device set the mixer device, default is the output device.\n"
" -i mixer-index set the mixer index, default is 0.\n");
system("if [ -d /proc/asound ] ; then echo \" hardware output devices:\" ; ls -al /proc/asound/ 2>/dev/null | grep '\\->' | tr -s ' ' | cut -d ' ' -f 9 | while read line; do echo \" \\\"hw:$line\\\"\" ; done ; fi");
int r = system("if [ -d /proc/asound ] ; then echo \" hardware output devices:\" ; ls -al /proc/asound/ 2>/dev/null | grep '\\->' | tr -s ' ' | cut -d ' ' -f 9 | while read line; do echo \" \\\"hw:$line\\\"\" ; done ; fi");
if (r != 0)
debug(2, "error %d executing a script to list alsa hardware device names", r);
}
void set_alsa_out_dev(char *dev) { alsa_out_dev = dev; }
@@ -510,7 +512,7 @@ int actual_open_alsa_device(int do_auto_setup) {
}
if (set_period_size_request != 0) {
debug(1, "Attempting to set the period size");
debug(1, "Attempting to set the period size to %lu", period_size_requested);
ret = snd_pcm_hw_params_set_period_size_near(alsa_handle, alsa_params, &period_size_requested,
&dir);
if (ret < 0) {
@@ -1037,6 +1039,8 @@ static int init(int argc, char **argv) {
/* Get the output format, using the same names as aplay does*/
if (config_lookup_string(config.cfg, "alsa.output_format", &str)) {
int temp_output_format_auto_requested = config.output_format_auto_requested;
config.output_format_auto_requested = 0; // assume a valid format will be given.
if (strcasecmp(str, "S16") == 0)
config.output_format = SPS_FORMAT_S16;
else if (strcasecmp(str, "S16_LE") == 0)
@@ -1066,11 +1070,12 @@ static int init(int argc, char **argv) {
else if (strcasecmp(str, "auto") == 0)
config.output_format_auto_requested = 1;
else {
warn("Invalid output format \"%s\". It should be \"U8\", \"S8\", "
config.output_format_auto_requested = temp_output_format_auto_requested; //format was invalid; recall the original setting
warn("Invalid output format \"%s\". It should be \"auto\", \"U8\", \"S8\", "
"\"S16\", \"S24\", \"S24_LE\", \"S24_BE\", "
"\"S24_3LE\", \"S24_3BE\" or "
"\"S32\", \"S32_LE\", \"S32_BE\". It is set to \"%s\".",
sps_format_description_string(config.output_format));
"\"S32\", \"S32_LE\", \"S32_BE\". It remains set to \"%s\".", str,
config.output_format_auto_requested == 1 ? "auto" : sps_format_description_string(config.output_format));
}
}
@@ -1078,25 +1083,35 @@ static int init(int argc, char **argv) {
if (strcasecmp(str, "auto") == 0) {
config.output_rate_auto_requested = 1;
} else {
/* Get the output rate, which must be a multiple of 44,100*/
if (config_lookup_int(config.cfg, "alsa.output_rate", &value)) {
debug(1, "alsa output rate is %d frames per second", value);
switch (value) {
case 44100:
case 88200:
case 176400:
case 352800:
config.output_rate = value;
break;
default:
warn("Invalid output rate \"%d\". It should be \"auto\" or a multiple of 44,100 up "
"to 352,800. It is "
"set to %d.",
value,config.output_rate);
}
}
if (config.output_rate_auto_requested == 1)
warn("Invalid output rate \"%s\". It should be \"auto\", 44100, 88200, 176400 or 352800. "
"It remains set to \"auto\". Note: numbers should not be placed in quotes.", str);
else
warn("Invalid output rate \"%s\". It should be \"auto\", 44100, 88200, 176400 or 352800. "
"It remains set to %d. Note: numbers should not be placed in quotes.", str, config.output_rate);
}
}
}
/* Get the output rate, which must be a multiple of 44,100*/
if (config_lookup_int(config.cfg, "alsa.output_rate", &value)) {
debug(1, "alsa output rate is %d frames per second", value);
switch (value) {
case 44100:
case 88200:
case 176400:
case 352800:
config.output_rate = value;
config.output_rate_auto_requested = 0;
break;
default:
if (config.output_rate_auto_requested == 1)
warn("Invalid output rate \"%d\". It should be \"auto\", 44100, 88200, 176400 or 352800. "
"It remains set to \"auto\".",value);
else
warn("Invalid output rate \"%d\".It should be \"auto\", 44100, 88200, 176400 or 352800. "
"It remains set to %d.", value, config.output_rate);
}
}
/* Get the use_mmap_if_available setting. */
if (config_lookup_string(config.cfg, "alsa.use_mmap_if_available", &str)) {
@@ -1107,7 +1122,7 @@ static int init(int argc, char **argv) {
else {
warn("Invalid use_mmap_if_available option choice \"%s\". It should be "
"\"yes\" or \"no\". "
"It is set to \"yes\".");
"It remains set to \"yes\".");
config.no_mmap = 0;
}
}
@@ -1163,7 +1178,7 @@ static int init(int argc, char **argv) {
else {
warn("Invalid disable_standby_mode option choice \"%s\". It should be "
"\"always\", \"auto\" or \"never\". "
"It is set to \"never\".");
"It remains set to \"never\".", str);
}
}
@@ -1179,7 +1194,7 @@ static int init(int argc, char **argv) {
else {
warn("Invalid use_precision_timing option choice \"%s\". It should be "
"\"yes\", \"auto\" or \"no\". "
"It is set to \"auto\".");
"It remains set to \"%s\".", config.use_precision_timing == YNA_NO ? "no" : config.use_precision_timing == YNA_AUTO ? "auto" : "yes");
}
}
+54 -6
View File
@@ -1376,12 +1376,14 @@ int64_t generate_zero_frames(char *outp, size_t number_of_frames, enum sps_forma
int64_t hyper_sample = 0;
// add a TPDF dither -- see
// http://www.users.qwest.net/%7Evolt42/cadenzarecording/DitherExplained.pdf
// http://educypedia.karadimov.info/library/DitherExplained.pdf
// and the discussion around https://www.hydrogenaud.io/forums/index.php?showtopic=16963&st=25
// I think, for a 32 --> 16 bits, the range of
// random numbers needs to be from -2^16 to 2^16, i.e. from -65536 to 65536 inclusive, not from
// -32768 to +32767
// Actually, what would be generated here is from -65535 to 65535, i.e. one less on the limits.
// See the original paper at
// http://www.ece.rochester.edu/courses/ECE472/resources/Papers/Lipshitz_1992.pdf
@@ -1392,23 +1394,23 @@ int64_t generate_zero_frames(char *outp, size_t number_of_frames, enum sps_forma
case SPS_FORMAT_S32:
case SPS_FORMAT_S32_LE:
case SPS_FORMAT_S32_BE:
dither_mask = (int64_t)1 << (64 + 1 - 32);
dither_mask = (int64_t)1 << (64 - 32);
break;
case SPS_FORMAT_S24:
case SPS_FORMAT_S24_LE:
case SPS_FORMAT_S24_BE:
case SPS_FORMAT_S24_3LE:
case SPS_FORMAT_S24_3BE:
dither_mask = (int64_t)1 << (64 + 1 - 24);
dither_mask = (int64_t)1 << (64 - 24);
break;
case SPS_FORMAT_S16:
case SPS_FORMAT_S16_LE:
case SPS_FORMAT_S16_BE:
dither_mask = (int64_t)1 << (64 + 1 - 16);
dither_mask = (int64_t)1 << (64 - 16);
break;
case SPS_FORMAT_S8:
case SPS_FORMAT_U8:
dither_mask = (int64_t)1 << (64 + 1 - 8);
dither_mask = (int64_t)1 << (64 - 8);
break;
case SPS_FORMAT_UNKNOWN:
die("Unexpected SPS_FORMAT_UNKNOWN while calculating dither mask.");
@@ -1442,6 +1444,30 @@ int64_t generate_zero_frames(char *outp, size_t number_of_frames, enum sps_forma
*(int32_t *)op = hyper_sample;
result = 4;
break;
case SPS_FORMAT_S32_LE:
hyper_sample >>= (64 - 32);
byt = (uint8_t)hyper_sample;
*op++ = byt;
byt = (uint8_t)(hyper_sample >> 8);
*op++ = byt;
byt = (uint8_t)(hyper_sample >> 16);
*op++ = byt;
byt = (uint8_t)(hyper_sample >> 24);
*op++ = byt;
result = 4;
break;
case SPS_FORMAT_S32_BE:
hyper_sample >>= (64 - 32);
byt = (uint8_t)(hyper_sample >> 24);
*op++ = byt;
byt = (uint8_t)(hyper_sample >> 16);
*op++ = byt;
byt = (uint8_t)(hyper_sample >> 8);
*op++ = byt;
byt = (uint8_t)hyper_sample;
*op++ = byt;
result = 4;
break;
case SPS_FORMAT_S24_3LE:
hyper_sample >>= (64 - 24);
byt = (uint8_t)hyper_sample;
@@ -1467,6 +1493,28 @@ int64_t generate_zero_frames(char *outp, size_t number_of_frames, enum sps_forma
*(int32_t *)op = hyper_sample;
result = 4;
break;
case SPS_FORMAT_S24_LE:
hyper_sample >>= (64 - 24);
byt = (uint8_t)hyper_sample;
*op++ = byt;
byt = (uint8_t)(hyper_sample >> 8);
*op++ = byt;
byt = (uint8_t)(hyper_sample >> 16);
*op++ = byt;
*op++ = 0;
result = 4;
break;
case SPS_FORMAT_S24_BE:
hyper_sample >>= (64 - 24);
*op++ = 0;
byt = (uint8_t)(hyper_sample >> 16);
*op++ = byt;
byt = (uint8_t)(hyper_sample >> 8);
*op++ = byt;
byt = (uint8_t)hyper_sample;
*op++ = byt;
result = 4;
break;
case SPS_FORMAT_S16_LE:
hyper_sample >>= (64 - 16);
byt = (uint8_t)hyper_sample;
@@ -1501,7 +1549,7 @@ int64_t generate_zero_frames(char *outp, size_t number_of_frames, enum sps_forma
break;
default:
result = 0; // stop a compiler warning
die("Unexpected SPS_FORMAT_UNKNOWN while outputting samples");
die("Unexpected SPS_FORMAT_* with index %d while outputting silence",format);
}
p += result;
previous_random_number = r;
+12 -5
View File
@@ -650,12 +650,14 @@ static inline void process_sample(int32_t sample, char **outp, enum sps_format_t
if (dither) {
// add a TPDF dither -- see
// http://www.users.qwest.net/%7Evolt42/cadenzarecording/DitherExplained.pdf
// http://educypedia.karadimov.info/library/DitherExplained.pdf
// and the discussion around https://www.hydrogenaud.io/forums/index.php?showtopic=16963&st=25
// I think, for a 32 --> 16 bits, the range of
// random numbers needs to be from -2^16 to 2^16, i.e. from -65536 to 65536 inclusive, not from
// -32768 to +32767
// Actually, what would be generated here is from -65535 to 65535, i.e. one less on the limits.
// See the original paper at
// http://www.ece.rochester.edu/courses/ECE472/resources/Papers/Lipshitz_1992.pdf
@@ -666,23 +668,23 @@ static inline void process_sample(int32_t sample, char **outp, enum sps_format_t
case SPS_FORMAT_S32:
case SPS_FORMAT_S32_LE:
case SPS_FORMAT_S32_BE:
dither_mask = (int64_t)1 << (64 + 1 - 32);
dither_mask = (int64_t)1 << (64 - 32);
break;
case SPS_FORMAT_S24:
case SPS_FORMAT_S24_LE:
case SPS_FORMAT_S24_BE:
case SPS_FORMAT_S24_3LE:
case SPS_FORMAT_S24_3BE:
dither_mask = (int64_t)1 << (64 + 1 - 24);
dither_mask = (int64_t)1 << (64 - 24);
break;
case SPS_FORMAT_S16:
case SPS_FORMAT_S16_LE:
case SPS_FORMAT_S16_BE:
dither_mask = (int64_t)1 << (64 + 1 - 16);
dither_mask = (int64_t)1 << (64 - 16);
break;
case SPS_FORMAT_S8:
case SPS_FORMAT_U8:
dither_mask = (int64_t)1 << (64 + 1 - 8);
dither_mask = (int64_t)1 << (64 - 8);
break;
case SPS_FORMAT_UNKNOWN:
die("Unexpected SPS_FORMAT_UNKNOWN while calculating dither mask.");
@@ -1673,10 +1675,15 @@ void *player_thread_func(void *arg) {
case SPS_FORMAT_S24_3BE:
conn->output_bytes_per_frame = 6;
break;
case SPS_FORMAT_S24:
case SPS_FORMAT_S24_LE:
case SPS_FORMAT_S24_BE:
conn->output_bytes_per_frame = 8;
break;
case SPS_FORMAT_S32:
case SPS_FORMAT_S32_LE:
case SPS_FORMAT_S32_BE:
conn->output_bytes_per_frame = 8;
break;
default:
+6 -6
View File
@@ -31,7 +31,7 @@ general =
// volume_control_profile = "standard" ; // use this advanced setting to specify how the airplay volume is transferred to the mixer volume.
// "standard" makes the volume change more quickly at lower volumes and slower at higher volumes.
// "flat" makes the volume change at the same rate at all volumes.
// volume_range_combined_hardware_priority = "no"; // when extending the volume range by combining the built-in software attenuator with the hardware mixer attenuator, set this to "yes" to reduce volume by using the hardware mixer first, then the built-in software attenuator.
// volume_range_combined_hardware_priority = "no"; // when extending the volume range by combining the built-in software attenuator with the hardware mixer attenuator, set this to "yes" to reduce volume by using the hardware mixer first, then the built-in software attenuator.
// run_this_when_volume_is_set = "/full/path/to/application/and/args"; // Run the specified application whenever the volume control is set or changed.
// The desired AirPlay volume is appended to the end of the command line – leave a space if you want it treated as an extra argument.
// AirPlay volume goes from 0 to -30 and -144 means "mute".
@@ -84,7 +84,7 @@ alsa =
// 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.
// output_rate = "auto"; // can be "auto", 44100, 88200, 176400 or 352800, but the device must have the capability.
// output_format = "auto"; // can be "auto", ""U8", "S8", "S16", "S16_LE", "S16_BE", "S24", "S24_LE", "S24_BE", "S24_3LE", "S24_3BE", "S32", "S32_LE" or "S32_BE" but the device must have the capability. Except where stated using (*LE or *BE), endianness matches that of the processor.
// output_format = "auto"; // can be "auto", "U8", "S8", "S16", "S16_LE", "S16_BE", "S24", "S24_LE", "S24_BE", "S24_3LE", "S24_3BE", "S32", "S32_LE" or "S32_BE" but the device must have the capability. Except where stated using (*LE or *BE), endianness matches that of the processor.
// disable_synchronization = "no"; // Set to "yes" to disable synchronization. Default is "no".
// period_size = <number>; // Use this optional advanced setting to set the alsa period size near to this value
// buffer_size = <number>; // Use this optional advanced setting to set the alsa buffer size near to this value
@@ -199,9 +199,9 @@ mqtt =
{
// enabled = "no"; // set this to yes to enable the mqtt-metadata-service
// hostname = "iot.eclipse.org"; // Hostname of the MQTT Broker
// port = "1883";
// username = NULL; //set this to a string with your username, to enable username authentication
// password = NULL; //set this to a string with your password, to enable username & password authentication
// port = 1883; // Port on the MQTT Broker to connect to
// username = NULL; //set this to a string to your username in order to enable username authentication
// password = NULL; //set this to a string you your password in order to enable username & password authentication
// capath = NULL; //set this to the folder with the CA-Certificates to be accepted for the server certificate. If not set, TLS is not used
// cafile = NULL; //this may be used as an (exclusive) alternative to capath with a single file for all ca-certificates
// certfile = NULL; //set this to a string to a user certificate to enable MQTT Client certificates. keyfile must also be set!
@@ -216,7 +216,7 @@ mqtt =
// Available commands are "command", "beginff", "beginrew", "mutetoggle", "nextitem", "previtem", "pause", "playpause", "play", "stop", "playresume", "shuffle_songs", "volumedown", "volumeup"
}
// Diagnostic settings. These are for diagnostic and debugging only. Normally you sould leave them commented out
// Diagnostic settings. These are for diagnostic and debugging only. Normally you should leave them commented out
diagnostics =
{
// disable_resend_requests = "no"; // set this to yes to stop Shairport Sync from requesting the retransmission of missing packets. Default is "no".
+7 -6
View File
@@ -992,7 +992,6 @@ int parse_options(int argc, char **argv) {
#endif
#ifdef CONFIG_MQTT
int tmpval = 0;
config_set_lookup_bool(config.cfg, "mqtt.enabled", &config.mqtt_enabled);
if (config.mqtt_enabled && !config.metadata_enabled) {
die("You need to have metadata enabled in order to use mqtt");
@@ -1001,11 +1000,13 @@ int parse_options(int argc, char **argv) {
config.mqtt_hostname = (char *)str;
// TODO: Document that, if this is false, whole mqtt func is disabled
}
if (config_lookup_int(config.cfg, "mqtt.port", &tmpval)) {
config.mqtt_port = tmpval;
} else {
// TODO: Is this the correct way to set a default value?
config.mqtt_port = 1883;
config.mqtt_port = 1883;
if (config_lookup_int(config.cfg, "mqtt.port", &value)) {
if ((value < 0) || (value > 65535))
die("Invalid mqtt port number \"%sd\". It should be between 0 and 65535, default is 1883",
value);
else
config.mqtt_port = value;
}
if (config_lookup_string(config.cfg, "mqtt.username", &str)) {