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 ...@@ -34,7 +34,7 @@ class RawConverterImpl : public RawConverter
{ {
public: public:
void to_raw (const std::vector<float>& samples, std::vector<unsigned char>& bytes) AUDIOWMARK_EXTRA_OPT; 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> template<int BIT_DEPTH, RawFormat::Endian ENDIAN>
...@@ -166,9 +166,9 @@ RawConverterImpl<BIT_DEPTH, ENDIAN, ENCODING>::to_raw (const vector<float>& samp ...@@ -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> template<int BIT_DEPTH, RawFormat::Endian ENDIAN, RawFormat::Encoding ENCODING>
void 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 int sample_width = BIT_DEPTH / 8;
constexpr auto eshift = make_endian_shift<BIT_DEPTH, ENDIAN>(); constexpr auto eshift = make_endian_shift<BIT_DEPTH, ENDIAN>();
constexpr unsigned char sign_flip = ENCODING == RawFormat::SIGNED ? 0x00 : 0x80; 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 ...@@ -177,11 +177,10 @@ RawConverterImpl<BIT_DEPTH, ENDIAN, ENCODING>::from_raw (const vector<unsigned c
#else #else
constexpr bool native_endian = ENDIAN == RawFormat::LITTLE; constexpr bool native_endian = ENDIAN == RawFormat::LITTLE;
#endif #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; 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) if (native_endian && ENCODING == RawFormat::SIGNED && BIT_DEPTH == 32)
samples[i] = ((int32_t *)ptr)[i] * norm; samples[i] = ((int32_t *)ptr)[i] * norm;
......
...@@ -28,7 +28,7 @@ public: ...@@ -28,7 +28,7 @@ public:
virtual ~RawConverter() = 0; virtual ~RawConverter() = 0;
virtual void to_raw (const std::vector<float>& samples, std::vector<unsigned char>& bytes) = 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 */ #endif /* AUDIOWMARK_RAW_CONVERTER_HH */
...@@ -146,7 +146,7 @@ RawInputStream::read_frames (vector<float>& samples, size_t count) ...@@ -146,7 +146,7 @@ RawInputStream::read_frames (vector<float>& samples, size_t count)
input_bytes.resize (r_count * n_channels * sample_width); 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; return Error::Code::NONE;
} }
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
using std::string; using std::string;
using std::vector; using std::vector;
using std::min; using std::min;
using std::max;
WavPipeInputStream::~WavPipeInputStream() WavPipeInputStream::~WavPipeInputStream()
{ {
...@@ -153,18 +154,34 @@ WavPipeInputStream::read_frames (vector<float>& samples, size_t count) ...@@ -153,18 +154,34 @@ WavPipeInputStream::read_frames (vector<float>& samples, size_t count)
{ {
assert (m_state == State::OPEN); assert (m_state == State::OPEN);
const size_t block_size = 1024;
const int n_channels = m_format.n_channels(); const int n_channels = m_format.n_channels();
const int sample_width = m_format.bit_depth() / 8; const int sample_width = m_format.bit_depth() / 8;
vector<unsigned char> input_bytes (count * n_channels * sample_width); m_input_bytes.resize (block_size * n_channels * sample_width);
size_t r_count = fread (input_bytes.data(), n_channels * sample_width, count, m_input_file); size_t pos = 0;
if (ferror (m_input_file))
return Error ("error reading sample data");
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; return Error::Code::NONE;
} }
......
...@@ -38,6 +38,7 @@ class WavPipeInputStream : public AudioInputStream ...@@ -38,6 +38,7 @@ class WavPipeInputStream : public AudioInputStream
FILE *m_input_file = nullptr; FILE *m_input_file = nullptr;
bool m_close_file = false; bool m_close_file = false;
std::vector<unsigned char> m_input_bytes;
std::unique_ptr<RawConverter> m_raw_converter; std::unique_ptr<RawConverter> m_raw_converter;
public: 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