The unconfigurable resync period of 10 seconds was not frequent
enough to keep my own ALSA device in sync with the AirPlay stream.
Now the period is configurable. The default is still at 10
seconds, to prevent any change in behavior unless opted in by
the user.
Currently the adjustment causes a tiny "click" distortion in the
ALSA output, so it is better to make the check as infrequent as
possible, while still being frequent enough to stay in sync
over lengthy sessions of playback.
Added source_sample_rate, target_sample_rate to alsa_session.
This is a first step toward rendering ALSA at a different
sampling rate than the AirPlay stream, so that (a) we will
be able to dynamically adjust the ALSA sampling rate for an
improved sync algorithm, and (b) later, a more generalized
resampling algorithm can accommodate very different hardware
sampling rates like 22050 Hz or 48000 Hz.
Reworked alsa_session_free() so that it can be used to
tear down a partially initialized alsa_session if an
error occurs in the middle of alsa_session_make().
This simplifies the error handling logic in alsa_session_make().
This refactoring will be helpful later when resampling is added,
because more data structures will be dynamically allocated
during initialization.
Signed-off-by: Don Cross <cosinekitty@gmail.com>
The current logic in httpd_dacp.c cannot handle non persistent items
correctly. The items are always shown with the dummy_mfi with "unkown
artist" etc.
Ommits useless update query for playcount for items that are not in the
library. Also avoids trying to scrobble these items (fixes error log
message "lastfm: Scrobble failed, track id 9999999 is unknown")
The connection test would not catch "No route to host", as this is returned
through the value-result buffer.
This fix might partially solve issue #498.
AirPlay 2 devices like Sonos One and AirPort Express with firmware 7.8
require auth-setup before ANNOUNCE, otherwise they will return 403.
Also fixed a problem where metadata did not get sent when toggling
a speaker on/off if we were playing an endless stream.
Avoid calling cache_daap_add() when hreq->user_agent is NULL
(user agent is not provided by the client), because it will
trigger a segfault when strdup() is called with that NULL pointer.
Fixes#571.
Avahi gives us several ipv6 addresses for an ATV4 that aren't actually
connectable. Here we simply try to make a connection to the address,
and if it is not possible within a timeout we ignore the announcement.
We also now don't start a mdns record browser if the address from the
resolver passes the connection test and isn't link-local.
Changing a speaker volume in a DACP clients results in two dacp requests
(at least in Retune):
setproperty?include-speaker-id=0&dmcp.volume=41
setproperty?speaker-id=198018693182577&dmcp.volume=43
The first request sets the absolute volume for the speaker (player.c -
volume_setabs_speaker). The second request is only triggered if the
volume from the first one is not the new master volume. This second
requests adjusts the relativ volume based on the loudest device (new
master volume) (player.c - volume_setrel_speaker). After the second
request the master volume and the relative volumes are correct (range
from 0 - 100 percent and master volume is 100 percent).
MPD and JSON API clients only set the absolute volume which results in
inconsistent master_volume and relative volumes. The added option to
update the master volume in volume_setabs_speaker/volume_setrel_speaker
makes sure the master volume and the relative volumes are correctly set.
Implements Active-Remote, which is sent to the speaker, so it can use this
to tell us who it is when it makes dacp request with a device-volume update.
These commands are not used by Remote, but some Airplay speakers are
able to make them (e.g. my Sony STR-DN1040).
Also prepare being able to set the device volume property.
Old Airport Express hangs up if we use GET_PARAMETER (despite announcing support
for it...), and since iTunes seems to use OPTIONS we also do that. We weren't
really using the return value of GET_PARAMETER anyway.
See also comment added to commit d9a67b6dce
Allows adding non-library spotify tracks to be added to the queue. The
path given to queue_add should either be a spotify track, album or
playlist uri.
For some reason it seems the Docker version of ffmpeg 3.4 uses "optimal"
Huffman tables (despite not being default), which cause ffmpeg to crash
when mjpeg encoder is encoding artwork jpeg's
Adds utility functions to httpd.c for checking the request headers for
either an "If-None-Match" or an "If-Not-Modified-Since" headers. If the
header value is found and it matches the current value for the requested
resource, we return early with a http response code 403 (Not Modified).
If the request header value is not present or does not match we add the
current ETag/Last-Modified values to the response headers and process
the request normally.
The query did not respect the filter and therefor always returned the
number of albums in the library and not the number of albums for the
given query.
Instead of asking a client to first scan the path into a media_file_info
object and afterwards add it to the queue, we now offer a library
function to directly add a path.
The library-source that can handle the given path translates the path
into new queue item(s) and adds them to the queue.
Defaults to an index.html file instead of redirecting to admin.html. It
will not redirect to index.html, but instead serve the file (if exists)
directly. This allows nicer uris in the webinterface.
We will still redirect to admin.html if no index.html is found for
requests to http://ip:port/
Before, we returned either unordered (for RSP, meaning client had to
sort) or ordered by a client selected sort_clause[]. The latter are
multi-purpose and therefore not optimised for browse queries.
To speed up, we predefine the entire set of browse queries, including
order, with matching indices. The predefined queries are used except
if the client explicitly requests a non-default order or query.
As a special bonus, the commit also allows queries with I_SUB that
have an offset but no limit.
ANALYZE collects and saves statistics even if there were no database
changes and the last collected data is still good.
According to the sqlite3 documentation, it is recommended to use "PRAGMA
optimize" which will call "ANALYZE" if it is necessary. "PRAGMA
optimize" will run "ANALYZE" based on prior queries on the same database
connection. It is recommended to run optimize before closing the
connection.
(see https://www.sqlite.org/lang_analyze.html)
Fixes missing queue updates in MPDroid after moving an item in the
queue. MPDroid moves items with the 'moveid' command and retrieves the
playlist changes with the 'plchanges' command, due to the missing
queue_version update the last command did not return any changes and the
queue in MPDroid did not get updated.
The web api might be accessed from different threads (library, worker,
dacp), therefor protect from concurrently running refresh-token requests
(accessing the globals in spotify_webapi.c)
The logged_in callback is called during relogin in the initscan.
Additionally initscan explicitly starts the scan leading to a duplicate
scan run.
To prevent this from happening removed the scan call in the logged_in
callback and split the spotify_login_user function into a private
function (without scan) and a public function (with scan).
Scanning saved albums/playlists over the webapi requires a logged in
libspotify session. To ensure, that the login process finished before
starting the webapi scan, the login needs to be synchronous.