Merge branch 'v0.20.x'
This commit is contained in:
commit
fbc4bb29dc
7
NEWS
7
NEWS
@ -15,6 +15,13 @@ ver 0.21 (not yet released)
|
||||
* mixer
|
||||
- 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)
|
||||
* database
|
||||
- upnp: adapt to libupnp 1.8 API changes
|
||||
|
@ -79,12 +79,20 @@ struct MusicChunk {
|
||||
*/
|
||||
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
|
||||
* changed since the last chunk. The magic value 0 indicates
|
||||
* that there is no replay gain info available.
|
||||
*/
|
||||
unsigned replay_gain_serial = 0;
|
||||
unsigned replay_gain_serial;
|
||||
|
||||
/** the data (probably PCM) */
|
||||
uint8_t data[CHUNK_SIZE];
|
||||
|
@ -106,7 +106,7 @@ Directory::PruneEmpty() noexcept
|
||||
child != end;) {
|
||||
child->PruneEmpty();
|
||||
|
||||
if (child->IsEmpty())
|
||||
if (child->IsEmpty() && !child->IsMount())
|
||||
child = children.erase_and_dispose(child,
|
||||
DeleteDisposer());
|
||||
else
|
||||
|
@ -130,7 +130,6 @@ public:
|
||||
*
|
||||
* @param name_utf8 the UTF-8 encoded name of the new sub directory
|
||||
*/
|
||||
gcc_malloc
|
||||
Directory *CreateChild(const char *name_utf8);
|
||||
|
||||
/**
|
||||
|
@ -104,7 +104,7 @@ inline void
|
||||
UpdateWalk::PurgeDeletedFromDirectory(Directory &directory)
|
||||
{
|
||||
directory.ForEachChildSafe([&](Directory &child){
|
||||
if (DirectoryExists(storage, child))
|
||||
if (child.IsMount() || DirectoryExists(storage, child))
|
||||
return;
|
||||
|
||||
editor.LockDeleteDirectory(&child);
|
||||
|
@ -23,12 +23,15 @@
|
||||
#include <upnp/upnp.h>
|
||||
|
||||
#if UPNP_VERSION < 10800
|
||||
#include "Compiler.h"
|
||||
|
||||
/* emulate the libupnp 1.8 API with older versions */
|
||||
|
||||
using UpnpDiscovery = Upnp_Discovery;
|
||||
|
||||
#endif
|
||||
|
||||
#if UPNP_VERSION < 10624
|
||||
#include "Compiler.h"
|
||||
|
||||
gcc_pure
|
||||
static inline int
|
||||
UpnpDiscovery_get_Expires(const UpnpDiscovery *disco) noexcept
|
||||
|
@ -142,7 +142,8 @@ AudioOutputSource::GetChunkData(const MusicChunk &chunk,
|
||||
replay_gain_filter_set_mode(*replay_gain_filter,
|
||||
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,
|
||||
chunk.replay_gain_serial != 0
|
||||
? &chunk.replay_gain_info
|
||||
|
@ -556,8 +556,10 @@ Player::SendSilence()
|
||||
partial frames */
|
||||
unsigned num_frames = sizeof(chunk->data) / frame_size;
|
||||
|
||||
chunk->bit_rate = 0;
|
||||
chunk->time = SignedSongTime::Negative(); /* undefined time stamp */
|
||||
chunk->length = num_frames * frame_size;
|
||||
chunk->replay_gain_serial = MusicChunk::IGNORE_REPLAY_GAIN;
|
||||
PcmSilence({chunk->data, chunk->length}, play_audio_format.format);
|
||||
|
||||
try {
|
||||
|
@ -75,8 +75,7 @@ playlist::MoveOrderToCurrent(unsigned old_order)
|
||||
} else {
|
||||
/* not playing anything: move the specified song to
|
||||
the front */
|
||||
queue.SwapOrders(old_order, 0);
|
||||
return 0;
|
||||
return queue.MoveOrderBefore(old_order, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ playlist::AppendSong(PlayerControl &pc, DetachedSong &&song)
|
||||
else
|
||||
start = current + 1;
|
||||
if (start < queue.GetLength())
|
||||
queue.ShuffleOrderLast(start, queue.GetLength());
|
||||
queue.ShuffleOrderLastWithPriority(start, queue.GetLength());
|
||||
}
|
||||
|
||||
UpdateQueuedSong(pc, queued_song);
|
||||
|
@ -359,8 +359,20 @@ Queue::ShuffleOrderFirst(unsigned start, unsigned end) noexcept
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
std::uniform_int_distribution<unsigned> distribution(start, end - 1);
|
||||
|
@ -357,11 +357,12 @@ struct Queue {
|
||||
void ShuffleOrderFirst(unsigned start, unsigned end) noexcept;
|
||||
|
||||
/**
|
||||
* Shuffles the virtual order of the last song in the specified
|
||||
* (order) range. This is used in random mode after a song has been
|
||||
* appended by queue_append().
|
||||
* Shuffles the virtual order of the last song in the
|
||||
* specified (order) range; only songs which match this song's
|
||||
* 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
|
||||
|
Loading…
Reference in New Issue
Block a user