Merge branch 'v0.21.x'
This commit is contained in:
@@ -208,10 +208,12 @@ MPDOpusDecoder::HandleTags(const ogg_packet &packet)
|
||||
TagBuilder tag_builder;
|
||||
AddTagHandler h(tag_builder);
|
||||
|
||||
if (ScanOpusTags(packet.packet, packet.bytes, &rgi, h) &&
|
||||
!tag_builder.empty()) {
|
||||
client.SubmitReplayGain(&rgi);
|
||||
if (!ScanOpusTags(packet.packet, packet.bytes, &rgi, h))
|
||||
return;
|
||||
|
||||
client.SubmitReplayGain(&rgi);
|
||||
|
||||
if (!tag_builder.empty()) {
|
||||
Tag tag = tag_builder.Commit();
|
||||
auto cmd = client.SubmitTag(input_stream, std::move(tag));
|
||||
if (cmd != DecoderCommand::NONE)
|
||||
|
@@ -581,8 +581,8 @@ PulseOutput::SetupStream(const pa_sample_spec &ss)
|
||||
|
||||
/* WAVE-EX is been adopted as the speaker map for most media files */
|
||||
pa_channel_map chan_map;
|
||||
pa_channel_map_init_auto(&chan_map, ss.channels,
|
||||
PA_CHANNEL_MAP_WAVEEX);
|
||||
pa_channel_map_init_extend(&chan_map, ss.channels,
|
||||
PA_CHANNEL_MAP_WAVEEX);
|
||||
stream = pa_stream_new(context, name, &ss, &chan_map);
|
||||
if (stream == nullptr)
|
||||
throw MakePulseError(context,
|
||||
|
@@ -22,13 +22,10 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
inline bool
|
||||
bool
|
||||
StringFilter::MatchWithoutNegation(const char *s) const noexcept
|
||||
{
|
||||
#if !CLANG_CHECK_VERSION(3,6)
|
||||
/* disabled on clang due to -Wtautological-pointer-compare */
|
||||
assert(s != nullptr);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PCRE
|
||||
if (regex)
|
||||
|
@@ -105,7 +105,9 @@ public:
|
||||
gcc_pure
|
||||
bool Match(const char *s) const noexcept;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Like Match(), but ignore the "negated" flag.
|
||||
*/
|
||||
gcc_pure
|
||||
bool MatchWithoutNegation(const char *s) const noexcept;
|
||||
};
|
||||
|
@@ -35,42 +35,41 @@ TagSongFilter::ToExpression() const noexcept
|
||||
}
|
||||
|
||||
bool
|
||||
TagSongFilter::MatchNN(const TagItem &item) const noexcept
|
||||
{
|
||||
return (type == TAG_NUM_OF_ITEM_TYPES || item.type == type) &&
|
||||
filter.Match(item.value);
|
||||
}
|
||||
|
||||
bool
|
||||
TagSongFilter::MatchNN(const Tag &tag) const noexcept
|
||||
TagSongFilter::Match(const Tag &tag) const noexcept
|
||||
{
|
||||
bool visited_types[TAG_NUM_OF_ITEM_TYPES]{};
|
||||
|
||||
for (const auto &i : tag) {
|
||||
visited_types[i.type] = true;
|
||||
|
||||
if (MatchNN(i))
|
||||
return true;
|
||||
if ((type == TAG_NUM_OF_ITEM_TYPES || i.type == type) &&
|
||||
filter.MatchWithoutNegation(i.value))
|
||||
return !filter.IsNegated();
|
||||
}
|
||||
|
||||
if (type < TAG_NUM_OF_ITEM_TYPES && !visited_types[type]) {
|
||||
/* if the specified tag is not present, try the
|
||||
fallback tags */
|
||||
|
||||
bool result = false;
|
||||
if (ApplyTagFallback(type,
|
||||
[&](TagType tag2) {
|
||||
if (!visited_types[tag2])
|
||||
return false;
|
||||
if (ApplyTagFallback(type, [&](TagType tag2) {
|
||||
if (!visited_types[tag2])
|
||||
/* we already know that this tag type
|
||||
isn't present, so let's bail out
|
||||
without checking again */
|
||||
return false;
|
||||
|
||||
for (const auto &item : tag) {
|
||||
if (item.type == tag2 &&
|
||||
filter.Match(item.value)) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (const auto &item : tag) {
|
||||
if (item.type == tag2 &&
|
||||
filter.MatchWithoutNegation(item.value)) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}))
|
||||
return result;
|
||||
return true;
|
||||
}))
|
||||
return result != filter.IsNegated();
|
||||
|
||||
/* If the search critieron was not visited during the
|
||||
sweep through the song's tag, it means this field
|
||||
@@ -79,14 +78,14 @@ TagSongFilter::MatchNN(const Tag &tag) const noexcept
|
||||
then it's a match as well and we should return
|
||||
true. */
|
||||
if (filter.empty())
|
||||
return true;
|
||||
return !filter.IsNegated();
|
||||
}
|
||||
|
||||
return false;
|
||||
return filter.IsNegated();
|
||||
}
|
||||
|
||||
bool
|
||||
TagSongFilter::Match(const LightSong &song) const noexcept
|
||||
{
|
||||
return MatchNN(song.tag);
|
||||
return Match(song.tag);
|
||||
}
|
||||
|
@@ -68,8 +68,7 @@ public:
|
||||
bool Match(const LightSong &song) const noexcept override;
|
||||
|
||||
private:
|
||||
bool MatchNN(const Tag &tag) const noexcept;
|
||||
bool MatchNN(const TagItem &tag) const noexcept;
|
||||
bool Match(const Tag &tag) const noexcept;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -22,6 +22,11 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
/**
|
||||
* Invoke the given function for all fallback tags of the given
|
||||
* #TagType, until the function returns true (or until there are no
|
||||
* more fallback tags).
|
||||
*/
|
||||
template<typename F>
|
||||
bool
|
||||
ApplyTagFallback(TagType type, F &&f) noexcept
|
||||
@@ -43,6 +48,11 @@ ApplyTagFallback(TagType type, F &&f) noexcept
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the given function for the given #TagType and all of its
|
||||
* fallback tags, until the function returns true (or until there are
|
||||
* no more fallback tags).
|
||||
*/
|
||||
template<typename F>
|
||||
bool
|
||||
ApplyTagWithFallback(TagType type, F &&f) noexcept
|
||||
|
Reference in New Issue
Block a user