Bring all the updates to 2.4.2
This commit is contained in:
+1
-1
@@ -14,7 +14,7 @@ git clone git://git.code.sf.net/p/soxr/code libsoxr
|
||||
cd libsoxr
|
||||
./go
|
||||
```
|
||||
Be patient! This takes a long time on a Raspberry Pi -- it looks like it gets stuck at 47%, but it will finish if you let it.
|
||||
Be patient! This takes a long time on a Raspberry Pi -- it looks like it gets stuck around 40% or 50%, but it will finish if you let it.
|
||||
|
||||
Having compiled `libsoxr`, it must now must be installed:
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Shairport Sync
|
||||
=============
|
||||
Shairport Sync emulates an AirPort Express for the purpose of streaming audio from iTunes, iPods, iPhones, iPads and AppleTVs.
|
||||
Shairport Sync is an AirPlay audio player -- it plays audio streamed from iTunes, iOS devices and third-party AirPlay sources such as ForkedDaapd and others.
|
||||
Audio played by a Shairport Sync-powered device stays synchronised with the source and hence with similar devices playing the same source. In this way, synchronised multi-room audio is possible without difficulty. (Hence the name Shairport Sync, BTW.)
|
||||
|
||||
Shairport Sync does not support AirPlay video or photo streaming.
|
||||
@@ -13,11 +13,11 @@ Shairport Sync works by using timing information and timestamps present in data
|
||||
|
||||
To maintain the exact latency required, if an output device is running slow relative to the source, Shairport Sync will delete frames of audio to allow the device to keep up. If the output device is running fast, Shairport Sync will insert frames to keep time. The number of frames inserted or deleted is so small as to be almost inaudible on normal audio material. Frames are inserted or deleted as necessary at pseudorandom intervals. Alternatively, with `libsoxr` support, Shairport Sync can resample the audio feed to ensure the output device can keep up. This is less obtrusive than insertion and deletion but requires a good deal of processing power — most embedded devices probably can't support it. The process of insertion/deletion or resampling is rather inelegantly called “stuffing”.
|
||||
|
||||
There are four default latency settings, chosen automatically. One latency matches the latency used by recent versions of iTunes when playing audio and another matches the latency used by so-called "AirPlay" devices — iOS devices and iTunes and Quicktime Player when they are playing video. A third latency is used when the audio source is `forked-daapd`. The fourth latency is the default if no other latency is chosen and is used for older versions of iTunes.
|
||||
The exact latency to be used is specified by the source when it negotiates with Shaiport Sync. Most sources set a latency of 88,200 frames -- exactly two seconds. Recent versions of iTunes and forkedDaapd use a latency of 99,577 frames (pretty close to the 99,400 frames estimated from listening tests!).
|
||||
|
||||
Shairport Sync is a pretty substantial rewrite of the fantastic work done in Shairport 1.0 by James Laird and others — please see https://github.com/abrasive/shairport/blob/master/README.md#contributors-to-version-1x for a list of the contributors to Shairport 1.x and Shairport 0.x. From a "heritage" point of view, Shairport Sync is a fork of Shairport 1.0.
|
||||
|
||||
Shairport Sync is designed for Linux and ALSA. It must have direct access to the output device, which must be a real sound card capable of working with 44,100 samples per second interleaved PCM stereo (you'll get a message in the logfile if there's a problem).
|
||||
Shairport Sync is mainly designed for `alsa` and thus for Linux, although since `alsa` has been ported to FreeBSD, Shairport Sync runs in FreeBSD too. It must have direct access to the output device, which must be a real sound card capable of working with 44,100 samples per second interleaved PCM stereo (you'll get a message in the logfile if there's a problem).
|
||||
|
||||
For more about the motivation behind Shairport Sync, please see the wiki at https://github.com/mikebrady/shairport-sync/wiki.
|
||||
|
||||
@@ -27,21 +27,21 @@ What else?
|
||||
* Hardware Mute — Shairport Sync will mute properly if the hardware supports it.
|
||||
* Fast Response — With hardware volume control, response is instantaneous; otherwise the response time is 0.15 seconds.
|
||||
* Non-Interruptible — Shairport Sync sends back a "busy" signal if it's already playing audio from another source, so other sources can't disrupt an existing Shairport Sync session. (If a source disappears without warning, the session automatically terminates after two minutes and the device becomes available again.)
|
||||
* Metadata — Shairport Sync can be configured to deliver metadata, such as Album Name, Artist Name, Cover Art, etc. through a pipe to a recipient application program — see https://github.com/mikebrady/shairport-sync-metadata-reader for a sample recipient.
|
||||
* Metadata — Shairport Sync can be configured to deliver metadata supplied by the source, such as Album Name, Artist Name, Cover Art, etc. through a pipe to a recipient application program — see https://github.com/mikebrady/shairport-sync-metadata-reader for a sample recipient. Sources that supply metadata include iTunes among others but the Music app in iOS 9 only supplies volume control metadata.
|
||||
* Raw Audio — Shairport Sync can deliver raw PCM audio to standard output or to a pipe. This output is delivered synchronously with the source after the appropriate latency and is not interpolated or "stuffed" on its way through Shairport Sync.
|
||||
* Autotools and Libtool Support — One important difference between Shairport Sync and other versions of Shairport is that the Shairport Sync build process uses GNU autotools and libtool to examine and configure the build environment — very important for cross compilation. Previous versions of Shairport looked at the current system to determine which packages were available, instead of looking at the target system for what packages were available.
|
||||
|
||||
Status
|
||||
------
|
||||
Shairport Sync works on a wide variety of Linux devices. It works on standard Ubuntu laptops, on the Raspberry Pi with Raspbian, Arch Linux and OpenWrt, and it runs on a Linksys NSLU2 and a TP-Link 710N using OpenWrt. It works with built-in audio and with a variety of USB-connected audio amplifiers and DACs, including a cheapo USB "3D Sound" dongle, a first generation iMic and a Topping TP30 amplifier with a USB DAC input. It will not work properly – if at all – with a PulseAudio (pseudo-)output device.
|
||||
Shairport Sync works on a wide variety of Linux devices. It works on standard Ubuntu laptops, on the Raspberry Pi with Raspbian Wheezy and Jessie, Arch Linux and OpenWrt, and it runs on a Linksys NSLU2 and a TP-Link 710N using OpenWrt. It works with built-in audio and with a variety of USB-connected audio amplifiers and DACs, including a cheapo USB "3D Sound" dongle, a first generation iMic and a Topping TP30 amplifier with a USB DAC input. It will not work properly – if at all – with a PulseAudio (pseudo-)output device. Using a port of the `alsa` system, Shairport Sync runs rather well on FreeBSD.
|
||||
|
||||
Shairport Sync runs well on the Raspberry Pi. It can drive the built-in sound card, though the audio out of the card is of poor quality. USB-connected sound cards work well on recent versions of Raspbian; however older versions of Raspbian appear to suffer from a problem — see http://www.raspberrypi.org/forums/viewtopic.php?t=23544, so it is wise to update. Shairport Sync works well with the IQAudIO Pi-DAC — see http://www.iqaudio.com.
|
||||
Shairport Sync runs well on the Raspberry Pi. It can drive the built-in sound card, though the audio out of the card is of poor quality (see the note below on configuring the Raspberry Pi to make best use of it). USB-connected sound cards work well on recent versions of Raspbian; however older versions of Raspbian appear to suffer from a problem — see http://www.raspberrypi.org/forums/viewtopic.php?t=23544, so it is wise to update. Shairport Sync works well with the IQAudIO Pi-DAC — see http://www.iqaudio.com.
|
||||
|
||||
At the time of writing, OpenWrt trunk does not support USB audio well on the Raspberry Pi.
|
||||
|
||||
Shairport Sync runs on Ubuntu, OpenWrt, Debian, Arch Linux and Fedora inside VMWare Fusion on a Mac, but synchronisation in inaccurate — possibly because the soundcard is being emulated.
|
||||
|
||||
Shairport Sync will output to alsa cards, to standard output and to pipes using appropriate backends. You can try compiling additional backends in as you wish, but it definitely will not work properly with them. Maybe someday...
|
||||
Shairport Sync will output to `alsa` cards, to standard output and to pipes using appropriate backends. You can try compiling additional backends in as you wish, but it definitely will not work properly with them. Maybe someday...
|
||||
|
||||
For information about changes and updates, please refer to the RELEASENOTES.md file in the distribution.
|
||||
|
||||
@@ -52,7 +52,7 @@ Building And Installing
|
||||
If you wish to install Shairport Sync on OpenWrt, Arch or Fedora platforms, please follow the appropriate instructions below. Otherwise follow the General Build Instructions. Then, when the program has been installed, refer to the section on Configuring Shairport Sync that follows.
|
||||
|
||||
**OpenWrt:**
|
||||
If you're interested in Shairport Sync for OpenWrt, there's an OpenWrt package at https://github.com/mikebrady/shairport-sync-for-openwrt. OpenWrt doesn't support the IQaudIO Pi-DAC.
|
||||
Thes is a Shairport Sync package in OpenWrt `trunk`. Also, there's an OpenWrt package at https://github.com/mikebrady/shairport-sync-for-openwrt, including one that builds back to `Attitude Adjustment`.
|
||||
|
||||
**Arch Linux:**
|
||||
An Arch Linux installation package is available at [EliaCereda/shairport-sync-PKGBUILD](https://github.com/EliaCereda/shairport-sync-PKGBUILD).
|
||||
@@ -106,7 +106,7 @@ Assuming the usual build essentials and git, Debian, Ubuntu and Raspbian users c
|
||||
- `apt-get install avahi-daemon libavahi-client-dev` if you want to use Avahi (recommended).
|
||||
- `apt-get install libssl-dev` if you want to use OpenSSL and libcrypto, or use PolarSSL otherwise.
|
||||
- `apt-get install libpolarssl-dev` if you want to use PolarSSL, or use OpenSSL/libcrypto otherwise.
|
||||
- `apt-get install libsoxr-dev` if you want support for libsoxr-based resampling. This library is not yet part of Raspbian; instructions for how to build it from source are available at [LIBSOXR.md](https://github.com/mikebrady/shairport-sync/blob/2.3/LIBSOXR.md).
|
||||
- `apt-get install libsoxr-dev` if you want support for libsoxr-based resampling. This library is not yet part of Raspbian; instructions for how to build it from source are available at [LIBSOXR.md](https://github.com/mikebrady/shairport-sync/blob/development/LIBSOXR.md).
|
||||
|
||||
Download Shairport Sync:
|
||||
|
||||
@@ -115,6 +115,7 @@ Download Shairport Sync:
|
||||
Next, `cd` into the shairport-sync directory and execute the following commands:
|
||||
|
||||
```
|
||||
$ git checkout development #select the development branch
|
||||
$ autoreconf -i -f
|
||||
```
|
||||
|
||||
@@ -133,28 +134,77 @@ Choose the appropriate `--with-*` options:
|
||||
- `--with-configfile` to install a configuration file and a separate sample file at the `make install` stage. Default is to install. An existing `/etc/shairport-sync.conf` will not be overwritten.
|
||||
- `--with-pkg-config` to use pkg-config to find libraries. Default is to use pkg-config — this option is for special purpose use.
|
||||
|
||||
**System V and `systemd`**
|
||||
|
||||
At the time of writing, there are two general systems for automatically starting programs automatically at startup: "System V" or `systemd`. To see if the `systemd` process is running on your system, enter the following command:
|
||||
|
||||
`ps aux | grep systemd | grep -v grep`
|
||||
|
||||
On a system using `systemd` (this is a Raspberry Pi running Raspbian Jessie) you'll get many lines containing `systemd`, for example:
|
||||
```
|
||||
pi@raspberrypi ~ $ ps aux | grep systemd | grep -v grep
|
||||
root 90 0.1 0.6 8088 2764 ? Ss 08:00 0:01 /lib/systemd/systemd-journald
|
||||
root 93 0.0 0.6 11816 3004 ? Ss 08:00 0:00 /lib/systemd/systemd-udevd
|
||||
root 502 0.0 0.5 3824 2436 ? Ss 08:00 0:00 /lib/systemd/systemd-logind
|
||||
message+ 528 0.0 0.7 5568 3172 ? Ss 08:00 0:01 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
|
||||
pi 983 0.0 0.7 4912 3256 ? Ss 08:00 0:00 /lib/systemd/systemd --user
|
||||
pi@raspberrypi ~ $
|
||||
```
|
||||
whereas on a system without `systemd` -- presumably using System V -- (this is a Raspberry Pi running Raspbian Wheezy) , you'll get nothing:
|
||||
```
|
||||
pi@raspberrypi ~ $ ps aux | grep systemd | grep -v grep
|
||||
pi@raspberrypi ~ $
|
||||
```
|
||||
Choose `--with-systemd` or `--with-systemv` on the basis of the outcome.
|
||||
|
||||
Here is an example, suitable for installations such as Ubuntu and Raspbian:
|
||||
|
||||
`$ ./configure --with-alsa --with-avahi --with-ssl=openssl --with-metadata --with-soxr --with-systemv`
|
||||
|
||||
Omit the `--with-soxr` if the libsoxr library is not available. For installation into a `systemd` system, replace the `--with-systemv` with `--with-systemd`.
|
||||
* Omit the `--with-soxr` if the libsoxr library is not available.
|
||||
* For installation into a `systemd` system, replace the `--with-systemv` with `--with-systemd`.
|
||||
|
||||
Enter:
|
||||
|
||||
`$ make`
|
||||
|
||||
to build the application. Next, run:
|
||||
to build the application.
|
||||
|
||||
**Installation to a System V system**
|
||||
If you are installing onto a System V system:
|
||||
|
||||
```
|
||||
$sudo make install
|
||||
$sudo update-rc.d shairport-sync defaults 90 10
|
||||
```
|
||||
|
||||
to install `shairport-sync` along with a `man` page, a default configuration file and a System V startup script to launch it automatically at system startup.
|
||||
The settings are the most basic defaults, so you will want to edit the configuration — the file is `/etc/shairport-sync.conf` — to give the service a name,
|
||||
use a specific sound card and mixer control, etc. — there are some examples in the sample configuration file.
|
||||
|
||||
*Man Page*
|
||||
To complete the installation, enter:
|
||||
```
|
||||
$sudo update-rc.d shairport-sync defaults 90 10
|
||||
```
|
||||
|
||||
**Installation to a `systemd` system**
|
||||
To complete the installation, you need to define a `shairport-sync` group and user. This is a security measure -- the user and group are relatively unprivileged, and the user does not have login priviliges. The user must be a member of the `audio` group to be able to access the audio hardware. The following commands define the group and user correctly if they do not already exist (note the use of `sudo` -- omit this if you already have superuser privileges:
|
||||
|
||||
```
|
||||
$getent group shairport-sync &>/dev/null || sudo groupadd -r shairport-sync >/dev/null
|
||||
$getent passwd shairport-sync &> /dev/null || sudo useradd -r -M -g shairport-sync -s /usr/bin/nologin -G audio shairport-sync >/dev/null
|
||||
```
|
||||
|
||||
Next, enter:
|
||||
|
||||
```
|
||||
$sudo make install
|
||||
```
|
||||
|
||||
to install `shairport-sync` along with a `man` page, a default configuration file and some `systemd` startup configuration files to launch it automatically at system startup.
|
||||
|
||||
To enable Shairport Sync to start automatically at system startup, enter:
|
||||
|
||||
`$sudo systemctl enable shairport-sync`
|
||||
|
||||
**Man Page**
|
||||
|
||||
You can view the man page here: http://htmlpreview.github.io/?https://github.com/mikebrady/shairport-sync/blob/master/man/shairport-sync.html
|
||||
|
||||
@@ -162,7 +212,7 @@ Configuring Shairport Sync
|
||||
--------
|
||||
There are two logically distinct parts to getting Shairport Sync to run properly on your machine — (1) starting and stopping it and (2) ensuring it has the right settings.
|
||||
|
||||
Starting and stopping automatically is taken care of differently in different versions of Linux. In the example above, when you run `$sudo make install`, a System V startup script is placed at `/etc/init.d/shairport-sync`. This will not be appropriate in Linuxes that use `systemd` such as Arch Linux, so please look at the separate installation scripts for those.
|
||||
Starting and stopping automatically is taken care of differently in different versions of Linux -- see the previous section for an example of installing into a System V or a `systemd` based system.
|
||||
|
||||
To get the best from Shairport Sync, you’ll need to (1) give Shairport Sync a service name by which it will be seen in iTunes etc., (2) specify the output device to use and (3) specify the name of the mixer volume control to use to control the output level. To get values for (2) and (3) you might need to explore the ALSA output devices with a program like `alsamixer` or similar.
|
||||
|
||||
@@ -201,6 +251,13 @@ Shairport Sync can run programs just before it starts to play an audio stream an
|
||||
|
||||
Please note that the full path to the programs must be specified, and script files will not be executed unless they are marked as executable and have the standard `#!/bin/...` first line. (This behaviour may be different from other Shairports.)
|
||||
|
||||
**Raspberry Pi**
|
||||
The Raspberry Pi has a built-in audio DAC that is connected to the device's headphone jack. This provides a low-quality output that is nevertheless useful for testing purposes and may indeed by quite adequate for [very] casual listening. It is not HiFi: it is noisy and can't play anything above about 15kHz. A further problem is that it declares itself to have a very large mixer volume control range -- all the way from -102.38dB up to +4dB, a range of 106.38 dB. In reality, only the top 35dB of it is in any way usable.
|
||||
|
||||
Accordingly, Shairport Sync has a `volume_range_db` setting in the `general` stanza which allows you to tell Shairport Sync to use a subrange of the declared range. For example, if you set the `volume_range_db` figure to 35, the top 35 dB of the range will the used. With this setting on the Raspberry Pi, maximum volume will be +4dB and minimum volume will be -31dB, below which muting will occur.
|
||||
|
||||
From a user's point of view, the effect of using this setting is to move the minimum usable volume all the way down to the bottom of the user's volume control, rather than have the minimum usable volume concentrated very close to the maximum volume.
|
||||
|
||||
*Command Line Arguments*
|
||||
|
||||
You can use command line arguments to provide settings to Shairport Sync as before. For full information, please read the Shairport Sync `man` page, also available at http://htmlpreview.github.io/?https://github.com/mikebrady/shairport-sync/blob/master/man/shairport-sync.html.
|
||||
@@ -232,7 +289,7 @@ alsa = {
|
||||
|
||||
This gives the service a particular name — "Joe's Stereo" and specifies that audio device hw:0 be used.
|
||||
|
||||
For best results — including getting true mute and instant response to volume control and pause commands — you should access the hardware volume controls. Use `amixer` or `alsamixer` or similar to discover the name of the volume controller to be used after the `-c` option.
|
||||
For best results — including getting true mute and instant response to volume control and pause commands — you should access the hardware volume controls. Use `amixer` or `alsamixer` or similar to discover the name of the mixer control to be used as the `mixer_control_name`.
|
||||
|
||||
Here is an example for for a Raspberry Pi using its internal soundcard — device hw:0 — that drives the headphone jack:
|
||||
```
|
||||
@@ -309,15 +366,11 @@ alsa = {
|
||||
|
||||
Latency
|
||||
-------
|
||||
Latency is the exact time from a sound signal's original timestamp until that signal actually "appears" on the output of the audio output device, usually a Digital to Audio Converter (DAC), irrespective of any internal delays, processing times, etc. in the computer. From listening tests, it seems that there are three latencies in current use:
|
||||
* If the source is iTunes 10 or later, a latency of 99,400 frames seems to bring Shairport Sync into exact synchronisation both with the speakers on the iTunes computer itself and with AirPort Express receivers.
|
||||
* If the source is an AirPlay device, the latency seems to be exactly 88,200 frames. AirPlay devices include AppleTV, iPod, iPad and iPhone and Quicktime Player on Mac.
|
||||
* If the source is a `forked-daapd`-powered device, the latency seems to be exactly 99,400 frames.
|
||||
* If the source cannot be identified as AirPlay or as iTunes 10 or later, then the default latency of 88,200 frames seems to work in general. Note that some third party programs masquerade as older versions of iTunes.
|
||||
Latency is the exact time from a sound signal's original timestamp until that signal actually "appears" on the output of the audio output device, usually a Digital to Audio Converter (DAC), irrespective of any internal delays, processing times, etc. in the computer.
|
||||
|
||||
Shairport Sync uses the latencies described above as defaults. You shouldn't need to change them.
|
||||
Shairport Sync uses latencies supplied by the source, typically either 88,200 or 99,577 frames. You shouldn't need to change them. (The `latencies` stanza in the configuration file and the various latency command-line options are deprecated.)
|
||||
|
||||
Problems can arise when you are trying to synchronise with speaker systems — typically surround-sound home theatre systems — that have their own inherent delays. You can compensate for an inherent delay using the `alsa` group `audio_backend_latency_offset`. Set this offset (in frames) to compensate for a fixed delay in the audio back end, for example, if the output device delays by 100 ms, set this to -4410.
|
||||
Problems can arise when you are trying to synchronise with speaker systems — typically surround-sound home theatre systems — that have their own inherent delays. You can compensate for an inherent delay using the appropriate backend (typically `alsa`) `audio_backend_latency_offset`. Set this offset (in frames) to compensate for a fixed delay in the audio back end, for example, if the output device delays by 100 ms, set this to -4410.
|
||||
|
||||
Resynchronisation
|
||||
-------------
|
||||
@@ -327,7 +380,7 @@ If synchronisation is lost — say due to a busy source or a congested network
|
||||
|
||||
Tolerance
|
||||
---------
|
||||
Playback synchronisation is allowed to wander a small amount before attempting to correct it. The default is 88 frames, i.e. 2 ms. The smaller the tolerance, the more likely it is that overcorrection will occur. Overcorrection is when more corrections (insertions and deletions) are made than are strictly necessary to keep the stream in sync. Use the statistics setting to monitor correction levels. Corrections should not greatly exceed net corrections.
|
||||
Playback synchronisation is allowed to wander, or to "drift") a small amount before attempting to correct it. The default is 88 frames, i.e. 2 ms. The smaller the tolerance, the more likely it is that overcorrection will occur. Overcorrection is when more corrections (insertions and deletions) are made than are strictly necessary to keep the stream in sync. Use the statistics setting to monitor correction levels. Corrections should not greatly exceed net corrections.
|
||||
* You can vary the tolerance with the `general` `drift` setting.
|
||||
|
||||
Some Statistics
|
||||
@@ -336,7 +389,7 @@ If you turn on the `general` `statistics` setting, statistics like this will be
|
||||
|
||||
`Sync error: -35.4 (frames); net correction: 24.2 (ppm); corrections: 24.2 (ppm); missing packets 0; late packets 5; too late packets 0; resend requests 6; min DAC queue size 4430.`
|
||||
|
||||
"Sync error" is the average deviation from exact synchronisation. The example above indicates that the output is on average 35.4 frames ahead of exact synchronisation. Sync is allowed to wander by the tolerance — 88 frames (± 2 milliseconds) by default — before a correction will be made.
|
||||
"Sync error" is the average deviation from exact synchronisation. The example above indicates that the output is on average 35.4 frames ahead of exact synchronisation. Sync is allowed to drift by the `general` `drift` setting — 88 frames (± 2 milliseconds) by default — before a correction will be made.
|
||||
|
||||
"Net correction" is actually the net sum of corrections — the number of frame insertions less the number of frame deletions — given as a moving average in parts per million. After an initial settling period, it represents the drift — the divergence between the rate at which frames are generated at the source and the rate at which the output device consumes them. The example above indicates that the output device is consuming frames 24.2 ppm faster than the source is generating them.
|
||||
|
||||
@@ -344,6 +397,6 @@ If you turn on the `general` `statistics` setting, statistics like this will be
|
||||
|
||||
For reference, a drift of one second per day is approximately 11.57 ppm. Left uncorrected, even a drift this small between two audio outputs will be audible after a short time. The above sample is from a second-generation iPod driving the Raspberry Pi which is connected over Ethernet.
|
||||
|
||||
It's not unusual to have resend requests, late packets and even missing packets if some part of the connection to the Shairport Sync device is over WiFi. Sometimes late packets can be asked for and received multiple times. Sometimes late packets are sent and arrive too late, but have already been sent and received in time, so weren't needed anyway...
|
||||
It's not unusual to have resend requests, late packets and even missing packets if some part of the connection to the Shairport Sync device is over WiFi. Late packets can sometimes be asked for and received multiple times. Sometimes late packets are sent and arrive too late, but have already been sent and received in time, so weren't needed anyway...
|
||||
|
||||
"Min DAC queue size" is the minimum size the queue of samples in the output device's hardware buffer was measured at. It is meant to stand at 0.15 seconds = 6,615 samples, and will go low if the processor is very busy. If it goes below about 2,000 then it's a sign that the processor can't really keep up.
|
||||
|
||||
@@ -1,3 +1,28 @@
|
||||
Version 2.4.2
|
||||
----
|
||||
This release has important enhancements, bug fixes and documentation updates. It also appears to bring compatiblity with Synology NAS devices.
|
||||
|
||||
|
||||
**New Features**
|
||||
* Source-specified Latencies. Shairport Sync now uses the latencies specified by the audio source. Background: the AirPlay protocol used by Shairport Sync allows the audio source to specify the exact delay or latency that should be applied to the audio stream. Until now, Shairport Sync ignored this information and used fixed preset latencies that were selected on the basis of the "User-Agent" setting. Using source-specified latencies means that Shairport Sync is able adapt automatically to different sources.
|
||||
Using source-specified latencies is now automatic unless non-standard static latencies have been specified in the configuration file or command line. Using non-standard latencies is usually done to compensate for delays in the back end of the system. For example, if the audio amplifier being driven by Shairport Sync has an inherent delay of its own -- as happens with many home theatre and surround sound systems -- then some users have reduced the latencies used by Shairport Sync to compensate. This usage is discouraged -- the `audio_backend_latency_offset` in the appropriate backend stanza (e.g. in the "alsa" stanza) should be used for this. Static latency settings are now deprecated, and will be removed in a future version of Shairport Sync.
|
||||
* Set Volume Range. This is a new setting that allows you to use just a portion of the full range of attenuation offered by a mixer. For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available. This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting. It is for this reason that many domestic HiFi systems have a volume control range of only 60 to 80 dB.
|
||||
Another possible reason to use this setting might be because the range specified by the mixer does not match the actual capabilities of the device. For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB. The new `volume_range_db` setting in the `general` stanza allows you to specify the maximum range from highest to lowest. The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 35. Using it in this case gives the volume control a much more useful range of settings.
|
||||
|
||||
**Bug fixes**
|
||||
* Sometimes, especially when using Shairport Sync as a system output, it would not play the audio stream. This was caused by an improperly initialised variable. Fixed. Synology NAS devices now seem to be working with Shairport Sync.
|
||||
* Fix in the `shairport.c`: the USE_CUSTOM_LOCAL_STATE_DIR macro was still being used when it should have been USE_CUSTOM_PID_DIR.
|
||||
* Fix a crashing bug -- if metadata was enabled but a pipename was not supplied, boom.
|
||||
|
||||
**Other Changes**
|
||||
* Initial timing accuracy improved. The estimate of when to play the starting frame of the audio sequence has improved significantly. This leads to fewer corrections being needed at the start.
|
||||
* Volume ratios expressed in decibels are now consistently denominated in voltage decibels rather than power decibels. The rationale is that the levels refer to voltage levels, and power is proportional to the square of voltage.
|
||||
Thus a ratio of levels of 65535 to 1 is 96.3 dB rather than the 48.15 dB used before.
|
||||
* The latency figure returned to the source as part of the response to an rtsp request packet is 11,025, which may (?) be meant to indicate the minimum latency the device is capable of.
|
||||
* An experimental handler for a GET_PARAMETER rtsp request has been added. It does nothing except log the occurence.
|
||||
* The RTSP request dispatcher now logs an event whenever an unrecognised rtsp has been made.
|
||||
|
||||
|
||||
Version 2.4.1
|
||||
----
|
||||
This release has three small bug fixes and some small documentation updates.
|
||||
|
||||
+54
-11
@@ -29,6 +29,7 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <memory.h>
|
||||
#include <math.h>
|
||||
#include <pthread.h>
|
||||
#include <alsa/asoundlib.h>
|
||||
#include "common.h"
|
||||
@@ -43,9 +44,9 @@ static void stop(void);
|
||||
static void flush(void);
|
||||
static uint32_t delay(void);
|
||||
static void volume(double vol);
|
||||
static void linear_volume(double vol);
|
||||
static void parameters(audio_parameters *info);
|
||||
static int has_mute = 0;
|
||||
static int has_db_vol = 0;
|
||||
static double set_volume;
|
||||
|
||||
audio_output audio_alsa = {
|
||||
@@ -183,6 +184,8 @@ static int init(int argc, char **argv) {
|
||||
|
||||
if (optind < argc)
|
||||
die("Invalid audio argument: %s", argv[optind]);
|
||||
|
||||
debug(1,"Output device name is \"%s\".",alsa_out_dev);
|
||||
|
||||
if (!hardware_mixer)
|
||||
return 0;
|
||||
@@ -191,13 +194,14 @@ static int init(int argc, char **argv) {
|
||||
alsa_mix_dev = alsa_out_dev;
|
||||
|
||||
int ret = 0;
|
||||
|
||||
|
||||
snd_mixer_selem_id_alloca(&alsa_mix_sid);
|
||||
snd_mixer_selem_id_set_index(alsa_mix_sid, alsa_mix_index);
|
||||
snd_mixer_selem_id_set_name(alsa_mix_sid, alsa_mix_ctrl);
|
||||
|
||||
if ((snd_mixer_open(&alsa_mix_handle, 0)) < 0)
|
||||
die("Failed to open mixer");
|
||||
debug(1,"Mixer device name is \"%s\".",alsa_mix_dev);
|
||||
if ((snd_mixer_attach(alsa_mix_handle, alsa_mix_dev)) < 0)
|
||||
die("Failed to attach mixer");
|
||||
if ((snd_mixer_selem_register(alsa_mix_handle, NULL, NULL)) < 0)
|
||||
@@ -206,28 +210,52 @@ static int init(int argc, char **argv) {
|
||||
ret = snd_mixer_load(alsa_mix_handle);
|
||||
if (ret < 0)
|
||||
die("Failed to load mixer element");
|
||||
alsa_mix_elem = snd_mixer_find_selem(alsa_mix_handle, alsa_mix_sid);
|
||||
|
||||
debug(1,"Mixer Control name is \"%s\".",alsa_mix_ctrl);
|
||||
|
||||
alsa_mix_elem = snd_mixer_find_selem(alsa_mix_handle, alsa_mix_sid);
|
||||
if (!alsa_mix_elem)
|
||||
die("Failed to find mixer element");
|
||||
|
||||
|
||||
if (snd_mixer_selem_get_playback_volume_range(alsa_mix_elem, &alsa_mix_minv, &alsa_mix_maxv) < 0)
|
||||
debug(1, "Can't read mixer's [linear] min and max volumes.");
|
||||
else {
|
||||
if ((snd_mixer_selem_ask_playback_vol_dB(alsa_mix_elem, alsa_mix_minv, &alsa_mix_mindb) == 0) &&
|
||||
(snd_mixer_selem_ask_playback_vol_dB(alsa_mix_elem, alsa_mix_maxv, &alsa_mix_maxdb) == 0)) {
|
||||
has_db_vol = 1;
|
||||
if (snd_mixer_selem_get_playback_dB_range (alsa_mix_elem, &alsa_mix_mindb, &alsa_mix_maxdb) == 0) {
|
||||
|
||||
audio_alsa.volume = &volume; // insert the volume function now we know it can do dB stuff
|
||||
audio_alsa.parameters = ¶meters; // likewise the parameters stuff
|
||||
if (alsa_mix_mindb == -9999999) {
|
||||
// trying to say that the lowest vol is mute, maybe? Raspberry Pi does this
|
||||
if (alsa_mix_mindb == SND_CTL_TLV_DB_GAIN_MUTE) {
|
||||
// Raspberry Pi does this
|
||||
debug(1, "Lowest dB value is a mute.");
|
||||
if (snd_mixer_selem_ask_playback_vol_dB(alsa_mix_elem, alsa_mix_minv + 1,
|
||||
&alsa_mix_mindb) == 0)
|
||||
debug(1, "Can't get dB value corresponding to a \"volume\" of 1.");
|
||||
}
|
||||
debug(1, "Hardware mixer has dB volume from %f to %f.", (1.0 * alsa_mix_mindb) / 100.0,
|
||||
(1.0 * alsa_mix_maxdb) / 100.0);
|
||||
if (config.volume_range_db) {
|
||||
long suggested_alsa_min_db = alsa_mix_maxdb - (long)trunc(config.volume_range_db*100);
|
||||
if (suggested_alsa_min_db > alsa_mix_mindb)
|
||||
alsa_mix_mindb = suggested_alsa_min_db;
|
||||
else
|
||||
inform("The volume_range_db setting, %f is greater than the native range of the mixer %f, so it is ignored.",config.volume_range_db,(alsa_mix_maxdb-alsa_mix_mindb)/100.0);
|
||||
}
|
||||
} else {
|
||||
inform("note: the hardware mixer specified -- \"%s\" -- does not have dB volume, so it can not be used for volume control.",alsa_mix_ctrl);
|
||||
}
|
||||
// use the linear scale and do the db conversion ourselves
|
||||
debug(1, "note: the hardware mixer specified -- \"%s\" -- does not have a dB volume scale, so it can't be used.",alsa_mix_ctrl);
|
||||
/*
|
||||
debug(1, "Min and max volumes are %d and %d.",alsa_mix_minv,alsa_mix_maxv);
|
||||
alsa_mix_maxdb = 0;
|
||||
if ((alsa_mix_maxv!=0) && (alsa_mix_minv!=0))
|
||||
alsa_mix_mindb = -20*100*(log10(alsa_mix_maxv*1.0)-log10(alsa_mix_minv*1.0));
|
||||
else if (alsa_mix_maxv!=0)
|
||||
alsa_mix_mindb = -20*100*log10(alsa_mix_maxv*1.0);
|
||||
audio_alsa.volume = &linear_volume; // insert the linear volume function
|
||||
audio_alsa.parameters = ¶meters; // likewise the parameters stuff
|
||||
debug(1,"Max and min dB calculated are %d and %d.",alsa_mix_maxdb,alsa_mix_mindb);
|
||||
*/
|
||||
}
|
||||
}
|
||||
if (snd_mixer_selem_has_playback_switch(alsa_mix_elem)) {
|
||||
has_mute = 1;
|
||||
@@ -320,7 +348,7 @@ static void play(short buf[], int samples) {
|
||||
if (alsa_handle == NULL) {
|
||||
ret = open_alsa_device();
|
||||
if ((ret == 0) && (audio_alsa.volume))
|
||||
volume(set_volume);
|
||||
audio_alsa.volume(set_volume);
|
||||
}
|
||||
if (ret == 0) {
|
||||
pthread_mutex_lock(&alsa_mutex);
|
||||
@@ -390,6 +418,7 @@ static void parameters(audio_parameters *info) {
|
||||
}
|
||||
|
||||
static void volume(double vol) {
|
||||
// debug(1,"Volume called %f.",vol);
|
||||
set_volume = vol;
|
||||
double vol_setting = vol2attn(vol, alsa_mix_maxdb, alsa_mix_mindb);
|
||||
// debug(1,"Setting volume db to %f, for volume input of %f.",vol_setting/100,vol);
|
||||
@@ -398,3 +427,17 @@ static void volume(double vol) {
|
||||
if (has_mute)
|
||||
snd_mixer_selem_set_playback_switch_all(alsa_mix_elem, (vol != -144.0));
|
||||
}
|
||||
|
||||
static void linear_volume(double vol) {
|
||||
set_volume = vol;
|
||||
double vol_setting = vol2attn(vol, 0, alsa_mix_mindb)/2000;
|
||||
// debug(1,"Adjusted volume is %f.",vol_setting);
|
||||
double linear_volume = pow(10, vol_setting);
|
||||
// debug(1,"Linear volume is %f.",linear_volume);
|
||||
long int_vol = alsa_mix_minv + (alsa_mix_maxv - alsa_mix_minv) * linear_volume;
|
||||
// debug(1,"Setting volume to %ld, for volume input of %f.",int_vol,vol);
|
||||
if (snd_mixer_selem_set_playback_volume_all(alsa_mix_elem, int_vol) != 0)
|
||||
die("Failed to set playback volume");
|
||||
if (has_mute)
|
||||
snd_mixer_selem_set_playback_switch_all(alsa_mix_elem, (vol != -144.0));
|
||||
}
|
||||
|
||||
@@ -63,13 +63,13 @@ typedef struct {
|
||||
char *mdns_name;
|
||||
mdns_backend *mdns;
|
||||
int buffer_start_fill;
|
||||
uint32_t latency;
|
||||
uint32_t userSuppliedLatency; // overrides all other latencies -- use with caution
|
||||
uint32_t iTunesLatency; // supplied with --iTunesLatency option
|
||||
uint32_t AirPlayLatency; // supplied with --AirPlayLatency option
|
||||
uint32_t ForkedDaapdLatency; // supplied with --ForkedDaapdLatency option
|
||||
int32_t latency;
|
||||
int32_t userSuppliedLatency; // overrides all other latencies -- use with caution
|
||||
int32_t iTunesLatency; // supplied with --iTunesLatency option
|
||||
int32_t AirPlayLatency; // supplied with --AirPlayLatency option
|
||||
int32_t ForkedDaapdLatency; // supplied with --ForkedDaapdLatency option
|
||||
int daemonise;
|
||||
int statistics_requested;
|
||||
int statistics_requested,use_negotiated_latencies;
|
||||
char *cmd_start, *cmd_stop;
|
||||
int cmd_blocking;
|
||||
int tolerance; // allow this much drift before attempting to correct it
|
||||
@@ -78,9 +78,10 @@ typedef struct {
|
||||
char *logfile;
|
||||
char *errfile;
|
||||
char *configfile;
|
||||
uint32_t audio_backend_buffer_desired_length; // this will be the desired number of frames in the
|
||||
int32_t audio_backend_buffer_desired_length; // this will be the desired number of frames in the
|
||||
// audio backend buffer -- the DAC buffer for ALSA
|
||||
uint32_t audio_backend_latency_offset; // this will be the offset to compensate for any fixed latency
|
||||
int32_t audio_backend_latency_offset; // this will be the offset to compensate for any fixed latency
|
||||
uint32_t volume_range_db; // the range, in dB, from max dB to min dB. Zero means use the mixer's native range.
|
||||
// there might be in the audio
|
||||
} shairport_cfg;
|
||||
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ([2.50])
|
||||
AC_INIT([shairport-sync], [2.4.1], [mikebrady@eircom.net])
|
||||
AC_INIT([shairport-sync], [2.4.2], [mikebrady@eircom.net])
|
||||
AM_INIT_AUTOMAKE
|
||||
AC_CONFIG_SRCDIR([shairport.c])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
|
||||
+63
-52
@@ -99,54 +99,8 @@ Use this to specify how much debugging information should be output or logged. "
|
||||
\fBignore_volume_control=\f1\fI"choice"\f1\fB;\f1
|
||||
Set this \fIchoice\f1 to "yes" if you want the volume to be at 100% no matter what the source's volume control is set to. This might be useful if you want to set the volume on the output device, independently of the setting at the source. The default is "no".
|
||||
.TP
|
||||
\fB"LATENCIES" SETTINGS\f1
|
||||
There are four default latency settings, chosen automatically. One latency matches the latency used by recent versions of iTunes when playing audio and another matches the latency used by so-called "AirPlay" devices, including iOS devices and iTunes and Quicktime Player when they are playing video. A third latency is used when the audio source is forked-daapd. The fourth latency is the default if no other latency is chosen and is used for older versions of iTunes.
|
||||
|
||||
If you want to change latencies to compensate for a delay in the audio output device (which will have the same effect on all sources), instead of changing these individual latencies, consider using the \fBaudio_backend_latency_offset\f1 setting in the \fBalsa\f1 group (or the appropriate other group if you're not outputing through the alsa backend).
|
||||
.TP
|
||||
\fBitunes=\f1\fIlatency\f1\fB;\f1
|
||||
This is the \fIlatency\f1, in frames, used for iTunes 10 or later. Default is 99,400.
|
||||
.TP
|
||||
\fBairplay=\f1\fIlatency\f1\fB;\f1
|
||||
This is the \fIlatency\f1, in frames, used for AirPlay devices, including iOS devices and iTunes and Quicktime Player when they are playing video. Default is 88,200.
|
||||
.TP
|
||||
\fBforkedDaapd=\f1\fIlatency\f1\fB;\f1
|
||||
This is the \fIlatency\f1, in frames, used for forkedDaapd sources. Default is 99,400.
|
||||
.TP
|
||||
\fBdefault=\f1\fIlatency\f1\fB;\f1
|
||||
This is the \fIlatency\f1, in frames, used when the source is unrecognised. Default is 88,200.
|
||||
.TP
|
||||
\fB"METADATA" SETTINGS\f1
|
||||
shairport-sync can process metadata provided by the source, such as Track Number, Album Name, cover art, etc. and can provide additional metadata such as volume level, pause/resume, etc. It provides the metadata to a pipe, by default \fI/tmp/shairport-sync-metadata\f1. To process metadata, shairport-sync must have been compiled with metadata support included. You can check that this is so by running \fBshairport-sync -V\f1; the identification string will contain the word \fBmetadata\f1.
|
||||
|
||||
The \fBmetadata\f1 group of settings allow you to enable metadata handling and to control certain aspects of it:
|
||||
.TP
|
||||
\fBenabled=\f1\fI"choice"\f1\fB;\f1
|
||||
Set the \fIchoice\f1 to "yes" to enable shairport-sync to look for metadata from the audio source and to forward it, along with metadata generated by shairport-sync itself, to the metadata pipe. The default is "no".
|
||||
.TP
|
||||
\fBinclude_cover_art=\f1\fI"choice"\f1\fB;\f1
|
||||
Set the \fIchoice\f1 to "yes" to enable shairport-sync to look for cover art from the audio source and to include it in the feed to the metadata pipe. You must also enable metadata (see above). One reason for not including cover art is that the images can sometimes be very large and may delay transmission of subsequent metadata through the pipe. The default is "no".
|
||||
.TP
|
||||
\fBpipe_name=\f1\fI"filepathname"\f1\fB;\f1
|
||||
Specify the absolute path name of the pipe through which metadata should be sent The default is \fI/tmp/shairport-sync-metadata\f1".
|
||||
.TP
|
||||
\fB"SESSIONCONTROL" SETTINGS\f1
|
||||
shairport-sync can run programs just before it starts to play an audio stream and just after it finishes. You specify them using the settings \fBrun_this_before_play_begins\f1 and \fBrun_this_after_play_ends\f1.
|
||||
.TP
|
||||
\fBrun_this_before_play_begins=\f1\fI"/path/to/application and args"\f1\fB;\f1
|
||||
Here you can specify a program and its arguments that will be run just before a play session begins. Be careful to include the full path to the application. The application must be marked as executable and, if it is a script, its first line must begin with the standard \fI#!/bin/...\f1 as appropriate.
|
||||
.TP
|
||||
\fBrun_this_after_play_ends=\f1\fI"/path/to/application and args"\f1\fB;\f1
|
||||
Here you can specify a program and its arguments that will be run just after a play session ends. Be careful to include the full path to the application. The application must be marked as executable and, if it is a script, its first line must begin with the standard \fI#!/bin/...\f1 as appropriate.
|
||||
.TP
|
||||
\fBwait_for_completion=\f1\fI"choice"\f1\fB;\f1
|
||||
Set \fIchoice\f1 to "yes" to make shairport-sync wait until the programs specified in the \fBrun_this_before_play_begins\f1 and \fBrun_this_after_play_ends\f1 have completed execution before continuing. The default is "no".
|
||||
.TP
|
||||
\fBallow_session_interruption=\f1\fI"choice"\f1\fB;\f1
|
||||
If \fBchoice\f1 is set to "yes", then another source will be able to interrupt an existing play session and start a new one. When set to "no" (the default), other devices attempting to interrupt a session will fail, receiving a busy signal.
|
||||
.TP
|
||||
\fBsession_timeout=\f1\fIseconds\f1\fB;\f1
|
||||
If a play session has been established and the source disappears without warning (such as a device going out of range of a network) then wait for \fIseconds\f1 seconds before ending the session. Once the session has terminated, other devices can use it. The default is 120 seconds.
|
||||
\fBvolume_range_db=\f1\fIdBvalue\f1\fB;\f1
|
||||
Set this \fIdBvalue\f1 to use just a portion of the full range of attenuation offered by a mixer. For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available. This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting -- indeed, many domestic HiFi systmes have a volume copntrol range of just 60 to 80dB. Another potential use might be where the range specified by the mixer does not match the capabilities of the device. For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB. The setting allows you to specify the maximum range from highest to lowest. The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 35. Using it in this case gives the volume control a much more useful range of settings. If you omit this setting, the full "native" range of the mixer is used.
|
||||
.TP
|
||||
\fB"ALSA" SETTINGS\f1
|
||||
These settings are for the ALSA back end, used to communicate with audio output devices in the ALSA system. (By the way, you can use tools such as \fBalsamixer\f1 or \fBaplay\f1 to discover what devices are available.) Use these settings to select the output device and the mixer control to be used to control the output volume. You can additionally set the desired size of the output buffer and you can adjust overall latency. Here are the \fBalsa\f1 group settings:
|
||||
@@ -198,8 +152,65 @@ Packets of audio frames are written to stdout synchronously -- that is, they are
|
||||
.TP
|
||||
\fBaudio_backend_buffer_desired_length=\f1\fIbuffer_length_in_frames\f1\fB;\f1
|
||||
Use this setting, in frames, to set the size of the output buffer. It works by determining how soon the second and subsequent packets of audio frames are sent to stdout. For example, if you send the first packet of audio exactly when it is due and, using a \fIaudio_backend_buffer_desired_length\f1 setting of 44100, send subsequent packets of audio a second before they are due to be played, they will be buffered in the stdout reader's buffer, giving it a nominal buffer size of 44,100 frames. Note that if the stdout reader consumes audio packets faster or slower than they are supplied, the buffer will eventually empty or overflow -- shairport-sync performs no stuffing or interpolation when writing to stdout. Default setting is 44,100 frames.
|
||||
.TP
|
||||
\fB"METADATA" SETTINGS\f1
|
||||
shairport-sync can process metadata provided by the source, such as Track Number, Album Name, cover art, etc. and can provide additional metadata such as volume level, pause/resume, etc. It sends the metadata to a pipe, by default \fI/tmp/shairport-sync-metadata\f1. To process metadata, shairport-sync must have been compiled with metadata support included. You can check that this is so by running \fBshairport-sync -V\f1; the identification string will contain the word \fBmetadata\f1.
|
||||
|
||||
Please note that different sources provide different levels of metadata. Some provide a lot; some provide almost none.
|
||||
|
||||
The \fBmetadata\f1 group of settings allow you to enable metadata handling and to control certain aspects of it:
|
||||
.TP
|
||||
\fBenabled=\f1\fI"choice"\f1\fB;\f1
|
||||
Set the \fIchoice\f1 to "yes" to enable shairport-sync to look for metadata from the audio source and to forward it, along with metadata generated by shairport-sync itself, to the metadata pipe. The default is "no".
|
||||
.TP
|
||||
\fBinclude_cover_art=\f1\fI"choice"\f1\fB;\f1
|
||||
Set the \fIchoice\f1 to "yes" to enable shairport-sync to look for cover art from the audio source and to include it in the feed to the metadata pipe. You must also enable metadata (see above). One reason for not including cover art is that the images can sometimes be very large and may delay transmission of subsequent metadata through the pipe. The default is "no".
|
||||
.TP
|
||||
\fBpipe_name=\f1\fI"filepathname"\f1\fB;\f1
|
||||
Specify the absolute path name of the pipe through which metadata should be sent The default is \fI/tmp/shairport-sync-metadata\f1".
|
||||
.TP
|
||||
\fB"SESSIONCONTROL" SETTINGS\f1
|
||||
shairport-sync can run programs just before it starts to play an audio stream and just after it finishes. You specify them using the sessioncontrol group settings run_this_before_play_begins and run_this_after_play_ends.
|
||||
.TP
|
||||
\fBrun_this_before_play_begins=\f1\fI"/path/to/application and args"\f1\fB;\f1
|
||||
Here you can specify a program and its arguments that will be run just before a play session begins. Be careful to include the full path to the application. The application must be marked as executable and, if it is a script, its first line must begin with the standard \fI#!/bin/...\f1 as appropriate.
|
||||
.TP
|
||||
\fBrun_this_after_play_ends=\f1\fI"/path/to/application and args"\f1\fB;\f1
|
||||
Here you can specify a program and its arguments that will be run just after a play session ends. Be careful to include the full path to the application. The application must be marked as executable and, if it is a script, its first line must begin with the standard \fI#!/bin/...\f1 as appropriate.
|
||||
.TP
|
||||
\fBwait_for_completion=\f1\fI"choice"\f1\fB;\f1
|
||||
Set \fIchoice\f1 to "yes" to make shairport-sync wait until the programs specified in the \fBrun_this_before_play_begins\f1 and \fBrun_this_after_play_ends\f1 have completed execution before continuing. The default is "no".
|
||||
.TP
|
||||
\fBallow_session_interruption=\f1\fI"choice"\f1\fB;\f1
|
||||
If \fBchoice\f1 is set to "yes", then another source will be able to interrupt an existing play session and start a new one. When set to "no" (the default), other devices attempting to interrupt a session will fail, receiving a busy signal.
|
||||
.TP
|
||||
\fBsession_timeout=\f1\fIseconds\f1\fB;\f1
|
||||
If a play session has been established and the source disappears without warning (such as a device going out of range of a network) then wait for \fIseconds\f1 seconds before ending the session. Once the session has terminated, other devices can use it. The default is 120 seconds.
|
||||
.TP
|
||||
\fB"LATENCIES" SETTINGS\f1
|
||||
The latencies settings are now deprecated. Do not use them for new installations. They will be removed from a future version of Shairport Sync.
|
||||
|
||||
Latency is the exact time from a sound signal's original timestamp until that signal actually "appears" on the output of the audio output device, usually a Digital to Audio Converter (DAC), irrespective of any internal delays, processing times, etc. in the computer.
|
||||
|
||||
Shairport Sync now sets latencies automatically using information supplied by the source, typically either 88,200 or 99,577 frames.
|
||||
|
||||
The following relates to the old scheme of using fixed latencies, which ignores the latency information supplied by the source. There are four default latency settings. One latency matches the latency used by recent versions of iTunes when playing audio and another matches the latency used by so-called "AirPlay" devices, including iOS devices and iTunes and Quicktime Player when they are playing video. A third latency is used when the audio source is forked-daapd. The fourth latency is the default if no other latency is chosen and is used for older versions of iTunes.
|
||||
|
||||
Note: If you are thinking of changing latencies to compensate for a delay in the audio output device, then instead of changing these individual latencies, consider using the \fBaudio_backend_latency_offset\f1 setting in the \fBalsa\f1 group (or the appropriate other group if you're not outputing through the alsa backend).
|
||||
.TP
|
||||
\fBitunes=\f1\fIlatency\f1\fB;\f1
|
||||
This is the \fIlatency\f1, in frames, used for iTunes 10 or later. Default is 99,400.
|
||||
.TP
|
||||
\fBairplay=\f1\fIlatency\f1\fB;\f1
|
||||
This is the \fIlatency\f1, in frames, used for AirPlay devices, including iOS devices and iTunes and Quicktime Player when they are playing video. Default is 88,200.
|
||||
.TP
|
||||
\fBforkedDaapd=\f1\fIlatency\f1\fB;\f1
|
||||
This is the \fIlatency\f1, in frames, used for forkedDaapd sources. Default is 99,400.
|
||||
.TP
|
||||
\fBdefault=\f1\fIlatency\f1\fB;\f1
|
||||
This is the \fIlatency\f1, in frames, used when the source is unrecognised. Default is 88,200.
|
||||
.SH OPTIONS
|
||||
Note: if you are setting up shairport-sync for the first time or are updating an existing installation, you are encouraged to use the configuration file settings described above. Most of the options described below simply replicate the configuration settings and are retained to provide backward compatability with older installations of shairport-sync.
|
||||
Note: if you are setting up Shairport Sync for the first time or are updating an existing installation, you are encouraged to use the configuration file settings described above. Most of the options described below simply replicate the configuration settings and are retained to provide backward compatability with older installations of Shairport Sync.
|
||||
|
||||
Many of the options take sensible default values, so you can normally ignore most of them. See the EXAMPLES section for typical usages.
|
||||
|
||||
@@ -322,10 +333,10 @@ The example above is slightly contrived in order to show the use of the \fB-m\f1
|
||||
|
||||
shairport-sync \fB-d\f1 \fB-a "Joe's Stereo"\f1 \fB-S soxr\f1 \fB--\f1 \fB-d hw:1\f1 \fB-c PCM\f1
|
||||
.SH CREDITS
|
||||
Mike Brady developed shairport-sync from the original shairport by James Laird.
|
||||
Mike Brady developed Shairport Sync from the original Shairport by James Laird.
|
||||
|
||||
shairport-sync can be found at \fBhttps://github.com/mikebrady/shairport-sync.\f1
|
||||
Shairport Sync can be found at \fBhttps://github.com/mikebrady/shairport-sync.\f1
|
||||
|
||||
shairport can be found at \fBhttps://github.com/abrasive/shairport.\f1
|
||||
Shairport can be found at \fBhttps://github.com/abrasive/shairport.\f1
|
||||
.SH COMMENTS
|
||||
This man page was written using \fBxml2man(1)\f1 by Oliver Kurth.
|
||||
|
||||
+109
-80
@@ -191,83 +191,19 @@
|
||||
<p><opt>ignore_volume_control=</opt><arg>"choice"</arg><opt>;</opt></p>
|
||||
<optdesc>Set this <arg>choice</arg> to "yes" if you want the volume to be at 100% no matter what the source's volume control is set to. This might be useful if you want to set the volume on the output device, independently of the setting at the source. The default is "no".</optdesc>
|
||||
</option>
|
||||
|
||||
<option><p><opt>"LATENCIES" SETTINGS</opt></p></option>
|
||||
<p>There are four default latency settings, chosen automatically. One latency matches the latency used by recent versions of iTunes when playing audio and another matches the latency used by so-called "AirPlay" devices, including iOS devices and iTunes and Quicktime Player when they are playing video. A third latency is used when the audio source is forked-daapd. The fourth latency is the default if no other latency is chosen and is used for older versions of iTunes.</p>
|
||||
<p>If you want to change latencies to compensate for a delay in the audio output device (which will have the same effect on all sources), instead of changing these individual latencies, consider using the <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>
|
||||
</option>
|
||||
<option>
|
||||
<p><opt>airplay=</opt><arg>latency</arg><opt>;</opt></p>
|
||||
<optdesc>This is the <arg>latency</arg>, in frames, used for AirPlay devices, including iOS devices and iTunes and Quicktime Player when they are playing video. Default is 88,200.</optdesc>
|
||||
</option>
|
||||
<option>
|
||||
<p><opt>forkedDaapd=</opt><arg>latency</arg><opt>;</opt></p>
|
||||
<optdesc>This is the <arg>latency</arg>, in frames, used for forkedDaapd sources. Default is 99,400.</optdesc>
|
||||
</option>
|
||||
<option>
|
||||
<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>
|
||||
|
||||
<option><p><opt>"METADATA" SETTINGS</opt></p></option>
|
||||
<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 provides 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>
|
||||
<p>The <opt>metadata</opt> group of settings allow you to enable metadata handling and to control certain aspects of it:</p>
|
||||
|
||||
|
||||
<option>
|
||||
<p><opt>enabled=</opt><arg>"choice"</arg><opt>;</opt></p>
|
||||
<optdesc>Set the <arg>choice</arg> to "yes" to enable shairport-sync to look for metadata from the audio source and to forward it,
|
||||
along with metadata generated by shairport-sync itself, to the metadata pipe. The default is "no".</optdesc>
|
||||
</option>
|
||||
<option>
|
||||
<p><opt>include_cover_art=</opt><arg>"choice"</arg><opt>;</opt></p>
|
||||
<optdesc>Set the <arg>choice</arg> 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".</optdesc>
|
||||
</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>
|
||||
</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 settings <opt>run_this_before_play_begins</opt> and <opt>run_this_after_play_ends</opt>. </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.
|
||||
The application must be marked as executable and, if it is a script, its first line must begin with the standard <file>#!/bin/...</file> as appropriate.</optdesc>
|
||||
</option>
|
||||
<option>
|
||||
<p><opt>run_this_after_play_ends=</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 after a play session ends. Be careful to include the full path to the application.
|
||||
The application must be marked as executable and, if it is a script, its first line must begin with the standard <file>#!/bin/...</file> as appropriate.</optdesc>
|
||||
</option>
|
||||
<option>
|
||||
<p><opt>wait_for_completion=</opt><arg>"choice"</arg><opt>;</opt></p>
|
||||
<optdesc>Set <arg>choice</arg> to "yes" to make shairport-sync wait until the programs specified in the <opt>run_this_before_play_begins</opt>
|
||||
and <opt>run_this_after_play_ends</opt> have completed execution before continuing. The default is "no".</optdesc>
|
||||
</option>
|
||||
<option>
|
||||
<p><opt>allow_session_interruption=</opt><arg>"choice"</arg><opt>;</opt></p>
|
||||
<optdesc>If <opt>choice</opt> is set to "yes", then another source will be able to interrupt an existing play session and start a new one.
|
||||
When set to "no" (the default), other devices attempting to interrupt a session will fail, receiving a busy signal.</optdesc>
|
||||
</option>
|
||||
<option>
|
||||
<p><opt>session_timeout=</opt><arg>seconds</arg><opt>;</opt></p>
|
||||
<optdesc>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 <arg>seconds</arg> seconds before ending the session. Once the session has terminated, other devices can use it.
|
||||
The default is 120 seconds.</optdesc>
|
||||
<p><opt>volume_range_db=</opt><arg>dBvalue</arg><opt>;</opt></p>
|
||||
<optdesc>Set this <arg>dBvalue</arg> to use just a portion of the full range of attenuation offered by a mixer.
|
||||
For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available.
|
||||
This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting --
|
||||
indeed, many domestic HiFi systmes have a volume copntrol range of just 60 to 80dB.
|
||||
Another potential use might be where the range specified by the mixer does not match the capabilities of the device.
|
||||
For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB.
|
||||
The setting allows you to specify the maximum range from highest to lowest.
|
||||
The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 35.
|
||||
Using it in this case gives the volume control a much more useful range of settings.
|
||||
If you omit this setting, the full "native" range of the mixer is used.</optdesc>
|
||||
</option>
|
||||
|
||||
<option><p><opt>"ALSA" SETTINGS</opt></p></option>
|
||||
@@ -370,14 +306,107 @@
|
||||
shairport-sync performs no stuffing or interpolation when writing to stdout. Default setting is 44,100 frames.
|
||||
</optdesc>
|
||||
</option>
|
||||
|
||||
<option><p><opt>"METADATA" SETTINGS</opt></p></option>
|
||||
<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>
|
||||
<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>
|
||||
|
||||
|
||||
<option>
|
||||
<p><opt>enabled=</opt><arg>"choice"</arg><opt>;</opt></p>
|
||||
<optdesc>Set the <arg>choice</arg> to "yes" to enable shairport-sync to look for metadata from the audio source and to forward it,
|
||||
along with metadata generated by shairport-sync itself, to the metadata pipe. The default is "no".</optdesc>
|
||||
</option>
|
||||
<option>
|
||||
<p><opt>include_cover_art=</opt><arg>"choice"</arg><opt>;</opt></p>
|
||||
<optdesc>Set the <arg>choice</arg> 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".</optdesc>
|
||||
</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>
|
||||
</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.
|
||||
The application must be marked as executable and, if it is a script, its first line must begin with the standard <file>#!/bin/...</file> as appropriate.</optdesc>
|
||||
</option>
|
||||
<option>
|
||||
<p><opt>run_this_after_play_ends=</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 after a play session ends. Be careful to include the full path to the application.
|
||||
The application must be marked as executable and, if it is a script, its first line must begin with the standard <file>#!/bin/...</file> as appropriate.</optdesc>
|
||||
</option>
|
||||
<option>
|
||||
<p><opt>wait_for_completion=</opt><arg>"choice"</arg><opt>;</opt></p>
|
||||
<optdesc>Set <arg>choice</arg> to "yes" to make shairport-sync wait until the programs specified in the <opt>run_this_before_play_begins</opt>
|
||||
and <opt>run_this_after_play_ends</opt> have completed execution before continuing. The default is "no".</optdesc>
|
||||
</option>
|
||||
<option>
|
||||
<p><opt>allow_session_interruption=</opt><arg>"choice"</arg><opt>;</opt></p>
|
||||
<optdesc>If <opt>choice</opt> is set to "yes", then another source will be able to interrupt an existing play session and start a new one.
|
||||
When set to "no" (the default), other devices attempting to interrupt a session will fail, receiving a busy signal.</optdesc>
|
||||
</option>
|
||||
<option>
|
||||
<p><opt>session_timeout=</opt><arg>seconds</arg><opt>;</opt></p>
|
||||
<optdesc>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 <arg>seconds</arg> seconds before ending the session. Once the session has terminated, other devices can use it.
|
||||
The default is 120 seconds.</optdesc>
|
||||
</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>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>The following relates to the old scheme of using fixed latencies, which ignores the latency information supplied by the source.
|
||||
There are four default latency settings. One latency matches the latency used by recent versions of
|
||||
iTunes when playing audio and another matches the latency
|
||||
used by so-called "AirPlay" devices, including iOS devices and iTunes and Quicktime Player when they are playing video.
|
||||
A third latency is used when the audio source is forked-daapd. The fourth latency is the default if no other latency is chosen and is used for older versions of iTunes.</p>
|
||||
<p>Note: If you are thinking of changing latencies to compensate for a delay in the audio output device, then
|
||||
instead of changing these individual latencies, consider using the <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>
|
||||
</option>
|
||||
<option>
|
||||
<p><opt>airplay=</opt><arg>latency</arg><opt>;</opt></p>
|
||||
<optdesc>This is the <arg>latency</arg>, in frames, used for AirPlay devices, including iOS devices and iTunes and Quicktime Player when they are playing video. Default is 88,200.</optdesc>
|
||||
</option>
|
||||
<option>
|
||||
<p><opt>forkedDaapd=</opt><arg>latency</arg><opt>;</opt></p>
|
||||
<optdesc>This is the <arg>latency</arg>, in frames, used for forkedDaapd sources. Default is 99,400.</optdesc>
|
||||
</option>
|
||||
<option>
|
||||
<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>Note: if you are setting up shairport-sync for the first time or are updating an existing installation,
|
||||
<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 compatability with older installations of shairport-sync.</p>
|
||||
simply replicate the configuration settings and are retained to provide backward compatability with older installations of Shairport Sync.</p>
|
||||
|
||||
<p>Many of the options take sensible default values, so you can normally
|
||||
ignore most of them. See the EXAMPLES section for typical usages.</p>
|
||||
@@ -742,9 +771,9 @@
|
||||
</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>shairport can be found at <url href="https://github.com/abrasive/shairport."/></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>
|
||||
|
||||
<section name="Comments">
|
||||
|
||||
+109
-80
@@ -173,83 +173,19 @@
|
||||
<p><b>ignore_volume_control=</b><em>"choice"</em><b>;</b></p>
|
||||
Set this <em>choice</em> to "yes" if you want the volume to be at 100% no matter what the source's volume control is set to. This might be useful if you want to set the volume on the output device, independently of the setting at the source. The default is "no".
|
||||
|
||||
|
||||
<p><b>"LATENCIES" SETTINGS</b></p>
|
||||
<p>There are four default latency settings, chosen automatically. One latency matches the latency used by recent versions of iTunes when playing audio and another matches the latency used by so-called "AirPlay" devices, including iOS devices and iTunes and Quicktime Player when they are playing video. A third latency is used when the audio source is forked-daapd. The fourth latency is the default if no other latency is chosen and is used for older versions of iTunes.</p>
|
||||
<p>If you want to change latencies to compensate for a delay in the audio output device (which will have the same effect on all sources), instead of changing these individual latencies, consider using the <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.
|
||||
|
||||
|
||||
<p><b>airplay=</b><em>latency</em><b>;</b></p>
|
||||
This is the <em>latency</em>, in frames, used for AirPlay devices, including iOS devices and iTunes and Quicktime Player when they are playing video. Default is 88,200.
|
||||
|
||||
|
||||
<p><b>forkedDaapd=</b><em>latency</em><b>;</b></p>
|
||||
This is the <em>latency</em>, in frames, used for forkedDaapd sources. Default is 99,400.
|
||||
|
||||
|
||||
<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.
|
||||
|
||||
|
||||
<p><b>"METADATA" SETTINGS</b></p>
|
||||
<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 provides 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>
|
||||
<p>The <b>metadata</b> group of settings allow you to enable metadata handling and to control certain aspects of it:</p>
|
||||
|
||||
|
||||
|
||||
<p><b>enabled=</b><em>"choice"</em><b>;</b></p>
|
||||
Set the <em>choice</em> to "yes" to enable shairport-sync to look for metadata from the audio source and to forward it,
|
||||
along with metadata generated by shairport-sync itself, to the metadata pipe. The default is "no".
|
||||
|
||||
|
||||
<p><b>include_cover_art=</b><em>"choice"</em><b>;</b></p>
|
||||
Set the <em>choice</em> 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".
|
||||
|
||||
|
||||
<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>".
|
||||
|
||||
|
||||
<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 settings <b>run_this_before_play_begins</b> and <b>run_this_after_play_ends</b>. </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.
|
||||
The application must be marked as executable and, if it is a script, its first line must begin with the standard <em>#!/bin/...</em> as appropriate.
|
||||
|
||||
|
||||
<p><b>run_this_after_play_ends=</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 after a play session ends. Be careful to include the full path to the application.
|
||||
The application must be marked as executable and, if it is a script, its first line must begin with the standard <em>#!/bin/...</em> as appropriate.
|
||||
|
||||
|
||||
<p><b>wait_for_completion=</b><em>"choice"</em><b>;</b></p>
|
||||
Set <em>choice</em> to "yes" to make shairport-sync wait until the programs specified in the <b>run_this_before_play_begins</b>
|
||||
and <b>run_this_after_play_ends</b> have completed execution before continuing. The default is "no".
|
||||
|
||||
|
||||
<p><b>allow_session_interruption=</b><em>"choice"</em><b>;</b></p>
|
||||
If <b>choice</b> is set to "yes", then another source will be able to interrupt an existing play session and start a new one.
|
||||
When set to "no" (the default), other devices attempting to interrupt a session will fail, receiving a busy signal.
|
||||
|
||||
|
||||
<p><b>session_timeout=</b><em>seconds</em><b>;</b></p>
|
||||
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 <em>seconds</em> seconds before ending the session. Once the session has terminated, other devices can use it.
|
||||
The default is 120 seconds.
|
||||
<p><b>volume_range_db=</b><em>dBvalue</em><b>;</b></p>
|
||||
Set this <em>dBvalue</em> to use just a portion of the full range of attenuation offered by a mixer.
|
||||
For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available.
|
||||
This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting --
|
||||
indeed, many domestic HiFi systmes have a volume copntrol range of just 60 to 80dB.
|
||||
Another potential use might be where the range specified by the mixer does not match the capabilities of the device.
|
||||
For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB.
|
||||
The setting allows you to specify the maximum range from highest to lowest.
|
||||
The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 35.
|
||||
Using it in this case gives the volume control a much more useful range of settings.
|
||||
If you omit this setting, the full "native" range of the mixer is used.
|
||||
|
||||
|
||||
<p><b>"ALSA" SETTINGS</b></p>
|
||||
@@ -352,6 +288,99 @@
|
||||
shairport-sync performs no stuffing or interpolation when writing to stdout. Default setting is 44,100 frames.
|
||||
|
||||
|
||||
|
||||
<p><b>"METADATA" SETTINGS</b></p>
|
||||
<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>
|
||||
<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>
|
||||
|
||||
|
||||
|
||||
<p><b>enabled=</b><em>"choice"</em><b>;</b></p>
|
||||
Set the <em>choice</em> to "yes" to enable shairport-sync to look for metadata from the audio source and to forward it,
|
||||
along with metadata generated by shairport-sync itself, to the metadata pipe. The default is "no".
|
||||
|
||||
|
||||
<p><b>include_cover_art=</b><em>"choice"</em><b>;</b></p>
|
||||
Set the <em>choice</em> 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".
|
||||
|
||||
|
||||
<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>".
|
||||
|
||||
|
||||
<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.
|
||||
The application must be marked as executable and, if it is a script, its first line must begin with the standard <em>#!/bin/...</em> as appropriate.
|
||||
|
||||
|
||||
<p><b>run_this_after_play_ends=</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 after a play session ends. Be careful to include the full path to the application.
|
||||
The application must be marked as executable and, if it is a script, its first line must begin with the standard <em>#!/bin/...</em> as appropriate.
|
||||
|
||||
|
||||
<p><b>wait_for_completion=</b><em>"choice"</em><b>;</b></p>
|
||||
Set <em>choice</em> to "yes" to make shairport-sync wait until the programs specified in the <b>run_this_before_play_begins</b>
|
||||
and <b>run_this_after_play_ends</b> have completed execution before continuing. The default is "no".
|
||||
|
||||
|
||||
<p><b>allow_session_interruption=</b><em>"choice"</em><b>;</b></p>
|
||||
If <b>choice</b> is set to "yes", then another source will be able to interrupt an existing play session and start a new one.
|
||||
When set to "no" (the default), other devices attempting to interrupt a session will fail, receiving a busy signal.
|
||||
|
||||
|
||||
<p><b>session_timeout=</b><em>seconds</em><b>;</b></p>
|
||||
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 <em>seconds</em> seconds before ending the session. Once the session has terminated, other devices can use it.
|
||||
The default is 120 seconds.
|
||||
|
||||
|
||||
<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>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>The following relates to the old scheme of using fixed latencies, which ignores the latency information supplied by the source.
|
||||
There are four default latency settings. One latency matches the latency used by recent versions of
|
||||
iTunes when playing audio and another matches the latency
|
||||
used by so-called "AirPlay" devices, including iOS devices and iTunes and Quicktime Player when they are playing video.
|
||||
A third latency is used when the audio source is forked-daapd. The fourth latency is the default if no other latency is chosen and is used for older versions of iTunes.</p>
|
||||
<p>Note: If you are thinking of changing latencies to compensate for a delay in the audio output device, then
|
||||
instead of changing these individual latencies, consider using the <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.
|
||||
|
||||
|
||||
<p><b>airplay=</b><em>latency</em><b>;</b></p>
|
||||
This is the <em>latency</em>, in frames, used for AirPlay devices, including iOS devices and iTunes and Quicktime Player when they are playing video. Default is 88,200.
|
||||
|
||||
|
||||
<p><b>forkedDaapd=</b><em>latency</em><b>;</b></p>
|
||||
This is the <em>latency</em>, in frames, used for forkedDaapd sources. Default is 99,400.
|
||||
|
||||
|
||||
<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.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -359,9 +388,9 @@
|
||||
<h2>Options</h2>
|
||||
|
||||
|
||||
<p>Note: if you are setting up shairport-sync for the first time or are updating an existing installation,
|
||||
<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 compatability with older installations of shairport-sync.</p>
|
||||
simply replicate the configuration settings and are retained to provide backward compatability with older installations of Shairport Sync.</p>
|
||||
|
||||
<p>Many of the options take sensible default values, so you can normally
|
||||
ignore most of them. See the EXAMPLES section for typical usages.</p>
|
||||
@@ -735,9 +764,9 @@
|
||||
|
||||
<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>shairport can be found at <a href = "https://github.com/abrasive/shairport.">https://github.com/abrasive/shairport.</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>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -299,6 +299,9 @@ void player_put_packet(seq_t seqno, uint32_t timestamp, uint8_t *data, int len)
|
||||
time_of_last_audio_packet = get_absolute_time_in_fp();
|
||||
if (connection_state_to_output) { // if we are supposed to be processing these packets
|
||||
|
||||
// if (flush_rtp_timestamp != 0)
|
||||
// debug(1,"Flush_rtp_timestamp is %u",flush_rtp_timestamp);
|
||||
|
||||
if ((flush_rtp_timestamp != 0) &&
|
||||
((timestamp == flush_rtp_timestamp) || seq32_order(timestamp, flush_rtp_timestamp))) {
|
||||
debug(2, "Dropping flushed packet in player_put_packet, seqno %u, timestamp %u, flushing to "
|
||||
@@ -489,16 +492,18 @@ static abuf_t *buffer_get_frame(void) {
|
||||
|
||||
if (curframe->ready) {
|
||||
if (ab_buffering) { // if we are getting packets but not yet forwarding them to the player
|
||||
int have_sent_prefiller_silence; // set true when we have send some silent frames to the DAC
|
||||
uint32_t reference_timestamp;
|
||||
uint64_t reference_timestamp_time,remote_reference_timestamp_time;
|
||||
get_reference_timestamp_stuff(&reference_timestamp, &reference_timestamp_time, &remote_reference_timestamp_time);
|
||||
if (first_packet_timestamp == 0) { // if this is the very first packet
|
||||
// debug(1,"First frame seen, time %u, with %d
|
||||
// frames...",curframe->timestamp,seq_diff(ab_read, ab_write));
|
||||
uint32_t reference_timestamp;
|
||||
uint64_t reference_timestamp_time,remote_reference_timestamp_time;
|
||||
get_reference_timestamp_stuff(&reference_timestamp, &reference_timestamp_time, &remote_reference_timestamp_time);
|
||||
if (reference_timestamp) { // if we have a reference time
|
||||
// debug(1,"First frame seen with timestamp...");
|
||||
first_packet_timestamp = curframe->timestamp; // we will keep buffering until we are
|
||||
// supposed to start playing this
|
||||
have_sent_prefiller_silence = 0;
|
||||
|
||||
// Here, calculate when we should start playing. We need to know when to allow the
|
||||
// packets to be sent to the player.
|
||||
@@ -524,7 +529,6 @@ static abuf_t *buffer_get_frame(void) {
|
||||
// -4410 frames.
|
||||
|
||||
int64_t delta = ((int64_t)first_packet_timestamp - (int64_t)reference_timestamp);
|
||||
|
||||
first_packet_time_to_play =
|
||||
reference_timestamp_time +
|
||||
((delta + (int64_t)config.latency + (int64_t)config.audio_backend_latency_offset)
|
||||
@@ -541,6 +545,13 @@ static abuf_t *buffer_get_frame(void) {
|
||||
}
|
||||
|
||||
if (first_packet_time_to_play != 0) {
|
||||
// recalculate first_packet_time_to_play -- the latency might change
|
||||
int64_t delta = ((int64_t)first_packet_timestamp - (int64_t)reference_timestamp);
|
||||
first_packet_time_to_play =
|
||||
reference_timestamp_time +
|
||||
((delta + (int64_t)config.latency + (int64_t)config.audio_backend_latency_offset)
|
||||
<< 32) /
|
||||
44100;
|
||||
|
||||
uint32_t filler_size = frame_size;
|
||||
uint32_t max_dac_delay = 4410;
|
||||
@@ -560,7 +571,7 @@ static abuf_t *buffer_get_frame(void) {
|
||||
first_packet_time_to_play = 0;
|
||||
time_since_play_started = 0;
|
||||
} else {
|
||||
if (config.output->delay) {
|
||||
if ((config.output->delay) && (have_sent_prefiller_silence != 0)) {
|
||||
dac_delay = config.output->delay();
|
||||
if (dac_delay == -1) {
|
||||
debug(1, "Error getting dac_delay in buffer_get_frame.");
|
||||
@@ -601,6 +612,7 @@ static abuf_t *buffer_get_frame(void) {
|
||||
// with %d packets.",exact_frame_gap,fs,dac_delay,seq_diff(ab_read, ab_write));
|
||||
config.output->play(silence, fs);
|
||||
free(silence);
|
||||
have_sent_prefiller_silence = 1;
|
||||
if (ab_buffering == 0) {
|
||||
uint64_t reference_timestamp_time; // don't need this...
|
||||
get_reference_timestamp_stuff(&play_segment_reference_frame, &reference_timestamp_time, &play_segment_reference_frame_remote_time);
|
||||
@@ -899,6 +911,7 @@ static void *player_thread_func(void *arg) {
|
||||
silence = malloc(OUTFRAME_BYTES(frame_size));
|
||||
memset(silence, 0, OUTFRAME_BYTES(frame_size));
|
||||
late_packet_message_sent = 0;
|
||||
first_packet_timestamp = 0;
|
||||
missing_packets = late_packets = too_late_packets = resend_requests = 0;
|
||||
flush_rtp_timestamp = 0; // it seems this number has a special significance -- it seems to be used
|
||||
// as a null operand, so we'll use it like that too
|
||||
@@ -1193,47 +1206,59 @@ void player_volume(double f) {
|
||||
// The volume ranges -144.0 (mute) or -30 -- 0. See
|
||||
// http://git.zx2c4.com/Airtunes2/about/#setting-volume
|
||||
// By examination, the -30 -- 0 range is linear on the slider; i.e. the slider is calibrated in 30
|
||||
// equal increments
|
||||
// So, we will pass this on without any weighting if we have a hardware mixer, as we expect the
|
||||
// mixer to be calibrated in dB.
|
||||
|
||||
// Here, we ask for an attenuation we will apply in software. The dB range of a value from 1 to
|
||||
// 65536 is about 48.1 dB (log10 of 65536 is 4.8164).
|
||||
// Thus, we ask our vol2attn function for an appropriate dB between -48.1 and 0 dB and translate
|
||||
// equal increments. Since the human ear's response is roughly logarithmic, we imagine these to
|
||||
// be power dB, i.e. from -30dB to 0dB.
|
||||
|
||||
// So, if we have a hardware mixer, we will pass this on to its dB volume settings.
|
||||
|
||||
// Without a hardware mixer, we have to do attenuation in software, so
|
||||
// here, we ask for an attenuation we will apply to the signal amplitude in software.
|
||||
// The dB range of a value from 1 to 65536 is about 96.3 dB (log10 of 65536 is 4.8164).
|
||||
// Since the levels correspond with amplitude, they correspond to voltage, hence voltage dB,
|
||||
// or 20 times the log of the ratio. Then multiplied by 100 for convenience.
|
||||
// Thus, we ask our vol2attn function for an appropriate dB between -96.3 and 0 dB and translate
|
||||
// it back to a number.
|
||||
|
||||
double scaled_volume = vol2attn(f, 0, -4810);
|
||||
double linear_volume = pow(10, scaled_volume / 1000);
|
||||
|
||||
if (f == -144.0)
|
||||
linear_volume = 0.0;
|
||||
double linear_volume = 0.0;
|
||||
|
||||
if (config.output->volume) {
|
||||
// debug(1,"Set volume to %f.",f);
|
||||
config.output->volume(f); // volume will be sent as metadata by the config.output device
|
||||
linear_volume =
|
||||
1.0; // no attenuation needed -- this value is used as a flag to avoid calculations
|
||||
linear_volume = 1.0; // no attenuation needed -- this value is used as a flag to avoid calculations
|
||||
}
|
||||
|
||||
if (config.output->parameters)
|
||||
config.output->parameters(&audio_information);
|
||||
else {
|
||||
long mindb = -9630;
|
||||
if (config.volume_range_db) {
|
||||
long suggested_alsa_min_db = -(long)trunc(config.volume_range_db*100);
|
||||
if (suggested_alsa_min_db > mindb)
|
||||
mindb = suggested_alsa_min_db;
|
||||
else
|
||||
inform("The volume_range_db setting, %f is greater than the native range of the mixer %f, so it is ignored.",config.volume_range_db,mindb/100.0);
|
||||
}
|
||||
double scaled_volume = vol2attn(f, 0, mindb);
|
||||
linear_volume = pow(10, scaled_volume / 2000);
|
||||
audio_information.airplay_volume = f;
|
||||
audio_information.minimum_volume_dB = -4810;
|
||||
audio_information.minimum_volume_dB = mindb;
|
||||
audio_information.maximum_volume_dB = 0;
|
||||
audio_information.current_volume_dB = scaled_volume;
|
||||
audio_information.has_true_mute = 0;
|
||||
audio_information.is_muted = 0;
|
||||
// debug(1,"Minimum software volume set to %d centi-dB",f,mindb);
|
||||
}
|
||||
audio_information.valid = 1;
|
||||
// debug(1,"Software volume set to %f on scale with a %f dB",f,linear_volume);
|
||||
pthread_mutex_lock(&vol_mutex);
|
||||
software_mixer_volume = linear_volume;
|
||||
fix_volume = 65536.0 * software_mixer_volume;
|
||||
pthread_mutex_unlock(&vol_mutex);
|
||||
#ifdef CONFIG_METADATA
|
||||
char *dv = malloc(64); // will be freed in the metadata thread
|
||||
char *dv = malloc(128); // will be freed in the metadata thread
|
||||
if (dv) {
|
||||
memset(dv, 0, 64);
|
||||
snprintf(dv, 63, "%.2f,%.2f,%.2f,%.2f", audio_information.airplay_volume,
|
||||
memset(dv, 0, 128);
|
||||
snprintf(dv, 127, "%.2f,%.2f,%.2f,%.2f", audio_information.airplay_volume,
|
||||
audio_information.current_volume_dB / 100.0,
|
||||
audio_information.minimum_volume_dB / 100.0,
|
||||
audio_information.maximum_volume_dB / 100.0);
|
||||
|
||||
@@ -193,7 +193,15 @@ static void *rtp_control_receiver(void *arg) {
|
||||
|
||||
rtp_timestamp_less_latency = ntohl(*((uint32_t *)&packet[4]));
|
||||
sync_rtp_timestamp = ntohl(*((uint32_t *)&packet[16]));
|
||||
|
||||
|
||||
if (config.use_negotiated_latencies) {
|
||||
uint32_t la = sync_rtp_timestamp-rtp_timestamp_less_latency+11025;
|
||||
if (la!=config.latency) {
|
||||
config.latency = la;
|
||||
// debug(1,"Using negotiated latency of %u frames.",config.latency);
|
||||
}
|
||||
}
|
||||
|
||||
if (packet[0] & 0x10) {
|
||||
// if it's a packet right after a flush or resume
|
||||
sync_rtp_timestamp += 352; // add frame_size -- can't see a reference to this anywhere,
|
||||
|
||||
@@ -584,9 +584,15 @@ static void msg_write_response(int fd, rtsp_message *resp) {
|
||||
}
|
||||
|
||||
static void handle_record(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) {
|
||||
debug(1,"Handle Record");
|
||||
//debug(1,"Handle Record");
|
||||
resp->respcode = 200;
|
||||
msg_add_header(resp, "Audio-Latency", "88200");
|
||||
// I think this is for telling the client what the absolute minimum latency actually is,
|
||||
// and when the client specifies a latency, it should be added to this figure.
|
||||
|
||||
// Thus, AirPlay's latency figure of 77175, when added to 11025 gives you exactly 88200
|
||||
// and iTunes' latency figure of 88553, when added to 11025 gives you 99578, pretty close to the 99400 we guessed.
|
||||
|
||||
msg_add_header(resp, "Audio-Latency", "11025");
|
||||
|
||||
char *p;
|
||||
uint32_t rtptime = 0;
|
||||
@@ -598,13 +604,14 @@ static void handle_record(rtsp_conn_info *conn, rtsp_message *req, rtsp_message
|
||||
p = strstr(hdr, "rtptime=");
|
||||
if (p) {
|
||||
p = strchr(p, '=') + 1;
|
||||
if (p)
|
||||
if (p) {
|
||||
rtptime = uatoi(p); // unsigned integer -- up to 2^32-1
|
||||
rtptime--;
|
||||
// debug(1,"RTSP Flush Requested by handle_record: %u.",rtptime);
|
||||
player_flush(rtptime);
|
||||
}
|
||||
}
|
||||
}
|
||||
rtptime--;
|
||||
debug(1,"RTSP Flush Requested by handle_record: %u.",rtptime);
|
||||
player_flush(rtptime);
|
||||
}
|
||||
|
||||
static void handle_options(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) {
|
||||
@@ -645,7 +652,7 @@ static void handle_flush(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *
|
||||
}
|
||||
|
||||
static void handle_setup(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) {
|
||||
debug(1,"Handle Setup");
|
||||
// debug(1,"Handle Setup");
|
||||
int cport, tport;
|
||||
int lsport, lcport, ltport;
|
||||
uint32_t active_remote = 0;
|
||||
@@ -669,13 +676,16 @@ static void handle_setup(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *
|
||||
}
|
||||
#endif
|
||||
|
||||
// select latency
|
||||
// This latency-setting mechanism is deprecated and will be removed.
|
||||
// If no non-standard latency is chosen, automatic negotiated latency setting is permitted.
|
||||
|
||||
// Select a static latency
|
||||
// if iTunes V10 or later is detected, use the iTunes latency setting
|
||||
// if AirPlay is detected, use the AirPlay latency setting
|
||||
// for everything else, use the general latency setting, if given, or
|
||||
// else use the default latency setting
|
||||
|
||||
config.latency = 88200;
|
||||
config.latency = -1;
|
||||
|
||||
if (config.userSuppliedLatency)
|
||||
config.latency = config.userSuppliedLatency;
|
||||
@@ -711,6 +721,12 @@ static void handle_setup(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *
|
||||
debug(2, "Unrecognised User-Agent. Using latency of %d frames.", config.latency);
|
||||
}
|
||||
}
|
||||
|
||||
if (config.latency==-1) {
|
||||
// this means that no static latency was set, so we'll allow it to be set dynamically
|
||||
config.latency=88198; // to be sure, to be sure -- make it slighty different from the default to ensure we get a debug message when set to 88200
|
||||
config.use_negotiated_latencies = 1;
|
||||
}
|
||||
char *hdr = msg_get_header(req, "Transport");
|
||||
if (!hdr)
|
||||
goto error;
|
||||
@@ -1097,6 +1113,12 @@ static void handle_set_parameter_metadata(rtsp_conn_info *conn, rtsp_message *re
|
||||
|
||||
#endif
|
||||
|
||||
static void handle_get_parameter(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) {
|
||||
debug(1, "received GET_PARAMETER request.");
|
||||
resp->respcode = 200;
|
||||
}
|
||||
|
||||
|
||||
static void handle_set_parameter(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) {
|
||||
// if (!req->contentlength)
|
||||
// debug(1, "received empty SET_PARAMETER request.");
|
||||
@@ -1238,7 +1260,7 @@ static struct method_handler {
|
||||
{"FLUSH", handle_flush},
|
||||
{"TEARDOWN", handle_teardown},
|
||||
{"SETUP", handle_setup},
|
||||
{"GET_PARAMETER", handle_ignore},
|
||||
{"GET_PARAMETER", handle_get_parameter},
|
||||
{"SET_PARAMETER", handle_set_parameter},
|
||||
{"RECORD", handle_record},
|
||||
{NULL, NULL}};
|
||||
@@ -1461,16 +1483,20 @@ static void *rtsp_conversation_thread_func(void *pconn) {
|
||||
goto respond;
|
||||
|
||||
struct method_handler *mh;
|
||||
int method_selected = 0;
|
||||
for (mh = method_handlers; mh->method; mh++) {
|
||||
if (!strcmp(mh->method, req->method)) {
|
||||
//debug(1,"RTSP Packet received of type \"%s\":",mh->method),
|
||||
//msg_print_debug_headers(req);
|
||||
method_selected = 1;
|
||||
mh->handler(conn, req, resp);
|
||||
//debug(1,"RTSP Response:");
|
||||
//msg_print_debug_headers(resp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (method_selected==0)
|
||||
debug(1,"Unrecognised and unhandled rtsp request \"%s\".",req->method);
|
||||
|
||||
respond:
|
||||
msg_write_response(conn->fd, resp);
|
||||
|
||||
+16
-13
@@ -5,7 +5,7 @@
|
||||
general =
|
||||
{
|
||||
// name = "Shairport Sync Player"; // This is the name the service will advertise to iTunes. The default is "Shairport Sync on <hostname>"
|
||||
// password = "secret"; // comment out this line if you want to have no password
|
||||
// password = "secret"; // leave this commented out if you don't want to require a password
|
||||
// interpolation = "basic"; // aka "stuffing". Default is "basic", alternative is "soxr". Use "soxr" only if you have a reasonably fast processor.
|
||||
// output_backend = "alsa"; // Run "shairport-sync -h" to get a list of all output_backends, e.g. "alsa", "pipe", "stdout". The default is the first one.
|
||||
// mdns_backend = "avahi"; // Run "shairport-sync -h" to get a list of all mdns_backends. The default is the first one.
|
||||
@@ -17,16 +17,7 @@ general =
|
||||
// resync_threshold = 2205; // a synchronisation error greater than this will cause resynchronisation; 0 disables it
|
||||
// log_verbosity = 0; // "0" means no debug verbosity, "3" is most verbose.
|
||||
// ignore_volume_control = "no"; // set this to "yes" if you want the volume to be at 100% no matter what the source's volume control is set to.
|
||||
};
|
||||
|
||||
// Latencies for different sources. These have been estimated from listening tests.
|
||||
// It's probably better to compensate for a delay in the output device using the alsa "audio_backend_latency_offset" setting -- see below.
|
||||
latencies =
|
||||
{
|
||||
// default = 88200; // used for unrecognised sources and for iTunes up to and including iTunes 9.X.
|
||||
// itunes = 99400; // used for iTunes 10 or later
|
||||
// airplay = 88200;
|
||||
// forkedDaapd = 99400;
|
||||
// volume_range_db = 60 ; // use this to set the range, in dB, you want between the maximum volume and the minimum volume. Range is 30 to 150 dB. Leave it commented out to use mixer's native range.
|
||||
};
|
||||
|
||||
// How to deal with metadata, including artwork
|
||||
@@ -47,9 +38,7 @@ sessioncontrol =
|
||||
// session_timeout = 120; // wait for this number of seconds after a source disappears before terminating the session and becoming available again.
|
||||
};
|
||||
|
||||
//
|
||||
// Back End Settings
|
||||
//
|
||||
|
||||
// These are parameters for the "alsa" audio back end, the only back end that supports synchronised audio.
|
||||
alsa =
|
||||
@@ -75,3 +64,17 @@ stdout =
|
||||
// audio_backend_latency_offset = 0; // Set this offset to compensate for a fixed delay in the audio back end. E.g. if the output device delays by 100 ms, set this to -4410.
|
||||
// audio_backend_buffer_desired_length = 44100; // Having started to send audio at the right time, send all subsequent audio this many frames ahead of time, creating a buffer this size.
|
||||
};
|
||||
|
||||
// The following static latency settings are deprecated -- do not use them for new installations. Shairport Sync now sets latencies automatically.
|
||||
// To compensate for a delay in the output device please use the alsa/stdio/pipe "audio_backend_latency_offset" setting.
|
||||
|
||||
// Static latencies for different sources. These have been estimated from listening tests.
|
||||
latencies =
|
||||
{
|
||||
// default = 88200; // used for unrecognised sources and for iTunes up to and including iTunes 9.X.
|
||||
// itunes = 99400; // used for iTunes 10 or later
|
||||
// airplay = 88200;
|
||||
// forkedDaapd = 99400;
|
||||
};
|
||||
|
||||
|
||||
|
||||
+65
-12
@@ -171,10 +171,10 @@ void usage(char *progname) {
|
||||
printf(" -a, --name=NAME set advertised name\n");
|
||||
printf(
|
||||
" -A, --AirPlayLatency=FRAMES set the latency for audio sent from an AirPlay device.\n");
|
||||
printf(" The default value is %u frames.\n", config.AirPlayLatency);
|
||||
printf(" The default value is %d frames.\n", config.AirPlayLatency);
|
||||
printf(
|
||||
" -i, --iTunesLatency=FRAMES set the latency for audio sent from iTunes 10 or later.\n");
|
||||
printf(" The default value is %u frames.\n", config.iTunesLatency);
|
||||
printf(" The default value is %d frames.\n", config.iTunesLatency);
|
||||
printf(" -L, --latency=FRAMES set the latency for audio sent from an unknown device\n");
|
||||
printf(" or from an old version of iTunes. Default is %d frames.\n",
|
||||
config.latency);
|
||||
@@ -397,19 +397,28 @@ int parse_options(int argc, char **argv) {
|
||||
die("Invalid ignore_volume_control option choice \"%s\". It should be \"yes\" or \"no\"");
|
||||
}
|
||||
|
||||
/* Get the default latency. */
|
||||
if (config_lookup_int(config.cfg, "latencies.default", &value))
|
||||
config.latency = value;
|
||||
/* Get the volume range, in dB, that should be used If not set, it means you just use the range set by the mixer. */
|
||||
if (config_lookup_int(config.cfg, "general.volume_range_db", &value)) {
|
||||
if ((value < 30) || (value > 150))
|
||||
die("Invalid volume range \"%sd\". It should be between 30 and 150 dB. Zero means use the mixer's native range",
|
||||
value);
|
||||
else
|
||||
config.volume_range_db = value;
|
||||
}
|
||||
|
||||
/* Get the itunes latency. */
|
||||
/* Get the default latency. Deprecated! */
|
||||
if (config_lookup_int(config.cfg, "latencies.default", &value))
|
||||
config.userSuppliedLatency = value;
|
||||
|
||||
/* Get the itunes latency. Deprecated! */
|
||||
if (config_lookup_int(config.cfg, "latencies.itunes", &value))
|
||||
config.iTunesLatency = value;
|
||||
|
||||
/* Get the AirPlay latency. */
|
||||
/* Get the AirPlay latency. Deprecated! */
|
||||
if (config_lookup_int(config.cfg, "latencies.airplay", &value))
|
||||
config.AirPlayLatency = value;
|
||||
|
||||
/* Get the forkedDaapd latency. */
|
||||
/* Get the forkedDaapd latency. Deprecated! */
|
||||
if (config_lookup_int(config.cfg, "latencies.forkedDaapd", &value))
|
||||
config.ForkedDaapdLatency = value;
|
||||
|
||||
@@ -636,14 +645,14 @@ int main(int argc, char **argv) {
|
||||
config.configfile = configuration_file_path;
|
||||
|
||||
config.statistics_requested = 0; // don't print stats in the log
|
||||
config.latency = 88200; // AirPlay. Is also reset in rtsp.c when play is about to start
|
||||
config.latency = -1; // -1 means not set. 88200 works well. This is also reset in rtsp.c when play is about to start
|
||||
config.userSuppliedLatency = 0; // zero means none supplied
|
||||
config.iTunesLatency = 99400; // this seems to work pretty well for iTunes from Version 10 (?)
|
||||
config.iTunesLatency = -1; // -1 means not supplied. 99400 seems to work pretty well for iTunes from Version 10 (?)
|
||||
// upwards-- two left-ear headphones, one from the iMac jack, one
|
||||
// from an NSLU2 running a cheap "3D Sound" USB Soundcard
|
||||
config.AirPlayLatency = 88200; // this seems to work pretty well for AirPlay -- Syncs sound and
|
||||
config.AirPlayLatency = -1; // -1 means not set. 88200 seems to work well for AirPlay -- Syncs sound and
|
||||
// vision on AppleTV, but also used for iPhone/iPod/iPad sources
|
||||
config.ForkedDaapdLatency = 99400; // Seems to be right
|
||||
config.ForkedDaapdLatency = -1; // -1 means not set. 99400 seems to be right
|
||||
config.resyncthreshold = 441 * 5; // this number of frames is 50 ms
|
||||
config.timeout = 120; // this number of seconds to wait for [more] audio before switching to idle.
|
||||
config.tolerance = 88; // this number of frames of error before attempting to correct it.
|
||||
@@ -821,6 +830,49 @@ int main(int argc, char **argv) {
|
||||
|
||||
daemon_log(LOG_NOTICE, "startup");
|
||||
|
||||
/* Mess around with the latency options */
|
||||
// Basically, we used to rely on static latencies -- 99400 for iTunes 10 or later and forkedDaapd, 88200 for everything else
|
||||
// Nowadays we allow the source to set the latency, which works out at 99651 for iTunes 10 and forkedDaapd and 88220 for everything else
|
||||
// What we want to do here is allow the source to set the latency unless the user has specified an non-standard latency.
|
||||
// If the user has specified a standard latency, we suggest to them to stop doing it.
|
||||
// If they specify a non-standard latency, we suggest the user to use the audio_backend_latency_offset instead.
|
||||
|
||||
if (config.AirPlayLatency!=-1) {
|
||||
if (config.AirPlayLatency==88200) {
|
||||
inform("It is not necessary to set the AirPlay latency to 88200 -- you should remove this setting or configuration option, as it is deprecated.");
|
||||
config.AirPlayLatency= -1;
|
||||
} else {
|
||||
inform("The AirPlay latency setting is deprecated, as Shairport Sync can now get the correct latency from the source.");
|
||||
inform("Please remove this setting and use the relevant audio_backend_latency_offset setting, if necessary, to compensate for delays elsewhere.");
|
||||
}
|
||||
}
|
||||
|
||||
if (config.iTunesLatency!=-1) {
|
||||
if (config.iTunesLatency==99400) {
|
||||
inform("It is not necessary to set the iTunes latency to 99400 -- you should remove this setting or configuration option, as it is deprecated and ignored.");
|
||||
config.iTunesLatency= -1;
|
||||
} else {
|
||||
inform("The iTunes latency setting is deprecated, as Shairport Sync can now get the correct latency from the source.");
|
||||
inform("Please remove this setting and use the relevant audio_backend_latency_offset setting, if necessary, to compensate for delays elsewhere.");
|
||||
}
|
||||
}
|
||||
|
||||
if (config.ForkedDaapdLatency!=-1) {
|
||||
if (config.ForkedDaapdLatency==99400) {
|
||||
inform("It is not necessary to set the forkedDaapd latency to 99400 -- you should remove this setting or configuration option, as it is deprecated and ignored.");
|
||||
config.ForkedDaapdLatency= -1;
|
||||
} else {
|
||||
inform("The forkedDaapd latency setting is deprecated, as Shairport Sync can now get the correct latency from the source.");
|
||||
inform("Please remove this setting and use the relevant audio_backend_latency_offset setting, if necessary, to compensate for delays elsewhere.");
|
||||
}
|
||||
}
|
||||
|
||||
if (config.userSuppliedLatency) {
|
||||
inform("The default latency setting is deprecated, as Shairport Sync can now get the correct latency from the source.");
|
||||
inform("Please remove this setting and use the relevant audio_backend_latency_offset setting, if necessary, to compensate for delays elsewhere.");
|
||||
}
|
||||
|
||||
|
||||
/* Print out options */
|
||||
|
||||
debug(2, "statistics_requester status is %d.", config.statistics_requested);
|
||||
@@ -848,6 +900,7 @@ int main(int argc, char **argv) {
|
||||
debug(2, "audio backend desired buffer length is %d.",
|
||||
config.audio_backend_buffer_desired_length);
|
||||
debug(2, "audio backend latency offset is %d.", config.audio_backend_latency_offset);
|
||||
debug(2, "volume range in dB (zero means use the range specified by the mixer): %u.", config.volume_range_db);
|
||||
|
||||
char *realConfigPath = realpath(config.configfile,NULL);
|
||||
if (realConfigPath) {
|
||||
|
||||
Reference in New Issue
Block a user