diff --git a/LIBSOXR.md b/LIBSOXR.md
index 20c40b9f..80a67987 100644
--- a/LIBSOXR.md
+++ b/LIBSOXR.md
@@ -14,7 +14,7 @@ git clone git://git.code.sf.net/p/soxr/code libsoxr
cd libsoxr
./go
```
-Be patient! This takes a long time on a Raspberry Pi -- it looks like it gets stuck at 47%, but it will finish if you let it.
+Be patient! This takes a long time on a Raspberry Pi -- it looks like it gets stuck around 40% or 50%, but it will finish if you let it.
Having compiled `libsoxr`, it must now must be installed:
```
diff --git a/README.md b/README.md
index 7c7d0709..9ada3453 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
Shairport Sync
=============
-Shairport Sync emulates an AirPort Express for the purpose of streaming audio from iTunes, iPods, iPhones, iPads and AppleTVs.
+Shairport Sync is an AirPlay audio player -- it plays audio streamed from iTunes, iOS devices and third-party AirPlay sources such as ForkedDaapd and others.
Audio played by a Shairport Sync-powered device stays synchronised with the source and hence with similar devices playing the same source. In this way, synchronised multi-room audio is possible without difficulty. (Hence the name Shairport Sync, BTW.)
Shairport Sync does not support AirPlay video or photo streaming.
@@ -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.
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index b6314fad..8c46591f 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -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.
diff --git a/audio_alsa.c b/audio_alsa.c
index d4e54973..3cfacea1 100644
--- a/audio_alsa.c
+++ b/audio_alsa.c
@@ -29,6 +29,7 @@
#include 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 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 The 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 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 Please note that different sources provide different levels of metadata. Some provide a lot; some provide almost none. The shairport-sync can run programs just before it starts to play an audio stream and just after it finishes.
+ You specify them using the sessioncontrol group settings run_this_before_play_begins and run_this_after_play_ends. The latencies settings are now deprecated. Do not use them for new installations. They will be removed from a future version of Shairport Sync. Latency is the exact time from a sound signal's original timestamp until that signal actually "appears" on the output of the audio output device,
+ usually a Digital to Audio Converter (DAC), irrespective of any internal delays, processing times, etc. in the computer. Shairport Sync now sets latencies automatically using information supplied by the source, typically either 88,200 or 99,577 frames. The following relates to the old scheme of using fixed latencies, which ignores the latency information supplied by the source.
+ There are four default latency settings. One latency matches the latency used by recent versions of
+ iTunes when playing audio and another matches the latency
+ used by so-called "AirPlay" devices, including iOS devices and iTunes and Quicktime Player when they are playing video.
+ A third latency is used when the audio source is forked-daapd. The fourth latency is the default if no other latency is chosen and is used for older versions of iTunes. Note: If you are thinking of changing latencies to compensate for a delay in the audio output device, then
+ instead of changing these individual latencies, consider using the Note: if you are setting up shairport-sync for the first time or are updating an existing installation,
+ Note: if you are setting up Shairport Sync for the first time or are updating an existing installation,
you are encouraged to use the configuration file settings described above. Most of the options described below
- simply replicate the configuration settings and are retained to provide backward compatability with older installations of shairport-sync.
Many of the options take sensible default values, so you can normally ignore most of them. See the EXAMPLES section for typical usages.
@@ -742,9 +771,9 @@Mike Brady developed shairport-sync from the original shairport by James Laird.
-shairport-sync can be found at
shairport can be found at
Mike Brady developed Shairport Sync from the original Shairport by James Laird.
+Shairport Sync can be found at
Shairport can be found at
ignore_volume_control="choice";
Set this choice to "yes" if you want the volume to be at 100% no matter what the source's volume control is set to. This might be useful if you want to set the volume on the output device, independently of the setting at the source. The default is "no". - -"LATENCIES" SETTINGS
-There are four default latency settings, chosen automatically. One latency matches the latency used by recent versions of iTunes when playing audio and another matches the latency used by so-called "AirPlay" devices, including iOS devices and iTunes and Quicktime Player when they are playing video. A third latency is used when the audio source is forked-daapd. The fourth latency is the default if no other latency is chosen and is used for older versions of iTunes.
-If you want to change latencies to compensate for a delay in the audio output device (which will have the same effect on all sources), instead of changing these individual latencies, consider using the audio_backend_latency_offset setting in the alsa group (or the appropriate other group if you're not outputing through the alsa backend).
- - - -itunes=latency;
- This is the latency, in frames, used for iTunes 10 or later. Default is 99,400. -airplay=latency;
- This is the latency, in frames, used for AirPlay devices, including iOS devices and iTunes and Quicktime Player when they are playing video. Default is 88,200. - - -forkedDaapd=latency;
- This is the latency, in frames, used for forkedDaapd sources. Default is 99,400. - - -default=latency;
- This is the latency, in frames, used when the source is unrecognised. Default is 88,200. - - -"METADATA" SETTINGS
-shairport-sync can process metadata provided by the source, such as Track Number, Album Name, cover art, etc. and can provide additional metadata such as volume level, - pause/resume, etc. It provides the metadata to a pipe, by default /tmp/shairport-sync-metadata. - To process metadata, shairport-sync must have been compiled with metadata support included. - You can check that this is so by running shairport-sync -V; the identification string will contain the word metadata.
-The metadata group of settings allow you to enable metadata handling and to control certain aspects of it:
- - - -enabled="choice";
- Set the choice to "yes" to enable shairport-sync to look for metadata from the audio source and to forward it, - along with metadata generated by shairport-sync itself, to the metadata pipe. The default is "no". - - -include_cover_art="choice";
- Set the choice to "yes" to enable shairport-sync to look for cover art from the audio source and to include it in the feed to the metadata pipe. - You must also enable metadata (see above). - One reason for not including cover art is that the images can sometimes be very large and may delay transmission of subsequent metadata through the pipe. - The default is "no". - - -pipe_name="filepathname";
- Specify the absolute path name of the pipe through which metadata should be sent The default is /tmp/shairport-sync-metadata". - - -"SESSIONCONTROL" SETTINGS
-shairport-sync can run programs just before it starts to play an audio stream and just after it finishes. - You specify them using the settings run_this_before_play_begins and run_this_after_play_ends.
- - -run_this_before_play_begins="/path/to/application and args";
- Here you can specify a program and its arguments that will be run just before a play session begins. Be careful to include the full path to the application. - The application must be marked as executable and, if it is a script, its first line must begin with the standard #!/bin/... as appropriate. - - -run_this_after_play_ends="/path/to/application and args";
- Here you can specify a program and its arguments that will be run just after a play session ends. Be careful to include the full path to the application. - The application must be marked as executable and, if it is a script, its first line must begin with the standard #!/bin/... as appropriate. - - -wait_for_completion="choice";
- Set choice to "yes" to make shairport-sync wait until the programs specified in the run_this_before_play_begins - and run_this_after_play_ends have completed execution before continuing. The default is "no". - - -allow_session_interruption="choice";
- If choice is set to "yes", then another source will be able to interrupt an existing play session and start a new one. - When set to "no" (the default), other devices attempting to interrupt a session will fail, receiving a busy signal. - - -session_timeout=seconds;
- If a play session has been established and the source disappears without warning (such as a device going out of range of a network) - then wait for seconds seconds before ending the session. Once the session has terminated, other devices can use it. - The default is 120 seconds. +volume_range_db=dBvalue;
+ Set this dBvalue to use just a portion of the full range of attenuation offered by a mixer. + For example, if a mixer has a minimum volume of -80 dB and a maximum of +20 dB, you might wish to use only 60 dB of the 100 dB available. + This might be because the sound becomes inaudible at the lowest setting and unbearably loud at the highest setting -- + indeed, many domestic HiFi systmes have a volume copntrol range of just 60 to 80dB. + Another potential use might be where the range specified by the mixer does not match the capabilities of the device. + For example, the Raspberry Pi's DAC that feeds the built-in audio jack claims a range of 106 dB but has a useful range of only about 35dB. + The setting allows you to specify the maximum range from highest to lowest. + The range suggested for the Raspberry Pi's built-in audio DAC, which feeds the headphone jack, is 35. + Using it in this case gives the volume control a much more useful range of settings. + If you omit this setting, the full "native" range of the mixer is used."ALSA" SETTINGS
@@ -352,6 +288,99 @@ shairport-sync performs no stuffing or interpolation when writing to stdout. Default setting is 44,100 frames. + +"METADATA" SETTINGS
+shairport-sync can process metadata provided by the source, such as Track Number, Album Name, cover art, etc. and can provide additional metadata such as volume level, + pause/resume, etc. It sends the metadata to a pipe, by default /tmp/shairport-sync-metadata. + To process metadata, shairport-sync must have been compiled with metadata support included. + You can check that this is so by running shairport-sync -V; the identification string will contain the word metadata.
+Please note that different sources provide different levels of metadata. Some provide a lot; some provide almost none.
+The metadata group of settings allow you to enable metadata handling and to control certain aspects of it:
+ + + +enabled="choice";
+ Set the choice to "yes" to enable shairport-sync to look for metadata from the audio source and to forward it, + along with metadata generated by shairport-sync itself, to the metadata pipe. The default is "no". + + +include_cover_art="choice";
+ Set the choice to "yes" to enable shairport-sync to look for cover art from the audio source and to include it in the feed to the metadata pipe. + You must also enable metadata (see above). + One reason for not including cover art is that the images can sometimes be very large and may delay transmission of subsequent metadata through the pipe. + The default is "no". + + +pipe_name="filepathname";
+ Specify the absolute path name of the pipe through which metadata should be sent The default is /tmp/shairport-sync-metadata". + + +"SESSIONCONTROL" SETTINGS
+shairport-sync can run programs just before it starts to play an audio stream and just after it finishes. + You specify them using the sessioncontrol group settings run_this_before_play_begins and run_this_after_play_ends.
+ + + +run_this_before_play_begins="/path/to/application and args";
+ Here you can specify a program and its arguments that will be run just before a play session begins. Be careful to include the full path to the application. + The application must be marked as executable and, if it is a script, its first line must begin with the standard #!/bin/... as appropriate. + + +run_this_after_play_ends="/path/to/application and args";
+ Here you can specify a program and its arguments that will be run just after a play session ends. Be careful to include the full path to the application. + The application must be marked as executable and, if it is a script, its first line must begin with the standard #!/bin/... as appropriate. + + +wait_for_completion="choice";
+ Set choice to "yes" to make shairport-sync wait until the programs specified in the run_this_before_play_begins + and run_this_after_play_ends have completed execution before continuing. The default is "no". + + +allow_session_interruption="choice";
+ If choice is set to "yes", then another source will be able to interrupt an existing play session and start a new one. + When set to "no" (the default), other devices attempting to interrupt a session will fail, receiving a busy signal. + + +session_timeout=seconds;
+ If a play session has been established and the source disappears without warning (such as a device going out of range of a network) + then wait for seconds seconds before ending the session. Once the session has terminated, other devices can use it. + The default is 120 seconds. + + +"LATENCIES" SETTINGS
+The latencies settings are now deprecated. Do not use them for new installations. They will be removed from a future version of Shairport Sync.
+Latency is the exact time from a sound signal's original timestamp until that signal actually "appears" on the output of the audio output device, + usually a Digital to Audio Converter (DAC), irrespective of any internal delays, processing times, etc. in the computer.
+ +Shairport Sync now sets latencies automatically using information supplied by the source, typically either 88,200 or 99,577 frames.
+ +The following relates to the old scheme of using fixed latencies, which ignores the latency information supplied by the source. + There are four default latency settings. One latency matches the latency used by recent versions of + iTunes when playing audio and another matches the latency + used by so-called "AirPlay" devices, including iOS devices and iTunes and Quicktime Player when they are playing video. + A third latency is used when the audio source is forked-daapd. The fourth latency is the default if no other latency is chosen and is used for older versions of iTunes.
+Note: If you are thinking of changing latencies to compensate for a delay in the audio output device, then + instead of changing these individual latencies, consider using the audio_backend_latency_offset setting in the alsa group + (or the appropriate other group if you're not outputing through the alsa backend).
+ + + +itunes=latency;
+ This is the latency, in frames, used for iTunes 10 or later. Default is 99,400. + + +airplay=latency;
+ This is the latency, in frames, used for AirPlay devices, including iOS devices and iTunes and Quicktime Player when they are playing video. Default is 88,200. + + +forkedDaapd=latency;
+ This is the latency, in frames, used for forkedDaapd sources. Default is 99,400. + + +default=latency;
+ This is the latency, in frames, used when the source is unrecognised. Default is 88,200. + + @@ -359,9 +388,9 @@Note: if you are setting up shairport-sync for the first time or are updating an existing installation, +
Note: if you are setting up Shairport Sync for the first time or are updating an existing installation, you are encouraged to use the configuration file settings described above. Most of the options described below - simply replicate the configuration settings and are retained to provide backward compatability with older installations of shairport-sync.
+ simply replicate the configuration settings and are retained to provide backward compatability with older installations of Shairport Sync.Many of the options take sensible default values, so you can normally ignore most of them. See the EXAMPLES section for typical usages.
@@ -735,9 +764,9 @@Mike Brady developed shairport-sync from the original shairport by James Laird.
-shairport-sync can be found at https://github.com/mikebrady/shairport-sync.
-shairport can be found at https://github.com/abrasive/shairport.
+Mike Brady developed Shairport Sync from the original Shairport by James Laird.
+Shairport Sync can be found at https://github.com/mikebrady/shairport-sync.
+Shairport can be found at https://github.com/abrasive/shairport.
diff --git a/player.c b/player.c index c86b9724..52a93f5f 100644 --- a/player.c +++ b/player.c @@ -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); diff --git a/rtp.c b/rtp.c index e00a7536..fcffd860 100644 --- a/rtp.c +++ b/rtp.c @@ -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, diff --git a/rtsp.c b/rtsp.c index c2be34bc..3925ab1a 100644 --- a/rtsp.c +++ b/rtsp.c @@ -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); diff --git a/scripts/shairport-sync.conf b/scripts/shairport-sync.conf index b2ac51a5..ff2651aa 100644 --- a/scripts/shairport-sync.conf +++ b/scripts/shairport-sync.conf @@ -5,7 +5,7 @@ general = { // name = "Shairport Sync Player"; // This is the name the service will advertise to iTunes. The default is "Shairport Sync on