Update to 2.8.5
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
/INSTALL
|
||||
/shairport-sync
|
||||
/shairport-sync.exe
|
||||
/*.o
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
Installation Instructions
|
||||
*************************
|
||||
|
||||
Please refer to README.md for installation instructions.
|
||||
+6
-6
@@ -3,7 +3,7 @@ SUBDIRS = man
|
||||
bin_PROGRAMS = shairport-sync
|
||||
shairport_sync_SOURCES = shairport.c rtsp.c mdns.c mdns_external.c common.c rtp.c player.c alac.c audio.c
|
||||
|
||||
AM_CFLAGS = -Wno-multichar
|
||||
AM_CFLAGS = -Wno-multichar -DSYSCONFDIR=\"$(sysconfdir)\"
|
||||
|
||||
if USE_CUSTOMPIDDIR
|
||||
AM_CFLAGS+= \
|
||||
@@ -52,13 +52,13 @@ endif
|
||||
|
||||
install-exec-hook:
|
||||
if INSTALL_CONFIG_FILES
|
||||
[ -e $(DESTDIR)/etc ] || mkdir $(DESTDIR)/etc
|
||||
cp scripts/shairport-sync.conf $(DESTDIR)/etc/shairport-sync.conf.sample
|
||||
[ -f $(DESTDIR)/etc/shairport-sync.conf ] || cp scripts/shairport-sync.conf $(DESTDIR)/etc/shairport-sync.conf
|
||||
[ -e $(DESTDIR)$(sysconfdir) ] || mkdir $(DESTDIR)$(sysconfdir)
|
||||
cp scripts/shairport-sync.conf $(DESTDIR)$(sysconfdir)/shairport-sync.conf.sample
|
||||
[ -f $(DESTDIR)$(sysconfdir)/shairport-sync.conf ] || cp scripts/shairport-sync.conf $(DESTDIR)$(sysconfdir)/shairport-sync.conf
|
||||
endif
|
||||
if INSTALL_SYSTEMV
|
||||
[ -e $(DESTDIR)/etc/init.d ] || mkdir -p $(DESTDIR)/etc/init.d
|
||||
[ -f $(DESTDIR)/etc/init.d/shairport-sync ] || cp scripts/shairport-sync $(DESTDIR)/etc/init.d/
|
||||
[ -e $(DESTDIR)$(sysconfdir)/init.d ] || mkdir -p $(DESTDIR)$(sysconfdir)/init.d
|
||||
[ -f $(DESTDIR)$(sysconfdir)/init.d/shairport-sync ] || cp scripts/shairport-sync $(DESTDIR)$(sysconfdir)/init.d/
|
||||
endif
|
||||
if INSTALL_SYSTEMD
|
||||
[ -e $(DESTDIR)$(systemdsystemunitdir) ] || mkdir -p $(DESTDIR)$(systemdsystemunitdir)
|
||||
|
||||
@@ -6,6 +6,8 @@ Audio played by a Shairport Sync-powered device stays synchronised with the sour
|
||||
Shairport Sync does not support AirPlay video or photo streaming.
|
||||
|
||||
This is the stable "master" branch. Changes and updates are incorporated into this branch relatively slowly. To access the development version, where all the latest changes are made first, please switch to the "development" branch.
|
||||
**Please note that, between 2.8.4 and 2.8.5, there is a change in the standard ./configure arguments which you should not ignore!**
|
||||
|
||||
|
||||
More Information
|
||||
----------
|
||||
@@ -51,6 +53,7 @@ Note: Historically, Shairport Sync has taken its settings from command line argu
|
||||
|
||||
Building And Installing
|
||||
---------------------
|
||||
|
||||
Shairport Sync may already be available as a package in your Linux distribution (search for `shairport-sync` – the package named `shairport` is a different program). Packages are available on recent versions of Debian, Ubuntu, Arch, OpenWrt and possibly more. If you wish to build and install the latest version of Shairport Sync on OpenWrt, Arch or Fedora platforms, please follow the appropriate instructions below. Limited support is also available for Mac OS X. Otherwise follow the General Build Instructions. Then, when the program has been installed, refer to the section on Configuring Shairport Sync that follows.
|
||||
|
||||
**Note**
|
||||
@@ -112,7 +115,7 @@ Debian, Ubuntu and Raspbian users can get the basics with:
|
||||
- `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 in many recent distributions, including Jessie and Raspioan Jessie; if not, instructions for how to build it from source for Raspian/Debian Wheezy are available at [LIBSOXR.md](https://github.com/mikebrady/shairport-sync/blob/master/LIBSOXR.md).
|
||||
|
||||
Download Shairport Sync:
|
||||
**Download Shairport Sync:**
|
||||
|
||||
`$ git clone https://github.com/mikebrady/shairport-sync.git`
|
||||
|
||||
@@ -123,7 +126,7 @@ $ autoreconf -i -f
|
||||
```
|
||||
(Note that the `autoreconf...` step may take some time on less powerful machines.)
|
||||
|
||||
Choose the appropriate `--with-*` options:
|
||||
**Choose the appropriate `--with-*` options:**
|
||||
|
||||
- `--with-alsa` for the ALSA audio back end. This is required.
|
||||
- `--with-stdout` include an optional backend module to enable raw audio to be output through standard output (stdout).
|
||||
@@ -138,7 +141,7 @@ 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.
|
||||
|
||||
**`systemd` and "System V"**
|
||||
**Determine if it's a `systemd` or a "System V" installation:**
|
||||
|
||||
At the time of writing, there are two widely-used systems for starting programs automatically at startup: `systemd` and "System V" . (There are others, but they are not considered here.) To see if the `systemd` process is running on your system, enter the following command:
|
||||
|
||||
@@ -161,20 +164,28 @@ pi@raspberrypi ~ $
|
||||
```
|
||||
Choose `--with-systemd` or `--with-systemv` on the basis of the outcome.
|
||||
|
||||
Here is an example, suitable for installations that use `systemd`, such as Ubuntu 15.10 and Raspbian Jessie:
|
||||
**Choose the location of the configuration file**
|
||||
|
||||
`$ ./configure --with-alsa --with-avahi --with-ssl=openssl --with-metadata --with-soxr --with-systemd`
|
||||
A final consideration is the location of the configuration file `shairport-sync.conf`. This will be placed in the directory specified by the `sysconfdir` configuration variable, which defaults to `/usr/local/etc`. This is normal in BSD Unixes, but is unusual in Linux. Hence, for Linux installations, you need to set the `sysconfdir` variable to `/etc` using the configuration setting `--sysconfdir=/etc`.
|
||||
|
||||
**Sample `./configure` command with parameters for a typical Linux `systemd` installation:**
|
||||
|
||||
Here is an example, suitable for Linux installations that use `systemd`, such as Ubuntu 15.10 and Raspbian Jessie:
|
||||
|
||||
`$ ./configure --sysconfdir=/etc --with-alsa --with-avahi --with-ssl=openssl --with-metadata --with-soxr --with-systemd`
|
||||
|
||||
* Omit the `--with-soxr` if the libsoxr library is not available.
|
||||
* For installation into a System V system, replace the `--with-systemd` with `--with-systemv`.
|
||||
|
||||
**Build the application:**
|
||||
|
||||
Enter:
|
||||
|
||||
`$ make`
|
||||
|
||||
to build the application.
|
||||
|
||||
**Installation to a `systemd` system**
|
||||
**Install into to a `systemd` system**
|
||||
To complete the installation, you need to define a `shairport-sync` group and user. This is a security measure – the user and group are relatively unprivileged, and the user does not have login 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:
|
||||
|
||||
```
|
||||
@@ -194,7 +205,7 @@ To enable Shairport Sync to start automatically at system startup, enter:
|
||||
|
||||
`$ sudo systemctl enable shairport-sync`
|
||||
|
||||
**Installation to a System V system**
|
||||
**Install into a System V system**
|
||||
If you are installing onto a System V system:
|
||||
|
||||
```
|
||||
|
||||
@@ -1,3 +1,77 @@
|
||||
Version 2.8.5 – Stable Version
|
||||
----
|
||||
This release includes bug fixes and minor enhancements and is recommended for all users.
|
||||
|
||||
There is once change you should not ignore:
|
||||
====
|
||||
|
||||
* The build process now uses the directory path `sysconfdir` to determine where to place the configuration file `shairport-sync.conf`.
|
||||
The default value for `sysconfdir` is `/usr/local/etc` which is used in the BSD family, whereas `/etc` is normally used in Linux.
|
||||
So, to retain the present behaviour of Shairport Sync, *you must add an extra parameter to the `./configure... ` command.* The parameter you must add is `--sysconfdir=/etc`. (This has been added to the sample configuration command line in README.md.)
|
||||
* Shairport Sync has been updated to use the value of `sysconfdir` to determine where to look for the configuration file.
|
||||
If `sysconfdir` has been left with its default value of `/usr/local/etc`, then Shairport Sync will look for `/usr/local/etc/shairport-sync.conf`.
|
||||
If, as recommended for Linux, `sysconfdir` has been set to `/etc`, then Shairport Sync will look, as before, for `/etc/shairport-sync.conf`.
|
||||
|
||||
For advice on updating an installation you built yourself,
|
||||
please visit the [UPDATING](https://github.com/mikebrady/shairport-sync/blob/master/UPDATING.md) page.
|
||||
|
||||
The enhancements and bug fixes were made in versions 2.8.4.1 to 2.8.4.8 inclusive. Please read below for the full list.
|
||||
|
||||
=======
|
||||
Version 2.8.4.8 – Development Version
|
||||
----
|
||||
**Enhancements**
|
||||
* Add a new metadata item `clip` (for `CL`ient `IP`). This item is a string comprising the IP number of the "client", and is sent when a play session is starting. The "client" is the sender of the audio stream, e.g. iTunes on a Mac, or the Music player in iOS.
|
||||
* When synchronisation has been disabled on the ALSA device (you should only do this for testing), Shairport Sync now refrains from asking for buffer length information from the device.
|
||||
|
||||
Version 2.8.4.7 – Development Version
|
||||
----
|
||||
|
||||
* This update means the build process now uses the directory path `sysconfdir` to determine where to place the configuration file `shairport-sync.conf`. The default value for `sysconfdir` is `/usr/local/etc` which is used in the BSD family, whereas `/etc` is normally used in Linux. So, to retain the present behaviour of Shairport Sync, you must add an extra parameter to the `./configure... ` command. The parameter you must add is `--sysconfdir=/etc`. (This has been added to the sample configuration command line in README.md.)
|
||||
* Shairport Sync has been updated to use the value of `sysconfdir` to determine where to look for the configuration file. If `sysconfdir` has been left with its default value of `/usr/local/etc`, then Shairport Sync will look for `/usr/local/etc/shairport-sync.conf`. If, as recommended for Linux, `sysconfdir` has been set to `/etc`, then Shairport Sync will look, as before, for `/etc/shairport-sync.conf`.
|
||||
|
||||
**Enhancement**
|
||||
* The version string output when you use the command-line option `-V` now includes the value of the `sysconfdir`, e.g. `2.8.4.7-OpenSSL-Avahi-ALSA-soxr-sysconfdir:/etc`.
|
||||
|
||||
Version 2.8.4.6 – Development Version
|
||||
----
|
||||
**Enhancement**
|
||||
* Add a new `alsa` configuration setting: `use_mmap_if_available` to control the use of mmap. The default is `"yes"` -- see [#351](https://github.com/mikebrady/shairport-sync/issues/351).
|
||||
|
||||
Version 2.8.4.5 – Development Version
|
||||
----
|
||||
**Enhancement**
|
||||
* Handle varying packet lengths -- this makes it compatible with the HTC Connect, HTCs AirPlay implementation. Thanks to [Jörg Krause](https://github.com/joerg-krause) for his detective work, and see [#338](https://github.com/mikebrady/shairport-sync/issues/338).
|
||||
|
||||
Version 2.8.4.4 – Development Version
|
||||
----
|
||||
**Enhancement**
|
||||
* Use alsa direct access (mmap) feature to improve performance if mmap is supported. Thanks to [Yihui Xiong](https://github.com/xiongyihui).
|
||||
|
||||
Version 2.8.4.3 – Development Version
|
||||
----
|
||||
**Bug Fix**
|
||||
|
||||
* Set the RTSP socket to close on `exec()` of child processes; otherwise, background `run_this_before_play_begins` or `run_this_after_play_ends` commands that are sleeping prevent the daemon from being restarted because the listening RTSP port is still in use. Fixes [#329](https://github.com/mikebrady/shairport-sync/issues/329).
|
||||
|
||||
Version 2.8.4.2 – Development Version
|
||||
----
|
||||
**Bug Fixes**
|
||||
|
||||
* Fixed an issue where you could not compile the audio_pipe back end without enabling metadata support (thanks to [busa-projects](https://github.com/busa-projects) for reporting the issue).
|
||||
* Fixed a few small issues causing compiler warnings in `mdns_dns_sd.c`.
|
||||
|
||||
|
||||
**Other**
|
||||
* Removed the INSTALL file – it's generated automatically by `autoreconf -fi` anyway – added it to the files to be ignored in `.gitignore` and added a simple `INSTALL.md` file.
|
||||
|
||||
Version 2.8.4.1 – Development Version
|
||||
----
|
||||
**Bug Fixes**
|
||||
|
||||
* Fixed two issues when including support for `pulseaudio`.
|
||||
* Corrected two small errors in sample parameters for the UDP metadata stream settings, thanks to [rkam](https://github.com/rkam).
|
||||
|
||||
Version 2.8.4 – Stable Version
|
||||
----
|
||||
This release includes important bug fixes and minor enhancements and is recommended for all users. No settings need to be changed. For advice on updating an installation you built yourself, please visit the [UPDATING](https://github.com/mikebrady/shairport-sync/blob/master/UPDATING.md) page.
|
||||
|
||||
+35
-3
@@ -48,6 +48,7 @@ static void linear_volume(double vol);
|
||||
static void parameters(audio_parameters *info);
|
||||
static void mute(int do_mute);
|
||||
static double set_volume;
|
||||
static int output_method_signalled = 0;
|
||||
|
||||
audio_output audio_alsa = {
|
||||
.name = "alsa",
|
||||
@@ -85,6 +86,8 @@ static int alsa_mix_index = 0;
|
||||
static int hardware_mixer = 0;
|
||||
static int has_softvol = 0;
|
||||
|
||||
static snd_pcm_sframes_t (*alsa_pcm_write)(snd_pcm_t *, const void *, snd_pcm_uframes_t) = snd_pcm_writei;
|
||||
|
||||
static int play_number;
|
||||
static int64_t accumulated_delay, accumulated_da_delay;
|
||||
int alsa_characteristics_already_listed = 0;
|
||||
@@ -202,6 +205,15 @@ static int init(int argc, char **argv) {
|
||||
die("Invalid disable_synchronization option choice \"%s\". It should be \"yes\" or \"no\"");
|
||||
}
|
||||
|
||||
/* Get the use_mmap_if_available setting. */
|
||||
if (config_lookup_string(config.cfg, "alsa.use_mmap_if_available", &str)) {
|
||||
if (strcasecmp(str, "no") == 0)
|
||||
config.no_mmap = 1;
|
||||
else if (strcasecmp(str, "yes") == 0)
|
||||
config.no_mmap = 0;
|
||||
else
|
||||
die("Invalid use_mmap_if_available option choice \"%s\". It should be \"yes\" or \"no\"");
|
||||
}
|
||||
/* Get the optional period size value */
|
||||
if (config_lookup_int(config.cfg, "alsa.period_size",
|
||||
&value)) {
|
||||
@@ -373,6 +385,11 @@ int open_alsa_device(void) {
|
||||
unsigned int my_sample_rate = desired_sample_rate;
|
||||
// snd_pcm_uframes_t frames = 441 * 10;
|
||||
snd_pcm_uframes_t buffer_size, actual_buffer_length;
|
||||
snd_pcm_access_t access;
|
||||
|
||||
// ensure no calls are made to the alsa device enquiring about the buffer length if synchronisation is disabled.
|
||||
if (config.no_sync!=0)
|
||||
audio_alsa.delay = NULL;
|
||||
|
||||
ret = snd_pcm_open(&alsa_handle, alsa_out_dev, SND_PCM_STREAM_PLAYBACK, 0);
|
||||
if (ret < 0)
|
||||
@@ -389,8 +406,23 @@ int open_alsa_device(void) {
|
||||
alsa_out_dev);
|
||||
}
|
||||
|
||||
ret = snd_pcm_hw_params_set_access(alsa_handle, alsa_params,
|
||||
SND_PCM_ACCESS_RW_INTERLEAVED);
|
||||
if ((config.no_mmap == 0) && (snd_pcm_hw_params_set_access(alsa_handle, alsa_params, SND_PCM_ACCESS_MMAP_INTERLEAVED) >= 0)) {
|
||||
if (output_method_signalled==0) {
|
||||
debug(1,"Output written using MMAP");
|
||||
output_method_signalled=1;
|
||||
}
|
||||
access = SND_PCM_ACCESS_MMAP_INTERLEAVED;
|
||||
alsa_pcm_write = snd_pcm_mmap_writei;
|
||||
} else {
|
||||
if (output_method_signalled==0) {
|
||||
debug(1,"Output written with RW");
|
||||
output_method_signalled=1;
|
||||
}
|
||||
access = SND_PCM_ACCESS_RW_INTERLEAVED;
|
||||
alsa_pcm_write = snd_pcm_writei;
|
||||
}
|
||||
|
||||
ret = snd_pcm_hw_params_set_access(alsa_handle, alsa_params, access);
|
||||
if (ret < 0) {
|
||||
die("audio_alsa: Access type not available for device \"%s\": %s",
|
||||
alsa_out_dev, snd_strerror(ret));
|
||||
@@ -684,7 +716,7 @@ static void play(short buf[], int samples) {
|
||||
if (samples==0)
|
||||
debug(1,"empty buffer being passed to pcm_writei -- skipping it");
|
||||
if ((samples!=0) && (buf!=NULL)) {
|
||||
err = snd_pcm_writei(alsa_handle, (char *)buf, samples);
|
||||
err = alsa_pcm_write(alsa_handle, (char *)buf, samples);
|
||||
if (err < 0) {
|
||||
debug(1, "Error %d writing %d samples in play(): \"%s\".", err, samples,
|
||||
snd_strerror(err));
|
||||
|
||||
+5
-5
@@ -42,8 +42,8 @@ static pa_simple *pa_dev = NULL;
|
||||
static struct {
|
||||
char *server;
|
||||
char *sink;
|
||||
char *apname;
|
||||
} pulse_options = {.server = NULL, .sink = NULL, .apname = NULL};
|
||||
char *service_name;
|
||||
} pulse_options = {.server = NULL, .sink = NULL, .service_name = NULL};
|
||||
|
||||
static int pa_error;
|
||||
|
||||
@@ -58,7 +58,7 @@ static void help(void) {
|
||||
|
||||
static int init(int argc, char **argv) {
|
||||
|
||||
pulse_options.apname = config.apname;
|
||||
pulse_options.service_name = config.service_name;
|
||||
|
||||
config.audio_backend_buffer_desired_length = 44100; // one second.
|
||||
config.audio_backend_latency_offset = 0;
|
||||
@@ -78,7 +78,7 @@ static int init(int argc, char **argv) {
|
||||
pulse_options.sink = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
pulse_options.apname = optarg;
|
||||
pulse_options.service_name = optarg;
|
||||
break;
|
||||
default:
|
||||
help();
|
||||
@@ -97,7 +97,7 @@ static int init(int argc, char **argv) {
|
||||
static void pulse_connect(void) {
|
||||
static const pa_sample_spec ss = {.format = PA_SAMPLE_S16LE, .rate = 44100, .channels = 2};
|
||||
|
||||
pa_dev = pa_simple_new(pulse_options.server, pulse_options.apname, PA_STREAM_PLAYBACK,
|
||||
pa_dev = pa_simple_new(pulse_options.server, pulse_options.service_name, PA_STREAM_PLAYBACK,
|
||||
pulse_options.sink, "Shairport Stream", &ss, NULL, NULL, &pa_error);
|
||||
|
||||
if (!pa_dev)
|
||||
|
||||
@@ -513,7 +513,6 @@ uint64_t get_absolute_time_in_fp() {
|
||||
return time_now_fp;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_METADATA
|
||||
ssize_t non_blocking_write(int fd, const void *buf, size_t count) {
|
||||
void *ibuf = (void *)buf;
|
||||
size_t bytes_remaining = count;
|
||||
@@ -523,7 +522,7 @@ ssize_t non_blocking_write(int fd, const void *buf, size_t count) {
|
||||
// check that we can do some writing
|
||||
ufds[0].fd = fd;
|
||||
ufds[0].events = POLLOUT;
|
||||
rc = poll(ufds, 1, config.metadata_pipe_timeout);
|
||||
rc = poll(ufds, 1, 5000);
|
||||
if (rc < 0) {
|
||||
// debug(1, "non-blocking write error waiting for pipe to become ready for writing...");
|
||||
} else if (rc == 0) {
|
||||
@@ -546,7 +545,6 @@ ssize_t non_blocking_write(int fd, const void *buf, size_t count) {
|
||||
return rc;
|
||||
// return write(fd,buf,count);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* from http://coding.debuntu.org/c-implementing-str_replace-replace-all-occurrences-substring#comment-722 */
|
||||
|
||||
|
||||
@@ -54,7 +54,6 @@ typedef struct {
|
||||
char *service_name; // the name for the shairport service, e.g. "Shairport Sync Version %v running on host %h"
|
||||
#ifdef CONFIG_METADATA
|
||||
int metadata_enabled;
|
||||
int metadata_pipe_timeout; // in milliseconds
|
||||
char *metadata_pipename;
|
||||
char *metadata_sockaddr;
|
||||
int metadata_sockport;
|
||||
@@ -67,6 +66,7 @@ typedef struct {
|
||||
int udp_port_range;
|
||||
int ignore_volume_control;
|
||||
int no_sync; // disable synchronisation, even if it's available
|
||||
int no_mmap; // disable use of mmap-based output, even if it's available
|
||||
int resyncthreshold; // if it get's out of whack my more than this, resync. Zero means never
|
||||
// resync.
|
||||
int allow_session_interruption;
|
||||
|
||||
+31
-29
@@ -15,11 +15,11 @@ shairport-sync -R\fB
|
||||
shairport-sync -V\fB
|
||||
\f1
|
||||
.SH DESCRIPTION
|
||||
shairport-sync plays audio streamed from iTunes or from an AirPlay device to an ALSA-compatible audio output device.
|
||||
shairport-sync plays audio streamed from iTunes or from an AirPlay device to an Advanced Linux Sound Architecture (ALSA) compatible audio output device.
|
||||
|
||||
A feature of shairport-sync is that the audio is played synchronously. This means that if many devices are playing the same stream at the same time, all the outputs will stay in step with one another. This allows multiple devices play the same source without getting out of phase with one another, enabling, for example, simultaneous multi-room operation.
|
||||
A feature of shairport-sync is that the audio is played synchronously. This means that if many devices are playing the same stream at the same time, all the outputs will stay in step with one another. This allows multiple devices to play the same source without getting out of phase with one another, enabling, for example, simultaneous multi-room operation.
|
||||
|
||||
shairport-sync can additionally be compiled and configured to stream raw audio to a pipe or to stdout.
|
||||
shairport-sync can be compiled to stream audio, without synchronisation, to a pipe, to stdout or to a libao output device (an "AO" device). It can also be compiled to stream metadata to a pipe or socket.
|
||||
|
||||
Settings can be made using the configuration file (recommended for all new installations) or by using command-line options.
|
||||
.SH CONFIGURATION FILE SETTINGS
|
||||
@@ -61,7 +61,7 @@ These are the settings available within the \fBgeneral\f1 group:
|
||||
\fBname=\f1\fI"service_name"\f1\fB;\f1
|
||||
Use this \fIservice_name\f1 to identify this player in iTunes, etc.
|
||||
|
||||
The following substitutions are allowed: \fB%h\f1 for the computer's hostname, \fB%H\f1 for the computer's hostname with the first letter capitalised (ASCII only), \fB%v\f1 for the Shairport Sync version number, e.g. "2.8.4" and \fB%V\f1 for the Shairport Sync version string, e.g. "2.8.4-OpenSSL-Avahi-ALSA-soxr-metadata".
|
||||
The following substitutions are allowed: \fB%h\f1 for the computer's hostname, \fB%H\f1 for the computer's hostname with the first letter capitalised (ASCII only), \fB%v\f1 for the shairport-sync version number, e.g. "2.8.4" and \fB%V\f1 for the shairport-sync version string, e.g. "2.8.4-OpenSSL-Avahi-ALSA-soxr-metadata".
|
||||
|
||||
The default is "%H", which is replaced by the hostname with the first letter capitalised.
|
||||
.TP
|
||||
@@ -106,7 +106,7 @@ Use this \fIdBvalue\f1 to reduce or increase the attenuation range, in decibels,
|
||||
|
||||
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 systems have a volume control 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.
|
||||
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 30 dB. 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 30. Using it in this case gives the volume control a much more useful range of settings.
|
||||
|
||||
As a third example, you can actually extend the range provided by a mixer. Many cheaper DACs have hardware mixers that offer a restricted attenuation range. If you specify a volume range greater than the range of the mixer, software attenuation and hardware attenuation will be combined to give the specified range.
|
||||
|
||||
@@ -139,7 +139,7 @@ Set this \fIoffset\f1, in frames, to compensate for a fixed delay in the audio b
|
||||
Use this to set the desired number frames to be in the output device's hardware output buffer. The default is 6,615 frames, or 0.15 seconds. If set too small, buffer underflow may occur on low-powered machines. If too large, the response times when using software volume control (i.e. when not using a mixer control to control volume) become annoying, or it may exceed the hardware buffer size. It may need to be larger on low-powered machines that are also performing other tasks, such as processing metadata.
|
||||
.TP
|
||||
\fBdisable_synchronization=\f1\fI"no"\f1\fB;\f1
|
||||
This is an advanced setting and is for debugging only. Set to "yes" to disable synchronization. Default is "no". If you use it to disable synchronisation, then soner or later you'll experience audio glitches due to audio buffer overflow or underflow.
|
||||
This is an advanced setting and is for debugging only. Set to "yes" to disable synchronization. Default is "no". If you use it to disable synchronisation, then sooner or later you'll experience audio glitches due to audio buffer overflow or underflow.
|
||||
.TP
|
||||
\fBperiod_size=\f1\fInumber\f1\fB;\f1
|
||||
Use this optional advanced setting to set the alsa period size near to this value.
|
||||
@@ -148,7 +148,7 @@ Use this optional advanced setting to set the alsa period size near to this valu
|
||||
Use this optional advanced setting to set the alsa buffer size near to this value.
|
||||
.TP
|
||||
\fB"PIPE" SETTINGS\f1
|
||||
These settings are for the PIPE backend, used to route audio to a named unix pipe. The audio is in raw CD audio format: PCM 16 bit little endian, 44,100 samples per second, stereo.
|
||||
These settings are for the PIPE backend, used to route audio to a named unix pipe. The audio is in raw CD audio format: PCM 16 bit little endian, 44,100 samples per second, interleaved stereo.
|
||||
|
||||
Use the \fIname\f1 setting to set the name and location of the pipe.
|
||||
|
||||
@@ -160,13 +160,13 @@ These are the settings available within the \fBpipe\f1 group:
|
||||
Use this to specify the name and location of the pipe. The pipe will be created and opened when shairport-sync starts up and will be closed upon shutdown. Frames of audio will be sent to the pipe in packets of 352 frames and will be discarded if the pipe has not have a reader attached. The sender will wait for up to five seconds for a packet to be written before discarding it.
|
||||
.TP
|
||||
\fBaudio_backend_latency_offset=\f1\fIoffset_in_frames\f1\fB;\f1
|
||||
Packets of audio frames are written to the pipe synchronously -- that is, they are written to at exactly the time they should be played. You can offset the time of initial audio output relative to its nominal time using this setting. For example to send an audio stream to the pipe 100 milliseconds before it is due to be played, set this to -4410. Default setting is 0.
|
||||
Packets of audio frames are written to the pipe synchronously -- that is, they are written at exactly the time they should be played. You can offset the time of initial audio output relative to its nominal time using this setting. For example to send an audio stream to the pipe 100 milliseconds before it is due to be played, set this to -4410. Default setting is 0.
|
||||
.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 the pipe. 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 pipe reader's buffer, giving it a nominal buffer size of 44,100 frames. Note that if the pipe 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 a pipe. Default setting is 44,100 frames.
|
||||
.TP
|
||||
\fB"STDOUT" SETTINGS\f1
|
||||
These settings are for the STDOUT backend, used to route audio to standard output ("stdout"). The audio is in raw CD audio format: PCM 16 bit little endian, 44,100 samples per second, stereo.
|
||||
These settings are for the STDOUT backend, used to route audio to standard output ("stdout"). The audio is in raw CD audio format: PCM 16 bit little endian, 44,100 samples per second, interleaved stereo.
|
||||
|
||||
There are two settings affecting timing that might be useful if the stdout reader is, for example, a program to play an audio stream such as \fBaplay\f1. The \fIaudio_backend_latency_offset\f1 affects precisely when the first audio packet is sent and the \fIaudio_backend_buffer_desired_length\f1 setting affects the nominal output buffer size.
|
||||
|
||||
@@ -189,10 +189,10 @@ These are the settings available within the \fBao\f1 group:
|
||||
Packets of audio frames are written to the libao system synchronously -- that is, they are written at exactly the time they should be played. You can offset the time of initial audio output relative to its nominal time using this setting. For example to send an audio stream to stdout 100 milliseconds before it is due to be played, set this to -4410. Default setting is 0.
|
||||
.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 to the libao system. 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 libao system 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 libao. Default setting is 44,100 frames.
|
||||
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 the libao system. 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 libao system 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 libao. 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.
|
||||
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 the command \fB$ shairport-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.
|
||||
|
||||
@@ -205,10 +205,10 @@ Set the \fIchoice\f1 to "yes" to enable shairport-sync to look for metadata from
|
||||
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".
|
||||
Specify the absolute path name of the pipe through which metadata should be sent The default is \fI/tmp/shairport-sync-metadata\f1.
|
||||
.TP
|
||||
\fBsocket_address=\f1\fI"hostnameOrIP"\f1\fB;\f1
|
||||
If \fIhostnameOrIP\f1 is set to a host name or and IP address, UDP packets containing metadata will be sent to this address. May be a multicast address. "socket-port" must be non-zero and "enabled" must be set to "yes".
|
||||
If \fIhostnameOrIP\f1 is set to a host name or and IP address, UDP packets containing metadata will be sent to this address. May be a multicast address. Additionally, \fIsocket-port\f1 must be non-zero and \fIenabled\f1 must be set to "yes".
|
||||
.TP
|
||||
\fBsocket_port=\f1\fIport\f1\fB;\f1
|
||||
If \fBsocket_address\f1 is set, use \fIport\f1 to specify the port to send UDP packets to. Must not be zero.
|
||||
@@ -235,11 +235,11 @@ If \fBchoice\f1 is set to "yes", then another source will be able to interrupt a
|
||||
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.
|
||||
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.
|
||||
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 ignored 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.
|
||||
|
||||
@@ -257,23 +257,25 @@ This is the \fIlatency\f1, in frames, used for forkedDaapd sources. Default is 9
|
||||
\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 compatibility with older installations of Shairport Sync.
|
||||
This section is about the command-line options available in 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.
|
||||
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 command-line options described below simply replicate the configuration settings and are retained to provide backward compatibility with older installations of shairport-sync.
|
||||
|
||||
The command line for shairport-sync can take two kinds of options: regular \fBprogram options\f1 and \fBaudio backend options\f1. Program options are always listed first, followed by any audio backend options, preceded by a \fB--\f1 symbol.
|
||||
Many command-line options take sensible default values, so you can normally ignore most of them. See the EXAMPLES section for typical usages.
|
||||
|
||||
There are two kinds of command-line options for shairport-sync: regular \fBprogram options\f1 and \fBaudio backend options\f1. Program options are always listed first, followed by any audio backend options, preceded by a \fB--\f1 symbol.
|
||||
.SH PROGRAM OPTIONS
|
||||
These options are used by shairport-sync itself.
|
||||
These command-line options are used by shairport-sync itself.
|
||||
.TP
|
||||
\fB-a \f1\fIservice name\f1\fB | --name=\f1\fIservice name\f1
|
||||
Use this \fIservice name\f1 to identify this player in iTunes, etc. The following substitutions are allowed: \fB%h\f1 for the computer's hostname, \fB%H\f1 for the computer's hostname with the first letter capitalised (ASCII only), \fB%v\f1 for the Shairport Sync version number, e.g. "2.8.4" and \fB%V\f1 for the Shairport Sync version string, e.g. "2.8.4-OpenSSL-Avahi-ALSA-soxr-metadata".
|
||||
Use this \fIservice name\f1 to identify this player in iTunes, etc. The following substitutions are allowed: \fB%h\f1 for the computer's hostname, \fB%H\f1 for the computer's hostname with the first letter capitalised (ASCII only), \fB%v\f1 for the shairport-sync version number, e.g. "2.8.4" and \fB%V\f1 for the shairport-sync version string, e.g. "2.8.4-OpenSSL-Avahi-ALSA-soxr-metadata".
|
||||
|
||||
The default is "%H", which is replaced by the hostname with the first letter capitalised.
|
||||
.TP
|
||||
\fB-A | --AirPlayLatency=\f1\fIlatency\f1
|
||||
Use this \fIlatency\f1, in frames, for audio streamed from an AirPlay device. The default is 88,200 frames, where there are 44,100 frames to the second.
|
||||
|
||||
Please note that this feature is deprecated and will be removed in a future version of Shairport Sync.
|
||||
Please note that this feature is deprecated and will be removed in a future version of shairport-sync.
|
||||
.TP
|
||||
\fB-B \f1\fIprogram\f1\fB | --on-start=\f1\fIprogram\f1
|
||||
Execute \fIprogram\f1 when playback is about to begin. Specify the full path to the program, e.g. \fI/usr/bin/logger\f1. Executable scripts can be used, but they must have \fI#!/bin/sh\f1 (or whatever is appropriate) in the headline.
|
||||
@@ -286,7 +288,7 @@ Read configuration settings from \fIfilename\f1. The default is to read them fro
|
||||
\fB-D | --disconnectFromOutput\f1
|
||||
Disconnect the shairport-sync daemon from the output device and exit. (Requires that the daemon has written its PID to an agreed file -- see the \fB-d\f1 option).
|
||||
|
||||
Please note that this feature is deprecated and will be removed in a future version of Shairport Sync.
|
||||
Please note that this feature is deprecated and will be removed in a future version of shairport-sync.
|
||||
.TP
|
||||
\fB-d | --daemon\f1
|
||||
Instruct shairport-sync to demonise itself. It will write its Process ID (PID) to a file, usually at \fI/var/run/shairport-sync.pid\f1, which is used by the \fB-k\f1, \fB-D\f1 and \fB-R\f1 options to locate the daemon at a later time.
|
||||
@@ -299,7 +301,7 @@ If you want shairport-sync to wait until the command has completed before contin
|
||||
\fB--forkedDaapdLatency=\f1\fIlatency\f1
|
||||
Use this \fIlatency\f1, in frames, for audio streamed from a forked-daapd based source. The default is 99,400 frames, where there are 44,100 frames to the second.
|
||||
|
||||
Please note that this feature is deprecated and will be removed in a future version of Shairport Sync.
|
||||
Please note that this feature is deprecated and will be removed in a future version of shairport-sync.
|
||||
.TP
|
||||
\fB--get-coverart\f1
|
||||
This option requires the \fB--meta-dir\f1 option to be set, and enables shairport-sync to request cover art from the source and to transmit it through the metadata pipe.
|
||||
@@ -312,7 +314,7 @@ Print brief help message and exit.
|
||||
\fB-i | --iTunesLatency=\f1\fIlatency\f1
|
||||
Use this \fIlatency\f1, in frames, for audio streamed from an iTunes source, where iTunes is Version 10 or later. The default is 99,400 frames, where there are 44,100 frames to the second. If the source is iTunes but is earler than Version 10, the \fIdefault latency\f1 is used (see the \fB-L\f1 option). Some third party programs masquerade as older versions of iTunes.
|
||||
|
||||
Please note that this feature is deprecated and will be removed in a future version of Shairport Sync.
|
||||
Please note that this feature is deprecated and will be removed in a future version of shairport-sync.
|
||||
.TP
|
||||
\fB-k | --kill\f1
|
||||
Kill the shairport-sync daemon and exit. (Requires that the daemon has written its PID to an agreed file -- see the \fB-d\f1 option).
|
||||
@@ -320,7 +322,7 @@ Kill the shairport-sync daemon and exit. (Requires that the daemon has written i
|
||||
\fB-L | --latency=\f1\fIlatency\f1
|
||||
Use this to set the \fIdefault latency\f1, in frames, for audio coming from an unidentified source or from an iTunes Version 9 or earlier source. The standard value for the \fIdefault latency\f1 is 88,200 frames, where there are 44,100 frames to the second.
|
||||
|
||||
Please note that this feature is deprecated and will be removed in a future version of Shairport Sync.
|
||||
Please note that this feature is deprecated and will be removed in a future version of shairport-sync.
|
||||
.TP
|
||||
\fB--meta-dir=\f1\fIdirectory\f1
|
||||
Listen for metadata coming from the source and send it, along with metadata from shairport-sync itself, to a pipe called \fIshairport-sync-metadata\f1 in the \fIdirectory\f1 you specify. If you add the \fB--get-cover-art\f1 then cover art will be sent through the pipe too. See \fBhttps://github.com/mikebrady/shairport-sync-metadata-reader\f1 for a sample metadata reader.
|
||||
@@ -340,7 +342,7 @@ Require the password \fIsecret\f1 to be able to connect and stream to the servic
|
||||
\fB-R | --reconnectToOutput\f1
|
||||
Reconnect the shairport-sync daemon to the output device and exit. It may take a few seconds to synchronise. (Requires that the daemon has written its PID to an agreed file -- see the \fB-d\f1 option).
|
||||
|
||||
Please note that this feature is deprecated and will be removed in a future version of Shairport Sync.
|
||||
Please note that this feature is deprecated and will be removed in a future version of shairport-sync.
|
||||
.TP
|
||||
\fB-r \f1\fIthreshold\f1\fB | --resync=\f1\fIthreshold\f1
|
||||
Resynchronise if timings differ by more than \fIthreshold\f1 frames. If the output timing differs from the source timing by more than the threshold, output will be muted and a full resynchronisation will occur. The default threshold is 2,205 frames, i.e. 50 milliseconds. Specify \fB0\f1 to disable resynchronisation.
|
||||
@@ -368,7 +370,7 @@ Print debug information. Repeat up to three times to get more detail.
|
||||
\fB-w | --wait-cmd\f1
|
||||
Wait for commands specified using \fB-B\f1 or \fB-E\f1 to complete before continuing execution.
|
||||
.SH AUDIO BACKEND OPTIONS
|
||||
These options are passed to the chosen audio backend. The audio backend options are preceded by a \fB--\f1 symbol to introduce them and to separate them from any program options. In this way, option letters can be used as program options and also as audio backend options without ambiguity.
|
||||
These command-line options are passed to the chosen audio backend. The audio backend options are preceded by a \fB--\f1 symbol to introduce them and to separate them from any program options. In this way, option letters can be used as program options and also as audio backend options without ambiguity.
|
||||
|
||||
In the ALSA backend, audio is sent to an output device which you can specify using the \fB-d\f1 option. The output level (the "volume") is controlled using a level control associated with a mixer. By default, the mixer is implemented in shairport-sync itself in software. To use a hardware level control on a mixer on the sound card, specify the name of the mixer control with the \fB-c\f1 option. If the mixer is not associated with the output device, then you need to specify where the mixer is to be found with the \fB-m\f1 option.
|
||||
.TP
|
||||
@@ -394,9 +396,9 @@ 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
|
||||
.SH COMMENTS
|
||||
|
||||
+42
-42
@@ -65,16 +65,16 @@
|
||||
|
||||
<description>
|
||||
<p>shairport-sync plays audio streamed from iTunes or from an AirPlay
|
||||
device to an ALSA-compatible audio output device.</p>
|
||||
device to an Advanced Linux Sound Architecture (ALSA) compatible audio output device.</p>
|
||||
|
||||
<p> A feature of shairport-sync is that the audio is played synchronously.
|
||||
<p>A feature of shairport-sync is that the audio is played synchronously.
|
||||
This means that if many devices are playing the same stream at the same
|
||||
time, all the outputs will stay in step with one another.
|
||||
This allows multiple devices play the same source without getting out of phase with one another,
|
||||
This allows multiple devices to play the same source without getting out of phase with one another,
|
||||
enabling, for example, simultaneous multi-room operation.
|
||||
</p>
|
||||
|
||||
<p>shairport-sync can additionally be compiled and configured to stream raw audio to a pipe or to stdout.</p>
|
||||
<p>shairport-sync can be compiled to stream audio, without synchronisation, to a pipe, to stdout or to a libao output device (an "AO" device). It can also be compiled to stream metadata to a pipe or socket.</p>
|
||||
|
||||
<p>Settings can be made using the configuration file (recommended for all new installations) or by using command-line options.</p>
|
||||
|
||||
@@ -122,8 +122,8 @@
|
||||
<p>The following substitutions are allowed:
|
||||
<opt>%h</opt> for the computer's hostname,
|
||||
<opt>%H</opt> for the computer's hostname with the first letter capitalised (ASCII only),
|
||||
<opt>%v</opt> for the Shairport Sync version number, e.g. "2.8.4" and
|
||||
<opt>%V</opt> for the Shairport Sync version string, e.g. "2.8.4-OpenSSL-Avahi-ALSA-soxr-metadata".</p>
|
||||
<opt>%v</opt> for the shairport-sync version number, e.g. "2.8.4" and
|
||||
<opt>%V</opt> for the shairport-sync version string, e.g. "2.8.4-OpenSSL-Avahi-ALSA-soxr-metadata".</p>
|
||||
<p>The default is "%H", which is replaced by the hostname with the first letter capitalised.</p>
|
||||
</optdesc>
|
||||
</option>
|
||||
@@ -204,9 +204,9 @@
|
||||
This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting --
|
||||
indeed, many domestic HiFi systems have a volume control range of just 60 to 80dB.</p>
|
||||
<p>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.
|
||||
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 30 dB.
|
||||
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.
|
||||
The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 30.
|
||||
Using it in this case gives the volume control a much more useful range of settings.</p>
|
||||
<p>As a third example, you can actually extend the range provided by a mixer.
|
||||
Many cheaper DACs have hardware mixers that offer a restricted attenuation range.
|
||||
@@ -269,7 +269,7 @@
|
||||
<option>
|
||||
<p><opt>disable_synchronization=</opt><arg>"no"</arg><opt>;</opt></p>
|
||||
<optdesc>This is an advanced setting and is for debugging only. Set to "yes" to disable synchronization. Default is "no".
|
||||
If you use it to disable synchronisation, then soner or later you'll experience audio glitches due to
|
||||
If you use it to disable synchronisation, then sooner or later you'll experience audio glitches due to
|
||||
audio buffer overflow or underflow.
|
||||
</optdesc>
|
||||
</option>
|
||||
@@ -284,16 +284,18 @@
|
||||
|
||||
<option><p><opt>"PIPE" SETTINGS</opt></p></option>
|
||||
<p>These settings are for the PIPE backend, used to route audio to a named unix pipe. The audio is in raw CD audio format: PCM 16 bit little endian, 44,100 samples per second,
|
||||
stereo.</p>
|
||||
interleaved stereo.</p>
|
||||
<p>Use the <arg>name</arg> setting to set the name and location of the pipe.</p>
|
||||
<p>There are two further settings affecting timing that might be useful if the pipe reader is, for example,
|
||||
a program to play an audio stream such as <opt>aplay</opt>. The <arg>audio_backend_latency_offset</arg> affects precisely when the first audio packet is sent
|
||||
a program to play an audio stream such as <opt>aplay</opt>. The <arg>audio_backend_latency_offset</arg> affects precisely
|
||||
when the first audio packet is sent
|
||||
and the <arg>audio_backend_buffer_desired_length</arg> setting affects the nominal output buffer size.</p>
|
||||
<p>These are the settings available within the <opt>pipe</opt> group:</p>
|
||||
|
||||
<option>
|
||||
<p><opt>name=</opt><arg>"/path/to/pipe"</arg><opt>;</opt></p>
|
||||
<optdesc>Use this to specify the name and location of the pipe. The pipe will be created and opened when shairport-sync starts up and will be closed upon shutdown.
|
||||
<optdesc>Use this to specify the name and location of the pipe. The pipe will be created and opened when shairport-sync starts up
|
||||
and will be closed upon shutdown.
|
||||
Frames of audio will be sent to the pipe in packets of 352 frames and will be discarded if the pipe has not have a reader attached.
|
||||
The sender will wait for up to five seconds for a packet to be written before discarding it.</optdesc>
|
||||
</option>
|
||||
@@ -301,7 +303,7 @@
|
||||
<option>
|
||||
<p><opt>audio_backend_latency_offset=</opt><arg>offset_in_frames</arg><opt>;</opt></p>
|
||||
<optdesc>
|
||||
Packets of audio frames are written to the pipe synchronously -- that is, they are written to at exactly the time they should be played.
|
||||
Packets of audio frames are written to the pipe synchronously -- that is, they are written at exactly the time they should be played.
|
||||
You can offset the time of initial audio output relative to its nominal time using this setting.
|
||||
For example to send an audio stream to the pipe 100 milliseconds before it is due to be played, set this to -4410. Default setting is 0.</optdesc>
|
||||
</option>
|
||||
@@ -319,7 +321,7 @@
|
||||
|
||||
<option><p><opt>"STDOUT" SETTINGS</opt></p></option>
|
||||
<p>These settings are for the STDOUT backend, used to route audio to standard output ("stdout").
|
||||
The audio is in raw CD audio format: PCM 16 bit little endian, 44,100 samples per second, stereo.</p>
|
||||
The audio is in raw CD audio format: PCM 16 bit little endian, 44,100 samples per second, interleaved stereo.</p>
|
||||
<p>There are two settings affecting timing that might be useful if the stdout reader is, for example,
|
||||
a program to play an audio stream such as <opt>aplay</opt>. The <arg>audio_backend_latency_offset</arg> affects precisely when the first audio packet is sent
|
||||
and the <arg>audio_backend_buffer_desired_length</arg> setting affects the nominal output buffer size.</p>
|
||||
@@ -363,7 +365,7 @@
|
||||
<p><opt>audio_backend_buffer_desired_length=</opt><arg>buffer_length_in_frames</arg><opt>;</opt></p>
|
||||
<optdesc>
|
||||
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 to the libao system.
|
||||
audio frames are sent to the libao system.
|
||||
For example, if you send the first packet of audio exactly when it is due and, using a <arg>audio_backend_buffer_desired_length</arg> 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 libao system consumes audio packets faster or slower than they are supplied, the buffer will eventually empty or overflow --
|
||||
@@ -375,7 +377,7 @@
|
||||
<p>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 <file>/tmp/shairport-sync-metadata</file>.
|
||||
To process metadata, shairport-sync must have been compiled with metadata support included.
|
||||
You can check that this is so by running <opt>shairport-sync -V</opt>; the identification string will contain the word <opt>metadata</opt>.</p>
|
||||
You can check that this is so by running the command <opt>$ shairport-sync -V</opt>; the identification string will contain the word <opt>metadata</opt>.</p>
|
||||
<p>Please note that different sources provide different levels of metadata. Some provide a lot; some provide almost none.</p>
|
||||
<p>The <opt>metadata</opt> group of settings allow you to enable metadata handling and to control certain aspects of it:</p>
|
||||
|
||||
@@ -394,13 +396,13 @@
|
||||
</option>
|
||||
<option>
|
||||
<p><opt>pipe_name=</opt><arg>"filepathname"</arg><opt>;</opt></p>
|
||||
<optdesc>Specify the absolute path name of the pipe through which metadata should be sent The default is <file>/tmp/shairport-sync-metadata</file>".</optdesc>
|
||||
<optdesc>Specify the absolute path name of the pipe through which metadata should be sent The default is <file>/tmp/shairport-sync-metadata</file>.</optdesc>
|
||||
</option>
|
||||
|
||||
<option>
|
||||
<p><opt>socket_address=</opt><arg>"hostnameOrIP"</arg><opt>;</opt></p>
|
||||
<optdesc>If <arg>hostnameOrIP</arg> is set to a host name or and IP address, UDP packets containing metadata will be sent to this address.
|
||||
May be a multicast address. "socket-port" must be non-zero and "enabled" must be set to "yes".</optdesc>
|
||||
May be a multicast address. Additionally, <arg>socket-port</arg> must be non-zero and <arg>enabled</arg> must be set to "yes".</optdesc>
|
||||
</option>
|
||||
<option>
|
||||
<p><opt>socket_port=</opt><arg>port</arg><opt>;</opt></p>
|
||||
@@ -411,12 +413,10 @@
|
||||
<optdesc>The maximum packet size for any UDP metadata. This must be between 500 or 65000. The default is 500.</optdesc>
|
||||
</option>
|
||||
|
||||
|
||||
<option><p><opt>"SESSIONCONTROL" SETTINGS</opt></p></option>
|
||||
<p>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.</p>
|
||||
|
||||
|
||||
<option>
|
||||
<p><opt>run_this_before_play_begins=</opt><arg>"/path/to/application and args"</arg><opt>;</opt></p>
|
||||
<optdesc>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.
|
||||
@@ -445,11 +445,11 @@
|
||||
</option>
|
||||
|
||||
<option><p><opt>"LATENCIES" SETTINGS</opt></p></option>
|
||||
<p>The latencies settings are now deprecated. Do not use them for new installations. They will be removed from a future version of Shairport Sync.</p>
|
||||
<p>The latencies settings are now deprecated. Do not use them for new installations. They will be removed from a future version of shairport-sync.</p>
|
||||
<p>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.</p>
|
||||
|
||||
<p>Shairport Sync now sets latencies automatically using information supplied by the source, typically either 88,200 or 99,577 frames.</p>
|
||||
<p>shairport-sync now sets latencies automatically using information supplied by the source, typically either 88,200 or 99,577 frames.</p>
|
||||
|
||||
<p>The following relates to the old scheme of using fixed latencies, which ignored the latency information supplied by the source.
|
||||
There are four default latency settings. One latency matches the latency used by recent versions of
|
||||
@@ -460,7 +460,6 @@
|
||||
instead of changing these individual latencies, use the <opt>audio_backend_latency_offset</opt> setting in the <opt>alsa</opt> group
|
||||
(or the appropriate other group if you're not outputing through the alsa backend).</p>
|
||||
|
||||
|
||||
<option>
|
||||
<p><opt>itunes=</opt><arg>latency</arg><opt>;</opt></p>
|
||||
<optdesc>This is the <arg>latency</arg>, in frames, used for iTunes 10 or later. Default is 99,400.</optdesc>
|
||||
@@ -477,27 +476,27 @@
|
||||
<p><opt>default=</opt><arg>latency</arg><opt>;</opt></p>
|
||||
<optdesc>This is the <arg>latency</arg>, in frames, used when the source is unrecognised. Default is 88,200.</optdesc>
|
||||
</option>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
<options>
|
||||
<p>This section is about the command-line options available in shairport-sync.</p>
|
||||
|
||||
<p>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 compatibility with older installations of Shairport Sync.</p>
|
||||
<p>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 command-line options described below
|
||||
simply replicate the configuration settings and are retained to provide backward compatibility with older installations of shairport-sync.</p>
|
||||
|
||||
<p>Many of the options take sensible default values, so you can normally
|
||||
<p>Many command-line options take sensible default values, so you can normally
|
||||
ignore most of them. See the EXAMPLES section for typical usages.</p>
|
||||
|
||||
<p>The command line for shairport-sync can take two kinds of options:
|
||||
<p>There are two kinds of command-line options for shairport-sync:
|
||||
regular <opt>program options</opt> and <opt>audio backend options</opt>.
|
||||
Program options are
|
||||
always listed first, followed by any audio backend options, preceded by
|
||||
a <opt>--</opt> symbol.</p>
|
||||
|
||||
<section name="Program Options">
|
||||
<p>These options are used by shairport-sync itself.</p>
|
||||
<p>These command-line options are used by shairport-sync itself.</p>
|
||||
</section>
|
||||
|
||||
<option>
|
||||
@@ -508,8 +507,8 @@
|
||||
<p>The following substitutions are allowed:
|
||||
<opt>%h</opt> for the computer's hostname,
|
||||
<opt>%H</opt> for the computer's hostname with the first letter capitalised (ASCII only),
|
||||
<opt>%v</opt> for the Shairport Sync version number, e.g. "2.8.4" and
|
||||
<opt>%V</opt> for the Shairport Sync version string, e.g. "2.8.4-OpenSSL-Avahi-ALSA-soxr-metadata".</p>
|
||||
<opt>%v</opt> for the shairport-sync version number, e.g. "2.8.4" and
|
||||
<opt>%V</opt> for the shairport-sync version string, e.g. "2.8.4-OpenSSL-Avahi-ALSA-soxr-metadata".</p>
|
||||
<p>The default is "%H", which is replaced by the hostname with the first letter capitalised.</p>
|
||||
</p></optdesc>
|
||||
</option>
|
||||
@@ -521,7 +520,7 @@
|
||||
device. The default is 88,200 frames, where there are 44,100
|
||||
frames to the second.
|
||||
</p>
|
||||
<p>Please note that this feature is deprecated and will be removed in a future version of Shairport Sync.</p>
|
||||
<p>Please note that this feature is deprecated and will be removed in a future version of shairport-sync.</p>
|
||||
</optdesc>
|
||||
</option>
|
||||
|
||||
@@ -552,7 +551,7 @@
|
||||
exit. (Requires that the daemon has written its PID to an agreed
|
||||
file -- see the <opt>-d</opt> option).
|
||||
</p>
|
||||
<p>Please note that this feature is deprecated and will be removed in a future version of Shairport Sync.</p>
|
||||
<p>Please note that this feature is deprecated and will be removed in a future version of shairport-sync.</p>
|
||||
</optdesc>
|
||||
</option>
|
||||
|
||||
@@ -586,7 +585,7 @@
|
||||
source. The default is 99,400 frames, where there are 44,100
|
||||
frames to the second.
|
||||
</p>
|
||||
<p>Please note that this feature is deprecated and will be removed in a future version of Shairport Sync.</p>
|
||||
<p>Please note that this feature is deprecated and will be removed in a future version of shairport-sync.</p>
|
||||
</optdesc>
|
||||
</option>
|
||||
|
||||
@@ -615,7 +614,7 @@
|
||||
source, where iTunes is Version 10 or later. The default is 99,400 frames, where there are 44,100
|
||||
frames to the second. If the source is iTunes but is earler than Version 10, the <arg>default latency</arg> is used (see the <opt>-L</opt> option). Some third party programs masquerade as older versions of iTunes.
|
||||
</p>
|
||||
<p>Please note that this feature is deprecated and will be removed in a future version of Shairport Sync.</p>
|
||||
<p>Please note that this feature is deprecated and will be removed in a future version of shairport-sync.</p>
|
||||
</optdesc>
|
||||
</option>
|
||||
|
||||
@@ -633,7 +632,7 @@
|
||||
Use this to set the <arg>default latency</arg>, in frames, for audio coming from an unidentified source or from an iTunes Version 9 or earlier source. The standard value for the <arg>default latency</arg> is 88,200 frames, where there are 44,100
|
||||
frames to the second.
|
||||
</p>
|
||||
<p>Please note that this feature is deprecated and will be removed in a future version of Shairport Sync.</p>
|
||||
<p>Please note that this feature is deprecated and will be removed in a future version of shairport-sync.</p>
|
||||
</optdesc>
|
||||
</option>
|
||||
|
||||
@@ -689,7 +688,7 @@
|
||||
the daemon has written its PID to an agreed file -- see the <opt>-d</opt>
|
||||
option).
|
||||
</p>
|
||||
<p>Please note that this feature is deprecated and will be removed in a future version of Shairport Sync.</p>
|
||||
<p>Please note that this feature is deprecated and will be removed in a future version of shairport-sync.</p>
|
||||
</optdesc>
|
||||
</option>
|
||||
|
||||
@@ -775,10 +774,11 @@
|
||||
</option>
|
||||
|
||||
<section name="Audio Backend Options">
|
||||
<p>These options are passed to the chosen audio backend. The audio backend options are
|
||||
<p>These command-line options are passed to the chosen audio backend. The audio backend options are
|
||||
preceded by a <opt>--</opt> symbol to introduce them and to separate them from any
|
||||
program options. In this way, option letters can be used as program
|
||||
options and also as audio backend options without ambiguity.</p>
|
||||
|
||||
<p>In the ALSA backend, audio is sent to an output device
|
||||
which you can specify using the <opt>-d</opt> option.
|
||||
The output level (the "volume") is controlled using a level control associated with a mixer.
|
||||
@@ -863,8 +863,8 @@
|
||||
</section>
|
||||
|
||||
<section name="Credits">
|
||||
<p>Mike Brady developed Shairport Sync from the original Shairport by James Laird.</p>
|
||||
<p>Shairport Sync can be found at <url href="https://github.com/mikebrady/shairport-sync."/></p>
|
||||
<p>Mike Brady developed shairport-sync from the original Shairport by James Laird.</p>
|
||||
<p>shairport-sync can be found at <url href="https://github.com/mikebrady/shairport-sync."/></p>
|
||||
<p>Shairport can be found at <url href="https://github.com/abrasive/shairport."/></p>
|
||||
</section>
|
||||
|
||||
|
||||
+42
-42
@@ -44,16 +44,16 @@
|
||||
<h2>Description</h2>
|
||||
|
||||
<p>shairport-sync plays audio streamed from iTunes or from an AirPlay
|
||||
device to an ALSA-compatible audio output device.</p>
|
||||
device to an Advanced Linux Sound Architecture (ALSA) compatible audio output device.</p>
|
||||
|
||||
<p> A feature of shairport-sync is that the audio is played synchronously.
|
||||
<p>A feature of shairport-sync is that the audio is played synchronously.
|
||||
This means that if many devices are playing the same stream at the same
|
||||
time, all the outputs will stay in step with one another.
|
||||
This allows multiple devices play the same source without getting out of phase with one another,
|
||||
This allows multiple devices to play the same source without getting out of phase with one another,
|
||||
enabling, for example, simultaneous multi-room operation.
|
||||
</p>
|
||||
|
||||
<p>shairport-sync can additionally be compiled and configured to stream raw audio to a pipe or to stdout.</p>
|
||||
<p>shairport-sync can be compiled to stream audio, without synchronisation, to a pipe, to stdout or to a libao output device (an "AO" device). It can also be compiled to stream metadata to a pipe or socket.</p>
|
||||
|
||||
<p>Settings can be made using the configuration file (recommended for all new installations) or by using command-line options.</p>
|
||||
|
||||
@@ -103,8 +103,8 @@
|
||||
<p>The following substitutions are allowed:
|
||||
<b>%h</b> for the computer's hostname,
|
||||
<b>%H</b> for the computer's hostname with the first letter capitalised (ASCII only),
|
||||
<b>%v</b> for the Shairport Sync version number, e.g. "2.8.4" and
|
||||
<b>%V</b> for the Shairport Sync version string, e.g. "2.8.4-OpenSSL-Avahi-ALSA-soxr-metadata".</p>
|
||||
<b>%v</b> for the shairport-sync version number, e.g. "2.8.4" and
|
||||
<b>%V</b> for the shairport-sync version string, e.g. "2.8.4-OpenSSL-Avahi-ALSA-soxr-metadata".</p>
|
||||
<p>The default is "%H", which is replaced by the hostname with the first letter capitalised.</p>
|
||||
|
||||
|
||||
@@ -185,9 +185,9 @@
|
||||
This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting --
|
||||
indeed, many domestic HiFi systems have a volume control range of just 60 to 80dB.</p>
|
||||
<p>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.
|
||||
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 30 dB.
|
||||
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.
|
||||
The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 30.
|
||||
Using it in this case gives the volume control a much more useful range of settings.</p>
|
||||
<p>As a third example, you can actually extend the range provided by a mixer.
|
||||
Many cheaper DACs have hardware mixers that offer a restricted attenuation range.
|
||||
@@ -250,7 +250,7 @@
|
||||
|
||||
<p><b>disable_synchronization=</b><em>"no"</em><b>;</b></p>
|
||||
This is an advanced setting and is for debugging only. Set to "yes" to disable synchronization. Default is "no".
|
||||
If you use it to disable synchronisation, then soner or later you'll experience audio glitches due to
|
||||
If you use it to disable synchronisation, then sooner or later you'll experience audio glitches due to
|
||||
audio buffer overflow or underflow.
|
||||
|
||||
|
||||
@@ -265,16 +265,18 @@
|
||||
|
||||
<p><b>"PIPE" SETTINGS</b></p>
|
||||
<p>These settings are for the PIPE backend, used to route audio to a named unix pipe. The audio is in raw CD audio format: PCM 16 bit little endian, 44,100 samples per second,
|
||||
stereo.</p>
|
||||
interleaved stereo.</p>
|
||||
<p>Use the <em>name</em> setting to set the name and location of the pipe.</p>
|
||||
<p>There are two further settings affecting timing that might be useful if the pipe reader is, for example,
|
||||
a program to play an audio stream such as <b>aplay</b>. The <em>audio_backend_latency_offset</em> affects precisely when the first audio packet is sent
|
||||
a program to play an audio stream such as <b>aplay</b>. The <em>audio_backend_latency_offset</em> affects precisely
|
||||
when the first audio packet is sent
|
||||
and the <em>audio_backend_buffer_desired_length</em> setting affects the nominal output buffer size.</p>
|
||||
<p>These are the settings available within the <b>pipe</b> group:</p>
|
||||
|
||||
|
||||
<p><b>name=</b><em>"/path/to/pipe"</em><b>;</b></p>
|
||||
Use this to specify the name and location of the pipe. The pipe will be created and opened when shairport-sync starts up and will be closed upon shutdown.
|
||||
Use this to specify the name and location of the pipe. The pipe will be created and opened when shairport-sync starts up
|
||||
and will be closed upon shutdown.
|
||||
Frames of audio will be sent to the pipe in packets of 352 frames and will be discarded if the pipe has not have a reader attached.
|
||||
The sender will wait for up to five seconds for a packet to be written before discarding it.
|
||||
|
||||
@@ -282,7 +284,7 @@
|
||||
|
||||
<p><b>audio_backend_latency_offset=</b><em>offset_in_frames</em><b>;</b></p>
|
||||
|
||||
Packets of audio frames are written to the pipe synchronously -- that is, they are written to at exactly the time they should be played.
|
||||
Packets of audio frames are written to the pipe synchronously -- that is, they are written at exactly the time they should be played.
|
||||
You can offset the time of initial audio output relative to its nominal time using this setting.
|
||||
For example to send an audio stream to the pipe 100 milliseconds before it is due to be played, set this to -4410. Default setting is 0.
|
||||
|
||||
@@ -300,7 +302,7 @@
|
||||
|
||||
<p><b>"STDOUT" SETTINGS</b></p>
|
||||
<p>These settings are for the STDOUT backend, used to route audio to standard output ("stdout").
|
||||
The audio is in raw CD audio format: PCM 16 bit little endian, 44,100 samples per second, stereo.</p>
|
||||
The audio is in raw CD audio format: PCM 16 bit little endian, 44,100 samples per second, interleaved stereo.</p>
|
||||
<p>There are two settings affecting timing that might be useful if the stdout reader is, for example,
|
||||
a program to play an audio stream such as <b>aplay</b>. The <em>audio_backend_latency_offset</em> affects precisely when the first audio packet is sent
|
||||
and the <em>audio_backend_buffer_desired_length</em> setting affects the nominal output buffer size.</p>
|
||||
@@ -344,7 +346,7 @@
|
||||
<p><b>audio_backend_buffer_desired_length=</b><em>buffer_length_in_frames</em><b>;</b></p>
|
||||
|
||||
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 to the libao system.
|
||||
audio frames are sent to the libao system.
|
||||
For example, if you send the first packet of audio exactly when it is due and, using a <em>audio_backend_buffer_desired_length</em> 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 libao system consumes audio packets faster or slower than they are supplied, the buffer will eventually empty or overflow --
|
||||
@@ -356,7 +358,7 @@
|
||||
<p>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 <em>/tmp/shairport-sync-metadata</em>.
|
||||
To process metadata, shairport-sync must have been compiled with metadata support included.
|
||||
You can check that this is so by running <b>shairport-sync -V</b>; the identification string will contain the word <b>metadata</b>.</p>
|
||||
You can check that this is so by running the command <b>$ shairport-sync -V</b>; the identification string will contain the word <b>metadata</b>.</p>
|
||||
<p>Please note that different sources provide different levels of metadata. Some provide a lot; some provide almost none.</p>
|
||||
<p>The <b>metadata</b> group of settings allow you to enable metadata handling and to control certain aspects of it:</p>
|
||||
|
||||
@@ -375,13 +377,13 @@
|
||||
|
||||
|
||||
<p><b>pipe_name=</b><em>"filepathname"</em><b>;</b></p>
|
||||
Specify the absolute path name of the pipe through which metadata should be sent The default is <em>/tmp/shairport-sync-metadata</em>".
|
||||
Specify the absolute path name of the pipe through which metadata should be sent The default is <em>/tmp/shairport-sync-metadata</em>.
|
||||
|
||||
|
||||
|
||||
<p><b>socket_address=</b><em>"hostnameOrIP"</em><b>;</b></p>
|
||||
If <em>hostnameOrIP</em> is set to a host name or and IP address, UDP packets containing metadata will be sent to this address.
|
||||
May be a multicast address. "socket-port" must be non-zero and "enabled" must be set to "yes".
|
||||
May be a multicast address. Additionally, <em>socket-port</em> must be non-zero and <em>enabled</em> must be set to "yes".
|
||||
|
||||
|
||||
<p><b>socket_port=</b><em>port</em><b>;</b></p>
|
||||
@@ -392,12 +394,10 @@
|
||||
The maximum packet size for any UDP metadata. This must be between 500 or 65000. The default is 500.
|
||||
|
||||
|
||||
|
||||
<p><b>"SESSIONCONTROL" SETTINGS</b></p>
|
||||
<p>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.</p>
|
||||
|
||||
|
||||
|
||||
<p><b>run_this_before_play_begins=</b><em>"/path/to/application and args"</em><b>;</b></p>
|
||||
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.
|
||||
@@ -426,11 +426,11 @@
|
||||
|
||||
|
||||
<p><b>"LATENCIES" SETTINGS</b></p>
|
||||
<p>The latencies settings are now deprecated. Do not use them for new installations. They will be removed from a future version of Shairport Sync.</p>
|
||||
<p>The latencies settings are now deprecated. Do not use them for new installations. They will be removed from a future version of shairport-sync.</p>
|
||||
<p>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.</p>
|
||||
|
||||
<p>Shairport Sync now sets latencies automatically using information supplied by the source, typically either 88,200 or 99,577 frames.</p>
|
||||
<p>shairport-sync now sets latencies automatically using information supplied by the source, typically either 88,200 or 99,577 frames.</p>
|
||||
|
||||
<p>The following relates to the old scheme of using fixed latencies, which ignored the latency information supplied by the source.
|
||||
There are four default latency settings. One latency matches the latency used by recent versions of
|
||||
@@ -441,7 +441,6 @@
|
||||
instead of changing these individual latencies, use the <b>audio_backend_latency_offset</b> setting in the <b>alsa</b> group
|
||||
(or the appropriate other group if you're not outputing through the alsa backend).</p>
|
||||
|
||||
|
||||
|
||||
<p><b>itunes=</b><em>latency</em><b>;</b></p>
|
||||
This is the <em>latency</em>, in frames, used for iTunes 10 or later. Default is 99,400.
|
||||
@@ -458,22 +457,22 @@
|
||||
<p><b>default=</b><em>latency</em><b>;</b></p>
|
||||
This is the <em>latency</em>, in frames, used when the source is unrecognised. Default is 88,200.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h2>Options</h2>
|
||||
|
||||
<p>This section is about the command-line options available in shairport-sync.</p>
|
||||
|
||||
<p>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 compatibility with older installations of Shairport Sync.</p>
|
||||
<p>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 command-line options described below
|
||||
simply replicate the configuration settings and are retained to provide backward compatibility with older installations of shairport-sync.</p>
|
||||
|
||||
<p>Many of the options take sensible default values, so you can normally
|
||||
<p>Many command-line options take sensible default values, so you can normally
|
||||
ignore most of them. See the EXAMPLES section for typical usages.</p>
|
||||
|
||||
<p>The command line for shairport-sync can take two kinds of options:
|
||||
<p>There are two kinds of command-line options for shairport-sync:
|
||||
regular <b>program options</b> and <b>audio backend options</b>.
|
||||
Program options are
|
||||
always listed first, followed by any audio backend options, preceded by
|
||||
@@ -481,7 +480,7 @@
|
||||
|
||||
<h2>Program Options</h2>
|
||||
|
||||
<p>These options are used by shairport-sync itself.</p>
|
||||
<p>These command-line options are used by shairport-sync itself.</p>
|
||||
|
||||
|
||||
|
||||
@@ -493,8 +492,8 @@
|
||||
<p>The following substitutions are allowed:
|
||||
<b>%h</b> for the computer's hostname,
|
||||
<b>%H</b> for the computer's hostname with the first letter capitalised (ASCII only),
|
||||
<b>%v</b> for the Shairport Sync version number, e.g. "2.8.4" and
|
||||
<b>%V</b> for the Shairport Sync version string, e.g. "2.8.4-OpenSSL-Avahi-ALSA-soxr-metadata".</p>
|
||||
<b>%v</b> for the shairport-sync version number, e.g. "2.8.4" and
|
||||
<b>%V</b> for the shairport-sync version string, e.g. "2.8.4-OpenSSL-Avahi-ALSA-soxr-metadata".</p>
|
||||
<p>The default is "%H", which is replaced by the hostname with the first letter capitalised.</p>
|
||||
</p>
|
||||
|
||||
@@ -506,7 +505,7 @@
|
||||
device. The default is 88,200 frames, where there are 44,100
|
||||
frames to the second.
|
||||
</p>
|
||||
<p>Please note that this feature is deprecated and will be removed in a future version of Shairport Sync.</p>
|
||||
<p>Please note that this feature is deprecated and will be removed in a future version of shairport-sync.</p>
|
||||
|
||||
|
||||
|
||||
@@ -537,7 +536,7 @@
|
||||
exit. (Requires that the daemon has written its PID to an agreed
|
||||
file -- see the <b>-d</b> option).
|
||||
</p>
|
||||
<p>Please note that this feature is deprecated and will be removed in a future version of Shairport Sync.</p>
|
||||
<p>Please note that this feature is deprecated and will be removed in a future version of shairport-sync.</p>
|
||||
|
||||
|
||||
|
||||
@@ -571,7 +570,7 @@
|
||||
source. The default is 99,400 frames, where there are 44,100
|
||||
frames to the second.
|
||||
</p>
|
||||
<p>Please note that this feature is deprecated and will be removed in a future version of Shairport Sync.</p>
|
||||
<p>Please note that this feature is deprecated and will be removed in a future version of shairport-sync.</p>
|
||||
|
||||
|
||||
|
||||
@@ -600,7 +599,7 @@
|
||||
source, where iTunes is Version 10 or later. The default is 99,400 frames, where there are 44,100
|
||||
frames to the second. If the source is iTunes but is earler than Version 10, the <em>default latency</em> is used (see the <b>-L</b> option). Some third party programs masquerade as older versions of iTunes.
|
||||
</p>
|
||||
<p>Please note that this feature is deprecated and will be removed in a future version of Shairport Sync.</p>
|
||||
<p>Please note that this feature is deprecated and will be removed in a future version of shairport-sync.</p>
|
||||
|
||||
|
||||
|
||||
@@ -618,7 +617,7 @@
|
||||
Use this to set the <em>default latency</em>, in frames, for audio coming from an unidentified source or from an iTunes Version 9 or earlier source. The standard value for the <em>default latency</em> is 88,200 frames, where there are 44,100
|
||||
frames to the second.
|
||||
</p>
|
||||
<p>Please note that this feature is deprecated and will be removed in a future version of Shairport Sync.</p>
|
||||
<p>Please note that this feature is deprecated and will be removed in a future version of shairport-sync.</p>
|
||||
|
||||
|
||||
|
||||
@@ -674,7 +673,7 @@
|
||||
the daemon has written its PID to an agreed file -- see the <b>-d</b>
|
||||
option).
|
||||
</p>
|
||||
<p>Please note that this feature is deprecated and will be removed in a future version of Shairport Sync.</p>
|
||||
<p>Please note that this feature is deprecated and will be removed in a future version of shairport-sync.</p>
|
||||
|
||||
|
||||
|
||||
@@ -761,10 +760,11 @@
|
||||
|
||||
<h2>Audio Backend Options</h2>
|
||||
|
||||
<p>These options are passed to the chosen audio backend. The audio backend options are
|
||||
<p>These command-line options are passed to the chosen audio backend. The audio backend options are
|
||||
preceded by a <b>--</b> symbol to introduce them and to separate them from any
|
||||
program options. In this way, option letters can be used as program
|
||||
options and also as audio backend options without ambiguity.</p>
|
||||
|
||||
<p>In the ALSA backend, audio is sent to an output device
|
||||
which you can specify using the <b>-d</b> option.
|
||||
The output level (the "volume") is controlled using a level control associated with a mixer.
|
||||
@@ -855,8 +855,8 @@
|
||||
|
||||
<h2>Credits</h2>
|
||||
|
||||
<p>Mike Brady developed Shairport Sync from the original Shairport by James Laird.</p>
|
||||
<p>Shairport Sync can be found at <a href = "https://github.com/mikebrady/shairport-sync.">https://github.com/mikebrady/shairport-sync.</a></p>
|
||||
<p>Mike Brady developed shairport-sync from the original Shairport by James Laird.</p>
|
||||
<p>shairport-sync can be found at <a href = "https://github.com/mikebrady/shairport-sync.">https://github.com/mikebrady/shairport-sync.</a></p>
|
||||
<p>Shairport can be found at <a href = "https://github.com/abrasive/shairport.">https://github.com/abrasive/shairport.</a></p>
|
||||
|
||||
|
||||
|
||||
+4
-3
@@ -27,15 +27,16 @@
|
||||
#include <dns_sd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "mdns.h"
|
||||
#include "common.h"
|
||||
|
||||
static DNSServiceRef service;
|
||||
|
||||
static int mdns_dns_sd_register(char *apname, int port) {
|
||||
const char *recordwithoutmetadata[] = {MDNS_RECORD_WITHOUT_METADATA, NULL};
|
||||
char *recordwithoutmetadata[] = {MDNS_RECORD_WITHOUT_METADATA, NULL};
|
||||
#ifdef CONFIG_METADATA
|
||||
const char *recordwithmetadata[] = {MDNS_RECORD_WITH_METADATA, NULL};
|
||||
char *recordwithmetadata[] = {MDNS_RECORD_WITH_METADATA, NULL};
|
||||
#endif
|
||||
char **record;
|
||||
#ifdef CONFIG_METADATA
|
||||
@@ -46,7 +47,7 @@ static int mdns_dns_sd_register(char *apname, int port) {
|
||||
record = recordwithoutmetadata;
|
||||
|
||||
uint16_t length = 0;
|
||||
const char **field;
|
||||
char **field;
|
||||
|
||||
// Concatenate string contained i record into buf.
|
||||
|
||||
|
||||
@@ -74,9 +74,13 @@ static AES_KEY aes;
|
||||
#endif
|
||||
static int sampling_rate, frame_size;
|
||||
|
||||
#define FRAME_BYTES(frame_size) (4 * frame_size)
|
||||
static int bytes_per_audio_frame = 4;
|
||||
|
||||
// The maximum frame size change there can be is +/- 1;
|
||||
static int max_frame_size_change = 1;
|
||||
// #define FRAME_BYTES(frame_size) (4 * frame_size)
|
||||
// maximal resampling shift - conservative
|
||||
#define OUTFRAME_BYTES(frame_size) (4 * (frame_size + 3))
|
||||
//#define OUTFRAME_BYTES(frame_size) (4 * (frame_size + 3))
|
||||
|
||||
#ifdef HAVE_LIBPOLARSSL
|
||||
static aes_context dctx;
|
||||
@@ -112,6 +116,7 @@ typedef struct audio_buffer_entry { // decoded audio packets
|
||||
uint32_t timestamp;
|
||||
seq_t sequence_number;
|
||||
signed short *data;
|
||||
int length; // the length of the decoded data
|
||||
} abuf_t;
|
||||
static abuf_t audio_buffer[BUFFER_FRAMES];
|
||||
#define BUFIDX(seqno) ((seq_t)(seqno) % BUFFER_FRAMES)
|
||||
@@ -222,12 +227,21 @@ static inline int seq32_order(uint32_t a, uint32_t b) {
|
||||
return (C & 0x80000000) == 0;
|
||||
}
|
||||
|
||||
static int alac_decode(short *dest, uint8_t *buf, int len) {
|
||||
static int alac_decode(short *dest, int *destlen, uint8_t *buf, int len) {
|
||||
// parameters: where the decoded stuff goes, its length in samples,
|
||||
// the incoming packet, the length of the incoming packet in bytes
|
||||
// destlen should contain the allowed max number of samples on entry
|
||||
|
||||
if (len>MAX_PACKET) {
|
||||
warn("Incoming audio packet size is too large at %d; it should not exceed %d.",len,MAX_PACKET);
|
||||
return -1;
|
||||
}
|
||||
unsigned char packet[MAX_PACKET];
|
||||
unsigned char packetp[MAX_PACKET];
|
||||
assert(len <= MAX_PACKET);
|
||||
// assert(len <= MAX_PACKET);
|
||||
int reply = 0; //everything okay
|
||||
int outsize=FRAME_BYTES(frame_size); // the size it should be
|
||||
int outsize=bytes_per_audio_frame*(*destlen); // the size the output should be, in bytes
|
||||
int toutsize = outsize;
|
||||
|
||||
if (encrypted) {
|
||||
unsigned char iv[16];
|
||||
@@ -244,14 +258,14 @@ static int alac_decode(short *dest, uint8_t *buf, int len) {
|
||||
} else {
|
||||
alac_decode_frame(decoder_info, buf, dest, &outsize);
|
||||
}
|
||||
if (outsize!=FRAME_BYTES(frame_size)) {
|
||||
if(outsize<FRAME_BYTES(frame_size)) {
|
||||
debug(2,"Output from alac_decode is smaller than expected. Encrypted = %d.",encrypted);
|
||||
} else {
|
||||
debug(2,"Output from alac_decode larger than expected -- truncated, but buffer overflow possible! Encrypted = %d.",encrypted);
|
||||
}
|
||||
reply = -1; // output frame is the wrong size
|
||||
}
|
||||
|
||||
if(outsize>toutsize) {
|
||||
debug(2,"Output from alac_decode larger (%d bytes, not frames) than expected (%d bytes) -- truncated, but buffer overflow possible! Encrypted = %d.",outsize, toutsize, encrypted);
|
||||
reply = -1; // output packet is the wrong size
|
||||
}
|
||||
*destlen = outsize / bytes_per_audio_frame;
|
||||
if ((outsize % bytes_per_audio_frame)!=0)
|
||||
debug(1,"Number of audio frames (%d) does not correspond exactly to the number of bytes (%d) and the audio frame size (%d).",*destlen,outsize,bytes_per_audio_frame);
|
||||
return reply;
|
||||
}
|
||||
|
||||
@@ -290,7 +304,7 @@ static void free_decoder(void) { alac_free(decoder_info); }
|
||||
static void init_buffer(void) {
|
||||
int i;
|
||||
for (i = 0; i < BUFFER_FRAMES; i++)
|
||||
audio_buffer[i].data = malloc(OUTFRAME_BYTES(frame_size));
|
||||
audio_buffer[i].data = malloc(bytes_per_audio_frame*(frame_size+max_frame_size_change));
|
||||
ab_resync();
|
||||
}
|
||||
|
||||
@@ -375,8 +389,10 @@ void player_put_packet(seq_t seqno, uint32_t timestamp, uint8_t *data, int len)
|
||||
// pthread_mutex_unlock(&ab_mutex);
|
||||
|
||||
if (abuf) {
|
||||
if (alac_decode(abuf->data, data, len)==0) {
|
||||
int datalen = frame_size;
|
||||
if (alac_decode(abuf->data, &datalen, data, len)==0) {
|
||||
abuf->ready = 1;
|
||||
abuf->length = datalen;
|
||||
abuf->timestamp = timestamp;
|
||||
abuf->sequence_number = seqno;
|
||||
|
||||
@@ -686,11 +702,11 @@ static abuf_t *buffer_get_frame(void) {
|
||||
// debug(2,"Zero length silence buffer needed with gross_frame_gap of %lld and dac_delay of %lld.",gross_frame_gap,dac_delay);
|
||||
// the fs (number of frames of silence to play) can be zero in the DAC doesn't start ouotputting frames for a while -- it could get loaded up but not start responding for many milliseconds.
|
||||
if (fs!=0) {
|
||||
silence = malloc(FRAME_BYTES(fs));
|
||||
silence = malloc(bytes_per_audio_frame*fs);
|
||||
if (silence==NULL)
|
||||
debug(1,"Failed to allocate %d byte silence buffer.",fs);
|
||||
else {
|
||||
memset(silence, 0, FRAME_BYTES(fs));
|
||||
memset(silence, 0, bytes_per_audio_frame*fs);
|
||||
// debug(1,"Exact frame gap is %llu; play %d frames of silence. Dac_delay is %d,
|
||||
// with %d packets.",exact_frame_gap,fs,dac_delay,seq_diff(ab_read, ab_write));
|
||||
config.output->play(silence, fs);
|
||||
@@ -822,7 +838,7 @@ static abuf_t *buffer_get_frame(void) {
|
||||
if (!curframe->ready) {
|
||||
// debug(1, "Supplying a silent frame for frame %u", read);
|
||||
missing_packets++;
|
||||
memset(curframe->data, 0, FRAME_BYTES(frame_size));
|
||||
memset(curframe->data, 0, bytes_per_audio_frame*frame_size);
|
||||
curframe->timestamp = 0;
|
||||
}
|
||||
curframe->ready = 0;
|
||||
@@ -842,17 +858,17 @@ static inline short shortmean(short a, short b) {
|
||||
}
|
||||
|
||||
// stuff: 1 means add 1; 0 means do nothing; -1 means remove 1
|
||||
static int stuff_buffer_basic(short *inptr, short *outptr, int stuff) {
|
||||
if ((stuff > 1) || (stuff < -1)) {
|
||||
debug(1, "Stuff argument to stuff_buffer must be from -1 to +1.");
|
||||
return frame_size;
|
||||
static int stuff_buffer_basic(short *inptr, int length, short *outptr, int stuff) {
|
||||
if ((stuff > 1) || (stuff < -1) || (length <100)) {
|
||||
// debug(1, "Stuff argument to stuff_buffer must be from -1 to +1 and length >100.");
|
||||
return length;
|
||||
}
|
||||
int i;
|
||||
int stuffsamp = frame_size;
|
||||
int stuffsamp = length;
|
||||
if (stuff)
|
||||
// stuffsamp = rand() % (frame_size - 1);
|
||||
// stuffsamp = rand() % (length - 1);
|
||||
stuffsamp =
|
||||
(rand() % (frame_size - 2)) + 1; // ensure there's always a sample before and after the item
|
||||
(rand() % (length - 2)) + 1; // ensure there's always a sample before and after the item
|
||||
|
||||
pthread_mutex_lock(&vol_mutex);
|
||||
for (i = 0; i < stuffsamp; i++) { // the whole frame, if no stuffing
|
||||
@@ -872,22 +888,28 @@ static int stuff_buffer_basic(short *inptr, short *outptr, int stuff) {
|
||||
inptr++;
|
||||
inptr++;
|
||||
}
|
||||
for (i = stuffsamp; i < frame_size + stuff; i++) {
|
||||
|
||||
// if you're removing, i.e. stuff < 0, copy that much less over. If you're adding, do all the rest.
|
||||
int remainder = length;
|
||||
if (stuff<0)
|
||||
remainder = remainder+stuff; // don't run over the correct end of the output buffer
|
||||
|
||||
for (i = stuffsamp; i < remainder; i++) {
|
||||
*outptr++ = dithered_vol(*inptr++);
|
||||
*outptr++ = dithered_vol(*inptr++);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&vol_mutex);
|
||||
|
||||
return frame_size + stuff;
|
||||
return length + stuff;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBSOXR
|
||||
// stuff: 1 means add 1; 0 means do nothing; -1 means remove 1
|
||||
static int stuff_buffer_soxr(short *inptr, short *outptr, int stuff) {
|
||||
if ((stuff > 1) || (stuff < -1)) {
|
||||
debug(1, "Stuff argument to sox_stuff_buffer must be from -1 to +1.");
|
||||
return frame_size;
|
||||
static int stuff_buffer_soxr(short *inptr, int length, short *outptr, int stuff) {
|
||||
if ((stuff > 1) || (stuff < -1) || (length < 100)) {
|
||||
// debug(1, "Stuff argument to sox_stuff_buffer must be from -1 to +1 and length must be > 100.");
|
||||
return length;
|
||||
}
|
||||
int i;
|
||||
short *ip, *op;
|
||||
@@ -905,16 +927,16 @@ static int stuff_buffer_soxr(short *inptr, short *outptr, int stuff) {
|
||||
|
||||
size_t odone;
|
||||
|
||||
soxr_error_t error = soxr_oneshot(frame_size, frame_size + stuff, 2, /* Rates and # of chans. */
|
||||
inptr, frame_size, NULL, /* Input. */
|
||||
outptr, frame_size + stuff, &odone, /* Output. */
|
||||
soxr_error_t error = soxr_oneshot(length, length + stuff, 2, /* Rates and # of chans. */
|
||||
inptr, length, NULL, /* Input. */
|
||||
outptr, length + stuff, &odone, /* Output. */
|
||||
&io_spec, /* Input, output and transfer spec. */
|
||||
NULL, NULL); /* Default configuration.*/
|
||||
|
||||
if (error)
|
||||
die("soxr error: %s\n", "error: %s\n", soxr_strerror(error));
|
||||
|
||||
if (odone > frame_size + 1)
|
||||
if (odone > length + 1)
|
||||
die("odone = %d!\n", odone);
|
||||
|
||||
const int gpm = 5;
|
||||
@@ -926,8 +948,8 @@ static int stuff_buffer_soxr(short *inptr, short *outptr, int stuff) {
|
||||
}
|
||||
|
||||
// keep the last (dpm) samples, to mitigate the Gibbs phenomenon
|
||||
op = outptr + (frame_size + stuff - gpm) * sizeof(short);
|
||||
ip = inptr + (frame_size - gpm) * sizeof(short);
|
||||
op = outptr + (length + stuff - gpm) * sizeof(short);
|
||||
ip = inptr + (length - gpm) * sizeof(short);
|
||||
for (i = 0; i < gpm; i++) {
|
||||
*op++ = *ip++;
|
||||
*op++ = *ip++;
|
||||
@@ -937,7 +959,7 @@ static int stuff_buffer_soxr(short *inptr, short *outptr, int stuff) {
|
||||
if (fix_volume != 65536.0) {
|
||||
// pthread_mutex_lock(&vol_mutex);
|
||||
op = outptr;
|
||||
for (i = 0; i < frame_size + stuff; i++) {
|
||||
for (i = 0; i < length + stuff; i++) {
|
||||
*op = dithered_vol(*op);
|
||||
op++;
|
||||
*op = dithered_vol(*op);
|
||||
@@ -949,13 +971,13 @@ static int stuff_buffer_soxr(short *inptr, short *outptr, int stuff) {
|
||||
} else { // the whole frame, if no stuffing
|
||||
|
||||
// pthread_mutex_lock(&vol_mutex);
|
||||
for (i = 0; i < frame_size; i++) {
|
||||
for (i = 0; i < length; i++) {
|
||||
*op++ = dithered_vol(*ip++);
|
||||
*op++ = dithered_vol(*ip++);
|
||||
};
|
||||
// pthread_mutex_unlock(&vol_mutex);
|
||||
}
|
||||
return frame_size + stuff;
|
||||
return length + stuff;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1012,13 +1034,13 @@ static void *player_thread_func(void *arg) {
|
||||
initstate(time(NULL), rnstate, 256);
|
||||
|
||||
signed short *inbuf, *outbuf, *silence;
|
||||
outbuf = malloc(OUTFRAME_BYTES(frame_size));
|
||||
outbuf = malloc(bytes_per_audio_frame*(frame_size+max_frame_size_change));
|
||||
if (outbuf==NULL)
|
||||
debug(1,"Failed to allocate memory for an output buffer.");
|
||||
silence = malloc(OUTFRAME_BYTES(frame_size));
|
||||
silence = malloc(bytes_per_audio_frame*frame_size);
|
||||
if (silence==NULL)
|
||||
debug(1,"Failed to allocate memory for a silence buffer.");
|
||||
memset(silence, 0, OUTFRAME_BYTES(frame_size));
|
||||
memset(silence, 0, bytes_per_audio_frame*frame_size);
|
||||
late_packet_message_sent = 0;
|
||||
first_packet_timestamp = 0;
|
||||
missing_packets = late_packets = too_late_packets = resend_requests = 0;
|
||||
@@ -1066,21 +1088,20 @@ static void *player_thread_func(void *arg) {
|
||||
while (!please_stop) {
|
||||
abuf_t *inframe = buffer_get_frame();
|
||||
if (inframe) {
|
||||
inbuf = inframe->data;
|
||||
if (inbuf) {
|
||||
if (inframe->data) {
|
||||
play_number++;
|
||||
// if it's a supplied silent frame, let us know...
|
||||
if (inframe->timestamp == 0) {
|
||||
// debug(1,"Player has a supplied silent frame.");
|
||||
last_seqno_read =
|
||||
(SUCCESSOR(last_seqno_read) & 0xffff); // manage the packet out of sequence minder
|
||||
if (inbuf==NULL)
|
||||
debug(1,"NULL inbuf to play -- skipping it.");
|
||||
if (inframe->data==NULL)
|
||||
debug(1,"NULL inframe->data to play -- skipping it.");
|
||||
else {
|
||||
if (frame_size==0)
|
||||
debug(1,"empty frame to play -- skipping it (1).");
|
||||
if (inframe->length==0)
|
||||
debug(1,"empty frame to play -- skipping it.");
|
||||
else
|
||||
config.output->play(inbuf, frame_size);
|
||||
config.output->play(inframe->data, inframe->length);
|
||||
}
|
||||
} else {
|
||||
// We have a frame of data. We need to see if we want to add or remove a frame from it to
|
||||
@@ -1146,7 +1167,9 @@ static void *player_thread_func(void *arg) {
|
||||
if (buffer_occupancy > maximum_buffer_occupancy)
|
||||
maximum_buffer_occupancy = buffer_occupancy;
|
||||
|
||||
// here, we want to check (a) if we are meant to do synchronisation, (b) if we have a delay procedure, (b) if we can get the delay.
|
||||
// here, we want to check (a) if we are meant to do synchronisation,
|
||||
// (b) if we have a delay procedure, (c) if we can get the delay.
|
||||
|
||||
// If any of these are false, we don't do any synchronisation stuff
|
||||
|
||||
int resp = -1; // use this as a flag -- if negative, we can't rely on a real known delay
|
||||
@@ -1223,29 +1246,29 @@ static void *player_thread_func(void *arg) {
|
||||
// if no stuffing needed and no volume adjustment, then
|
||||
// don't send to stuff_buffer_* and don't copy to outbuf; just send directly to the
|
||||
// output device...
|
||||
if (inbuf==NULL)
|
||||
debug(1,"NULL inbuf to play -- skipping it.");
|
||||
if (inframe->data==NULL)
|
||||
debug(1,"NULL inframe->data to play -- skipping it.");
|
||||
else {
|
||||
if (frame_size==0)
|
||||
if (inframe->length==0)
|
||||
debug(1,"empty frame to play -- skipping it (2).");
|
||||
else
|
||||
config.output->play(inbuf, frame_size);
|
||||
config.output->play(inframe->data, inframe->length);
|
||||
}
|
||||
} else {
|
||||
#ifdef HAVE_LIBSOXR
|
||||
switch (config.packet_stuffing) {
|
||||
case ST_basic:
|
||||
// if (amount_to_stuff) debug(1,"Basic stuff...");
|
||||
play_samples = stuff_buffer_basic(inbuf, outbuf, amount_to_stuff);
|
||||
play_samples = stuff_buffer_basic(inframe->data, inframe->length, outbuf, amount_to_stuff);
|
||||
break;
|
||||
case ST_soxr:
|
||||
// if (amount_to_stuff) debug(1,"Soxr stuff...");
|
||||
play_samples = stuff_buffer_soxr(inbuf, outbuf, amount_to_stuff);
|
||||
play_samples = stuff_buffer_soxr(inframe->data, inframe->length, outbuf, amount_to_stuff);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
// if (amount_to_stuff) debug(1,"Standard stuff...");
|
||||
play_samples = stuff_buffer_basic(inbuf, outbuf, amount_to_stuff);
|
||||
play_samples = stuff_buffer_basic(inframe->data, inframe->length, outbuf, amount_to_stuff);
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -1303,24 +1326,24 @@ static void *player_thread_func(void *arg) {
|
||||
|
||||
if (fix_volume == 0x10000)
|
||||
|
||||
if (inbuf==NULL)
|
||||
debug(1,"NULL inbuf to play -- skipping it.");
|
||||
if (inframe->data==NULL)
|
||||
debug(1,"NULL inframe->data to play -- skipping it.");
|
||||
else {
|
||||
if (frame_size==0)
|
||||
if (inframe->length==0)
|
||||
debug(1,"empty frame to play -- skipping it (3).");
|
||||
else
|
||||
config.output->play(inbuf, frame_size);
|
||||
config.output->play(inframe->data, inframe->length);
|
||||
}
|
||||
else {
|
||||
play_samples = stuff_buffer_basic(inbuf, outbuf, 0); // no stuffing, but volume adjustment
|
||||
play_samples = stuff_buffer_basic(inframe->data, inframe->length, outbuf, 0); // no stuffing, but volume adjustment
|
||||
|
||||
if (outbuf==NULL)
|
||||
debug(1,"NULL outbuf to play -- skipping it.");
|
||||
else {
|
||||
if (frame_size==0)
|
||||
if (inframe->length==0)
|
||||
debug(1,"empty frame to play -- skipping it (4).");
|
||||
else
|
||||
config.output->play(outbuf, frame_size);
|
||||
config.output->play(outbuf, play_samples);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -967,6 +967,9 @@ static void handle_set_parameter_parameter(rtsp_conn_info *conn,
|
||||
// string to identify the source's remote control on the network.
|
||||
// 'acre' -- this is the source's Active-Remote token, necessary if you want
|
||||
// to send commands to the source's remote control (if it has one).
|
||||
// `clip` -- the payload is the IP number of the client, i.e. the sender of audio.
|
||||
// Can be an IPv4 or an IPv6 number.
|
||||
|
||||
//
|
||||
// including a simple base64 encoder to minimise malloc/free activity
|
||||
|
||||
@@ -1838,7 +1841,12 @@ void rtsp_listen_loop(void) {
|
||||
// strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Set the RTSP socket to close on exec() of child processes
|
||||
// otherwise background run_this_before_play_begins or run_this_after_play_ends commands
|
||||
// that are sleeping prevent the daemon from being restarted because
|
||||
// the listening RTSP port is still in use.
|
||||
// See: https://github.com/mikebrady/shairport-sync/issues/329
|
||||
fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||
ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
|
||||
|
||||
#ifdef IPV6_V6ONLY
|
||||
@@ -1877,7 +1885,7 @@ void rtsp_listen_loop(void) {
|
||||
freeaddrinfo(info);
|
||||
|
||||
if (!nsock)
|
||||
die("Could not establish a service on port %d -- program terminating. Is another Shairport Sync running?",config.port);
|
||||
die("Could not establish a service on port %d -- program terminating. Is another Shairport Sync running on this device?",config.port);
|
||||
|
||||
int maxfd = -1;
|
||||
fd_set fds;
|
||||
@@ -1945,6 +1953,10 @@ void rtsp_listen_loop(void) {
|
||||
sa = (struct sockaddr_in*)&conn->remote;
|
||||
inet_ntop(AF_INET, &(sa->sin_addr), remote_ip4, INET_ADDRSTRLEN);
|
||||
unsigned short int rport = ntohs(sa->sin_port);
|
||||
#ifdef CONFIG_METADATA
|
||||
send_ssnc_metadata('clip', strdup(ip4), strlen(ip4) , 1);
|
||||
#endif
|
||||
|
||||
debug(1,"New RTSP connection from %s:%u to self at %s:%u.",remote_ip4,rport,ip4,tport);
|
||||
}
|
||||
#ifdef AF_INET6
|
||||
@@ -1960,7 +1972,9 @@ void rtsp_listen_loop(void) {
|
||||
sa6 = (struct sockaddr_in6*)&conn->remote; // pretend this is loaded with something
|
||||
inet_ntop(AF_INET6, &(sa6->sin6_addr), remote_ip6, INET6_ADDRSTRLEN);
|
||||
u_int16_t rport = ntohs(sa6->sin6_port);
|
||||
|
||||
#ifdef CONFIG_METADATA
|
||||
send_ssnc_metadata('clip', strdup(ip6), strlen(ip6), 1);
|
||||
#endif
|
||||
debug(1,"New RTSP connection from [%s]:%u to self at [%s]:%u.",remote_ip6,rport,ip6,tport);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -63,7 +63,7 @@ alsa =
|
||||
// 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.
|
||||
// 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
|
||||
// use_mmap_if_available = "yes"; // Use this optional advanced setting to control whether MMAP-based output is used to communicate with the DAC. Default is "yes"
|
||||
};
|
||||
|
||||
// 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.
|
||||
|
||||
+5
-12
@@ -151,6 +151,8 @@ char* get_version_string() {
|
||||
#ifdef CONFIG_METADATA
|
||||
strcat(version_string, "-metadata");
|
||||
#endif
|
||||
strcat(version_string, "-sysconfdir:");
|
||||
strcat(version_string, SYSCONFDIR);
|
||||
}
|
||||
return version_string;
|
||||
}
|
||||
@@ -490,14 +492,6 @@ int parse_options(int argc, char **argv) {
|
||||
if (config_lookup_int(config.cfg, "metadata.socket_msglength", &value)) {
|
||||
config.metadata_sockmsglength = value < 500 ? 500 : value > 65000 ? 65000 : value;
|
||||
}
|
||||
if (config_lookup_int(config.cfg, "metadata.pipe_timeout", &value)) {
|
||||
|
||||
if ((value < 1) || (value > 150000))
|
||||
die("Invalid timeout range \"%sd\". It should be in the range 1 to 150,000 milliseconds.",
|
||||
value);
|
||||
else
|
||||
config.metadata_pipe_timeout = value;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -737,7 +731,8 @@ int main(int argc, char **argv) {
|
||||
endianness = SS_BIG_ENDIAN;
|
||||
else die("Can not recognise the endianness of the processor.");
|
||||
|
||||
strcpy(configuration_file_path, "/etc/");
|
||||
strcpy(configuration_file_path, SYSCONFDIR);
|
||||
strcat(configuration_file_path, "/");
|
||||
strcat(configuration_file_path, appName);
|
||||
strcat(configuration_file_path, ".conf");
|
||||
config.configfile = configuration_file_path;
|
||||
@@ -763,9 +758,6 @@ int main(int argc, char **argv) {
|
||||
//snprintf(config.service_name, 20 + 100, "Shairport Sync on %s", hostname);
|
||||
set_requested_connection_state_to_output(1); // we expect to be able to connect to the output device
|
||||
config.audio_backend_buffer_desired_length = 6615; // 0.15 seconds.
|
||||
#ifdef CONFIG_METADATA
|
||||
config.metadata_pipe_timeout = 5000; //milliseconds
|
||||
#endif
|
||||
config.udp_port_base = 6001;
|
||||
config.udp_port_range = 100;
|
||||
|
||||
@@ -1023,6 +1015,7 @@ int main(int argc, char **argv) {
|
||||
debug(1, "ignore_volume_control is %d.", config.ignore_volume_control);
|
||||
debug(1, "playback_mode is %d (0-stereo, 1-mono).", config.playback_mode);
|
||||
debug(1, "disable_synchronization is %d.", config.no_sync);
|
||||
debug(1, "use_mmap_if_available is %d.", config.no_mmap ? 0 : 1);
|
||||
debug(1, "audio backend desired buffer length is %d.",
|
||||
config.audio_backend_buffer_desired_length);
|
||||
debug(1, "audio backend latency offset is %d.", config.audio_backend_latency_offset);
|
||||
|
||||
Reference in New Issue
Block a user