Commit 721bd177 authored by Stefan Westerfeld's avatar Stefan Westerfeld

WavPipeInputStream: avoid filling sample array with zeros before read.

Signed-off-by: Stefan Westerfeld's avatarStefan Westerfeld <stefan@space.twc.de>
parent 4cea1061
......@@ -34,7 +34,7 @@ class RawConverterImpl : public RawConverter
{
public:
void to_raw (const std::vector<float>& samples, std::vector<unsigned char>& bytes) AUDIOWMARK_EXTRA_OPT;
void from_raw (const std::vector<unsigned char>& bytes, std::vector<float>& samples) AUDIOWMARK_EXTRA_OPT;
void from_raw (const unsigned char *bytes, float *samples, size_t n_samples) AUDIOWMARK_EXTRA_OPT;
};
template<int BIT_DEPTH, RawFormat::Endian ENDIAN>
......@@ -166,9 +166,9 @@ RawConverterImpl<BIT_DEPTH, ENDIAN, ENCODING>::to_raw (const vector<float>& samp
template<int BIT_DEPTH, RawFormat::Endian ENDIAN, RawFormat::Encoding ENCODING>
void
RawConverterImpl<BIT_DEPTH, ENDIAN, ENCODING>::from_raw (const vector<unsigned char>& input_bytes, vector<float>& samples)
RawConverterImpl<BIT_DEPTH, ENDIAN, ENCODING>::from_raw (const unsigned char *input_bytes, float *samples, size_t n_samples)
{
const unsigned char *ptr = input_bytes.data();
const unsigned char *ptr = input_bytes;
constexpr int sample_width = BIT_DEPTH / 8;
constexpr auto eshift = make_endian_shift<BIT_DEPTH, ENDIAN>();
constexpr unsigned char sign_flip = ENCODING == RawFormat::SIGNED ? 0x00 : 0x80;
......@@ -177,11 +177,10 @@ RawConverterImpl<BIT_DEPTH, ENDIAN, ENCODING>::from_raw (const vector<unsigned c
#else
constexpr bool native_endian = ENDIAN == RawFormat::LITTLE;
#endif
assert ((uintptr_t (input_bytes.data()) & 3) == 0); // ensure alignment for optimized 32 bit native endian version
assert ((uintptr_t (input_bytes) & 3) == 0); // ensure alignment for optimized 32 bit native endian version
samples.resize (input_bytes.size() / sample_width);
const float norm = 1.0 / 0x80000000LL;
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)
samples[i] = ((int32_t *)ptr)[i] * norm;
......
......@@ -28,7 +28,7 @@ public:
virtual ~RawConverter() = 0;
virtual void to_raw (const std::vector<float>& samples, std::vector<unsigned char>& bytes) = 0;
virtual void from_raw (const std::vector<unsigned char>& bytes, std::vector<float>& samples) = 0;
virtual void from_raw (const unsigned char *bytes, float *samples, size_t n_samples) = 0;
};
#endif /* AUDIOWMARK_RAW_CONVERTER_HH */
......@@ -146,7 +146,7 @@ RawInputStream::read_frames (vector<float>& samples, size_t count)
input_bytes.resize (r_count * n_channels * sample_width);
m_raw_converter->from_raw (input_bytes, samples);
m_raw_converter->from_raw (input_bytes.data(), samples.data(), r_count * n_channels);
return Error::Code::NONE;
}
......
......@@ -25,6 +25,7 @@
using std::string;
using std::vector;
using std::min;
using std::max;
WavPipeInputStream::~WavPipeInputStream()
{
......@@ -153,18 +154,34 @@ WavPipeInputStream::read_frames (vector<float>& samples, size_t count)
{
assert (m_state == State::OPEN);
const size_t block_size = 1024;
const int n_channels = m_format.n_channels();
const int sample_width = m_format.bit_depth() / 8;
vector<unsigned char> input_bytes (count * n_channels * sample_width);
size_t r_count = fread (input_bytes.data(), n_channels * sample_width, count, m_input_file);
if (ferror (m_input_file))
return Error ("error reading sample data");
m_input_bytes.resize (block_size * n_channels * sample_width);
size_t pos = 0;
input_bytes.resize (r_count * n_channels * sample_width);
for (;;)
{
size_t todo = min (count, block_size);
if (!todo)
break;
size_t r_count = fread (m_input_bytes.data(), n_channels * sample_width, todo, m_input_file);
if (ferror (m_input_file))
return Error ("error reading sample data");
if (!r_count)
break;
m_raw_converter->from_raw (input_bytes, samples);
samples.resize (max (samples.size(), (pos + r_count) * n_channels));
m_raw_converter->from_raw (m_input_bytes.data(), samples.data() + pos * n_channels, r_count * n_channels);
pos += r_count;
count -= r_count;
}
samples.resize (pos * n_channels);
return Error::Code::NONE;
}
......
......@@ -38,6 +38,7 @@ class WavPipeInputStream : public AudioInputStream
FILE *m_input_file = nullptr;
bool m_close_file = false;
std::vector<unsigned char> m_input_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