Commit 1dc5f353 authored by Stefan Westerfeld's avatar Stefan Westerfeld

Use more efficient float->int conversion in SFOutputStream.

Signed-off-by: Stefan Westerfeld's avatarStefan Westerfeld <stefan@space.twc.de>
parent 4c331b4c
...@@ -104,24 +104,6 @@ make_endian_shift () ...@@ -104,24 +104,6 @@ make_endian_shift ()
} }
} }
template<int BITS>
static int
float_to_int_clip (float f)
{
const int64_t inorm = (1LL << (BITS - 1));
const float min_value = -inorm;
const float max_value = inorm - 1;
const float norm = inorm;
const float snorm = f * norm;
if (snorm >= max_value)
return inorm - 1;
else if (snorm <= min_value)
return -inorm;
else
return snorm;
}
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>::to_raw (const float *samples, unsigned char *output_bytes, size_t n_samples) RawConverterImpl<BIT_DEPTH, ENDIAN, ENCODING>::to_raw (const float *samples, unsigned char *output_bytes, size_t n_samples)
......
...@@ -31,4 +31,22 @@ public: ...@@ -31,4 +31,22 @@ public:
virtual void from_raw (const unsigned char *bytes, float *samples, size_t n_samples) = 0; virtual void from_raw (const unsigned char *bytes, float *samples, size_t n_samples) = 0;
}; };
template<int BITS>
static inline int
float_to_int_clip (float f)
{
const int64_t inorm = (1LL << (BITS - 1));
const float min_value = -inorm;
const float max_value = inorm - 1;
const float norm = inorm;
const float snorm = f * norm;
if (snorm >= max_value)
return inorm - 1;
else if (snorm <= min_value)
return -inorm;
else
return snorm;
}
#endif /* AUDIOWMARK_RAW_CONVERTER_HH */ #endif /* AUDIOWMARK_RAW_CONVERTER_HH */
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
*/ */
#include "sfoutputstream.hh" #include "sfoutputstream.hh"
#include "rawconverter.hh"
#include "utils.hh" #include "utils.hh"
#include <math.h> #include <math.h>
...@@ -103,13 +104,7 @@ SFOutputStream::write_frames (const vector<float>& samples) ...@@ -103,13 +104,7 @@ SFOutputStream::write_frames (const vector<float>& samples)
{ {
vector<int> isamples (samples.size()); vector<int> isamples (samples.size());
for (size_t i = 0; i < samples.size(); i++) for (size_t i = 0; i < samples.size(); i++)
{ isamples[i] = float_to_int_clip<32> (samples[i]);
const double norm = 0x80000000LL;
const double min_value = -0x80000000LL;
const double max_value = 0x7FFFFFFF;
isamples[i] = lrint (bound<double> (min_value, samples[i] * norm, max_value));
}
sf_count_t frames = samples.size() / m_n_channels; sf_count_t frames = samples.size() / m_n_channels;
sf_count_t count = sf_writef_int (m_sndfile, isamples.data(), frames); sf_count_t count = sf_writef_int (m_sndfile, isamples.data(), frames);
......
...@@ -51,7 +51,7 @@ public: ...@@ -51,7 +51,7 @@ public:
Error open (const std::string& filename, int n_channels, int sample_rate, int bit_depth, OutFormat out_format = OutFormat::WAV); Error open (const std::string& filename, int n_channels, int sample_rate, int bit_depth, OutFormat out_format = OutFormat::WAV);
Error open (std::vector<unsigned char> *data, int n_channels, int sample_rate, int bit_depth, OutFormat out_format = OutFormat::WAV); Error open (std::vector<unsigned char> *data, int n_channels, int sample_rate, int bit_depth, OutFormat out_format = OutFormat::WAV);
Error write_frames (const std::vector<float>& frames) override; Error write_frames (const std::vector<float>& frames) override AUDIOWMARK_EXTRA_OPT;
Error close() override; Error close() override;
int bit_depth() const override; int bit_depth() const override;
int sample_rate() const override; int sample_rate() const override;
......
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