31
31
#include "samplerateconverter.h"
32
#include "sfl_types.h"
36
SamplerateConverter::SamplerateConverter(int freq) : floatBufferIn_(0),
37
floatBufferOut_(0), samples_(0), maxFreq_(freq), src_state_(0)
34
SamplerateConverter::SamplerateConverter(int freq, size_t channels /* = 1 */) : floatBufferIn_(),
35
floatBufferOut_(), scratchBuffer_(), samples_(0), channels_(channels), maxFreq_(freq), src_state_(0)
40
src_state_ = src_new(SRC_LINEAR, 1, &err);
38
src_state_ = src_new(SRC_LINEAR, channels_, &err);
42
40
samples_ = (freq * 20) / 1000; // start with 20 ms buffers
44
floatBufferIn_ = new float[samples_];
45
floatBufferOut_ = new float[samples_];
42
floatBufferIn_.resize(samples_);
43
floatBufferOut_.resize(samples_);
44
scratchBuffer_.resize(samples_);
48
47
SamplerateConverter::~SamplerateConverter()
50
delete [] floatBufferIn_;
51
delete [] floatBufferOut_;
53
49
src_delete(src_state_);
57
SamplerateConverter::Short2FloatArray(const short *in, float *out, int len)
53
SamplerateConverter::Short2FloatArray(const SFLAudioSample *in, float *out, int len)
59
55
// factor is 1/(2^15), used to rescale the short int range to the
60
56
// [-1.0 - 1.0] float range.
57
static const float FACTOR = 1.0f / (1 << 15);
63
out[len] = (float) in[len] * .000030517578125f;
60
out[len] = (float) in[len] * FACTOR;
66
void SamplerateConverter::resample(SFLDataFormat *dataIn,
67
SFLDataFormat *dataOut,
68
size_t dataOutSize, int inputFreq,
69
int outputFreq, size_t nbSamples)
63
void SamplerateConverter::resample(const AudioBuffer &dataIn, AudioBuffer &dataOut)
71
double sampleFactor = (double) outputFreq / inputFreq;
65
const double inputFreq = dataIn.getSampleRate();
66
const double outputFreq = dataOut.getSampleRate();
67
const double sampleFactor = outputFreq / inputFreq;
73
69
if (sampleFactor == 1.0)
76
size_t outSamples = nbSamples * sampleFactor;
77
const unsigned int maxSamples = std::max(outSamples, nbSamples);
72
const size_t nbFrames = dataIn.frames();
73
const size_t nbChans = dataIn.channels();
79
if (maxSamples > samples_) {
80
/* grow buffer if needed */
81
samples_ = maxSamples;
82
delete [] floatBufferIn_;
83
delete [] floatBufferOut_;
84
floatBufferIn_ = new float[samples_];
85
floatBufferOut_ = new float[samples_];
75
if (nbChans != channels_) {
76
// change channel num if needed
78
src_delete(src_state_);
79
src_state_ = src_new(SRC_LINEAR, nbChans, &err);
83
size_t inSamples = nbChans * nbFrames;
84
size_t outSamples = inSamples * sampleFactor;
86
// grow buffer if needed
87
samples_ = std::max(inSamples, outSamples);
88
floatBufferIn_.resize(inSamples);
89
floatBufferOut_.resize(outSamples);
90
scratchBuffer_.resize(outSamples);
89
src_data.data_in = floatBufferIn_;
90
src_data.data_out = floatBufferOut_;
91
src_data.input_frames = nbSamples;
92
src_data.output_frames = outSamples;
93
src_data.data_in = floatBufferIn_.data();
94
src_data.data_out = floatBufferOut_.data();
95
src_data.input_frames = nbFrames;
96
src_data.output_frames = nbFrames * sampleFactor;
93
97
src_data.src_ratio = sampleFactor;
94
98
src_data.end_of_input = 0; // More data will come
96
Short2FloatArray(dataIn, floatBufferIn_, nbSamples);
100
dataIn.interleaveFloat(floatBufferIn_.data());
97
102
src_process(src_state_, &src_data);
99
if (outSamples > dataOutSize) {
100
ERROR("Outsamples exceeds output buffer size, clamping to %u", dataOutSize);
101
outSamples = dataOutSize;
103
src_float_to_short_array(floatBufferOut_, dataOut, outSamples);
105
TODO: one-shot deinterleave and float-to-short conversion
107
src_float_to_short_array(floatBufferOut_.data(), scratchBuffer_.data(), outSamples);
108
dataOut.deinterleave(scratchBuffer_.data(), src_data.output_frames, nbChans);