diff --git a/src/pcm/PcmPack.cxx b/src/pcm/PcmPack.cxx index f368d3059..72c18287e 100644 --- a/src/pcm/PcmPack.cxx +++ b/src/pcm/PcmPack.cxx @@ -94,3 +94,12 @@ pcm_unpack_24(int32_t *dest, const uint8_t *src, const uint8_t *src_end) src += 3; } } + +void +pcm_unpack_24be(int32_t *dest, const uint8_t *src, const uint8_t *src_end) +{ + while (src < src_end) { + *dest++ = ReadS24BE(src); + src += 3; + } +} diff --git a/src/pcm/PcmPack.hxx b/src/pcm/PcmPack.hxx index 813363715..9b4d58c08 100644 --- a/src/pcm/PcmPack.hxx +++ b/src/pcm/PcmPack.hxx @@ -49,4 +49,11 @@ pcm_pack_24(uint8_t *dest, const int32_t *src, const int32_t *src_end); void pcm_unpack_24(int32_t *dest, const uint8_t *src, const uint8_t *src_end); +/** + * Like pcm_unpack_24(), but assume the source byte order is + * big-endian. The destination byte order ia always native. + */ +void +pcm_unpack_24be(int32_t *dest, const uint8_t *src, const uint8_t *src_end); + #endif diff --git a/test/test_pcm_all.hxx b/test/test_pcm_all.hxx index ace822ab8..594012468 100644 --- a/test/test_pcm_all.hxx +++ b/test/test_pcm_all.hxx @@ -40,11 +40,13 @@ class PcmPackTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(PcmPackTest); CPPUNIT_TEST(TestPack24); CPPUNIT_TEST(TestUnpack24); + CPPUNIT_TEST(TestUnpack24BE); CPPUNIT_TEST_SUITE_END(); public: void TestPack24(); void TestUnpack24(); + void TestUnpack24BE(); }; class PcmChannelsTest : public CppUnit::TestFixture { diff --git a/test/test_pcm_pack.cxx b/test/test_pcm_pack.cxx index fd92861b0..df3a99459 100644 --- a/test/test_pcm_pack.cxx +++ b/test/test_pcm_pack.cxx @@ -70,3 +70,23 @@ PcmPackTest::TestUnpack24() CPPUNIT_ASSERT_EQUAL(s, dest[i]); } } + +void +PcmPackTest::TestUnpack24BE() +{ + constexpr unsigned N = 509; + const auto src = TestDataBuffer(); + + int32_t dest[N]; + pcm_unpack_24be(dest, src.begin(), src.end()); + + for (unsigned i = 0; i < N; ++i) { + int32_t s; + s = (src[i * 3] << 16) | (src[i * 3 + 1] << 8) + | src[i * 3 + 2]; + if (s & 0x800000) + s |= 0xff000000; + + CPPUNIT_ASSERT_EQUAL(s, dest[i]); + } +}