Commit beed004b authored by Max Kellermann's avatar Max Kellermann

pcm/Export: add GetSilence()

parent 730e67d7
...@@ -21,10 +21,13 @@ ...@@ -21,10 +21,13 @@
#include "AudioFormat.hxx" #include "AudioFormat.hxx"
#include "Order.hxx" #include "Order.hxx"
#include "Pack.hxx" #include "Pack.hxx"
#include "Silence.hxx"
#include "util/ByteReverse.hxx" #include "util/ByteReverse.hxx"
#include "util/ConstBuffer.hxx" #include "util/ConstBuffer.hxx"
#include "util/WritableBuffer.hxx"
#include <assert.h> #include <assert.h>
#include <string.h>
void void
PcmExport::Open(SampleFormat sample_format, unsigned _channels, PcmExport::Open(SampleFormat sample_format, unsigned _channels,
...@@ -89,6 +92,16 @@ PcmExport::Open(SampleFormat sample_format, unsigned _channels, ...@@ -89,6 +92,16 @@ PcmExport::Open(SampleFormat sample_format, unsigned _channels,
if (sample_size > 1) if (sample_size > 1)
reverse_endian = sample_size; reverse_endian = sample_size;
} }
/* prepare a moment of silence for GetSilence() */
char buffer[sizeof(silence_buffer)];
const size_t buffer_size = GetInputBlockSize();
assert(buffer_size < sizeof(buffer));
PcmSilence({buffer, buffer_size}, src_sample_format);
auto s = Export({buffer, buffer_size});
assert(s.size < sizeof(silence_buffer));
silence_size = s.size;
memcpy(silence_buffer, s.data, s.size);
} }
void void
...@@ -190,6 +203,12 @@ PcmExport::GetOutputBlockSize() const noexcept ...@@ -190,6 +203,12 @@ PcmExport::GetOutputBlockSize() const noexcept
return GetOutputFrameSize(); return GetOutputFrameSize();
} }
ConstBuffer<void>
PcmExport::GetSilence() const noexcept
{
return {silence_buffer, silence_size};
}
unsigned unsigned
PcmExport::Params::CalcOutputSampleRate(unsigned sample_rate) const noexcept PcmExport::Params::CalcOutputSampleRate(unsigned sample_rate) const noexcept
{ {
......
...@@ -79,6 +79,10 @@ class PcmExport { ...@@ -79,6 +79,10 @@ class PcmExport {
*/ */
PcmBuffer reverse_buffer; PcmBuffer reverse_buffer;
size_t silence_size;
uint8_t silence_buffer[64]; /* worst-case size */
/** /**
* The sample format of input data. * The sample format of input data.
*/ */
...@@ -211,6 +215,14 @@ public: ...@@ -211,6 +215,14 @@ public:
size_t GetOutputBlockSize() const noexcept; size_t GetOutputBlockSize() const noexcept;
/** /**
* @return one block of silence output; its size is the same
* as GetOutputBlockSize(); the pointer is valid as long as
* this #PcmExport object exists and until the next Open()
* call
*/
ConstBuffer<void> GetSilence() const noexcept;
/**
* Export a PCM buffer. * Export a PCM buffer.
* *
* @param src the source PCM buffer * @param src the source PCM buffer
......
...@@ -49,6 +49,12 @@ TEST(PcmTest, ExportShift8) ...@@ -49,6 +49,12 @@ TEST(PcmTest, ExportShift8)
auto dest = e.Export({src, sizeof(src)}); auto dest = e.Export({src, sizeof(src)});
EXPECT_EQ(sizeof(expected), dest.size); EXPECT_EQ(sizeof(expected), dest.size);
EXPECT_TRUE(memcmp(dest.data, expected, dest.size) == 0); EXPECT_TRUE(memcmp(dest.data, expected, dest.size) == 0);
const auto silence = e.GetSilence();
constexpr uint8_t expected_silence[8]{};
EXPECT_EQ(silence.size, sizeof(expected_silence));
EXPECT_EQ(memcmp(silence.data, expected_silence,
sizeof(expected_silence)), 0);
} }
TEST(PcmTest, ExportPack24) TEST(PcmTest, ExportPack24)
...@@ -92,6 +98,12 @@ TEST(PcmTest, ExportPack24) ...@@ -92,6 +98,12 @@ TEST(PcmTest, ExportPack24)
auto dest = e.Export({src, sizeof(src)}); auto dest = e.Export({src, sizeof(src)});
EXPECT_EQ(expected_size, dest.size); EXPECT_EQ(expected_size, dest.size);
EXPECT_TRUE(memcmp(dest.data, expected, dest.size) == 0); EXPECT_TRUE(memcmp(dest.data, expected, dest.size) == 0);
const auto silence = e.GetSilence();
constexpr uint8_t expected_silence[6]{};
EXPECT_EQ(silence.size, sizeof(expected_silence));
EXPECT_EQ(memcmp(silence.data, expected_silence,
sizeof(expected_silence)), 0);
} }
TEST(PcmTest, ExportReverseEndian) TEST(PcmTest, ExportReverseEndian)
...@@ -147,6 +159,12 @@ TEST(PcmTest, ExportReverseEndian) ...@@ -147,6 +159,12 @@ TEST(PcmTest, ExportReverseEndian)
dest = e.Export({src, sizeof(src)}); dest = e.Export({src, sizeof(src)});
EXPECT_EQ(sizeof(expected4), dest.size); EXPECT_EQ(sizeof(expected4), dest.size);
EXPECT_TRUE(memcmp(dest.data, expected4, dest.size) == 0); EXPECT_TRUE(memcmp(dest.data, expected4, dest.size) == 0);
const auto silence = e.GetSilence();
constexpr uint8_t expected_silence[8]{};
EXPECT_EQ(silence.size, sizeof(expected_silence));
EXPECT_EQ(memcmp(silence.data, expected_silence,
sizeof(expected_silence)), 0);
} }
#ifdef ENABLE_DSD #ifdef ENABLE_DSD
...@@ -205,6 +223,12 @@ TEST(PcmTest, ExportDsdU16) ...@@ -205,6 +223,12 @@ TEST(PcmTest, ExportDsdU16)
dest = e.Export({src4, sizeof(src4)}); dest = e.Export({src4, sizeof(src4)});
EXPECT_EQ(sizeof(expected4), dest.size); EXPECT_EQ(sizeof(expected4), dest.size);
EXPECT_TRUE(memcmp(dest.data, expected4, dest.size) == 0); EXPECT_TRUE(memcmp(dest.data, expected4, dest.size) == 0);
const auto silence = e.GetSilence();
constexpr uint8_t expected_silence[]{0x69, 0x69, 0x69, 0x69};
EXPECT_EQ(silence.size, sizeof(expected_silence));
EXPECT_EQ(memcmp(silence.data, expected_silence,
sizeof(expected_silence)), 0);
} }
TEST(PcmTest, ExportDsdU32) TEST(PcmTest, ExportDsdU32)
...@@ -261,6 +285,12 @@ TEST(PcmTest, ExportDsdU32) ...@@ -261,6 +285,12 @@ TEST(PcmTest, ExportDsdU32)
dest = e.Export({src4, sizeof(src4)}); dest = e.Export({src4, sizeof(src4)});
EXPECT_EQ(sizeof(expected4), dest.size); EXPECT_EQ(sizeof(expected4), dest.size);
EXPECT_TRUE(memcmp(dest.data, expected4, dest.size) == 0); EXPECT_TRUE(memcmp(dest.data, expected4, dest.size) == 0);
const auto silence = e.GetSilence();
constexpr uint8_t expected_silence[]{0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69};
EXPECT_EQ(silence.size, sizeof(expected_silence));
EXPECT_EQ(memcmp(silence.data, expected_silence,
sizeof(expected_silence)), 0);
} }
TEST(PcmTest, ExportDop) TEST(PcmTest, ExportDop)
...@@ -329,6 +359,12 @@ TEST(PcmTest, ExportDop) ...@@ -329,6 +359,12 @@ TEST(PcmTest, ExportDop)
dest = e.Export({src6, sizeof(src6)}); dest = e.Export({src6, sizeof(src6)});
ASSERT_EQ(sizeof(expected6), dest.size); ASSERT_EQ(sizeof(expected6), dest.size);
ASSERT_TRUE(memcmp(dest.data, expected6, dest.size) == 0); ASSERT_TRUE(memcmp(dest.data, expected6, dest.size) == 0);
const auto silence = e.GetSilence();
constexpr uint32_t expected_silence[]{0xff056969, 0xff056969, 0xfffa6969, 0xfffa6969};
EXPECT_EQ(silence.size, sizeof(expected_silence));
EXPECT_EQ(memcmp(silence.data, expected_silence,
sizeof(expected_silence)), 0);
} }
#endif #endif
...@@ -391,6 +427,12 @@ TestAlsaChannelOrder71() ...@@ -391,6 +427,12 @@ TestAlsaChannelOrder71()
auto dest = e.Export({src, sizeof(src)}); auto dest = e.Export({src, sizeof(src)});
EXPECT_EQ(sizeof(expected), dest.size); EXPECT_EQ(sizeof(expected), dest.size);
EXPECT_TRUE(memcmp(dest.data, expected, dest.size) == 0); EXPECT_TRUE(memcmp(dest.data, expected, dest.size) == 0);
const auto silence = e.GetSilence();
constexpr value_type expected_silence[8]{};
EXPECT_EQ(silence.size, sizeof(expected_silence));
EXPECT_EQ(memcmp(silence.data, expected_silence,
sizeof(expected_silence)), 0);
} }
TEST(PcmTest, ExportAlsaChannelOrder) TEST(PcmTest, ExportAlsaChannelOrder)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment