Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,14 @@ jobs:
uses: lukka/get-cmake@latest

- name: Restore artifacts, or run vcpkg, build and cache artifacts
uses: lukka/run-vcpkg@v7
uses: lukka/run-vcpkg@v11
id: runvcpkg
with:
vcpkgArguments: 'boost-variant boost-optional boost-format boost-functional boost-range boost-iterator boost-rational'
vcpkgTriplet: '${{ matrix.triplet }}'
vcpkgDirectory: '${{ runner.workspace }}/b/vcpkg'
vcpkgGitCommitId: '7ad236f60f5f7197e93c4d7f0807622f4899076d'
vcpkgGitCommitId: 'b46d9050a9d40d54d24cac3ef8d50402d421f598'

# Setup MSVC environment on windows, otherwise we get minsys2 / gcc
- uses: ilammy/msvc-dev-cmd@v1

- name: 'Install ubuntu dependencies'
if: matrix.os == 'ubuntu-latest'
Expand Down
1 change: 1 addition & 0 deletions include/adm/elements.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@

#include "adm/elements/time.hpp"
#include "adm/elements/audio_programme_ref_screen.hpp"
#include "adm/elements/cartesian.hpp"
#include "adm/elements/channel_lock.hpp"
#include "adm/elements/dialogue.hpp"
#include "adm/elements/format_descriptor.hpp"
Expand Down
14 changes: 14 additions & 0 deletions include/adm/elements/audio_block_format_direct_speakers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ namespace adm {
* +---------------------+------------------------------------+----------------------------+
* | initializeBlock | :type:`InitializeBlock` | :class:`OptionalParameter` |
* +---------------------+------------------------------------+----------------------------+
* | cartesian | :type:`Cartesian` | custom, see below |
* +---------------------+------------------------------------+----------------------------+
* | position | - :type:`SpeakerPosition` | :class:`VariantParameter` |
* | | - :type:`SphericalSpeakerPosition` | |
* | | - :type:`CartesianSpeakerPosition` | :class:`RequiredParameter` |
Expand All @@ -83,6 +85,11 @@ namespace adm {
* | speakerLabel | :type:`SpeakerLabels` | :class:`VectorParameter` |
* +---------------------+------------------------------------+----------------------------+
* \endrst
*
* ``cartesian`` and ``position`` attributes are linked; see
* :func:`void set(Cartesian)`, :func:`void set(SpeakerPosition)`,
* :func:`void set(CartesianSpeakerPosition)` and
* :func:`void set(SphericalSpeakerPosition)`.
*
* @warning not all methods are implemented for speakerLabel
*/
Expand Down Expand Up @@ -138,6 +145,8 @@ namespace adm {
ADM_EXPORT void set(Rtime rtime);
/// @brief Duration setter
ADM_EXPORT void set(Duration duration);
/// @brief Cartesian setter
ADM_EXPORT void set(Cartesian cartesian);
/// @brief CartesianSpeakerPosition setter
ADM_EXPORT void set(CartesianSpeakerPosition speakerPosition);
/// @brief SphericalSpeakerPosition setter
Expand Down Expand Up @@ -174,6 +183,7 @@ namespace adm {
ADM_EXPORT Duration get(detail::ParameterTraits<Duration>::tag) const;
ADM_EXPORT SpeakerLabels
get(detail::ParameterTraits<SpeakerLabels>::tag) const;
ADM_EXPORT Cartesian get(detail::ParameterTraits<Cartesian>::tag) const;
ADM_EXPORT CartesianSpeakerPosition
get(detail::ParameterTraits<CartesianSpeakerPosition>::tag) const;
ADM_EXPORT SphericalSpeakerPosition
Expand All @@ -183,6 +193,7 @@ namespace adm {
ADM_EXPORT bool has(detail::ParameterTraits<Rtime>::tag) const;
ADM_EXPORT bool has(detail::ParameterTraits<Duration>::tag) const;
ADM_EXPORT bool has(detail::ParameterTraits<SpeakerLabels>::tag) const;
ADM_EXPORT bool has(detail::ParameterTraits<Cartesian>::tag) const;
ADM_EXPORT bool has(
detail::ParameterTraits<CartesianSpeakerPosition>::tag) const;
ADM_EXPORT bool has(
Expand All @@ -192,15 +203,18 @@ namespace adm {
bool isDefault(Tag) const {
return false;
}
ADM_EXPORT bool isDefault(detail::ParameterTraits<Cartesian>::tag) const;

ADM_EXPORT void unset(detail::ParameterTraits<Rtime>::tag);
ADM_EXPORT void unset(detail::ParameterTraits<Duration>::tag);
ADM_EXPORT void unset(detail::ParameterTraits<SpeakerLabels>::tag);
ADM_EXPORT void unset(detail::ParameterTraits<Cartesian>::tag);

AudioBlockFormatId id_;
boost::optional<Rtime> rtime_;
boost::optional<Duration> duration_;
SpeakerLabels speakerLabels_;
boost::optional<Cartesian> cartesian_;
SpeakerPosition speakerPosition_;
};

Expand Down
5 changes: 0 additions & 5 deletions include/adm/elements/audio_block_format_objects.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,6 @@
namespace adm {

class Document;

/// @brief Tag for NamedType ::Cartesian
struct CartesianTag {};
/// @brief NamedType for cartesian parameter
using Cartesian = detail::NamedType<bool, CartesianTag>;
/// @brief Tag for NamedType ::Width
struct WidthTag {};
/// @brief NamedType for width parameter
Expand Down
11 changes: 11 additions & 0 deletions include/adm/elements/cartesian.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/// @file cartesian.hpp
#pragma once

#include "adm/detail/named_type.hpp"

namespace adm {
/// @brief Tag for NamedType ::Cartesian
struct CartesianTag {};
/// @brief NamedType for cartesian parameter
using Cartesian = detail::NamedType<bool, CartesianTag>;
} // namespace adm
1 change: 1 addition & 0 deletions include/adm/elements/common_parameters.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once
#include "adm/detail/auto_base.hpp"
#include "adm/elements/audio_block_format_id.hpp"
#include "adm/elements/cartesian.hpp"
#include "adm/elements/gain.hpp"
#include "adm/elements/headphone_virtualise.hpp"
#include "adm/elements/head_locked.hpp"
Expand Down
50 changes: 49 additions & 1 deletion src/elements/audio_block_format_direct_speakers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ namespace adm {
detail::ParameterTraits<SpeakerLabels>::tag) const {
return speakerLabels_;
}
Cartesian AudioBlockFormatDirectSpeakers::get(
detail::ParameterTraits<Cartesian>::tag) const {
if (cartesian_ != boost::none) {
return cartesian_.get();
} else {
if (has<SphericalSpeakerPosition>()) {
return Cartesian(false);
} else {
return Cartesian(true);
}
}
}
CartesianSpeakerPosition AudioBlockFormatDirectSpeakers::get(
detail::ParameterTraits<CartesianSpeakerPosition>::tag) const {
return boost::get<CartesianSpeakerPosition>(speakerPosition_);
Expand All @@ -50,6 +62,10 @@ namespace adm {
detail::ParameterTraits<SpeakerLabels>::tag) const {
return speakerLabels_.size() > 0;
}
bool AudioBlockFormatDirectSpeakers::has(
detail::ParameterTraits<Cartesian>::tag) const {
return true;
}
bool AudioBlockFormatDirectSpeakers::has(
detail::ParameterTraits<CartesianSpeakerPosition>::tag) const {
return (boost::get<CartesianSpeakerPosition>(&speakerPosition_));
Expand All @@ -64,23 +80,48 @@ namespace adm {
detail::ParameterTraits<Rtime>::tag) const {
return duration_ == boost::none;
}
bool AudioBlockFormatDirectSpeakers::isDefault(
detail::ParameterTraits<Cartesian>::tag) const {
return cartesian_ == boost::none;
}

// ---- Setter ---- //
void AudioBlockFormatDirectSpeakers::set(AudioBlockFormatId id) { id_ = id; }
void AudioBlockFormatDirectSpeakers::set(Rtime rtime) { rtime_ = rtime; }
void AudioBlockFormatDirectSpeakers::set(Duration duration) {
duration_ = duration;
}
void AudioBlockFormatDirectSpeakers::set(Cartesian cartesian) {
cartesian_ = cartesian;

if (cartesian.get()) {
if (has<SphericalSpeakerPosition>()) {
speakerPosition_ = CartesianSpeakerPosition{};
}
} else {
if (has<CartesianSpeakerPosition>()) {
speakerPosition_ = SphericalSpeakerPosition{};
}
}
}
void AudioBlockFormatDirectSpeakers::set(
CartesianSpeakerPosition speakerPosition) {
speakerPosition_ = speakerPosition;
cartesian_ = Cartesian(true);
}
void AudioBlockFormatDirectSpeakers::set(
SphericalSpeakerPosition speakerPosition) {
speakerPosition_ = speakerPosition;
if (cartesian_ != boost::none) {
cartesian_ = Cartesian(false);
}
}
void AudioBlockFormatDirectSpeakers::set(SpeakerPosition speakerPosition) {
speakerPosition_ = speakerPosition;
if (speakerPosition.which() == 0) {
set(boost::get<SphericalSpeakerPosition>(speakerPosition));
} else if (speakerPosition.which() == 1) {
set(boost::get<CartesianSpeakerPosition>(speakerPosition));
}
}

// ---- Unsetter ---- //
Expand All @@ -96,6 +137,13 @@ namespace adm {
detail::ParameterTraits<SpeakerLabels>::tag) {
speakerLabels_.clear();
}
void AudioBlockFormatDirectSpeakers::unset(
detail::ParameterTraits<Cartesian>::tag) {
cartesian_ = boost::none;
if (!has<SphericalSpeakerPosition>()) {
set(SphericalSpeakerPosition{});
}
}

// ---- Add ---- //
bool AudioBlockFormatDirectSpeakers::add(SpeakerLabel speakerLabel) {
Expand Down
1 change: 1 addition & 0 deletions src/private/document_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,7 @@ namespace adm {
setOptionalAttribute<AudioBlockFormatId>(node, "audioBlockFormatID", audioBlockFormat, &parseAudioBlockFormatId);
addTimeParametersToBlock(node, audioBlockFormat, timeReference);
setOptionalAttribute<InitializeBlock>(node, "initializeBlock", audioBlockFormat);
setOptionalElement<Cartesian>(node, "cartesian", audioBlockFormat);
setMultiElement<SpeakerPosition>(node, "position", audioBlockFormat, &parseSpeakerPosition);
addOptionalElements<SpeakerLabel>(node, "speakerLabel", audioBlockFormat, &parseSpeakerLabel);
setOptionalElement<HeadLocked>(node, "headLocked", audioBlockFormat);
Expand Down
1 change: 1 addition & 0 deletions src/private/rapidxml_formatter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ namespace adm {
if(audioBlock.has<CartesianSpeakerPosition>()) {
node.addMultiElement<CartesianSpeakerPosition>(&audioBlock, "position", &formatCartesianSpeakerPosition);
}
node.addOptionalElement<Cartesian>(&audioBlock, "cartesian");

node.addOptionalElement<HeadLocked>(&audioBlock, "headLocked");
node.addOptionalElement<HeadphoneVirtualise>(&audioBlock, "headphoneVirtualise", &formatHeadphoneVirtualise);
Expand Down
68 changes: 68 additions & 0 deletions tests/audio_block_format_direct_speakers_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ TEST_CASE("DirectSpeakers block format common subelements") {
REQUIRE(blockFormat.has<Rtime>() == true);
REQUIRE(blockFormat.has<Duration>() == false);
REQUIRE(blockFormat.has<SpeakerLabels>() == false);
REQUIRE(blockFormat.has<Cartesian>() == true);

REQUIRE(blockFormat.isDefault<Rtime>() == true);
REQUIRE(blockFormat.isDefault<Cartesian>() == true);

auto defaultRtime = std::chrono::seconds{0};
REQUIRE(blockFormat.get<Rtime>().get() == defaultRtime);
REQUIRE(blockFormat.get<Cartesian>() == false);

auto rTime = std::chrono::seconds{1};
auto duration = std::chrono::seconds{10};
Expand Down Expand Up @@ -60,6 +63,8 @@ TEST_CASE("DirectSpeakers block format with Spherical coordinates") {
defaultPosition.get<Azimuth>());
REQUIRE(blockFormat.get<SphericalSpeakerPosition>().get<Elevation>() ==
defaultPosition.get<Elevation>());
REQUIRE(blockFormat.get<Cartesian>() == false);
REQUIRE(blockFormat.isDefault<Cartesian>() == true);

auto speakerPosition =
SphericalSpeakerPosition(Azimuth(30), Elevation(10), Distance(0.5));
Expand All @@ -70,6 +75,8 @@ TEST_CASE("DirectSpeakers block format with Spherical coordinates") {
Approx(10));
REQUIRE(blockFormat.get<SphericalSpeakerPosition>().get<Distance>() ==
Approx(0.5));
REQUIRE(blockFormat.get<Cartesian>() == false);
REQUIRE(blockFormat.isDefault<Cartesian>() == true);
}
}

Expand All @@ -85,4 +92,65 @@ TEST_CASE("DirectSpeakers block format with Cartesian coordinates") {
REQUIRE(retrievedPosition.get<X>() == speakerPosition.get<X>());
REQUIRE(retrievedPosition.get<Y>() == speakerPosition.get<Y>());
REQUIRE(retrievedPosition.get<Z>() == speakerPosition.get<Z>());
REQUIRE(blockFormat.get<Cartesian>() == true);
REQUIRE(blockFormat.isDefault<Cartesian>() == false);
}

TEST_CASE("DirectSpeakers block format cartesian interactions") {
using namespace adm;

SECTION("spherical speaker position does not set cartesian when unset") {
auto blockFormat = AudioBlockFormatDirectSpeakers{};
blockFormat.set(SphericalSpeakerPosition{Azimuth{30.0f}, Elevation{5.0f}});

REQUIRE(blockFormat.has<SphericalSpeakerPosition>() == true);
REQUIRE(blockFormat.has<CartesianSpeakerPosition>() == false);
REQUIRE(blockFormat.get<Cartesian>() == false);
REQUIRE(blockFormat.isDefault<Cartesian>() == true);
}

SECTION(
"unsetting cartesian with cartesian position sets default spherical") {
auto blockFormat = AudioBlockFormatDirectSpeakers{};
blockFormat.set(CartesianSpeakerPosition{X{0.8f}, Y{-0.3f}, Z{0.2f}});

REQUIRE(blockFormat.has<CartesianSpeakerPosition>() == true);
REQUIRE(blockFormat.get<Cartesian>() == true);

blockFormat.unset<Cartesian>();

REQUIRE(blockFormat.has<SphericalSpeakerPosition>() == true);
REQUIRE(blockFormat.has<CartesianSpeakerPosition>() == false);
REQUIRE(blockFormat.get<SphericalSpeakerPosition>().get<Azimuth>() ==
Approx(0.0f));
REQUIRE(blockFormat.get<SphericalSpeakerPosition>().get<Elevation>() ==
Approx(0.0f));
REQUIRE(blockFormat.get<SphericalSpeakerPosition>().has<Distance>() ==
false);
REQUIRE(blockFormat.get<Cartesian>() == false);
REQUIRE(blockFormat.isDefault<Cartesian>() == true);
}

SECTION(
"setting cartesian true with spherical position sets default cartesian") {
auto blockFormat = AudioBlockFormatDirectSpeakers{};
blockFormat.set(SphericalSpeakerPosition{Azimuth{10.0f}, Elevation{15.0f},
Distance{1.0f}});

REQUIRE(blockFormat.has<SphericalSpeakerPosition>() == true);
REQUIRE(blockFormat.get<SphericalSpeakerPosition>().get<Azimuth>() ==
Approx(10.0f));

blockFormat.set(Cartesian{true});

REQUIRE(blockFormat.has<CartesianSpeakerPosition>() == true);
REQUIRE(blockFormat.has<SphericalSpeakerPosition>() == false);
REQUIRE(blockFormat.get<CartesianSpeakerPosition>().get<X>() ==
Approx(0.0f));
REQUIRE(blockFormat.get<CartesianSpeakerPosition>().get<Y>() ==
Approx(0.0f));
REQUIRE(blockFormat.get<CartesianSpeakerPosition>().has<Z>() == false);
REQUIRE(blockFormat.get<Cartesian>() == true);
REQUIRE(blockFormat.isDefault<Cartesian>() == false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<audioBlockFormat audioBlockFormatID="AB_00011001_00000001">
<position coordinate="X">0.000000</position>
<position coordinate="Y">0.000000</position>
<cartesian>1</cartesian>
</audioBlockFormat>
</audioChannelFormat>
</audioFormatExtended>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<position coordinate="Z">0.500000</position>
<position coordinate="Z" bound="min">0.400000</position>
<position coordinate="Z" bound="max">0.600000</position>
<cartesian>1</cartesian>
<headLocked>1</headLocked>
<gain>0.500000</gain>
<importance>5</importance>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<audioBlockFormat audioBlockFormatID="AB_00011001_00000001">
<position coordinate="X">0.000000</position>
<position coordinate="Y">0.000000</position>
<cartesian>1</cartesian>
<headphoneVirtualise bypass="0" DRR="30.000000"/>
</audioBlockFormat>
</audioChannelFormat>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@
<position coordinate="Z">0.500000</position>
<position coordinate="Z" bound="min">0.400000</position>
<position coordinate="Z" bound="max">0.600000</position>
<cartesian>1</cartesian>
</audioBlockFormat>
</audioChannelFormat>
</audioFormatExtended>
</format>
</coreMetadata>
</ebuCoreMain>


Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<ebuCoreMain>
<coreMetadata>
<format>
<audioFormatExtended>
<audioChannelFormat audioChannelFormatID="AC_00011001" audioChannelFormatName="FrontLeft" typeLabel="0001" typeDefinition="DirectSpeakers">
<audioBlockFormat audioBlockFormatID="AB_00011001_00000001">
<position coordinate="X">0.0</position>
<position coordinate="Y">0.0</position>
<position coordinate="Z">0.5</position>
<cartesian>0</cartesian>
</audioBlockFormat>
</audioChannelFormat>
</audioFormatExtended>
</format>
</coreMetadata>
</ebuCoreMain>
Loading
Loading