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
|
* 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
|
||||||
|
@ -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];
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user