pcm/PcmExport: add flag to export to DSD_U32
This commit is contained in:
parent
d1be643c0d
commit
fb4f02cd38
@ -25,6 +25,7 @@
|
|||||||
#include "util/ConstBuffer.hxx"
|
#include "util/ConstBuffer.hxx"
|
||||||
|
|
||||||
#ifdef ENABLE_DSD
|
#ifdef ENABLE_DSD
|
||||||
|
#include "PcmDsd.hxx"
|
||||||
#include "PcmDop.hxx"
|
#include "PcmDop.hxx"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -42,7 +43,15 @@ PcmExport::Open(SampleFormat sample_format, unsigned _channels,
|
|||||||
: SampleFormat::UNDEFINED;
|
: SampleFormat::UNDEFINED;
|
||||||
|
|
||||||
#ifdef ENABLE_DSD
|
#ifdef ENABLE_DSD
|
||||||
|
assert(!params.dsd_u32 || !params.dop);
|
||||||
assert(!params.dop || audio_valid_channel_count(_channels));
|
assert(!params.dop || audio_valid_channel_count(_channels));
|
||||||
|
|
||||||
|
dsd_u32 = params.dsd_u32 && sample_format == SampleFormat::DSD;
|
||||||
|
if (dsd_u32)
|
||||||
|
/* after the conversion to DSD_U32, the DSD samples
|
||||||
|
are stuffed inside fake 32 bit samples */
|
||||||
|
sample_format = SampleFormat::S32;
|
||||||
|
|
||||||
dop = params.dop && sample_format == SampleFormat::DSD;
|
dop = params.dop && sample_format == SampleFormat::DSD;
|
||||||
if (dop)
|
if (dop)
|
||||||
/* after the conversion to DoP, the DSD
|
/* after the conversion to DoP, the DSD
|
||||||
@ -77,6 +86,9 @@ PcmExport::GetFrameSize(const AudioFormat &audio_format) const
|
|||||||
return audio_format.channels * 3;
|
return audio_format.channels * 3;
|
||||||
|
|
||||||
#ifdef ENABLE_DSD
|
#ifdef ENABLE_DSD
|
||||||
|
if (dsd_u32)
|
||||||
|
return channels * 4;
|
||||||
|
|
||||||
if (dop)
|
if (dop)
|
||||||
/* the DSD-over-USB draft says that DSD 1-bit samples
|
/* the DSD-over-USB draft says that DSD 1-bit samples
|
||||||
are enclosed within 24 bit samples, and MPD's
|
are enclosed within 24 bit samples, and MPD's
|
||||||
@ -96,6 +108,11 @@ PcmExport::Export(ConstBuffer<void> data)
|
|||||||
alsa_channel_order, channels);
|
alsa_channel_order, channels);
|
||||||
|
|
||||||
#ifdef ENABLE_DSD
|
#ifdef ENABLE_DSD
|
||||||
|
if (dsd_u32)
|
||||||
|
data = Dsd8To32(dop_buffer, channels,
|
||||||
|
ConstBuffer<uint8_t>::FromVoid(data))
|
||||||
|
.ToVoid();
|
||||||
|
|
||||||
if (dop)
|
if (dop)
|
||||||
data = pcm_dsd_to_dop(dop_buffer, channels,
|
data = pcm_dsd_to_dop(dop_buffer, channels,
|
||||||
ConstBuffer<uint8_t>::FromVoid(data))
|
ConstBuffer<uint8_t>::FromVoid(data))
|
||||||
|
@ -35,6 +35,7 @@ template<typename T> struct ConstBuffer;
|
|||||||
struct PcmExport {
|
struct PcmExport {
|
||||||
struct Params {
|
struct Params {
|
||||||
bool alsa_channel_order = false;
|
bool alsa_channel_order = false;
|
||||||
|
bool dsd_u32 = false;
|
||||||
bool dop = false;
|
bool dop = false;
|
||||||
bool shift8 = false;
|
bool shift8 = false;
|
||||||
bool pack24 = false;
|
bool pack24 = false;
|
||||||
@ -88,6 +89,11 @@ struct PcmExport {
|
|||||||
SampleFormat alsa_channel_order;
|
SampleFormat alsa_channel_order;
|
||||||
|
|
||||||
#ifdef ENABLE_DSD
|
#ifdef ENABLE_DSD
|
||||||
|
/**
|
||||||
|
* Convert DSD (U8) to DSD_U32?
|
||||||
|
*/
|
||||||
|
bool dsd_u32;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert DSD to DSD-over-PCM (DoP)? Input format must be
|
* Convert DSD to DSD-over-PCM (DoP)? Input format must be
|
||||||
* SampleFormat::DSD and output format must be
|
* SampleFormat::DSD and output format must be
|
||||||
|
@ -125,6 +125,7 @@ class PcmExportTest : public CppUnit::TestFixture {
|
|||||||
CPPUNIT_TEST(TestShift8);
|
CPPUNIT_TEST(TestShift8);
|
||||||
CPPUNIT_TEST(TestPack24);
|
CPPUNIT_TEST(TestPack24);
|
||||||
CPPUNIT_TEST(TestReverseEndian);
|
CPPUNIT_TEST(TestReverseEndian);
|
||||||
|
CPPUNIT_TEST(TestDsdU32);
|
||||||
CPPUNIT_TEST(TestDop);
|
CPPUNIT_TEST(TestDop);
|
||||||
CPPUNIT_TEST(TestAlsaChannelOrder);
|
CPPUNIT_TEST(TestAlsaChannelOrder);
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
@ -133,6 +134,7 @@ public:
|
|||||||
void TestShift8();
|
void TestShift8();
|
||||||
void TestPack24();
|
void TestPack24();
|
||||||
void TestReverseEndian();
|
void TestReverseEndian();
|
||||||
|
void TestDsdU32();
|
||||||
void TestDop();
|
void TestDop();
|
||||||
void TestAlsaChannelOrder();
|
void TestAlsaChannelOrder();
|
||||||
};
|
};
|
||||||
|
@ -115,6 +115,30 @@ PcmExportTest::TestReverseEndian()
|
|||||||
CPPUNIT_ASSERT(memcmp(dest.data, expected4, dest.size) == 0);
|
CPPUNIT_ASSERT(memcmp(dest.data, expected4, dest.size) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PcmExportTest::TestDsdU32()
|
||||||
|
{
|
||||||
|
static constexpr uint8_t src[] = {
|
||||||
|
0x01, 0x23, 0x45, 0x67,
|
||||||
|
0x89, 0xab, 0xcd, 0xef,
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr uint32_t expected[] = {
|
||||||
|
0xcd894501,
|
||||||
|
0xefab6723,
|
||||||
|
};
|
||||||
|
|
||||||
|
PcmExport::Params params;
|
||||||
|
params.dsd_u32 = true;
|
||||||
|
|
||||||
|
PcmExport e;
|
||||||
|
e.Open(SampleFormat::DSD, 2, params);
|
||||||
|
|
||||||
|
auto dest = e.Export({src, sizeof(src)});
|
||||||
|
CPPUNIT_ASSERT_EQUAL(sizeof(expected), dest.size);
|
||||||
|
CPPUNIT_ASSERT(memcmp(dest.data, expected, dest.size) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PcmExportTest::TestDop()
|
PcmExportTest::TestDop()
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user