diff options
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | doc/protocol.xml | 7 | ||||
-rw-r--r-- | src/song/AudioFormatSongFilter.cxx | 36 | ||||
-rw-r--r-- | src/song/AudioFormatSongFilter.hxx | 43 | ||||
-rw-r--r-- | src/song/Filter.cxx | 21 |
5 files changed, 109 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am index 38d386fc1..fc735d7ef 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1036,6 +1036,7 @@ libsong_a_SOURCES = \ src/song/BaseSongFilter.cxx src/song/BaseSongFilter.hxx \ src/song/TagSongFilter.cxx src/song/TagSongFilter.hxx \ src/song/ModifiedSinceSongFilter.cxx src/song/ModifiedSinceSongFilter.hxx \ + src/song/AudioFormatSongFilter.cxx src/song/AudioFormatSongFilter.hxx \ src/song/AndSongFilter.cxx src/song/AndSongFilter.hxx \ src/song/Filter.cxx src/song/Filter.hxx \ src/song/LightSong.cxx src/song/LightSong.hxx @@ -1932,6 +1933,7 @@ endif test_ParseSongFilter_LDADD = \ libsong.a \ + libpcm.a \ $(TAG_LIBS) \ $(ICU_LDADD) \ libutil.a diff --git a/doc/protocol.xml b/doc/protocol.xml index 0b49cedab..86534db74 100644 --- a/doc/protocol.xml +++ b/doc/protocol.xml @@ -271,6 +271,13 @@ <listitem> <para> + "<code>(AudioFormat == 'SAMPLERATE:BITS:CHANNELS')</code>": + compares the audio format with the given value. + </para> + </listitem> + + <listitem> + <para> "<code>EXPRESSION1 AND EXPRESSION2 ...</code>": combine two or more expressions with logical "and". </para> diff --git a/src/song/AudioFormatSongFilter.cxx b/src/song/AudioFormatSongFilter.cxx new file mode 100644 index 000000000..6ea8dd250 --- /dev/null +++ b/src/song/AudioFormatSongFilter.cxx @@ -0,0 +1,36 @@ +/* + * Copyright 2003-2018 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "AudioFormatSongFilter.hxx" +#include "LightSong.hxx" +#include "util/StringBuffer.hxx" + +std::string +AudioFormatSongFilter::ToExpression() const noexcept +{ + // TODO: support mask + return std::string("(AudioFormat == \"") + ToString(value).c_str() + "\")"; +} + +bool +AudioFormatSongFilter::Match(const LightSong &song) const noexcept +{ + // TODO: support mask + return song.audio_format == value; +} diff --git a/src/song/AudioFormatSongFilter.hxx b/src/song/AudioFormatSongFilter.hxx new file mode 100644 index 000000000..36d5591c0 --- /dev/null +++ b/src/song/AudioFormatSongFilter.hxx @@ -0,0 +1,43 @@ +/* + * Copyright 2003-2018 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_AUDIO_FORMAT_SONG_FILTER_HXX +#define MPD_AUDIO_FORMAT_SONG_FILTER_HXX + +#include "ISongFilter.hxx" +#include "AudioFormat.hxx" + +class AudioFormatSongFilter final : public ISongFilter { + AudioFormat value; + +public: + explicit AudioFormatSongFilter(const AudioFormat &_value) noexcept + :value(_value) {} + + + /* virtual methods from ISongFilter */ + ISongFilterPtr Clone() const noexcept override { + return std::make_unique<AudioFormatSongFilter>(*this); + } + + std::string ToExpression() const noexcept override; + bool Match(const LightSong &song) const noexcept override; +}; + +#endif diff --git a/src/song/Filter.cxx b/src/song/Filter.cxx index 66616fc93..e9d978dd5 100644 --- a/src/song/Filter.cxx +++ b/src/song/Filter.cxx @@ -23,7 +23,9 @@ #include "BaseSongFilter.hxx" #include "TagSongFilter.hxx" #include "ModifiedSinceSongFilter.hxx" +#include "AudioFormatSongFilter.hxx" #include "LightSong.hxx" +#include "AudioParser.hxx" #include "tag/ParseName.hxx" #include "tag/Tag.hxx" #include "util/CharUtil.hxx" @@ -55,6 +57,7 @@ enum { LOCATE_TAG_BASE_TYPE = TAG_NUM_OF_ITEM_TYPES + 1, LOCATE_TAG_MODIFIED_SINCE, + LOCATE_TAG_AUDIO_FORMAT, LOCATE_TAG_FILE_TYPE, LOCATE_TAG_ANY_TYPE, }; @@ -79,6 +82,9 @@ locate_parse_type(const char *str) noexcept if (strcmp(str, "modified-since") == 0) return LOCATE_TAG_MODIFIED_SINCE; + if (StringEqualsCaseASCII(str, "AudioFormat")) + return LOCATE_TAG_AUDIO_FORMAT; + return tag_name_parse_i(str); } @@ -223,6 +229,21 @@ SongFilter::ParseExpression(const char *&s, bool fold_case) s = StripLeft(s + 1); return std::make_unique<BaseSongFilter>(std::move(value)); + } else if (type == LOCATE_TAG_AUDIO_FORMAT) { + if (s[0] != '=' || s[1] != '=') + throw std::runtime_error("'==' expected"); + + s = StripLeft(s + 2); + + // TODO: support mask + const auto value = ParseAudioFormat(ExpectQuoted(s).c_str(), + false); + + if (*s != ')') + throw std::runtime_error("')' expected"); + s = StripLeft(s + 1); + + return std::make_unique<AudioFormatSongFilter>(value); } else { bool negated = false; if (s[0] == '!' && s[1] == '=') |