Merge branch 'v0.20.x'

This commit is contained in:
Max Kellermann 2017-12-03 16:22:08 +01:00
commit fbc4bb29dc
12 changed files with 47 additions and 15 deletions

7
NEWS
View File

@ -15,6 +15,13 @@ ver 0.21 (not yet released)
* mixer * mixer
- sndio: new mixer plugin - sndio: new mixer plugin
ver 0.20.13 (not yet released)
* database
- simple: don't purge mount points on update/rescan
- simple: fix "mount" bug caused by bad compiler optimization
- upnp: work around libupnp 1.6.24 API breakage
* queue: fix spuriously misplaced prioritized songs
ver 0.20.12 (2017/11/25) ver 0.20.12 (2017/11/25)
* database * database
- upnp: adapt to libupnp 1.8 API changes - upnp: adapt to libupnp 1.8 API changes

View File

@ -79,12 +79,20 @@ struct MusicChunk {
*/ */
ReplayGainInfo replay_gain_info; ReplayGainInfo replay_gain_info;
/**
* A magic value for #replay_gain_serial which omits updating
* the #ReplayGainFilter. This is used by "silence" chunks
* (see PlayerThread::SendSilence()) so they don't affect the
* replay gain.
*/
static constexpr unsigned IGNORE_REPLAY_GAIN = ~0u;
/** /**
* A serial number for checking if replay gain info has * A serial number for checking if replay gain info has
* changed since the last chunk. The magic value 0 indicates * changed since the last chunk. The magic value 0 indicates
* that there is no replay gain info available. * that there is no replay gain info available.
*/ */
unsigned replay_gain_serial = 0; unsigned replay_gain_serial;
/** the data (probably PCM) */ /** the data (probably PCM) */
uint8_t data[CHUNK_SIZE]; uint8_t data[CHUNK_SIZE];

View File

@ -106,7 +106,7 @@ Directory::PruneEmpty() noexcept
child != end;) { child != end;) {
child->PruneEmpty(); child->PruneEmpty();
if (child->IsEmpty()) if (child->IsEmpty() && !child->IsMount())
child = children.erase_and_dispose(child, child = children.erase_and_dispose(child,
DeleteDisposer()); DeleteDisposer());
else else

View File

@ -130,7 +130,6 @@ public:
* *
* @param name_utf8 the UTF-8 encoded name of the new sub directory * @param name_utf8 the UTF-8 encoded name of the new sub directory
*/ */
gcc_malloc
Directory *CreateChild(const char *name_utf8); Directory *CreateChild(const char *name_utf8);
/** /**

View File

@ -104,7 +104,7 @@ inline void
UpdateWalk::PurgeDeletedFromDirectory(Directory &directory) UpdateWalk::PurgeDeletedFromDirectory(Directory &directory)
{ {
directory.ForEachChildSafe([&](Directory &child){ directory.ForEachChildSafe([&](Directory &child){
if (DirectoryExists(storage, child)) if (child.IsMount() || DirectoryExists(storage, child))
return; return;
editor.LockDeleteDirectory(&child); editor.LockDeleteDirectory(&child);

View File

@ -23,12 +23,15 @@
#include <upnp/upnp.h> #include <upnp/upnp.h>
#if UPNP_VERSION < 10800 #if UPNP_VERSION < 10800
#include "Compiler.h"
/* emulate the libupnp 1.8 API with older versions */ /* emulate the libupnp 1.8 API with older versions */
using UpnpDiscovery = Upnp_Discovery; using UpnpDiscovery = Upnp_Discovery;
#endif
#if UPNP_VERSION < 10624
#include "Compiler.h"
gcc_pure gcc_pure
static inline int static inline int
UpnpDiscovery_get_Expires(const UpnpDiscovery *disco) noexcept UpnpDiscovery_get_Expires(const UpnpDiscovery *disco) noexcept

View File

@ -142,7 +142,8 @@ AudioOutputSource::GetChunkData(const MusicChunk &chunk,
replay_gain_filter_set_mode(*replay_gain_filter, replay_gain_filter_set_mode(*replay_gain_filter,
replay_gain_mode); replay_gain_mode);
if (chunk.replay_gain_serial != *replay_gain_serial_p) { if (chunk.replay_gain_serial != *replay_gain_serial_p &&
chunk.replay_gain_serial != MusicChunk::IGNORE_REPLAY_GAIN) {
replay_gain_filter_set_info(*replay_gain_filter, replay_gain_filter_set_info(*replay_gain_filter,
chunk.replay_gain_serial != 0 chunk.replay_gain_serial != 0
? &chunk.replay_gain_info ? &chunk.replay_gain_info

View File

@ -556,8 +556,10 @@ Player::SendSilence()
partial frames */ partial frames */
unsigned num_frames = sizeof(chunk->data) / frame_size; unsigned num_frames = sizeof(chunk->data) / frame_size;
chunk->bit_rate = 0;
chunk->time = SignedSongTime::Negative(); /* undefined time stamp */ chunk->time = SignedSongTime::Negative(); /* undefined time stamp */
chunk->length = num_frames * frame_size; chunk->length = num_frames * frame_size;
chunk->replay_gain_serial = MusicChunk::IGNORE_REPLAY_GAIN;
PcmSilence({chunk->data, chunk->length}, play_audio_format.format); PcmSilence({chunk->data, chunk->length}, play_audio_format.format);
try { try {

View File

@ -75,8 +75,7 @@ playlist::MoveOrderToCurrent(unsigned old_order)
} else { } else {
/* not playing anything: move the specified song to /* not playing anything: move the specified song to
the front */ the front */
queue.SwapOrders(old_order, 0); return queue.MoveOrderBefore(old_order, 0);
return 0;
} }
} }

View File

@ -112,7 +112,7 @@ playlist::AppendSong(PlayerControl &pc, DetachedSong &&song)
else else
start = current + 1; start = current + 1;
if (start < queue.GetLength()) if (start < queue.GetLength())
queue.ShuffleOrderLast(start, queue.GetLength()); queue.ShuffleOrderLastWithPriority(start, queue.GetLength());
} }
UpdateQueuedSong(pc, queued_song); UpdateQueuedSong(pc, queued_song);

View File

@ -359,8 +359,20 @@ Queue::ShuffleOrderFirst(unsigned start, unsigned end) noexcept
} }
void void
Queue::ShuffleOrderLast(unsigned start, unsigned end) noexcept Queue::ShuffleOrderLastWithPriority(unsigned start, unsigned end) noexcept
{ {
assert(end <= length);
assert(start < end);
/* skip all items at the start which have a higher priority,
because the last item shall only be shuffled within its
priority group */
const auto last_priority = items[OrderToPosition(end - 1)].priority;
while (items[OrderToPosition(start)].priority != last_priority) {
++start;
assert(start < end);
}
rand.AutoCreate(); rand.AutoCreate();
std::uniform_int_distribution<unsigned> distribution(start, end - 1); std::uniform_int_distribution<unsigned> distribution(start, end - 1);

View File

@ -357,11 +357,12 @@ struct Queue {
void ShuffleOrderFirst(unsigned start, unsigned end) noexcept; void ShuffleOrderFirst(unsigned start, unsigned end) noexcept;
/** /**
* Shuffles the virtual order of the last song in the specified * Shuffles the virtual order of the last song in the
* (order) range. This is used in random mode after a song has been * specified (order) range; only songs which match this song's
* appended by queue_append(). * priority are considered. This is used in random mode after
* a song has been appended by Append().
*/ */
void ShuffleOrderLast(unsigned start, unsigned end) noexcept; void ShuffleOrderLastWithPriority(unsigned start, unsigned end) noexcept;
/** /**
* Shuffles a (position) range in the queue. The songs are physically * Shuffles a (position) range in the queue. The songs are physically