Skip to content

Commit

Permalink
Add nmos::parse_fmtp_channel_order
Browse files Browse the repository at this point in the history
  • Loading branch information
garethsb committed May 4, 2023
1 parent 841212e commit 772feb6
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 0 deletions.
48 changes: 48 additions & 0 deletions Development/nmos/channels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,4 +155,52 @@ namespace nmos

return channel_order.str();
}

// See SMPTE ST 2110-30:2017 Section 6.2.2 Channel Order Convention
std::vector<nmos::channel_symbol> parse_fmtp_channel_order(const utility::string_t& channel_order)
{
std::vector<nmos::channel_symbol> channels;

const auto first = channel_order.data();
const auto last = first + channel_order.size();
auto it = first;

// check prefix

static const auto prefix = U("SMPTE2110.(");
auto pit = &prefix[0];
while (it != last && *pit != U('\0') && *it == *pit) ++it, ++pit;
if (*pit != U('\0')) return {};

// parse comma-separated channel group symbols

while (true)
{
const auto git = it;
while (it != last && *it != U(')') && *it != U(',')) ++it;
if (it == last) return {};

const channel_group_symbol symbol(utility::string_t(git, it));

// hm, does not handle 22.2 Surround ('222'), SDI audio group ('SGRP') or Undefined ('U01' to 'U64')
auto group = std::find_if(details::channel_groups.begin(), details::channel_groups.end(),
[&](const std::pair<std::vector<channel_symbol>, channel_group_symbol>& group)
{
return symbol == group.second;
});
if (details::channel_groups.end() == group) return {};
channels.insert(channels.end(), group->first.begin(), group->first.end());

if (*it == U(')')) break;
++it;
}

// check suffix

if (it == last) return {};
++it;
if (it != last) return {};

return channels;
}
}
1 change: 1 addition & 0 deletions Development/nmos/channels.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ namespace nmos

// See SMPTE ST 2110-30:2017 Section 6.2.2 Channel Order Convention
utility::string_t make_fmtp_channel_order(const std::vector<channel_symbol>& channels);
std::vector<nmos::channel_symbol> parse_fmtp_channel_order(const utility::string_t& channel_order);
}

#endif
37 changes: 37 additions & 0 deletions Development/nmos/test/channels_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,40 @@ BST_TEST_CASE(testMakeFmtpChannelOrder)
const std::vector<nmos::channel_symbol> example_3{ M1, M1, M1, M1, L, R, C, LFE };
BST_REQUIRE_EQUAL(U("SMPTE2110.(M,M,M,M,ST,U02)"), nmos::make_fmtp_channel_order(example_3));
}

////////////////////////////////////////////////////////////////////////////////////////////
BST_TEST_CASE(testParseFmtpChannelOrder)
{
using namespace nmos::channel_symbols;

// two simple examples

const std::vector<nmos::channel_symbol> stereo{ L, R };
BST_REQUIRE_EQUAL(stereo, nmos::parse_fmtp_channel_order(U("SMPTE2110.(ST)")));

const std::vector<nmos::channel_symbol> dual_mono{ M1, M2 };
BST_REQUIRE_EQUAL(dual_mono, nmos::parse_fmtp_channel_order(U("SMPTE2110.(DM)")));

// two examples from ST 2110-30:2017 Section 6.2.2 Channel Order Convention

const std::vector<nmos::channel_symbol> example_1{ L, R, C, LFE, Ls, Rs, L, R };
BST_REQUIRE_EQUAL(example_1, nmos::parse_fmtp_channel_order(U("SMPTE2110.(51,ST)")));

//const std::vector<nmos::channel_symbol> example_2{ M1, M1, M1, M1, L, R, Undefined(1), Undefined(2) };
//BST_REQUIRE_EQUAL(example_2, nmos::parse_fmtp_channel_order(U("SMPTE2110.(M,M,M,M,ST,U02)")));

// bad examples

const std::vector<nmos::channel_symbol> empty;
BST_REQUIRE_EQUAL(empty, nmos::parse_fmtp_channel_order(U("SMPTE2110.(51,ST)BAD")));
BST_REQUIRE_EQUAL(empty, nmos::parse_fmtp_channel_order(U("SMPTE2110.(51,ST,)")));
BST_REQUIRE_EQUAL(empty, nmos::parse_fmtp_channel_order(U("SMPTE2110.(51,,ST)")));
BST_REQUIRE_EQUAL(empty, nmos::parse_fmtp_channel_order(U("SMPTE2110.(51,BAD)")));
BST_REQUIRE_EQUAL(empty, nmos::parse_fmtp_channel_order(U("SMPTE2110.(51,ST")));
BST_REQUIRE_EQUAL(empty, nmos::parse_fmtp_channel_order(U("SMPTE2110.(51,")));
BST_REQUIRE_EQUAL(empty, nmos::parse_fmtp_channel_order(U("SMPTE2110.(51")));
BST_REQUIRE_EQUAL(empty, nmos::parse_fmtp_channel_order(U("SMPTE2110.(")));
BST_REQUIRE_EQUAL(empty, nmos::parse_fmtp_channel_order(U("SMPTE2110.")));
BST_REQUIRE_EQUAL(empty, nmos::parse_fmtp_channel_order(U("BAD")));
BST_REQUIRE_EQUAL(empty, nmos::parse_fmtp_channel_order(U("")));
}

0 comments on commit 772feb6

Please sign in to comment.