├── docs ├── changelog.rst ├── irt_logo.png ├── reference_read_write.rst ├── reference_document.rst ├── reference_helpers.rst ├── update_deps.sh ├── requirements.txt ├── Doxyfile ├── reference_utilities.rst ├── index.rst └── reference_sadm_elements.rst ├── .clang_complete ├── .readthedocs.yml ├── submodules ├── catch2 │ └── catch_main.cpp ├── rapidxml.cmake └── catch2.cmake ├── .gitignore ├── .clang-format ├── include └── adm │ ├── adm.hpp │ ├── elements │ ├── head_locked.hpp │ ├── screen_ref.hpp │ ├── nfc_ref_dist.hpp │ ├── normalization.hpp │ ├── importance.hpp │ ├── audio_programme_ref_screen.hpp │ ├── private │ │ └── auto_parent.hpp │ ├── format_descriptor.hpp │ ├── gain.hpp │ ├── type_descriptor.hpp │ └── position_offset_types.hpp │ ├── utilities │ ├── element_io.hpp │ ├── copy.hpp │ ├── time_conversion.hpp │ └── lookup.hpp │ ├── serial.hpp │ ├── private │ ├── rapidxml_utils.hpp │ └── xml_writer.hpp │ ├── helper │ └── get_optional_property.hpp │ ├── detail │ ├── type_traits.hpp │ ├── named_option_helper.hpp │ ├── auto_base_detail.hpp │ ├── print_helper.hpp │ └── id_assigner.hpp │ ├── elements_fwd.hpp │ └── serial │ └── frame_header_parser.hpp ├── tests ├── test_data │ ├── xml_parser │ │ ├── find_audio_format_extended_itu.xml │ │ ├── find_audio_format_extended_ebu.xml │ │ ├── version.xml │ │ ├── audio_track_uid.xml │ │ ├── audio_pack_format.xml │ │ ├── audio_track_format.xml │ │ ├── audio_stream_format.xml │ │ ├── unresolved_references │ │ │ ├── audio_track_uid_1.xml │ │ │ ├── audio_track_uid_2.xml │ │ │ ├── audio_object_1.xml │ │ │ ├── audio_content.xml │ │ │ ├── audio_object_3.xml │ │ │ ├── audio_object_2.xml │ │ │ ├── audio_programme.xml │ │ │ ├── audio_pack_format_1.xml │ │ │ ├── audio_pack_format_2.xml │ │ │ ├── audio_stream_format_2.xml │ │ │ ├── audio_track_format.xml │ │ │ └── audio_stream_format_1.xml │ │ ├── audio_track_uid_duplicate_id.xml │ │ ├── audio_object_duplicate_id.xml │ │ ├── audio_pack_format_hoa.xml │ │ ├── audio_programme_duplicate_id.xml │ │ ├── audio_channel_format.xml │ │ ├── profile_list.xml │ │ ├── audio_content_duplicate_id.xml │ │ ├── audio_pack_format_duplicate_id.xml │ │ ├── audio_track_format_duplicate_id.xml │ │ ├── audio_stream_format_duplicate_id.xml │ │ ├── audio_content.xml │ │ ├── audio_track_uid_track_format_reference.xml │ │ ├── audio_track_uid_channel_format_reference.xml │ │ ├── audio_programme.xml │ │ ├── with_common_definitions.xml │ │ ├── find_audio_format_extended_ebu_with_other_metadata.xml │ │ ├── audio_object_complementary_audio_objects.xml │ │ ├── audio_block_format_direct_speakers_cartesian_bad_coord.xml │ │ ├── audio_object.xml │ │ ├── audio_channel_format_duplicate_id.xml │ │ ├── audio_object_track_refs.xml │ │ ├── audio_block_format_direct_speakers_cartesian_bad_bound.xml │ │ ├── audio_block_format_objects_gain_unit_error.xml │ │ ├── audio_block_format_binaural.xml │ │ ├── audio_block_format_direct_speakers.xml │ │ ├── audio_block_format_direct_speakers_cartesian.xml │ │ ├── audio_object_position_offset.xml │ │ ├── audio_block_format_hoa.xml │ │ ├── time_format_sadm.xml │ │ ├── time_format.xml │ │ └── audio_object_interaction.xml │ ├── version.accepted.xml │ ├── profile_list_frame_header.accepted.xml │ ├── write_objects_silent_track_ref.accepted.xml │ ├── profile_list.accepted.xml │ ├── write_default_binaural_block.accepted.xml │ ├── write_complementary_audio_objects.accepted.xml │ ├── write_specified_binaural_block_sadm.accepted.xml │ ├── write_default_HOA_block.accepted.xml │ ├── write_audio_content.accepted.xml │ ├── write_object_attributes.accepted.xml │ ├── write_audio_programme.accepted.xml │ ├── write_total_time_reference.accepted.xml │ ├── write_local_time_reference.accepted.xml │ ├── write_default_cartesian_speaker.accepted.xml │ ├── write_specified_binaural_block.accepted.xml │ ├── write_default_spherical_speaker.accepted.xml │ ├── write_partially_specified_spherical.accepted.xml │ ├── write_partially_specified_cartesian.accepted.xml │ ├── write_specified_HOA_block.accepted.xml │ ├── write_objects_with_position_offset.accepted.xml │ ├── write_audio_track_uid_channel_format_reference.accepted.xml │ ├── write_simple_object_short_structure.accepted.xml │ ├── write_specified_cartesian_speaker.accepted.xml │ ├── write_time_format.accepted.xml │ ├── write_time_format_sadm.accepted.xml │ ├── write_specified_spherical_speaker.accepted.xml │ ├── write_labels.accepted.xml │ ├── write_simple_object.accepted.xml │ ├── write_specified_headphone_virtualise.accepted.xml │ ├── write_simple_common_definitions_object.accepted.xml │ └── write_audio_object_interaction.accepted.xml ├── xml_parser_common_definitions_tests.cpp ├── label_tests.cpp ├── xml_parser_find_audio_format_extended_tests.cpp ├── version_tests.cpp ├── frame_header_parser_frame_format_tests.cpp ├── xml_parser_unresolved_references_tests.cpp ├── format_descriptor_tests.cpp ├── xml_parser_audio_block_format_binaural_tests.cpp ├── gain_tests.cpp ├── gain_interaction_range_tests.cpp ├── xml_writer_audio_content_tests.cpp ├── channel_lock_tests.cpp ├── headphone_virtualise_tests.cpp ├── xml_parser_audio_stream_format_tests.cpp ├── xml_writer_audio_programme_tests.cpp ├── xml_parser_audio_track_format_tests.cpp ├── xml_parser_audio_channel_format_tests.cpp ├── audio_block_format_matrix_tests.cpp ├── object_creation_tests.cpp ├── frequency_tests.cpp ├── audio_block_format_binaural_tests.cpp ├── xml_parser_tests.cpp ├── jump_position_tests.cpp ├── xml_parser_audio_content_tests.cpp ├── xml_writer_audio_track_uid_tests.cpp ├── xml_loudness_metadata_tests.cpp ├── helper │ ├── file_comparator.hpp │ └── ostream_operators.hpp ├── adm_common_definitions_tests.cpp ├── xml_parser_audio_programme_tests.cpp ├── xml_writer_audio_object_interaction_tests.cpp ├── dialogue_tests.cpp ├── xml_parser_audio_track_uid_tests.cpp ├── audio_object_interaction_tests.cpp ├── object_divergence_tests.cpp ├── xml_writer_label_tests.cpp ├── type_descriptor_tests.cpp └── xml_parser_audio_block_format_hoa_tests.cpp ├── codecov.yml ├── src ├── serial │ ├── frame_header.cpp │ ├── sadm_xml_reader.cpp │ ├── audio_track.cpp │ ├── transport_track_format.cpp │ ├── changed_ids.cpp │ ├── frame_format.cpp │ └── transport_id.cpp ├── elements │ ├── headphone_virtualise.cpp │ ├── audio_block_format_hoa.cpp │ ├── profile_list.cpp │ ├── label.cpp │ ├── common_parameters.cpp │ ├── audio_pack_format_hoa.cpp │ ├── position_offset.cpp │ ├── screen_edge_lock.cpp │ ├── gain_interaction_range.cpp │ ├── audio_block_format_matrix.cpp │ ├── format_descriptor.cpp │ ├── frequency.cpp │ ├── audio_block_format_binaural.cpp │ └── channel_lock.cpp ├── utilities │ └── copy.cpp ├── path.cpp ├── write.cpp └── parse.cpp ├── config ├── version.hpp.in └── admConfig.cmake.in ├── cmake ├── embedded_resource.hpp.in ├── embedded_resource.cpp.in └── uninstall.cmake.in ├── .github └── workflows │ └── check_format.yml ├── examples ├── parse_xml.cpp ├── parse_sadm_xml.cpp ├── CMakeLists.txt ├── create_from_scratch.cpp ├── voice_over.cpp ├── create_sadm_from_scratch.cpp ├── multiple_languages_2.cpp └── multiple_languages_1.cpp └── format.sh /docs/changelog.rst: -------------------------------------------------------------------------------- 1 | .. changelog: 2 | 3 | .. mdinclude:: ../CHANGELOG.md 4 | -------------------------------------------------------------------------------- /docs/irt_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebu/libadm/HEAD/docs/irt_logo.png -------------------------------------------------------------------------------- /.clang_complete: -------------------------------------------------------------------------------- 1 | -I. 2 | -I./include 3 | -I./build/src 4 | -I./build 5 | -I./submodules 6 | -------------------------------------------------------------------------------- /.readthedocs.yml: -------------------------------------------------------------------------------- 1 | python: 2 | version: 3 3 | requirements_file: docs/requirements.txt 4 | -------------------------------------------------------------------------------- /submodules/catch2/catch_main.cpp: -------------------------------------------------------------------------------- 1 | #define CATCH_CONFIG_MAIN 2 | #include 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build* 2 | *.swp 3 | .DS_Store 4 | .vscode 5 | .idea 6 | docs/.build 7 | docs/venv 8 | *.user 9 | cmake-build-* 10 | -------------------------------------------------------------------------------- /submodules/rapidxml.cmake: -------------------------------------------------------------------------------- 1 | add_library(rapidxml INTERFACE) 2 | target_include_directories(rapidxml INTERFACE ${PROJECT_SOURCE_DIR}/submodules) -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: Google 2 | NamespaceIndentation: All 3 | AlignTrailingComments: false 4 | SortIncludes: false 5 | ReflowComments: false 6 | -------------------------------------------------------------------------------- /docs/reference_read_write.rst: -------------------------------------------------------------------------------- 1 | .. reference_read_write: 2 | 3 | Read and write XML 4 | ################## 5 | 6 | .. doxygengroup:: xml 7 | :content-only: 8 | -------------------------------------------------------------------------------- /docs/reference_document.rst: -------------------------------------------------------------------------------- 1 | .. reference_document: 2 | 3 | ADM Document 4 | ############ 5 | 6 | .. doxygenclass:: adm::Document 7 | .. doxygentypedef:: adm::Version 8 | -------------------------------------------------------------------------------- /include/adm/adm.hpp: -------------------------------------------------------------------------------- 1 | #include "adm/document.hpp" 2 | #include "adm/elements.hpp" 3 | 4 | /** 5 | @brief Adm library namespace 6 | */ 7 | namespace adm {} // namespace adm 8 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/find_audio_format_extended_itu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | ignore: 2 | - "/usr/**/*" 3 | - "examples/*" 4 | - "examples/**/*" 5 | - "submodules/*" 6 | - "submodules/**/*" 7 | - "tests/*" 8 | - "tests/**/*" 9 | - "tools/*" 10 | - "tools/**/*" 11 | -------------------------------------------------------------------------------- /docs/reference_helpers.rst: -------------------------------------------------------------------------------- 1 | .. reference_helpers: 2 | 3 | Helpers 4 | ####### 5 | 6 | .. doxygenclass:: adm::Route 7 | .. doxygenclass:: adm::Path 8 | .. doxygentypedef:: adm::RouteTracer 9 | .. doxygenfunction:: adm::getPropertyOr 10 | -------------------------------------------------------------------------------- /tests/xml_parser_common_definitions_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "adm/parse.hpp" 4 | 5 | TEST_CASE("xml_parser/with_common_definitions") { 6 | adm::parseXml("xml_parser/with_common_definitions.xml"); 7 | } 8 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/find_audio_format_extended_ebu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/serial/frame_header.cpp: -------------------------------------------------------------------------------- 1 | #include "adm/serial/frame_header.hpp" 2 | #include "adm/utilities/element_io.hpp" 3 | 4 | namespace adm { 5 | 6 | void FrameHeader::set(FrameFormat frameFormat) { 7 | frameFormat_ = std::move(frameFormat); 8 | } 9 | } // namespace adm 10 | -------------------------------------------------------------------------------- /config/version.hpp.in: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #define ADM_VERSION "@PROJECT_VERSION@" 3 | #define ADM_VERSION_MAJOR @PROJECT_VERSION_MAJOR@ 4 | #define ADM_VERSION_MINOR @PROJECT_VERSION_MINOR@ 5 | #define ADM_VERSION_PATCH @PROJECT_VERSION_PATCH@ 6 | #define ADM_BUILD_DATE "@PROJECT_BUILD_DATE@" 7 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/version.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/elements/headphone_virtualise.cpp: -------------------------------------------------------------------------------- 1 | #include "adm/elements/headphone_virtualise.hpp" 2 | 3 | namespace adm { 4 | namespace detail { 5 | template class DefaultParameter; 6 | template class DefaultParameter; 7 | } // namespace detail 8 | } // namespace adm -------------------------------------------------------------------------------- /include/adm/elements/head_locked.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "adm/detail/named_type.hpp" 4 | 5 | namespace adm { 6 | /// Tag for NamedType ::HeadLocked 7 | struct HeadLockedTag {}; 8 | /// @brief NamedType for the headLocked parameter 9 | using HeadLocked = detail::NamedType; 10 | } // namespace adm 11 | -------------------------------------------------------------------------------- /src/elements/audio_block_format_hoa.cpp: -------------------------------------------------------------------------------- 1 | #include "adm/elements/audio_block_format_hoa.hpp" 2 | 3 | namespace adm { 4 | namespace detail { 5 | template class OptionalParameter; 6 | template class OptionalParameter; 7 | template class OptionalParameter; 8 | } // namespace 9 | } // namespace adm 10 | -------------------------------------------------------------------------------- /submodules/catch2.cmake: -------------------------------------------------------------------------------- 1 | add_library(catch2 STATIC ${PROJECT_SOURCE_DIR}/submodules/catch2/catch_main.cpp) 2 | target_include_directories(catch2 PUBLIC ${PROJECT_SOURCE_DIR}/submodules) 3 | target_compile_features(catch2 PUBLIC cxx_auto_type cxx_trailing_return_types) 4 | target_compile_definitions(catch2 PUBLIC CATCH_CONFIG_ENABLE_BENCHMARKING) 5 | -------------------------------------------------------------------------------- /include/adm/utilities/element_io.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace adm { 5 | 6 | template 7 | auto operator<<(std::ostream& os, 8 | const Element& element) -> decltype(element.print(os), os) { 9 | element.print(os); 10 | return os; 11 | } 12 | 13 | } // namespace adm 14 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_track_uid.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /include/adm/elements/screen_ref.hpp: -------------------------------------------------------------------------------- 1 | /// @file screen_ref.hpp 2 | #pragma once 3 | 4 | #include "adm/detail/named_type.hpp" 5 | 6 | namespace adm { 7 | /// @brief Tag for NamedType ::ScreenRef 8 | struct ScreenRefTag {}; 9 | /// @brief NamedType for screenref parameter 10 | using ScreenRef = detail::NamedType; 11 | } // namespace adm 12 | -------------------------------------------------------------------------------- /cmake/embedded_resource.hpp.in: -------------------------------------------------------------------------------- 1 | // WARNING This file is auto-generated during configuration by the cmake 2 | // function embed_resource(). Do not manually edit as changes will be lost 3 | 4 | #pragma once 5 | #include 6 | #include 7 | 8 | namespace @EMBED_NAMESPACE@ { 9 | bool getEmbeddedFile(std::string const& fileName, std::ostream& stream); 10 | } 11 | -------------------------------------------------------------------------------- /include/adm/elements/nfc_ref_dist.hpp: -------------------------------------------------------------------------------- 1 | /// @file nfc_ref_dist.hpp 2 | #pragma once 3 | 4 | #include "adm/detail/named_type.hpp" 5 | 6 | namespace adm { 7 | /// @brief Tag for NamedType ::NfcRefDist 8 | struct NfcRefDistTag {}; 9 | /// @brief NamedType for degree parameter 10 | using NfcRefDist = detail::NamedType; 11 | } // namespace adm 12 | -------------------------------------------------------------------------------- /include/adm/utilities/copy.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "adm/document.hpp" 4 | 5 | namespace adm { 6 | 7 | ADM_EXPORT std::shared_ptr deepCopy( 8 | std::shared_ptr document); 9 | 10 | ADM_EXPORT void deepCopyTo(std::shared_ptr src, 11 | std::shared_ptr dest); 12 | 13 | } // namespace adm 14 | -------------------------------------------------------------------------------- /.github/workflows/check_format.yml: -------------------------------------------------------------------------------- 1 | name: Check Format 2 | on: [workflow_dispatch, pull_request] 3 | 4 | jobs: 5 | check_format: 6 | name: Check Format 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | 11 | - name: format code 12 | run: ./format.sh 13 | 14 | - name: check diff 15 | run: git diff --color=always --exit-code 16 | -------------------------------------------------------------------------------- /cmake/embedded_resource.cpp.in: -------------------------------------------------------------------------------- 1 | // WARNING This file is auto-generated during configuration by the cmake 2 | // function embed_resource(). Do not manually edit as changes will be lost 3 | 4 | #include "@EMBED_BASE_NAME@.hpp" 5 | 6 | namespace { 7 | @EMBED_BYTE_ARRAYS@ 8 | } 9 | 10 | bool @EMBED_NAMESPACE@::getEmbeddedFile(std::string const& fileName, std::ostream& stream) { 11 | @EMBED_LOOKUPS@ 12 | return false; 13 | } 14 | -------------------------------------------------------------------------------- /include/adm/elements/normalization.hpp: -------------------------------------------------------------------------------- 1 | /// @file normalization.hpp 2 | #pragma once 3 | 4 | #include "adm/detail/named_type.hpp" 5 | 6 | namespace adm { 7 | /// @brief Tag for NamedType ::Normalization 8 | struct NormalizationTag {}; 9 | /// @brief NamedType for a normalization parameter, defaulting to SN3D 10 | using Normalization = detail::NamedType; 11 | } // namespace adm 12 | -------------------------------------------------------------------------------- /tests/test_data/version.accepted.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_pack_format.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_track_format.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_stream_format.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/unresolved_references/audio_track_uid_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | AP_00031001 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/update_deps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # updates requirements.txt by installing the latest requirements into a 4 | # temporary virtualenv 5 | 6 | REQUIREMENTS="breathe sphinx-rtd-theme m2r2" 7 | 8 | ### 9 | 10 | set -eu 11 | 12 | ENV=$(mktemp -d env.XXXXX) 13 | python -m venv $ENV 14 | source $ENV/bin/activate 15 | 16 | pip install $REQUIREMENTS 17 | pip freeze | grep -v '^-' > requirements.txt 18 | 19 | deactivate 20 | rm -r $ENV 21 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_track_uid_duplicate_id.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/unresolved_references/audio_track_uid_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | AT_00031001_01 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/serial/sadm_xml_reader.cpp: -------------------------------------------------------------------------------- 1 | #include "adm/serial/sadm_xml_reader.hpp" 2 | #include 3 | #include 4 | #include "adm/serial/frame_header_parser.hpp" 5 | 6 | namespace adm { 7 | 8 | std::shared_ptr parseSadmXml(std::istream& stream, 9 | xml::ParserOptions /*options*/) { 10 | xml::SadmXmlParser parser(stream); 11 | return parser.parse(); 12 | } 13 | } // namespace adm 14 | -------------------------------------------------------------------------------- /src/elements/profile_list.cpp: -------------------------------------------------------------------------------- 1 | #include "adm/elements/profile_list.hpp" 2 | 3 | namespace adm { 4 | namespace detail { 5 | template class RequiredParameter; 6 | template class RequiredParameter; 7 | template class RequiredParameter; 8 | template class RequiredParameter; 9 | template class VectorParameter; 10 | } // namespace detail 11 | } // namespace adm 12 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/unresolved_references/audio_object_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | AO_1002 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_object_duplicate_id.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/unresolved_references/audio_content.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | AO_1001 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/unresolved_references/audio_object_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | ATU_00000001 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/unresolved_references/audio_object_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | AP_00031001 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /tests/label_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "adm/elements/label.hpp" 3 | #include "helper/parameter_checks.hpp" 4 | 5 | using namespace adm; 6 | using namespace adm_test; 7 | 8 | TEST_CASE("label") { 9 | Label label(LabelValue("label")); 10 | 11 | check_required_param(label, hasDefaultOf("label"), 12 | canBeSetTo("foo")); 13 | check_optional_param(label, canBeSetTo("EN")); 14 | } 15 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_pack_format_hoa.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/unresolved_references/audio_programme.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | ACO_1001 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/serial/audio_track.cpp: -------------------------------------------------------------------------------- 1 | #include "adm/serial/audio_track.hpp" 2 | #include "adm/utilities/element_io.hpp" 3 | 4 | namespace adm { 5 | 6 | // ---- Common ---- // 7 | void AudioTrack::print(std::ostream& os) const { 8 | os << get(); 9 | os << ", formatLabel=" << formatFormatLabel(get()); 10 | os << ", formatDefinition=" 11 | << formatFormatDefinition(get()); 12 | os << ")"; 13 | } 14 | 15 | } // namespace adm 16 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_programme_duplicate_id.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/unresolved_references/audio_pack_format_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | AP_00031002 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_channel_format.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 120 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/unresolved_references/audio_pack_format_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | AC_00031001 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /include/adm/elements/importance.hpp: -------------------------------------------------------------------------------- 1 | /// @file importance.hpp 2 | #pragma once 3 | 4 | #include "adm/detail/named_type.hpp" 5 | 6 | namespace adm { 7 | 8 | /// @brief Tag for NamedType ::Importance 9 | struct ImportanceTag {}; 10 | /** 11 | * @brief NamedType for the importance parameter 12 | * 13 | * Valid values are in the range [0, 10]. 14 | */ 15 | using Importance = 16 | detail::NamedType>; 17 | 18 | } // namespace adm 19 | -------------------------------------------------------------------------------- /include/adm/elements/audio_programme_ref_screen.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace adm { 5 | 6 | struct AudioProgrammeReferenceScreenTag {}; 7 | 8 | class AudioProgrammeReferenceScreen { 9 | public: 10 | typedef AudioProgrammeReferenceScreenTag tag; 11 | 12 | AudioProgrammeReferenceScreen() {} 13 | 14 | /** 15 | * @brief Print overview to ostream 16 | */ 17 | void print(std::ostream &os) const { os << "()"; }; 18 | }; 19 | 20 | } // namespace adm 21 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/unresolved_references/audio_stream_format_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | AP_00031001 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/unresolved_references/audio_track_format.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | AS_00031001 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/unresolved_references/audio_stream_format_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | AT_00031001_01 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/profile_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | value1 8 | value2 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/utilities/copy.cpp: -------------------------------------------------------------------------------- 1 | #include "adm/utilities/copy.hpp" 2 | #include "adm/private/copy.hpp" 3 | #include 4 | 5 | namespace adm { 6 | 7 | std::shared_ptr deepCopy(std::shared_ptr document) { 8 | return document->deepCopy(); 9 | } 10 | 11 | void deepCopyTo(std::shared_ptr src, 12 | std::shared_ptr dest) { 13 | auto copiedElements = copyAllElements(src); 14 | addElements(copiedElements, dest); 15 | } 16 | 17 | } // namespace adm 18 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_content_duplicate_id.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/parse_xml.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "adm/common_definitions.hpp" 4 | #include "adm/parse.hpp" 5 | #include "adm/write.hpp" 6 | 7 | int main(int argc, char const *argv[]) { 8 | if (argc != 2) { 9 | std::cout << "usage: " << argv[0] << " [XML_FILE]" << std::endl; 10 | exit(1); 11 | } 12 | auto admDocument = adm::parseXml(argv[1]); 13 | 14 | // write XML data to stdout 15 | std::stringstream xmlStream; 16 | writeXml(xmlStream, admDocument); 17 | std::cout << xmlStream.str(); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /tests/test_data/profile_list_frame_header.accepted.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | value1 7 | value2 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_pack_format_duplicate_id.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_track_format_duplicate_id.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/test_data/write_objects_silent_track_ref.accepted.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | ATU_00000000 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_stream_format_duplicate_id.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_content.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 1 8 | My Content 9 | Mein Inhalt 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_track_uid_track_format_reference.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | AT_00001001_01 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/serial/transport_track_format.cpp: -------------------------------------------------------------------------------- 1 | #include "adm/serial/transport_track_format.hpp" 2 | 3 | #include 4 | #include 5 | #include "adm/utilities/element_io.hpp" 6 | 7 | namespace adm { 8 | 9 | // ---- Common ---- // 10 | void TransportTrackFormat::print(std::ostream& os) const { 11 | os << get(); 12 | if (has()) { 13 | os << " (TransportName="; 14 | os << get(); 15 | } 16 | os << ", NumTracks=" << get().get(); 17 | os << ", NumIds=" << get().get(); 18 | os << ")"; 19 | } 20 | 21 | } // namespace adm 22 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_track_uid_channel_format_reference.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | AC_00011001 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_programme.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Good morning 8 | Bonjour 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | alabaster==0.7.13 2 | Babel==2.12.1 3 | breathe==4.35.0 4 | certifi==2023.5.7 5 | charset-normalizer==3.1.0 6 | docutils==0.18.1 7 | idna==3.4 8 | imagesize==1.4.1 9 | Jinja2==3.1.2 10 | m2r2==0.3.2 11 | MarkupSafe==2.1.3 12 | mistune==0.8.4 13 | packaging==23.1 14 | Pygments==2.15.1 15 | requests==2.31.0 16 | snowballstemmer==2.2.0 17 | Sphinx==6.2.1 18 | sphinx-rtd-theme==1.2.1 19 | sphinxcontrib-applehelp==1.0.4 20 | sphinxcontrib-devhelp==1.0.2 21 | sphinxcontrib-htmlhelp==2.0.1 22 | sphinxcontrib-jquery==4.1 23 | sphinxcontrib-jsmath==1.0.1 24 | sphinxcontrib-qthelp==1.0.3 25 | sphinxcontrib-serializinghtml==1.1.5 26 | urllib3==2.0.3 27 | -------------------------------------------------------------------------------- /tests/xml_parser_find_audio_format_extended_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "adm/parse.hpp" 4 | 5 | TEST_CASE("xml_parser/find_audio_format_extended_ebu") { 6 | adm::parseXml("xml_parser/find_audio_format_extended_ebu.xml"); 7 | } 8 | 9 | TEST_CASE("find_audio_format_extended_itu") { 10 | adm::parseXml("xml_parser/find_audio_format_extended_itu.xml", 11 | adm::xml::ParserOptions::recursive_node_search); 12 | } 13 | 14 | TEST_CASE("xml_parser/find_audio_format_extended_ebu_with_other_metadata") { 15 | adm::parseXml( 16 | "xml_parser/find_audio_format_extended_ebu_with_other_metadata.xml"); 17 | } 18 | -------------------------------------------------------------------------------- /include/adm/serial.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /** 4 | * @file serial.hpp 5 | * 6 | * Convenience header to inlcude all ADM element headers. 7 | */ 8 | 9 | /** 10 | * @defgroup sadm Serial ADM elements 11 | * 12 | * @brief C++ representations of the elements required by the serialized version 13 | * of ADM 14 | * 15 | * These extend the classes of @ref main by the additional elements introducted 16 | * in ITU-R BS.[ADM-Serial] 17 | * 18 | */ 19 | #include "adm/serial/frame_header.hpp" 20 | #include "adm/serial/frame_format.hpp" 21 | #include "adm/serial/transport_track_format.hpp" 22 | #include "adm/serial/transport_id.hpp" 23 | #include "adm/serial/audio_track.hpp" 24 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/with_common_definitions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | AP_00010001 8 | ATU_00000001 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/test_data/profile_list.accepted.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | value1 8 | value2 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/test_data/write_default_binaural_block.accepted.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /include/adm/private/rapidxml_utils.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rapidxml/rapidxml.hpp" 4 | #include 5 | 6 | namespace adm { 7 | namespace xml { 8 | template 9 | int countLines(It begin, It end) { 10 | return static_cast(std::count(begin, end, '\n')); 11 | } 12 | 13 | inline int getDocumentLine(rapidxml::xml_node<>* node) { 14 | return countLines(node->document()->first_node()->name(), node->name()); 15 | } 16 | inline int getDocumentLine(rapidxml::xml_attribute<>* attr) { 17 | return countLines(attr->document()->first_node()->name(), attr->name()); 18 | } 19 | } // namespace xml 20 | } // namespace adm 21 | -------------------------------------------------------------------------------- /include/adm/helper/get_optional_property.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace adm { 4 | 5 | /** 6 | * Return value of a property or a given defaultValue if the property is not 7 | available. 8 | * 9 | * This is just a more expressive shorthand equivalent to 10 | @code 11 | element->has() ? element->get() : defaultValue; 12 | @endcode 13 | */ 14 | template 15 | Property getPropertyOr(ElementPtr element, Property defaultValue) { 16 | if (!element->template has()) { 17 | return defaultValue; 18 | } 19 | return element->template get(); 20 | } 21 | 22 | } // namespace adm 23 | -------------------------------------------------------------------------------- /tests/test_data/write_complementary_audio_objects.accepted.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | AO_1002 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/find_audio_format_extended_ebu_with_other_metadata.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <dc:title xml:lang="en">Mono ADM Test File</dc:title> 6 | 7 | 8 | 9 | IRT 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_object_complementary_audio_objects.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | AO_1002 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_block_format_direct_speakers_cartesian_bad_coord.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | testLabel 9 | 0.500000 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_object.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | My Object 8 | Mein Objekt 9 | 0.5 10 | 1 11 | 1 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /docs/Doxyfile: -------------------------------------------------------------------------------- 1 | PROJECT_NAME = libadm 2 | INPUT = ../include/adm/ 3 | RECURSIVE = YES 4 | 5 | GENERATE_HTML = NO 6 | GENERATE_LATEX = NO 7 | GENERATE_XML = YES 8 | XML_OUTPUT = .build/doxygenxml 9 | XML_PROGRAMLISTING = YES 10 | 11 | MACRO_EXPANSION = YES 12 | EXPAND_ONLY_PREDEF = YES 13 | EXPAND_AS_DEFINED = ADM_EXPORT 14 | PREDEFINED = ADM_EXPORT= 15 | PREDEFINED += IN_DOXYGEN= 16 | 17 | ALIASES = "rst=\verbatim embed:rst:leading-asterisk" 18 | ALIASES += "endrst=\endverbatim" 19 | 20 | QUIET = YES 21 | WARNINGS = YES 22 | WARN_IF_UNDOCUMENTED = NO 23 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_channel_format_duplicate_id.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 120 8 | 9 | 10 | 120 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_object_track_refs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | ATU_00000001 8 | ATU_00000000 9 | 10 | 11 | 12 | AT_00010003_01 13 | AP_00010001 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_block_format_direct_speakers_cartesian_bad_bound.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | testLabel 9 | -0.100000 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /examples/parse_sadm_xml.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "adm/parse.hpp" 5 | #include "adm/write.hpp" 6 | 7 | int main(int argc, char const *argv[]) { 8 | if (argc != 2) { 9 | std::cout << "usage: " << argv[0] << " [SADM_XML_FILE]" << std::endl; 10 | exit(1); 11 | } 12 | 13 | std::string fileName = argv[1]; 14 | auto header = adm::parseFrameHeader(fileName); 15 | auto document = adm::parseXml(fileName, header, 16 | adm::xml::ParserOptions::recursive_node_search); 17 | 18 | // write XML data to stdout 19 | std::stringstream xmlStream; 20 | writeXml(xmlStream, document, header); 21 | std::cout << xmlStream.str(); 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /tests/test_data/write_specified_binaural_block_sadm.accepted.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0.500000 10 | 5 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /tests/test_data/write_default_HOA_block.accepted.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 0 9 | 0 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /docs/reference_utilities.rst: -------------------------------------------------------------------------------- 1 | .. reference_utilities: 2 | 3 | Utilities 4 | ######### 5 | 6 | Object Creation 7 | =============== 8 | 9 | .. doxygenstruct:: adm::SimpleObjectHolder 10 | 11 | .. doxygenfunction:: adm::createSimpleObject 12 | 13 | .. doxygenfunction:: adm::addSimpleObjectTo 14 | 15 | .. doxygenstruct:: adm::SimpleCommonDefinitionsObjectHolder 16 | 17 | .. doxygenfunction:: adm::addSimpleCommonDefinitionsObjectTo 18 | 19 | .. doxygenfunction:: adm::addTailoredCommonDefinitionsObjectTo 20 | 21 | audioBlockFormat timing fixes 22 | ============================= 23 | 24 | .. doxygenfunction:: adm::updateBlockFormatDurations(std::shared_ptr) 25 | 26 | .. doxygenfunction:: adm::updateBlockFormatDurations(std::shared_ptr, const Time &) 27 | -------------------------------------------------------------------------------- /tests/test_data/write_audio_content.accepted.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 1 8 | My Content 9 | Mein Inhalt 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /include/adm/elements/private/auto_parent.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /// check and update the parents of self and other 4 | /// 5 | /// if only one has no parent, set it to the parent of the other 6 | /// 7 | /// returns true if they both have the same parent after this (or both have no 8 | /// parent) 9 | template 10 | bool autoParent(T1& self, const std::shared_ptr& other) { 11 | auto selfParent = self.getParent().lock(); 12 | auto otherParent = other->getParent().lock(); 13 | if (selfParent && !otherParent) { 14 | selfParent->add(other); 15 | return true; 16 | } 17 | if (!selfParent && otherParent) { 18 | otherParent->add(self.shared_from_this()); 19 | return true; 20 | } 21 | 22 | return selfParent == otherParent; 23 | } 24 | -------------------------------------------------------------------------------- /tests/test_data/write_object_attributes.accepted.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | label 8 | 0.500000 9 | 1 10 | 1 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/elements/label.cpp: -------------------------------------------------------------------------------- 1 | #include "adm/elements/label.hpp" 2 | 3 | namespace adm { 4 | Label::Label(const char* s) { 5 | // to avoid UB from std::string 6 | if (!s) { 7 | throw error::AdmGenericRuntimeError{ 8 | "Cannot construct Label from null const char*"}; 9 | } 10 | set(LabelValue{std::string{s}}); 11 | } 12 | 13 | void adm::Label::print(std::ostream& os) const { 14 | os << get().get(); 15 | if (has()) { 16 | os << " (language= " << get().get() << ")"; 17 | } 18 | } 19 | 20 | namespace detail { 21 | template class RequiredParameter; 22 | template class OptionalParameter; 23 | template class VectorParameter; 24 | } // namespace detail 25 | } // namespace adm 26 | -------------------------------------------------------------------------------- /tests/test_data/write_audio_programme.accepted.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | My Programme 8 | Mein Programm 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /include/adm/utilities/time_conversion.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "../elements/time.hpp" 4 | 5 | namespace adm { 6 | // utilities for working with times as boost::rational 7 | using RationalTime = boost::rational; 8 | 9 | inline RationalTime asRational(const FractionalTime &t) { 10 | return {t.numerator(), t.denominator()}; 11 | } 12 | 13 | inline RationalTime asRational(const Time &t) { 14 | FractionalTime fractional = t.asFractional(); 15 | return {fractional.numerator(), fractional.denominator()}; 16 | } 17 | 18 | inline FractionalTime asFractionalTime(const RationalTime &t) { 19 | return {t.numerator(), t.denominator()}; 20 | } 21 | 22 | inline Time asTime(const RationalTime &t) { return asFractionalTime(t); } 23 | } // namespace adm 24 | -------------------------------------------------------------------------------- /src/elements/common_parameters.cpp: -------------------------------------------------------------------------------- 1 | #include "adm/elements/common_parameters.hpp" 2 | 3 | namespace adm { 4 | namespace detail { 5 | template class RequiredParameter; 6 | 7 | template class DefaultParameter; 8 | 9 | template class DefaultParameter; 10 | 11 | template class DefaultParameter; 12 | template class OptionalParameter; 13 | template class OptionalParameter; 14 | 15 | template class DefaultParameter; 16 | 17 | template class DefaultParameter; 18 | 19 | template class DefaultParameter; 20 | 21 | template class DefaultParameter; 22 | template class DefaultParameter; 23 | } // namespace detail 24 | } // namespace adm 25 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_block_format_objects_gain_unit_error.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 30.0 9 | 0.0 10 | 1.0 11 | 0.8 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /tests/test_data/write_total_time_reference.accepted.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0.000000 10 | 1.000000 11 | 1 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /tests/test_data/write_local_time_reference.accepted.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0.000000 10 | 1.000000 11 | 1 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /tests/test_data/write_default_cartesian_speaker.accepted.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 0.000000 9 | 0.000000 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /tests/test_data/write_specified_binaural_block.accepted.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 0.500000 9 | 5 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /tests/version_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "helper/parameter_checks.hpp" 3 | #include "adm/document.hpp" 4 | #include "adm/parse.hpp" 5 | #include "adm/write.hpp" 6 | #include "helper/file_comparator.hpp" 7 | 8 | using namespace adm; 9 | using namespace adm_test; 10 | 11 | TEST_CASE("version") { 12 | auto document = Document::create(); 13 | 14 | check_optional_param(document, 15 | canBeSetTo(Version{"ITU-R_BS.2076-2"})); 16 | } 17 | 18 | TEST_CASE("xml/version") { 19 | auto document = parseXml("xml_parser/version.xml"); 20 | 21 | REQUIRE(document->has()); 22 | REQUIRE(document->get().get() == "ITU-R_BS.2076-2"); 23 | 24 | std::stringstream xml; 25 | writeXml(xml, document); 26 | 27 | CHECK_THAT(xml.str(), EqualsXmlFile("version")); 28 | } 29 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_block_format_binaural.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 0.500000 9 | 5 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /tests/test_data/write_default_spherical_speaker.accepted.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 0.000000 9 | 0.000000 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /include/adm/private/xml_writer.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "adm/write.hpp" 3 | 4 | namespace adm { 5 | class Document; 6 | namespace xml { 7 | 8 | class XmlWriter { 9 | public: 10 | explicit XmlWriter(WriterOptions options = WriterOptions::none); 11 | 12 | std::ostream& write(std::shared_ptr document, 13 | std::ostream& stream); 14 | 15 | private: 16 | WriterOptions options_; 17 | }; 18 | 19 | class SadmXmlWriter { 20 | public: 21 | SadmXmlWriter(SadmWriterOptions options = SadmWriterOptions::none); 22 | std::ostream& write(std::shared_ptr document, 23 | FrameHeader const& header, std::ostream& stream); 24 | 25 | private: 26 | SadmWriterOptions options_; 27 | }; 28 | 29 | } // namespace xml 30 | } // namespace adm 31 | -------------------------------------------------------------------------------- /tests/test_data/write_partially_specified_spherical.accepted.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 60.000000 9 | 30.000000 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /tests/frame_header_parser_frame_format_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | namespace { 7 | constexpr const char* MINIMAL_HEADER = 8 | R"( 9 | 10 | 11 | 12 | 13 | 14 | 15 | ATU_00000001 16 | 17 | 18 | 19 | 20 | )"; 21 | } 22 | 23 | TEST_CASE("Test minimal frame header parsing") { 24 | std::stringstream header_xml{MINIMAL_HEADER}; 25 | CHECK_NOTHROW(adm::parseFrameHeader(header_xml)); 26 | } -------------------------------------------------------------------------------- /tests/test_data/write_partially_specified_cartesian.accepted.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 0.000000 9 | 0.000000 10 | 1 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /format.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | clang-format --version 3 | DIRS="examples include src tests" 4 | 5 | IGNORE=" 6 | src/elements/audio_pack_format.cpp 7 | src/elements/audio_track_format_id.cpp 8 | src/elements/audio_block_format_id.cpp 9 | src/elements/audio_block_format_hoa.cpp 10 | src/document.cpp 11 | include/adm/elements/audio_block_format_hoa.hpp 12 | include/adm/elements/audio_pack_format.hpp 13 | include/adm/elements/audio_channel_format.hpp 14 | include/adm/elements/normalization.hpp 15 | include/adm/elements/audio_pack_format_hoa.hpp 16 | include/adm/elements/nfc_ref_dist.hpp 17 | tests/adm_common_definitions_tests.cpp 18 | tests/xml_parser_audio_block_format_hoa_tests.cpp 19 | tests/xml_parser_audio_block_format_objects_tests.cpp 20 | tests/xml_parser_audio_pack_format_tests.cpp 21 | " 22 | 23 | find $DIRS \( -iname '*.cpp' -or -iname '*.hpp' \) $(printf "! -wholename %s " $IGNORE) -exec clang-format -style=file -i '{}' + 24 | -------------------------------------------------------------------------------- /tests/xml_parser_unresolved_references_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "adm/parse.hpp" 4 | #include "adm/errors.hpp" 5 | 6 | std::string formatFilepath(const std::string& filename) { 7 | std::stringstream ss; 8 | ss << "xml_parser/unresolved_references/" << filename << ".xml"; 9 | return ss.str(); 10 | } 11 | 12 | TEST_CASE("xml_parser/unresolved_references") { 13 | for (auto filename : 14 | {"audio_programme", "audio_content", "audio_object_1", "audio_object_2", 15 | "audio_object_3", "audio_pack_format_1", "audio_pack_format_2", 16 | "audio_track_uid_1", "audio_track_uid_2", "audio_track_format", 17 | "audio_stream_format_1", "audio_stream_format_2"}) { 18 | SECTION(filename) { 19 | REQUIRE_THROWS_AS(adm::parseXml(formatFilepath(filename)), 20 | adm::error::XmlParsingUnresolvedReference); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/path.cpp: -------------------------------------------------------------------------------- 1 | #include "adm/path.hpp" 2 | 3 | namespace adm { 4 | 5 | struct AddElementVisitor : public boost::static_visitor<> { 6 | explicit AddElementVisitor(Path* path) : path_(path) {} 7 | 8 | template 9 | void operator()(T v) const { 10 | path_->add(v); 11 | } 12 | 13 | private: 14 | Path* path_; 15 | }; 16 | 17 | struct AddIdVisitor : public boost::static_visitor<> { 18 | explicit AddIdVisitor(Path* path) : path_(path) {} 19 | 20 | template 21 | void operator()(T v) const { 22 | path_->add(v); 23 | } 24 | 25 | private: 26 | Path* path_; 27 | }; 28 | 29 | void Path::add(ElementConstVariant elementVariant) { 30 | boost::apply_visitor(AddElementVisitor(this), elementVariant); 31 | } 32 | 33 | void Path::add(ElementIdVariant elementIdVariant) { 34 | boost::apply_visitor(AddIdVisitor(this), elementIdVariant); 35 | } 36 | 37 | } // namespace adm 38 | -------------------------------------------------------------------------------- /tests/format_descriptor_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "adm/elements/format_descriptor.hpp" 3 | 4 | TEST_CASE("format_descriptor") { 5 | using namespace adm; 6 | 7 | // parseFormatLabel 8 | { 9 | REQUIRE(parseFormatLabel("0000") == FormatDefinition::UNDEFINED); 10 | REQUIRE(parseFormatLabel("0001") == FormatDefinition::PCM); 11 | } 12 | // parseFormatDefinition 13 | { 14 | REQUIRE(parseFormatDefinition("Undefined") == FormatDefinition::UNDEFINED); 15 | REQUIRE(parseFormatDefinition("PCM") == FormatDefinition::PCM); 16 | } 17 | // formatFormatDefinition 18 | { 19 | REQUIRE(formatFormatDefinition(FormatDefinition::UNDEFINED) == "Undefined"); 20 | REQUIRE(formatFormatDefinition(FormatDefinition::PCM) == "PCM"); 21 | } 22 | // formatFormatDefinition 23 | { 24 | REQUIRE(formatFormatLabel(FormatDefinition::UNDEFINED) == "0000"); 25 | REQUIRE(formatFormatLabel(FormatDefinition::PCM) == "0001"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/xml_parser_audio_block_format_binaural_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "adm/document.hpp" 4 | #include "adm/elements/audio_channel_format.hpp" 5 | #include "adm/elements/frequency.hpp" 6 | #include "adm/parse.hpp" 7 | 8 | using namespace adm; 9 | 10 | TEST_CASE("xml_parser/audio_block_format_hoa") { 11 | auto document = parseXml("xml_parser/audio_block_format_binaural.xml"); 12 | auto channelFormat = 13 | document->lookup(parseAudioChannelFormatId("AC_00051001")); 14 | 15 | auto blockFormatsIterator = 16 | channelFormat->getElements().begin(); 17 | auto firstBlockFormat = *(blockFormatsIterator++); 18 | 19 | CHECK(firstBlockFormat.get().get() == std::chrono::seconds(0)); 20 | CHECK(firstBlockFormat.get().get() == std::chrono::seconds(1)); 21 | CHECK(firstBlockFormat.get().asLinear() == 0.5); 22 | CHECK(firstBlockFormat.get() == 5); 23 | } 24 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_block_format_direct_speakers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | M+30 9 | 30.0 10 | 0.0 11 | 1.0 12 | 13 | 0.5 14 | 5 15 | 1 16 | 17 | 18 | " 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /tests/gain_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace adm; 6 | 7 | TEST_CASE("Gain linear") { 8 | Gain g = Gain::fromLinear(10.0); 9 | CHECK(g.isLinear()); 10 | CHECK(!g.isDb()); 11 | CHECK(g.asLinear() == 10.0); 12 | CHECK(g.asDb() == Approx(20.0)); 13 | } 14 | 15 | TEST_CASE("Gain linear 0") { 16 | Gain g = Gain::fromLinear(0.0); 17 | CHECK(g.asDb() == -std::numeric_limits::infinity()); 18 | } 19 | 20 | TEST_CASE("Gain Db") { 21 | Gain g = Gain::fromDb(20.0); 22 | CHECK(g.isDb()); 23 | CHECK(!g.isLinear()); 24 | CHECK(g.asDb() == 20.0); 25 | CHECK(g.asLinear() == Approx(10.0)); 26 | } 27 | 28 | TEST_CASE("Gain Db -inf") { 29 | Gain g = Gain::fromDb(-std::numeric_limits::infinity()); 30 | CHECK(g.asLinear() == 0.0); 31 | } 32 | 33 | TEST_CASE("Gain NamedType compatibility") { 34 | Gain g(1.5); 35 | CHECK(g.isLinear()); 36 | CHECK(g.get() == 1.5); 37 | CHECK(*g == 1.5); 38 | } 39 | -------------------------------------------------------------------------------- /tests/gain_interaction_range_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "adm/elements/audio_object_interaction.hpp" 3 | 4 | TEST_CASE("gain_interaction_range") { 5 | using namespace adm; 6 | 7 | GainInteractionRange gainRange; 8 | REQUIRE(gainRange.has() == false); 9 | REQUIRE(gainRange.has() == false); 10 | 11 | gainRange.set(GainInteractionMin(Gain::fromLinear(0.5f))); 12 | gainRange.set(GainInteractionMax(Gain::fromLinear(1.5f))); 13 | 14 | REQUIRE(gainRange.has() == true); 15 | REQUIRE(gainRange.has() == true); 16 | REQUIRE(gainRange.get().get().asLinear() == Approx(0.5f)); 17 | REQUIRE(gainRange.get().get().asLinear() == Approx(1.5f)); 18 | 19 | gainRange.unset(); 20 | gainRange.unset(); 21 | 22 | REQUIRE(gainRange.has() == false); 23 | REQUIRE(gainRange.has() == false); 24 | } 25 | -------------------------------------------------------------------------------- /tests/xml_writer_audio_content_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "adm/document.hpp" 3 | #include "adm/elements.hpp" 4 | #include "adm/utilities/id_assignment.hpp" 5 | #include "adm/utilities/object_creation.hpp" 6 | #include "adm/write.hpp" 7 | #include "helper/file_comparator.hpp" 8 | 9 | TEST_CASE("write_audio_object_interaction") { 10 | using namespace adm; 11 | 12 | auto audioContent = AudioContent::create(AudioContentName("MyContent")); 13 | audioContent->set(AudioContentId(AudioContentIdValue(0x1001))); 14 | audioContent->set(AudioContentLanguage("de")); 15 | audioContent->set(DialogueContent::AUDIO_DESCRIPTION); 16 | audioContent->add(Label(LabelLanguage("en"), LabelValue("My Content"))); 17 | audioContent->add(Label(LabelLanguage("deu"), LabelValue("Mein Inhalt"))); 18 | 19 | auto document = Document::create(); 20 | document->add(audioContent); 21 | 22 | std::stringstream xml; 23 | writeXml(xml, document); 24 | 25 | CHECK_THAT(xml.str(), EqualsXmlFile("write_audio_content")); 26 | } 27 | -------------------------------------------------------------------------------- /tests/channel_lock_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "adm/elements/channel_lock.hpp" 3 | 4 | TEST_CASE("channel_lock") { 5 | using namespace adm; 6 | { 7 | ChannelLock channelLock; 8 | REQUIRE(channelLock.has() == true); 9 | REQUIRE(channelLock.has() == false); 10 | 11 | REQUIRE(channelLock.get() == false); 12 | 13 | channelLock.set(ChannelLockFlag(true)); 14 | channelLock.set(MaxDistance(1.5f)); 15 | 16 | REQUIRE(channelLock.get() == true); 17 | REQUIRE(channelLock.get() == 1.5f); 18 | 19 | REQUIRE(channelLock.isDefault() == false); 20 | 21 | channelLock.unset(); 22 | channelLock.unset(); 23 | 24 | REQUIRE(channelLock.isDefault() == true); 25 | 26 | REQUIRE(isEnabled(channelLock) == false); 27 | enable(channelLock); 28 | REQUIRE(isEnabled(channelLock) == true); 29 | disable(channelLock); 30 | REQUIRE(isEnabled(channelLock) == false); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /include/adm/detail/type_traits.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "adm/detail/named_type.hpp" 4 | #include "adm/elements_fwd.hpp" 5 | 6 | namespace adm { 7 | 8 | #define ADD_TRAIT(TYPE, TAG) \ 9 | namespace detail { \ 10 | template <> \ 11 | struct ParameterTraits { \ 12 | struct TAG {}; \ 13 | typedef TAG tag; \ 14 | }; \ 15 | } 16 | namespace detail { 17 | template 18 | struct ParameterTraits { 19 | typedef typename T::tag tag; 20 | }; 21 | 22 | /** 23 | * NOTE: These template specializations are necessary because the 24 | * AudioTrackFormat and the AudioStreamFormat reference each other. 25 | */ 26 | template <> 27 | struct ParameterTraits { 28 | typedef AudioTrackFormatTag tag; 29 | }; 30 | 31 | template <> 32 | struct ParameterTraits { 33 | typedef AudioStreamFormatTag tag; 34 | }; 35 | } // namespace detail 36 | } // namespace adm 37 | -------------------------------------------------------------------------------- /tests/test_data/write_specified_HOA_block.accepted.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 2 9 | 1 10 | 2.000000 11 | 1 12 | N3D 13 | do not use equation! 14 | 1 15 | 0.500000 16 | 5 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /include/adm/detail/named_option_helper.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | namespace adm { 7 | 8 | namespace detail { 9 | 10 | template 11 | inline void setNamedOptionHelper(Element&& /*element*/) {} 12 | 13 | template 14 | void setNamedOptionHelper(Element&& element, T v, Parameters... args) { 15 | element->set(std::move(v)); 16 | setNamedOptionHelper(std::forward(element), std::move(args)...); 17 | } 18 | 19 | /// check that the first template type is present in the remainder 20 | template 21 | constexpr bool optionInList() { 22 | return false; 23 | } 24 | 25 | template 26 | constexpr bool optionInList() { 27 | using ParamT = std::remove_const_t>; 28 | return std::is_same::value || optionInList(); 29 | } 30 | 31 | } // namespace detail 32 | } // namespace adm 33 | -------------------------------------------------------------------------------- /tests/headphone_virtualise_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "adm/elements/headphone_virtualise.hpp" 3 | #include "helper/parameter_checks.hpp" 4 | 5 | TEST_CASE("headphone_virtualise") { 6 | using namespace adm; 7 | { 8 | SECTION("Default initialisation") { 9 | using namespace adm_test; 10 | check_defaulted_param(HeadphoneVirtualise{}, hasDefaultOf(false), 11 | canBeSetTo(true)); 12 | check_defaulted_param( 13 | HeadphoneVirtualise{}, hasDefaultOf(130.0f), canBeSetTo(20.0f)); 14 | } 15 | 16 | SECTION("Explicit initialisation") { 17 | auto hpv = 18 | HeadphoneVirtualise(Bypass(true), DirectToReverberantRatio(60)); 19 | REQUIRE(hpv.has() == true); 20 | REQUIRE(hpv.has() == true); 21 | REQUIRE(hpv.isDefault() == false); 22 | REQUIRE(hpv.isDefault() == false); 23 | REQUIRE(hpv.get() == true); 24 | REQUIRE(hpv.get() == 60); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/serial/changed_ids.cpp: -------------------------------------------------------------------------------- 1 | #include "adm/serial/changed_ids.hpp" 2 | 3 | namespace adm { 4 | namespace detail { 5 | template class VectorParameter; 6 | template class VectorParameter; 7 | template class VectorParameter; 8 | template class VectorParameter; 9 | template class VectorParameter; 10 | template class VectorParameter; 11 | template class VectorParameter; 12 | template class VectorParameter; 13 | } // namespace detail 14 | } // namespace adm 15 | 16 | std::string adm::formatValue(adm::ChangedIdStatus status) { 17 | switch (status) { 18 | case ChangedIdStatus::NEW: 19 | return "new"; 20 | case ChangedIdStatus::CHANGED: 21 | return "changed"; 22 | case ChangedIdStatus::EXTENDED: 23 | return "extended"; 24 | case ChangedIdStatus::EXPIRED: 25 | return "expired"; 26 | } 27 | throw std::runtime_error("Unsupported StatusValue"); 28 | } 29 | -------------------------------------------------------------------------------- /tests/xml_parser_audio_stream_format_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "adm/document.hpp" 4 | #include "adm/elements/audio_stream_format.hpp" 5 | #include "adm/elements/frequency.hpp" 6 | #include "adm/parse.hpp" 7 | #include "adm/errors.hpp" 8 | 9 | TEST_CASE("xml_parser/audio_stream_format") { 10 | using namespace adm; 11 | auto document = parseXml("xml_parser/audio_stream_format.xml"); 12 | auto streamFormat = document->lookup(parseAudioStreamFormatId("AS_00031001")); 13 | REQUIRE(streamFormat->get() 14 | .get() == 0x1001u); 15 | REQUIRE(streamFormat->get().get() == 16 | TypeDefinition::OBJECTS); 17 | REQUIRE(streamFormat->get() == "MyStreamFormat"); 18 | REQUIRE(streamFormat->get() == FormatDefinition::PCM); 19 | } 20 | 21 | TEST_CASE("xml_parser/audio_stream_format_duplicate_id") { 22 | REQUIRE_THROWS_AS( 23 | adm::parseXml("xml_parser/audio_stream_format_duplicate_id.xml"), 24 | adm::error::XmlParsingDuplicateId); 25 | } 26 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # --- examples --- 2 | 3 | add_executable(create_from_scratch create_from_scratch.cpp) 4 | target_link_libraries(create_from_scratch PRIVATE adm) 5 | 6 | add_executable(parse_xml parse_xml.cpp) 7 | target_link_libraries(parse_xml PRIVATE adm) 8 | 9 | add_executable(foreground_background foreground_background.cpp) 10 | target_link_libraries(foreground_background PRIVATE adm) 11 | 12 | add_executable(multiple_languages_1 multiple_languages_1.cpp) 13 | target_link_libraries(multiple_languages_1 PRIVATE adm) 14 | 15 | add_executable(multiple_languages_2 multiple_languages_2.cpp) 16 | target_link_libraries(multiple_languages_2 PRIVATE adm) 17 | 18 | add_executable(multiple_storylines multiple_storylines.cpp) 19 | target_link_libraries(multiple_storylines PRIVATE adm) 20 | 21 | add_executable(voice_over voice_over.cpp) 22 | target_link_libraries(voice_over PRIVATE adm) 23 | 24 | add_executable(create_sadm_from_scratch create_sadm_from_scratch.cpp) 25 | target_link_libraries(create_sadm_from_scratch PRIVATE adm) 26 | 27 | add_executable(parse_sadm_xml parse_sadm_xml.cpp) 28 | target_link_libraries(parse_sadm_xml PRIVATE adm) 29 | -------------------------------------------------------------------------------- /tests/xml_writer_audio_programme_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "adm/document.hpp" 3 | #include "adm/elements.hpp" 4 | #include "adm/utilities/id_assignment.hpp" 5 | #include "adm/utilities/object_creation.hpp" 6 | #include "adm/write.hpp" 7 | #include "helper/file_comparator.hpp" 8 | 9 | TEST_CASE("write_audio_object_interaction") { 10 | using namespace adm; 11 | 12 | auto audioProgramme = 13 | AudioProgramme::create(AudioProgrammeName("MyProgramme")); 14 | audioProgramme->set(AudioProgrammeId(AudioProgrammeIdValue(0x1001))); 15 | audioProgramme->set(AudioProgrammeLanguage("de")); 16 | audioProgramme->set(Start(std::chrono::seconds(0))); 17 | audioProgramme->set(End(std::chrono::seconds(10))); 18 | audioProgramme->set(MaxDuckingDepth(-30)); 19 | audioProgramme->add(Label(LabelLanguage("en"), LabelValue("My Programme"))); 20 | audioProgramme->add(Label(LabelLanguage("deu"), LabelValue("Mein Programm"))); 21 | 22 | auto document = Document::create(); 23 | document->add(audioProgramme); 24 | 25 | std::stringstream xml; 26 | writeXml(xml, document); 27 | 28 | CHECK_THAT(xml.str(), EqualsXmlFile("write_audio_programme")); 29 | } 30 | -------------------------------------------------------------------------------- /examples/create_from_scratch.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "adm/adm.hpp" 4 | #include "adm/utilities/id_assignment.hpp" 5 | #include "adm/utilities/object_creation.hpp" 6 | #include "adm/write.hpp" 7 | 8 | int main() { 9 | using namespace adm; 10 | 11 | // create ADM elements 12 | auto admProgramme = AudioProgramme::create( 13 | AudioProgrammeName("Alice and Bob talking in the forrest")); 14 | auto speechContent = AudioContent::create(AudioContentName("Speech")); 15 | auto atmoContent = AudioContent::create(AudioContentName("Atmo")); 16 | 17 | admProgramme->addReference(speechContent); 18 | admProgramme->addReference(atmoContent); 19 | auto holder = createSimpleObject("Alice"); 20 | speechContent->addReference(holder.audioObject); 21 | 22 | holder = createSimpleObject("Bob"); 23 | speechContent->addReference(holder.audioObject); 24 | 25 | auto admDocument = Document::create(); 26 | admDocument->add(admProgramme); 27 | reassignIds(admDocument); 28 | 29 | // write XML data to stdout 30 | std::stringstream xmlStream; 31 | writeXml(xmlStream, admDocument); 32 | std::cout << xmlStream.str(); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /include/adm/utilities/lookup.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "adm/document.hpp" 7 | 8 | namespace adm { 9 | 10 | template 11 | std::vector> lookup( 12 | std::shared_ptr document, const Attribute attribute) { 13 | std::vector> elements; 14 | std::copy_if(document->template getElements().begin(), 15 | document->template getElements().end(), 16 | std::back_inserter(elements), 17 | [attribute](const std::shared_ptr element) { 18 | return element->template get() == attribute; 19 | }); 20 | return elements; 21 | } 22 | 23 | template 24 | std::shared_ptr lookupById(const ElementRange& range, 25 | const ElementId& id) { 26 | for (auto& element : range) { 27 | if (element->template get() == id) { 28 | return element; 29 | } 30 | } 31 | return nullptr; 32 | } 33 | 34 | } // namespace adm 35 | -------------------------------------------------------------------------------- /tests/test_data/xml_parser/audio_block_format_direct_speakers_cartesian.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | testLabel 9 | 0.000000 10 | -0.100000 11 | 0.100000 12 | 0.000000 13 | -0.100000 14 | 0.100000 15 | 0.500000 16 | 0.400000 17 | 0.600000 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /include/adm/detail/auto_base_detail.hpp: -------------------------------------------------------------------------------- 1 | 2 | namespace adm { 3 | namespace detail { 4 | /// Combine A and B using F if defined_in_both, otherwise Base 5 | template class F, 7 | typename A, typename B, typename Base> 8 | struct ApplyIfT; 9 | 10 | template