Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature multiple loudness metadata squash tests #110

Merged
merged 9 commits into from
Jun 29, 2021
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
- fixed erroneous test acceptance data
- updated required C++ standard from C++11 to C++14
- implemented fractional time format from BS.2076-2
- audioProgramme and audioContent may now have multiple loudnessMetadata elements, as per BS.2076-2

### Fixed
- updateBlockFormatDurations now throws an exception when given an audioChannelFormat with no audioBlockFormats, rather than segfaulting
Expand Down
18 changes: 14 additions & 4 deletions include/adm/detail/auto_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,11 @@ namespace adm {
boost::optional<T> value_;
};

template <typename T>
struct ParameterCompare {
static bool compare(T const& lhs, T const& rhs) { return lhs == rhs; }
};

/// base class for storage of multiple elements in a std::vector.
/// T should be a std::vector<Something>, as this is what the tag is
/// associated with.
Expand All @@ -206,11 +211,11 @@ namespace adm {
ADM_BASE_EXPORT T get(Tag) const { return value_; }
ADM_BASE_EXPORT void set(T value) { value_ = value; }
ADM_BASE_EXPORT bool has(Tag) const { return value_.size() > 0; }
ADM_BASE_EXPORT bool isDefault(Tag) const { return value_.size() == 0; }
ADM_BASE_EXPORT bool isDefault(Tag) const { return false; }
ADM_BASE_EXPORT void unset(Tag) { value_.clear(); }

ADM_BASE_EXPORT bool add(Value item) {
auto it = std::find(value_.begin(), value_.end(), item);
auto it = find_item(item);
if (it == value_.end()) {
value_.push_back(item);
return true;
Expand All @@ -220,13 +225,18 @@ namespace adm {
}

ADM_BASE_EXPORT void remove(Value item) {
auto it = std::find(value_.begin(), value_.end(), item);
auto it = find_item(item);
if (it != value_.end()) value_.erase(it);
}

private:
T value_;
ADM_BASE_EXPORT typename T::iterator find_item(Value const& item) {
return std::find_if(
value_.begin(), value_.end(), [&item, this](Value const& val) {
return ParameterCompare<Value>::compare(item, val);
});
}
};

} // namespace detail
} // namespace adm
40 changes: 40 additions & 0 deletions include/adm/detail/optional_comparison.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#pragma once
namespace adm {
namespace detail {
namespace comparison {
template <typename ParameterT, typename ElementT>
bool compareOptionalParameter(ElementT const& lhs, ElementT const& rhs) {
// if one has the parameter and the other doesn't they're not equal
if (lhs.template has<ParameterT>() != rhs.template has<ParameterT>()) {
return false;
}
// either both have it or neither does. If neither, they're equal.
if (!lhs.template has<ParameterT>()) {
return true;
}
// otherwise both have the parameter, so compare.
return lhs.template get<ParameterT>() == rhs.template get<ParameterT>();
}

template <typename FirstParam, typename... Params>
struct OptionalComparator {
template <typename ElementT>
static bool compareAll(ElementT const& lhs, ElementT const& rhs) {
return (compareOptionalParameter<FirstParam>(lhs, rhs) &&
OptionalComparator<Params...>::compareAll(lhs, rhs));
}
};
template <typename FirstParam>
struct OptionalComparator<FirstParam> {
template <typename ElementT>
static bool compareAll(ElementT const& lhs, ElementT const& rhs) {
return compareOptionalParameter<FirstParam>(lhs, rhs);
}
};
} // namespace comparison
template <typename... Params, typename ElementT>
bool compareOptionals(ElementT const& lhs, ElementT const& rhs) {
return comparison::OptionalComparator<Params...>::compareAll(lhs, rhs);
}
} // namespace detail
} // namespace adm
34 changes: 23 additions & 11 deletions include/adm/elements/audio_content.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "adm/helper/element_range.hpp"
#include "adm/detail/named_option_helper.hpp"
#include "adm/export.h"
#include "adm/detail/auto_base.hpp"

namespace adm {

Expand All @@ -30,12 +31,18 @@ namespace adm {

/// @brief Tag for AudioContent
struct AudioContentTag {};

namespace detail {
using AudioContentBase = HasParameters<VectorParameter<LoudnessMetadatas>>;
} // namespace detail

/**
* @brief Class representation of the audioContent ADM element
*
* @headerfile audio_content.hpp <adm/elements/audio_content.hpp>
*/
class AudioContent : public std::enable_shared_from_this<AudioContent> {
class AudioContent : public std::enable_shared_from_this<AudioContent>,
private detail::AudioContentBase {
public:
typedef AudioContentTag tag;
/// Type that holds the id for this element;
Expand Down Expand Up @@ -101,8 +108,6 @@ namespace adm {
ADM_EXPORT void set(AudioContentName name);
/// @brief AudioContentLanguage setter
ADM_EXPORT void set(AudioContentLanguage language);
/// @brief LoudnessMetadata setter
ADM_EXPORT void set(LoudnessMetadata loudnessMetadata);
///@{

/**
Expand Down Expand Up @@ -180,26 +185,33 @@ namespace adm {
/**
* @brief Print overview to ostream
*/
ADM_EXPORT void print(std::ostream &os) const;
ADM_EXPORT void print(std::ostream& os) const;

/// Get adm::Document this element belongs to
ADM_EXPORT std::weak_ptr<Document> getParent() const;

using detail::AudioContentBase::add;
using detail::AudioContentBase::remove;
using detail::AudioContentBase::set;

private:
friend class AudioContentAttorney;

ADM_EXPORT AudioContent(AudioContentName name);
ADM_EXPORT AudioContent(const AudioContent &) = default;
ADM_EXPORT AudioContent(AudioContent &&) = default;
ADM_EXPORT AudioContent(const AudioContent&) = default;
ADM_EXPORT AudioContent(AudioContent&&) = default;

using detail::AudioContentBase::get;
using detail::AudioContentBase::has;
using detail::AudioContentBase::isDefault;
using detail::AudioContentBase::unset;

ADM_EXPORT AudioContentId
get(detail::ParameterTraits<AudioContentId>::tag) const;
ADM_EXPORT AudioContentName
get(detail::ParameterTraits<AudioContentName>::tag) const;
ADM_EXPORT AudioContentLanguage
get(detail::ParameterTraits<AudioContentLanguage>::tag) const;
ADM_EXPORT LoudnessMetadata
get(detail::ParameterTraits<LoudnessMetadata>::tag) const;
ADM_EXPORT DialogueId get(detail::ParameterTraits<DialogueId>::tag) const;
ADM_EXPORT ContentKind get(detail::ParameterTraits<ContentKind>::tag) const;
ADM_EXPORT NonDialogueContentKind
Expand All @@ -213,7 +225,6 @@ namespace adm {
ADM_EXPORT bool has(detail::ParameterTraits<AudioContentName>::tag) const;
ADM_EXPORT bool has(
detail::ParameterTraits<AudioContentLanguage>::tag) const;
ADM_EXPORT bool has(detail::ParameterTraits<LoudnessMetadata>::tag) const;
ADM_EXPORT bool has(detail::ParameterTraits<DialogueId>::tag) const;
ADM_EXPORT bool has(detail::ParameterTraits<ContentKind>::tag) const;
ADM_EXPORT bool has(
Expand All @@ -228,7 +239,6 @@ namespace adm {
}

ADM_EXPORT void unset(detail::ParameterTraits<AudioContentLanguage>::tag);
ADM_EXPORT void unset(detail::ParameterTraits<LoudnessMetadata>::tag);
ADM_EXPORT void unset(detail::ParameterTraits<DialogueId>::tag);
ADM_EXPORT void unset(detail::ParameterTraits<ContentKind>::tag);
ADM_EXPORT void unset(detail::ParameterTraits<NonDialogueContentKind>::tag);
Expand All @@ -252,13 +262,15 @@ namespace adm {
AudioContentName name_;
boost::optional<AudioContentLanguage> language_;
std::vector<std::shared_ptr<AudioObject>> audioObjects_;
boost::optional<LoudnessMetadata> loudnessMetadata_;
boost::optional<DialogueId> dialogueId_;
boost::optional<NonDialogueContentKind> nonDialogueContentKind_;
boost::optional<DialogueContentKind> dialogueContentKind_;
boost::optional<MixedContentKind> mixedContentKind_;
};

ADM_EXPORT std::ostream& operator<<(
std::ostream& stream, const LoudnessMetadatas& loudnessMetaDatas);

// ---- Implementation ---- //

template <typename... Parameters>
Expand Down
26 changes: 18 additions & 8 deletions include/adm/elements/audio_programme.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "adm/detail/named_option_helper.hpp"
#include "adm/detail/named_type.hpp"
#include "adm/export.h"
#include "adm/detail/auto_base.hpp"

namespace adm {

Expand Down Expand Up @@ -42,6 +43,12 @@ namespace adm {

/// @brief Tag for AudioProgramme
struct AudioProgrammeTag {};

namespace detail {
using AudioProgrammeBase =
HasParameters<VectorParameter<LoudnessMetadatas>>;
} // namespace detail

/**
* @brief Class representation of the audioProgramme ADM element
*
Expand All @@ -50,7 +57,8 @@ namespace adm {
*
* @headerfile audio_programme.hpp <adm/elements/audio_programme.hpp>
*/
class AudioProgramme : public std::enable_shared_from_this<AudioProgramme> {
class AudioProgramme : public std::enable_shared_from_this<AudioProgramme>,
private detail::AudioProgrammeBase {
public:
typedef AudioProgrammeTag tag;
/// @brief Type that holds the id for this element;
Expand Down Expand Up @@ -116,8 +124,6 @@ namespace adm {
ADM_EXPORT void set(Start start);
/// @brief End setter
ADM_EXPORT void set(End end);
/// @brief LoudnessMetadata setter
ADM_EXPORT void set(LoudnessMetadata loudnessMetadata);
/// @brief MaxDuckingDepth setter
ADM_EXPORT void set(MaxDuckingDepth depth);
/// @brief AudioProgrammeReferenceScreen setter
Expand Down Expand Up @@ -177,13 +183,22 @@ namespace adm {
/// Get adm::Document this element belongs to
ADM_EXPORT std::weak_ptr<Document> getParent() const;

using detail::AudioProgrammeBase::add;
using detail::AudioProgrammeBase::remove;
using detail::AudioProgrammeBase::set;

private:
friend class AudioProgrammeAttorney;

ADM_EXPORT AudioProgramme(AudioProgrammeName name);
ADM_EXPORT AudioProgramme(const AudioProgramme &) = default;
ADM_EXPORT AudioProgramme(AudioProgramme &&) = default;

using detail::AudioProgrammeBase::get;
using detail::AudioProgrammeBase::has;
using detail::AudioProgrammeBase::isDefault;
using detail::AudioProgrammeBase::unset;

ADM_EXPORT AudioProgrammeId
get(detail::ParameterTraits<AudioProgrammeId>::tag) const;
ADM_EXPORT AudioProgrammeName
Expand All @@ -192,8 +207,6 @@ namespace adm {
get(detail::ParameterTraits<AudioProgrammeLanguage>::tag) const;
ADM_EXPORT Start get(detail::ParameterTraits<Start>::tag) const;
ADM_EXPORT End get(detail::ParameterTraits<End>::tag) const;
ADM_EXPORT LoudnessMetadata
get(detail::ParameterTraits<LoudnessMetadata>::tag) const;
ADM_EXPORT MaxDuckingDepth
get(detail::ParameterTraits<MaxDuckingDepth>::tag) const;
ADM_EXPORT AudioProgrammeReferenceScreen
Expand All @@ -205,7 +218,6 @@ namespace adm {
detail::ParameterTraits<AudioProgrammeLanguage>::tag) const;
ADM_EXPORT bool has(detail::ParameterTraits<Start>::tag) const;
ADM_EXPORT bool has(detail::ParameterTraits<End>::tag) const;
ADM_EXPORT bool has(detail::ParameterTraits<LoudnessMetadata>::tag) const;
ADM_EXPORT bool has(detail::ParameterTraits<MaxDuckingDepth>::tag) const;
ADM_EXPORT bool has(
detail::ParameterTraits<AudioProgrammeReferenceScreen>::tag) const;
Expand All @@ -220,7 +232,6 @@ namespace adm {
ADM_EXPORT void unset(detail::ParameterTraits<AudioProgrammeLanguage>::tag);
ADM_EXPORT void unset(detail::ParameterTraits<Start>::tag);
ADM_EXPORT void unset(detail::ParameterTraits<End>::tag);
ADM_EXPORT void unset(detail::ParameterTraits<LoudnessMetadata>::tag);
ADM_EXPORT void unset(detail::ParameterTraits<MaxDuckingDepth>::tag);
ADM_EXPORT void unset(
detail::ParameterTraits<AudioProgrammeReferenceScreen>::tag);
Expand All @@ -244,7 +255,6 @@ namespace adm {
boost::optional<Start> start_;
boost::optional<End> end_;
std::vector<std::shared_ptr<AudioContent>> audioContents_;
boost::optional<LoudnessMetadata> loudnessMetadata_;
boost::optional<MaxDuckingDepth> maxDuckingDepth_;
boost::optional<AudioProgrammeReferenceScreen> refScreen_;
};
Expand Down
26 changes: 24 additions & 2 deletions include/adm/elements/loudness_metadata.hpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
#pragma once
#include "adm/detail/named_option_helper.hpp"
#include "adm/detail/named_type.hpp"
#include "adm/detail/auto_base.hpp"
#include "adm/detail/optional_comparison.hpp"
#include "adm/export.h"
#include <boost/optional.hpp>
#include <string>
#include <ostream>
#include <vector>

namespace adm {

Expand Down Expand Up @@ -50,6 +53,14 @@ namespace adm {
/// @brief Tag for LoudnessMetadata class
struct LoudnessMetadataTag {};

using LoudnessMetadatas = std::vector<LoudnessMetadata>;
ADD_TRAIT(LoudnessMetadatas, LoudnessMetadatasTag);

namespace detail {
extern template class ADM_EXPORT_TEMPLATE_METHODS
VectorParameter<LoudnessMetadatas>;
}

class LoudnessMetadata {
public:
typedef LoudnessMetadataTag tag;
Expand All @@ -61,7 +72,7 @@ namespace adm {
* in random order after the mandatory ADM parameters.
*/
template <typename... Parameters>
LoudnessMetadata(Parameters... optionalNamedArgs);
explicit LoudnessMetadata(Parameters... optionalNamedArgs);

/**
* @brief ADM parameter getter template
Expand Down Expand Up @@ -123,7 +134,7 @@ namespace adm {
/**
* @brief Print overview to ostream
*/
ADM_EXPORT void print(std::ostream &os) const;
ADM_EXPORT void print(std::ostream& os) const;

private:
ADM_EXPORT LoudnessMethod
Expand Down Expand Up @@ -212,4 +223,15 @@ namespace adm {
typedef typename detail::ParameterTraits<Parameter>::tag Tag;
return unset(Tag());
}

namespace detail {
template <>
struct ParameterCompare<LoudnessMetadata> {
static bool compare(LoudnessMetadata const& lhs,
LoudnessMetadata const& rhs) {
return compareOptionals<LoudnessRecType, LoudnessMethod,
LoudnessCorrectionType>(lhs, rhs);
}
};
} // namespace detail
} // namespace adm
2 changes: 2 additions & 0 deletions include/adm/private/rapidxml_formatter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ namespace adm {
XmlNode &node, const std::shared_ptr<const AudioProgramme> programme);
void formatLoudnessMetadata(XmlNode &node,
const LoudnessMetadata loudnessMetadata);
void formatLoudnessMetadatas(XmlNode &node, const std::string &name,
const LoudnessMetadatas &loudnessMetadatas);
void formatNonDialogueContentKind(XmlNode &node,
const NonDialogueContentKind contentKind);
void formatDialogueContentKind(XmlNode &node,
Expand Down
1 change: 1 addition & 0 deletions include/adm/private/xml_parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ namespace adm {
SphericalPosition parseSphericalPosition(std::vector<NodePtr> nodes);
CartesianPosition parseCartesianPosition(std::vector<NodePtr> nodes);
LoudnessMetadata parseLoudnessMetadata(NodePtr node);
LoudnessMetadatas parseLoudnessMetadatas(const std::vector<NodePtr>& nodes);
AudioProgrammeReferenceScreen parseAudioProgrammeReferenceScreen(
NodePtr node);
AudioBlockFormatObjects parseAudioBlockFormatObjects(NodePtr node);
Expand Down
Loading