├── .clang-format ├── .clang_complete ├── .github └── workflows │ ├── build.yml │ └── check_format.yml ├── .gitignore ├── .readthedocs.yml ├── CHANGELOG.md ├── CMakeLists.txt ├── LICENSE ├── README.md ├── cmake ├── embed_resource.cmake ├── embedded_resource.cpp.in ├── embedded_resource.hpp.in └── uninstall.cmake.in ├── codecov.yml ├── config ├── admConfig.cmake.in └── version.hpp.in ├── docs ├── Doxyfile ├── Makefile ├── changelog.rst ├── conf.py ├── element_api.rst ├── getting_started.rst ├── index.rst ├── irt_logo.png ├── library_design.rst ├── reference_document.rst ├── reference_elements.rst ├── reference_helpers.rst ├── reference_read_write.rst ├── reference_sadm_elements.rst ├── reference_utilities.rst ├── requirements.txt ├── tutorial.rst └── update_deps.sh ├── examples ├── CMakeLists.txt ├── create_from_scratch.cpp ├── create_sadm_from_scratch.cpp ├── foreground_background.cpp ├── multiple_languages_1.cpp ├── multiple_languages_2.cpp ├── multiple_storylines.cpp ├── parse_sadm_xml.cpp ├── parse_xml.cpp └── voice_over.cpp ├── format.sh ├── include └── adm │ ├── adm.hpp │ ├── common_definitions.hpp │ ├── detail │ ├── auto_base.hpp │ ├── auto_base_detail.hpp │ ├── enum_bitmask.hpp │ ├── id_assigner.hpp │ ├── id_map.hpp │ ├── id_parser.hpp │ ├── named_option_helper.hpp │ ├── named_type.hpp │ ├── named_type_validators.hpp │ ├── optional_comparison.hpp │ ├── print_helper.hpp │ └── type_traits.hpp │ ├── document.hpp │ ├── element_variant.hpp │ ├── elements.hpp │ ├── elements │ ├── audio_block_format_binaural.hpp │ ├── audio_block_format_direct_speakers.hpp │ ├── audio_block_format_hoa.hpp │ ├── audio_block_format_id.hpp │ ├── audio_block_format_matrix.hpp │ ├── audio_block_format_objects.hpp │ ├── audio_channel_format.hpp │ ├── audio_channel_format_id.hpp │ ├── audio_content.hpp │ ├── audio_content_id.hpp │ ├── audio_object.hpp │ ├── audio_object_id.hpp │ ├── audio_object_interaction.hpp │ ├── audio_pack_format.hpp │ ├── audio_pack_format_hoa.hpp │ ├── audio_pack_format_id.hpp │ ├── audio_programme.hpp │ ├── audio_programme_id.hpp │ ├── audio_programme_ref_screen.hpp │ ├── audio_stream_format.hpp │ ├── audio_stream_format_id.hpp │ ├── audio_track_format.hpp │ ├── audio_track_format_id.hpp │ ├── audio_track_uid.hpp │ ├── audio_track_uid_id.hpp │ ├── channel_lock.hpp │ ├── common_parameters.hpp │ ├── dialogue.hpp │ ├── format_descriptor.hpp │ ├── frequency.hpp │ ├── gain.hpp │ ├── gain_interaction_range.hpp │ ├── head_locked.hpp │ ├── headphone_virtualise.hpp │ ├── importance.hpp │ ├── jump_position.hpp │ ├── label.hpp │ ├── loudness_metadata.hpp │ ├── nfc_ref_dist.hpp │ ├── normalization.hpp │ ├── object_divergence.hpp │ ├── position.hpp │ ├── position_interaction_range.hpp │ ├── position_offset.hpp │ ├── position_offset_types.hpp │ ├── position_types.hpp │ ├── private │ │ ├── auto_parent.hpp │ │ └── parent_attorneys.hpp │ ├── profile_list.hpp │ ├── screen_edge_lock.hpp │ ├── screen_ref.hpp │ ├── speaker_position.hpp │ ├── time.hpp │ └── type_descriptor.hpp │ ├── elements_fwd.hpp │ ├── errors.hpp │ ├── helper │ ├── element_range.hpp │ └── get_optional_property.hpp │ ├── parse.hpp │ ├── path.hpp │ ├── private │ ├── changed_id_traits.hpp │ ├── copy.hpp │ ├── document_parser.hpp │ ├── rapidxml_formatter.hpp │ ├── rapidxml_utils.hpp │ ├── rapidxml_wrapper.hpp │ ├── xml_parser_helper.hpp │ └── xml_writer.hpp │ ├── route.hpp │ ├── route_tracer.hpp │ ├── serial.hpp │ ├── serial │ ├── audio_track.hpp │ ├── changed_ids.hpp │ ├── frame_format.hpp │ ├── frame_format_id.hpp │ ├── frame_header.hpp │ ├── frame_header_parser.hpp │ ├── transport_id.hpp │ └── transport_track_format.hpp │ ├── utilities │ ├── block_duration_assignment.hpp │ ├── comparator.hpp │ ├── copy.hpp │ ├── element_io.hpp │ ├── id_assignment.hpp │ ├── lookup.hpp │ ├── object_creation.hpp │ └── time_conversion.hpp │ └── write.hpp ├── resources └── common_definitions.xml ├── src ├── CMakeLists.txt ├── common_definitions.cpp ├── detail │ └── id_assigner.cpp ├── document.cpp ├── elements │ ├── audio_block_format_binaural.cpp │ ├── audio_block_format_direct_speakers.cpp │ ├── audio_block_format_hoa.cpp │ ├── audio_block_format_id.cpp │ ├── audio_block_format_matrix.cpp │ ├── audio_block_format_objects.cpp │ ├── audio_channel_format.cpp │ ├── audio_channel_format_id.cpp │ ├── audio_content.cpp │ ├── audio_content_id.cpp │ ├── audio_object.cpp │ ├── audio_object_id.cpp │ ├── audio_object_interaction.cpp │ ├── audio_pack_format.cpp │ ├── audio_pack_format_hoa.cpp │ ├── audio_pack_format_id.cpp │ ├── audio_programme.cpp │ ├── audio_programme_id.cpp │ ├── audio_stream_format.cpp │ ├── audio_stream_format_id.cpp │ ├── audio_track_format.cpp │ ├── audio_track_format_id.cpp │ ├── audio_track_uid.cpp │ ├── audio_track_uid_id.cpp │ ├── channel_lock.cpp │ ├── common_parameters.cpp │ ├── format_descriptor.cpp │ ├── frequency.cpp │ ├── gain_interaction_range.cpp │ ├── headphone_virtualise.cpp │ ├── jump_position.cpp │ ├── label.cpp │ ├── loudness_metadata.cpp │ ├── object_divergence.cpp │ ├── position.cpp │ ├── position_interaction_range.cpp │ ├── position_offset.cpp │ ├── profile_list.cpp │ ├── screen_edge_lock.cpp │ ├── speaker_position.cpp │ ├── time.cpp │ └── type_descriptor.cpp ├── errors.cpp ├── parse.cpp ├── path.cpp ├── private │ ├── copy.cpp │ ├── document_parser.cpp │ ├── rapidxml_formatter.cpp │ ├── rapidxml_wrapper.cpp │ └── xml_writer.cpp ├── serial │ ├── audio_track.cpp │ ├── changed_ids.cpp │ ├── frame_format.cpp │ ├── frame_format_id.cpp │ ├── frame_header.cpp │ ├── frame_header_parser.cpp │ ├── sadm_xml_reader.cpp │ ├── transport_id.cpp │ └── transport_track_format.cpp ├── utilities │ ├── block_duration_assignment.cpp │ ├── copy.cpp │ ├── id_assignment.cpp │ └── object_creation.cpp └── write.cpp ├── submodules ├── catch2.cmake ├── catch2 │ ├── catch.hpp │ └── catch_main.cpp ├── rapidxml.cmake └── rapidxml │ ├── license.txt │ ├── manual.html │ ├── rapidxml.hpp │ ├── rapidxml_iterators.hpp │ ├── rapidxml_print.hpp │ └── rapidxml_utils.hpp └── tests ├── CMakeLists.txt ├── adm_auto_parenting_tests.cpp ├── adm_common_definitions_tests.cpp ├── adm_document_tests.cpp ├── adm_id_tests.cpp ├── adm_time_tests.cpp ├── audio_block_format_binaural_tests.cpp ├── audio_block_format_common_tests.cpp ├── audio_block_format_direct_speakers_tests.cpp ├── audio_block_format_hoa_tests.cpp ├── audio_block_format_matrix_tests.cpp ├── audio_block_format_objects_tests.cpp ├── audio_channel_format_tests.cpp ├── audio_content_tests.cpp ├── audio_object_interaction_tests.cpp ├── audio_object_tests.cpp ├── audio_pack_format_hoa_tests.cpp ├── audio_pack_format_tests.cpp ├── audio_programme_tests.cpp ├── audio_stream_format_tests.cpp ├── audio_track_format_tests.cpp ├── audio_track_uid_tests.cpp ├── auto_base_tests.cpp ├── benchmarks.cpp ├── block_duration_fixing_tests.cpp ├── channel_lock_tests.cpp ├── dialogue_tests.cpp ├── enum_bitmask_options_tests.cpp ├── format_descriptor_tests.cpp ├── frame_format_tests.cpp ├── frame_header_parser_frame_format_tests.cpp ├── frequency_tests.cpp ├── gain_interaction_range_tests.cpp ├── gain_tests.cpp ├── headphone_virtualise_tests.cpp ├── helper ├── file_comparator.hpp ├── ostream_operators.hpp ├── parameter_checks.hpp └── parameter_comparators.hpp ├── id_parser_tests.cpp ├── jump_position_tests.cpp ├── label_tests.cpp ├── loudness_metadata_tests.cpp ├── named_type_tests.cpp ├── object_creation_tests.cpp ├── object_divergence_tests.cpp ├── position_interaction_range_tests.cpp ├── position_offset_tests.cpp ├── position_tests.cpp ├── profile_list_tests.cpp ├── route_tracer_tests.cpp ├── screen_edge_lock_tests.cpp ├── speaker_position_tests.cpp ├── test_data ├── loudness_metadata.accepted.xml ├── profile_list.accepted.xml ├── profile_list_frame_header.accepted.xml ├── simple_scene_default.accepted.xml ├── simple_scene_itu.accepted.xml ├── sink.xml ├── version.accepted.xml ├── write_audio_block_format_objects.accepted.xml ├── write_audio_content.accepted.xml ├── write_audio_object_interaction.accepted.xml ├── write_audio_programme.accepted.xml ├── write_audio_track_uid_channel_format_reference.accepted.xml ├── write_complementary_audio_objects.accepted.xml ├── write_default_HOA_block.accepted.xml ├── write_default_binaural_block.accepted.xml ├── write_default_cartesian_speaker.accepted.xml ├── write_default_spherical_speaker.accepted.xml ├── write_labels.accepted.xml ├── write_local_time_reference.accepted.xml ├── write_mixed_objects_and_structures.accepted.xml ├── write_object_attributes.accepted.xml ├── write_objects_silent_track_ref.accepted.xml ├── write_objects_with_position_offset.accepted.xml ├── write_optional_defaults.accepted.xml ├── write_partially_specified_cartesian.accepted.xml ├── write_partially_specified_spherical.accepted.xml ├── write_simple_common_definitions_object.accepted.xml ├── write_simple_object.accepted.xml ├── write_simple_object_short_structure.accepted.xml ├── write_specified_HOA_block.accepted.xml ├── write_specified_binaural_block.accepted.xml ├── write_specified_binaural_block_sadm.accepted.xml ├── write_specified_cartesian_speaker.accepted.xml ├── write_specified_headphone_virtualise.accepted.xml ├── write_specified_spherical_speaker.accepted.xml ├── write_time_format.accepted.xml ├── write_time_format_sadm.accepted.xml ├── write_total_time_reference.accepted.xml └── xml_parser │ ├── audio_block_format_binaural.xml │ ├── audio_block_format_direct_speakers.xml │ ├── audio_block_format_direct_speakers_cartesian.xml │ ├── audio_block_format_direct_speakers_cartesian_bad_bound.xml │ ├── audio_block_format_direct_speakers_cartesian_bad_coord.xml │ ├── audio_block_format_hoa.xml │ ├── audio_block_format_objects.xml │ ├── audio_block_format_objects_gain_unit_error.xml │ ├── audio_channel_format.xml │ ├── audio_channel_format_duplicate_id.xml │ ├── audio_content.xml │ ├── audio_content_duplicate_id.xml │ ├── audio_object.xml │ ├── audio_object_complementary_audio_objects.xml │ ├── audio_object_duplicate_id.xml │ ├── audio_object_interaction.xml │ ├── audio_object_position_offset.xml │ ├── audio_object_track_refs.xml │ ├── audio_pack_format.xml │ ├── audio_pack_format_duplicate_id.xml │ ├── audio_pack_format_hoa.xml │ ├── audio_programme.xml │ ├── audio_programme_duplicate_id.xml │ ├── audio_stream_format.xml │ ├── audio_stream_format_duplicate_id.xml │ ├── audio_track_format.xml │ ├── audio_track_format_duplicate_id.xml │ ├── audio_track_uid.xml │ ├── audio_track_uid_channel_format_reference.xml │ ├── audio_track_uid_duplicate_id.xml │ ├── audio_track_uid_track_format_reference.xml │ ├── find_audio_format_extended_ebu.xml │ ├── find_audio_format_extended_ebu_with_other_metadata.xml │ ├── find_audio_format_extended_itu.xml │ ├── labels.xml │ ├── loudness_metadata.xml │ ├── profile_list.xml │ ├── time_format.xml │ ├── time_format_sadm.xml │ ├── unresolved_references │ ├── audio_content.xml │ ├── audio_object_1.xml │ ├── audio_object_2.xml │ ├── audio_object_3.xml │ ├── audio_pack_format_1.xml │ ├── audio_pack_format_2.xml │ ├── audio_programme.xml │ ├── audio_stream_format_1.xml │ ├── audio_stream_format_2.xml │ ├── audio_track_format.xml │ ├── audio_track_uid_1.xml │ └── audio_track_uid_2.xml │ ├── version.xml │ └── with_common_definitions.xml ├── type_descriptor_tests.cpp ├── version_tests.cpp ├── xml_audio_block_format_objects_tests.cpp ├── xml_loudness_metadata_tests.cpp ├── xml_parser_audio_block_format_binaural_tests.cpp ├── xml_parser_audio_block_format_direct_speakers_tests.cpp ├── xml_parser_audio_block_format_hoa_tests.cpp ├── xml_parser_audio_channel_format_tests.cpp ├── xml_parser_audio_content_tests.cpp ├── xml_parser_audio_object_tests.cpp ├── xml_parser_audio_pack_format_tests.cpp ├── xml_parser_audio_programme_tests.cpp ├── xml_parser_audio_stream_format_tests.cpp ├── xml_parser_audio_track_format_tests.cpp ├── xml_parser_audio_track_uid_tests.cpp ├── xml_parser_common_definitions_tests.cpp ├── xml_parser_find_audio_format_extended_tests.cpp ├── xml_parser_label_tests.cpp ├── xml_parser_tests.cpp ├── xml_parser_unresolved_references_tests.cpp ├── xml_time_format_tests.cpp ├── xml_writer_audio_block_format_tests.cpp ├── xml_writer_audio_content_tests.cpp ├── xml_writer_audio_object_interaction_tests.cpp ├── xml_writer_audio_programme_tests.cpp ├── xml_writer_audio_track_uid_tests.cpp ├── xml_writer_label_tests.cpp ├── xml_writer_objects_creation_tests.cpp └── xml_writer_tests.cpp /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: Google 2 | NamespaceIndentation: All 3 | AlignTrailingComments: false 4 | SortIncludes: false 5 | ReflowComments: false 6 | -------------------------------------------------------------------------------- /.clang_complete: -------------------------------------------------------------------------------- 1 | -I. 2 | -I./include 3 | -I./build/src 4 | -I./build 5 | -I./submodules 6 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build* 2 | *.swp 3 | .DS_Store 4 | .vscode 5 | .idea 6 | docs/.build 7 | docs/venv 8 | *.user 9 | cmake-build-* 10 | -------------------------------------------------------------------------------- /.readthedocs.yml: -------------------------------------------------------------------------------- 1 | python: 2 | version: 3 3 | requirements_file: docs/requirements.txt 4 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /cmake/uninstall.cmake.in: -------------------------------------------------------------------------------- 1 | # Custom uninstall target see: 2 | # https://cmake.org/Wiki/CMake_FAQ#Can_I_do_.22make_uninstall.22_with_CMake.3F 3 | 4 | # cmake_policy(SET CMP0007 NEW) 5 | if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 6 | message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") 7 | endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 8 | 9 | file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) 10 | string(REGEX REPLACE "\n" ";" files "${files}") 11 | list(REVERSE files) 12 | foreach (file ${files}) 13 | message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") 14 | if (EXISTS "$ENV{DESTDIR}${file}") 15 | execute_process( 16 | COMMAND @CMAKE_COMMAND@ -E remove "$ENV{DESTDIR}${file}" 17 | OUTPUT_VARIABLE rm_out 18 | RESULT_VARIABLE rm_retval 19 | ) 20 | if(NOT ${rm_retval} EQUAL 0) 21 | message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") 22 | endif (NOT ${rm_retval} EQUAL 0) 23 | else (EXISTS "$ENV{DESTDIR}${file}") 24 | message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") 25 | endif (EXISTS "$ENV{DESTDIR}${file}") 26 | endforeach(file) 27 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | ignore: 2 | - "/usr/**/*" 3 | - "examples/*" 4 | - "examples/**/*" 5 | - "submodules/*" 6 | - "submodules/**/*" 7 | - "tests/*" 8 | - "tests/**/*" 9 | - "tools/*" 10 | - "tools/**/*" 11 | -------------------------------------------------------------------------------- /config/admConfig.cmake.in: -------------------------------------------------------------------------------- 1 | include(CMakeFindDependencyMacro) 2 | 3 | @PACKAGE_INIT@ 4 | 5 | find_dependency(Boost 1.57) 6 | 7 | set(errorVar ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE) 8 | set(foundVar ${CMAKE_FIND_PACKAGE_NAME}_FOUND) 9 | set(findQuietly ${${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY}) 10 | 11 | if(${adm_USE_STATIC_LIBS}) 12 | if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/admTargetsStatic.cmake") 13 | include("${CMAKE_CURRENT_LIST_DIR}/admTargetsStatic.cmake") 14 | else() 15 | set(${errorVar} "Could not find static version of libadm.") 16 | set(${foundVar} FALSE) 17 | return() 18 | endif() 19 | elseif(${adm_USE_SHARED_LIBS}) 20 | if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/admTargetsShared.cmake") 21 | include("${CMAKE_CURRENT_LIST_DIR}/admTargetsShared.cmake") 22 | else() 23 | set(${errorVar} "Could not find shared version of libadm.") 24 | set(${foundVar} FALSE) 25 | return() 26 | endif() 27 | else() 28 | if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/admTargetsShared.cmake") 29 | include("${CMAKE_CURRENT_LIST_DIR}/admTargetsShared.cmake") 30 | else() 31 | include("${CMAKE_CURRENT_LIST_DIR}/admTargetsStatic.cmake") 32 | endif() 33 | endif() 34 | 35 | check_required_components(adm) 36 | 37 | if(NOT findQuietly) 38 | get_target_property(adm_LOCATION_ONLY_FOR_DISPLAY adm LOCATION) 39 | message(STATUS "Found adm library ${adm_VERSION}: ${adm_LOCATION_ONLY_FOR_DISPLAY}") 40 | endif() 41 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /docs/changelog.rst: -------------------------------------------------------------------------------- 1 | .. changelog: 2 | 3 | .. mdinclude:: ../CHANGELOG.md 4 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. libadm documentation master file 2 | 3 | .. image:: irt_logo.png 4 | :alt: IRT Logo 5 | 6 | ------------------------------ 7 | 8 | libadm – ITU-R BS.2076 Library 9 | ============================== 10 | 11 | .. toctree:: 12 | :hidden: 13 | :maxdepth: 1 14 | 15 | getting_started 16 | tutorial 17 | library_design 18 | changelog 19 | 20 | .. toctree:: 21 | :hidden: 22 | :maxdepth: 2 23 | :caption: Reference 24 | 25 | reference_document 26 | element_api 27 | reference_elements 28 | reference_sadm_elements 29 | reference_helpers 30 | reference_utilities 31 | reference_read_write 32 | 33 | The `libadm `_ library is a modern 34 | C++11 library to parse, modify, create and write `Recommendation ITU-R BS.2076-1 35 | `_ conform XML document. It works well 36 | with the header-only library `libbw64 37 | `_ to write ADM related applications 38 | with minimal dependencies. 39 | 40 | Features 41 | -------- 42 | 43 | - minimal dependencies 44 | - expressive syntax 45 | - easy access to referenced ADM elements 46 | - common definitions support 47 | 48 | Acknowledgement 49 | --------------- 50 | 51 | This project has received funding from the European Union’s Horizon 2020 52 | research and innovation programme under grant agreement No 687645. 53 | -------------------------------------------------------------------------------- /docs/irt_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebu/libadm/ee831285c5131c34c17abbfb3dc4a090e8999395/docs/irt_logo.png -------------------------------------------------------------------------------- /docs/reference_document.rst: -------------------------------------------------------------------------------- 1 | .. reference_document: 2 | 3 | ADM Document 4 | ############ 5 | 6 | .. doxygenclass:: adm::Document 7 | .. doxygentypedef:: adm::Version 8 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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_sadm_elements.rst: -------------------------------------------------------------------------------- 1 | .. reference_sadm_elements: 2 | 3 | SADM Elements 4 | ############# 5 | 6 | Frame Header 7 | ------------ 8 | 9 | .. doxygenclass:: adm::FrameHeader 10 | .. doxygenclass:: adm::ProfileList 11 | .. doxygentypedef:: adm::TransportTrackFormats 12 | 13 | FrameFormat 14 | ----------- 15 | 16 | .. doxygenclass:: adm::FrameFormat 17 | .. doxygenclass:: adm::FrameFormatId 18 | .. doxygenenum:: adm::FrameType 19 | .. doxygenenum:: adm::TimeReference 20 | .. doxygentypedef:: adm::FlowId 21 | .. doxygentypedef:: adm::CountToFull 22 | .. doxygentypedef:: adm::NumMetadataChunks 23 | .. doxygentypedef:: adm::CountToSameChunk 24 | .. doxygentypedef:: adm::FrameIndex 25 | .. doxygentypedef:: adm::ChunkIndex 26 | 27 | ChangedIds 28 | ---------- 29 | 30 | .. doxygenclass:: adm::ChangedIds 31 | .. doxygenclass:: adm::ChangedId 32 | .. doxygenenum:: adm::ChangedIdStatus 33 | .. doxygentypedef:: adm::ChangedAudioChannelFormatIds 34 | .. doxygentypedef:: adm::ChangedAudioPackFormatIds 35 | .. doxygentypedef:: adm::ChangedAudioTrackUidIds 36 | .. doxygentypedef:: adm::ChangedAudioStreamFormatIds 37 | .. doxygentypedef:: adm::ChangedAudioObjectIds 38 | .. doxygentypedef:: adm::ChangedAudioContentIds 39 | .. doxygentypedef:: adm::ChangedAudioProgrammeIds 40 | 41 | TransportTrackFormat 42 | -------------------- 43 | 44 | .. doxygenclass:: adm::TransportTrackFormat 45 | .. doxygenclass:: adm::TransportId 46 | .. doxygentypedef:: adm::TransportName 47 | .. doxygentypedef:: adm::NumTracks 48 | .. doxygentypedef:: adm::NumIds 49 | .. doxygentypedef:: adm::AudioTracks 50 | 51 | AudioTrack 52 | ---------- 53 | .. doxygenclass:: adm::AudioTrack 54 | .. doxygentypedef:: adm::TrackId 55 | .. doxygentypedef:: adm::AudioTrackUidRefs -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /examples/create_sadm_from_scratch.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "adm/elements.hpp" 4 | #include "adm/serial.hpp" 5 | #include "adm/utilities/id_assignment.hpp" 6 | #include "adm/utilities/object_creation.hpp" 7 | #include "adm/write.hpp" 8 | 9 | int main() { 10 | using namespace adm; 11 | auto uuid = "1f399874-dfa9-4a9b-82cd-fedc483d1223"; 12 | auto frameFormatId = parseFrameFormatId("FF_00000001"); 13 | auto frameHeader = FrameHeader{FrameFormat{ 14 | frameFormatId, Start(std::chrono::milliseconds(0)), 15 | Duration(std::chrono::milliseconds(40)), FrameType::FULL, FlowId{uuid}}}; 16 | auto document = Document::create(); 17 | 18 | // create ADM elements 19 | auto admProgramme = AudioProgramme::create( 20 | AudioProgrammeName("Alice and Bob talking in the forrest")); 21 | auto speechContent = AudioContent::create(AudioContentName("Speech")); 22 | auto atmoContent = AudioContent::create(AudioContentName("Atmo")); 23 | 24 | admProgramme->addReference(speechContent); 25 | admProgramme->addReference(atmoContent); 26 | auto holder1 = createSimpleObject("Alice"); 27 | speechContent->addReference(holder1.audioObject); 28 | 29 | auto holder2 = createSimpleObject("Bob"); 30 | speechContent->addReference(holder2.audioObject); 31 | 32 | document->add(admProgramme); 33 | 34 | reassignIds(document); 35 | 36 | auto trackFormat = TransportTrackFormat(TransportId(TransportIdValue(1))); 37 | 38 | AudioTrack audioTrack1(TrackId(1)); 39 | audioTrack1.add(holder1.audioTrackUid->get()); 40 | trackFormat.add(audioTrack1); 41 | 42 | AudioTrack audioTrack2(TrackId(2)); 43 | audioTrack2.add(holder2.audioTrackUid->get()); 44 | trackFormat.add(audioTrack2); 45 | 46 | frameHeader.add(trackFormat); 47 | 48 | // write XML data to stdout 49 | std::stringstream xmlStream; 50 | writeXml(xmlStream, document, frameHeader); 51 | std::cout << xmlStream.str(); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /examples/multiple_languages_1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "adm/adm.hpp" 4 | #include "adm/utilities/object_creation.hpp" 5 | #include "adm/write.hpp" 6 | 7 | int main() { 8 | using namespace adm; 9 | 10 | // create ADM elements 11 | auto programmeEn = AudioProgramme::create( 12 | AudioProgrammeName("English Programme"), AudioProgrammeLanguage("en")); 13 | auto programmeDe = AudioProgramme::create( 14 | AudioProgrammeName("German Programme"), AudioProgrammeLanguage("de")); 15 | auto contentEn = AudioContent::create(AudioContentName("Englisch Content"), 16 | AudioContentLanguage("en")); 17 | auto contentDe = AudioContent::create(AudioContentName("German Content"), 18 | AudioContentLanguage("de")); 19 | auto ambienceContent = AudioContent::create(AudioContentName("Ambience")); 20 | auto musicContent = AudioContent::create(AudioContentName("Music")); 21 | 22 | auto englishNarrator = createSimpleObject("English Narrator"); 23 | auto germanNarrator = createSimpleObject("German Narrator"); 24 | auto ambience = createSimpleObject("Ambience"); 25 | auto music = createSimpleObject("Music"); 26 | 27 | englishNarrator.audioChannelFormat->add( 28 | AudioBlockFormatObjects(SphericalPosition())); 29 | germanNarrator.audioChannelFormat->add( 30 | AudioBlockFormatObjects(SphericalPosition())); 31 | ambience.audioChannelFormat->add( 32 | AudioBlockFormatObjects(SphericalPosition())); 33 | music.audioChannelFormat->add(AudioBlockFormatObjects(SphericalPosition())); 34 | 35 | programmeEn->addReference(contentEn); 36 | programmeEn->addReference(ambienceContent); 37 | programmeEn->addReference(musicContent); 38 | programmeDe->addReference(contentDe); 39 | programmeDe->addReference(ambienceContent); 40 | programmeDe->addReference(musicContent); 41 | 42 | contentEn->addReference(englishNarrator.audioObject); 43 | contentDe->addReference(germanNarrator.audioObject); 44 | ambienceContent->addReference(ambience.audioObject); 45 | musicContent->addReference(music.audioObject); 46 | 47 | auto admDocument = Document::create(); 48 | admDocument->add(programmeEn); 49 | admDocument->add(programmeDe); 50 | 51 | // write XML data to stdout 52 | std::stringstream xmlStream; 53 | writeXml(xmlStream, admDocument); 54 | std::cout << xmlStream.str(); 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /examples/multiple_languages_2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "adm/adm.hpp" 4 | #include "adm/utilities/object_creation.hpp" 5 | #include "adm/write.hpp" 6 | 7 | int main() { 8 | using namespace adm; 9 | 10 | // create ADM elements 11 | auto programme = AudioProgramme::create(AudioProgrammeName("Programme")); 12 | auto contentEn = AudioContent::create(AudioContentName("Englisch Content"), 13 | AudioContentLanguage("en")); 14 | auto contentDe = AudioContent::create(AudioContentName("German Content"), 15 | AudioContentLanguage("de")); 16 | auto ambienceContent = AudioContent::create(AudioContentName("Ambience")); 17 | auto musicContent = AudioContent::create(AudioContentName("Music")); 18 | 19 | auto englishNarrator = createSimpleObject("English Narrator"); 20 | auto germanNarrator = createSimpleObject("German Narrator"); 21 | auto ambience = createSimpleObject("Ambience"); 22 | auto music = createSimpleObject("Music"); 23 | 24 | englishNarrator.audioChannelFormat->add( 25 | AudioBlockFormatObjects(SphericalPosition())); 26 | englishNarrator.audioObject->addComplementary(germanNarrator.audioObject); 27 | germanNarrator.audioChannelFormat->add( 28 | AudioBlockFormatObjects(SphericalPosition())); 29 | ambience.audioChannelFormat->add( 30 | AudioBlockFormatObjects(SphericalPosition())); 31 | music.audioChannelFormat->add(AudioBlockFormatObjects(SphericalPosition())); 32 | 33 | programme->addReference(contentEn); 34 | programme->addReference(contentDe); 35 | programme->addReference(ambienceContent); 36 | programme->addReference(musicContent); 37 | 38 | contentEn->addReference(englishNarrator.audioObject); 39 | contentDe->addReference(germanNarrator.audioObject); 40 | ambienceContent->addReference(ambience.audioObject); 41 | musicContent->addReference(music.audioObject); 42 | 43 | auto admDocument = Document::create(); 44 | admDocument->add(programme); 45 | 46 | // write XML data to stdout 47 | std::stringstream xmlStream; 48 | writeXml(xmlStream, admDocument); 49 | std::cout << xmlStream.str(); 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /examples/voice_over.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "adm/adm.hpp" 4 | #include "adm/utilities/object_creation.hpp" 5 | #include "adm/write.hpp" 6 | 7 | int main() { 8 | using namespace adm; 9 | 10 | // create ADM elements 11 | auto programme = AudioProgramme::create(AudioProgrammeName("Programme")); 12 | auto programmeVoiceOver = 13 | AudioProgramme::create(AudioProgrammeName("Programme - Voice Over")); 14 | 15 | auto speechContent = AudioContent::create(AudioContentName("Speech")); 16 | auto speechDuckedContent = 17 | AudioContent::create(AudioContentName("Speech Ducked")); 18 | auto voiceOverContent = AudioContent::create(AudioContentName("Voice Over")); 19 | 20 | auto speech = createSimpleObject("Speech"); 21 | auto speechDucked = createSimpleObject("Speech Ducked"); 22 | auto voiceOver = createSimpleObject("Voice Over"); 23 | 24 | speech.audioChannelFormat->add(AudioBlockFormatObjects(SphericalPosition())); 25 | speechDucked.audioChannelFormat->add( 26 | AudioBlockFormatObjects(SphericalPosition())); 27 | voiceOver.audioChannelFormat->add( 28 | AudioBlockFormatObjects(SphericalPosition())); 29 | 30 | programme->addReference(speechContent); 31 | programmeVoiceOver->addReference(speechDuckedContent); 32 | programmeVoiceOver->addReference(voiceOverContent); 33 | 34 | speechContent->addReference(speech.audioObject); 35 | speechDuckedContent->addReference(speechDucked.audioObject); 36 | voiceOverContent->addReference(voiceOver.audioObject); 37 | 38 | auto admDocument = Document::create(); 39 | admDocument->add(programme); 40 | admDocument->add(programmeVoiceOver); 41 | 42 | // write XML data to stdout 43 | std::stringstream xmlStream; 44 | writeXml(xmlStream, admDocument); 45 | std::cout << xmlStream.str(); 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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