Commit 23774f55 authored by Stefan Westerfeld's avatar Stefan Westerfeld

Use similar API for from/to raw conversion in RawConverter.

Signed-off-by: Stefan Westerfeld's avatarStefan Westerfeld <stefan@space.twc.de>
parent 721bd177
......@@ -30,11 +30,11 @@ RawConverter::~RawConverter()
}
template<int BIT_DEPTH, RawFormat::Endian ENDIAN, RawFormat::Encoding ENCODING>
class RawConverterImpl : public RawConverter
class RawConverterImpl final : public RawConverter
{
public:
void to_raw (const std::vector<float>& samples, std::vector<unsigned char>& bytes) AUDIOWMARK_EXTRA_OPT;
void from_raw (const unsigned char *bytes, float *samples, size_t n_samples) AUDIOWMARK_EXTRA_OPT;
void to_raw (const float *samples, unsigned char *bytes, size_t n_samples) override AUDIOWMARK_EXTRA_OPT;
void from_raw (const unsigned char *bytes, float *samples, size_t n_samples) override AUDIOWMARK_EXTRA_OPT;
};
template<int BIT_DEPTH, RawFormat::Endian ENDIAN>
......@@ -124,7 +124,7 @@ float_to_int_clip (float f)
template<int BIT_DEPTH, RawFormat::Endian ENDIAN, RawFormat::Encoding ENCODING>
void
RawConverterImpl<BIT_DEPTH, ENDIAN, ENCODING>::to_raw (const vector<float>& samples, vector<unsigned char>& output_bytes)
RawConverterImpl<BIT_DEPTH, ENDIAN, ENCODING>::to_raw (const float *samples, unsigned char *output_bytes, size_t n_samples)
{
constexpr int sample_width = BIT_DEPTH / 8;
constexpr auto eshift = make_endian_shift<BIT_DEPTH, ENDIAN>();
......@@ -134,13 +134,11 @@ RawConverterImpl<BIT_DEPTH, ENDIAN, ENCODING>::to_raw (const vector<float>& samp
#else
constexpr bool native_endian = ENDIAN == RawFormat::LITTLE;
#endif
assert ((uintptr_t (output_bytes.data()) & 3) == 0); // ensure alignment for optimized 32 bit native endian version
assert ((uintptr_t (output_bytes) & 3) == 0); // ensure alignment for optimized 32 bit native endian version
output_bytes.resize (sample_width * samples.size());
unsigned char *ptr = output_bytes;
unsigned char *ptr = output_bytes.data();
for (size_t i = 0; i < samples.size(); i++)
for (size_t i = 0; i < n_samples; i++)
{
if (native_endian && ENCODING == RawFormat::SIGNED && BIT_DEPTH == 32)
((int32_t *)ptr)[i] = float_to_int_clip<32> (samples[i]);
......
......@@ -27,7 +27,7 @@ public:
virtual ~RawConverter() = 0;
virtual void to_raw (const std::vector<float>& samples, std::vector<unsigned char>& bytes) = 0;
virtual void to_raw (const float *samples, unsigned char *bytes, size_t n_samples) = 0;
virtual void from_raw (const unsigned char *bytes, float *samples, size_t n_samples) = 0;
};
......
......@@ -144,7 +144,7 @@ RawInputStream::read_frames (vector<float>& samples, size_t count)
if (ferror (m_input_file))
return Error ("error reading sample data");
input_bytes.resize (r_count * n_channels * sample_width);
samples.resize (r_count * n_channels);
m_raw_converter->from_raw (input_bytes.data(), samples.data(), r_count * n_channels);
......
......@@ -91,8 +91,8 @@ RawOutputStream::write_frames (const vector<float>& samples)
if (samples.empty())
return Error::Code::NONE;
vector<unsigned char> bytes;
m_raw_converter->to_raw (samples, bytes);
vector<unsigned char> bytes (samples.size() * m_format.bit_depth() / 8);
m_raw_converter->to_raw (samples.data(), bytes.data(), samples.size());
fwrite (&bytes[0], 1, bytes.size(), m_output_file);
if (ferror (m_output_file))
......
......@@ -23,6 +23,7 @@
using std::string;
using std::vector;
using std::min;
StdoutWavOutputStream::~StdoutWavOutputStream()
{
......@@ -145,15 +146,26 @@ StdoutWavOutputStream::write_frames (const vector<float>& samples)
if (samples.empty())
return Error::Code::NONE;
vector<unsigned char> output_bytes;
const size_t block_size = 1024;
const int sample_width = m_bit_depth / 8;
m_raw_converter->to_raw (samples, output_bytes);
m_output_bytes.resize (sample_width * block_size);
size_t pos = 0;
fwrite (&output_bytes[0], 1, output_bytes.size(), stdout);
if (ferror (stdout))
return Error ("write sample data failed");
for (;;)
{
size_t todo = min (block_size, samples.size() - pos);
if (!todo)
return Error::Code::NONE;
return Error::Code::NONE;
m_raw_converter->to_raw (samples.data() + pos, m_output_bytes.data(), todo);
fwrite (m_output_bytes.data(), 1, todo * sample_width, stdout);
if (ferror (stdout))
return Error ("write sample data failed");
pos += todo;
}
}
Error
......
......@@ -37,6 +37,7 @@ class StdoutWavOutputStream : public AudioOutputStream
};
State m_state = State::NEW;
std::vector<unsigned char> m_output_bytes;
std::unique_ptr<RawConverter> m_raw_converter;
public:
......
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