Merge from branch bqresample, with some resampler fixes

This commit is contained in:
Chris Cannam
2020-10-22 17:25:27 +01:00
5 changed files with 534 additions and 433 deletions

View File

@@ -672,9 +672,12 @@ RubberBandStretcher::Impl::configure()
if (m_channelData[c]->resampler) continue; if (m_channelData[c]->resampler) continue;
m_channelData[c]->resampler = Resampler::Parameters params;
new Resampler(Resampler::FastestTolerable, 1, 4096 * 16, params.quality = Resampler::FastestTolerable;
m_debugLevel); params.maxBufferSize = 4096 * 16;
params.debugLevel = m_debugLevel;
m_channelData[c]->resampler = new Resampler(params, 1);
// rbs is the amount of buffer space we think we'll need // rbs is the amount of buffer space we think we'll need
// for resampling; but allocate a sensible amount in case // for resampling; but allocate a sensible amount in case
@@ -813,9 +816,12 @@ RubberBandStretcher::Impl::reconfigure()
std::cerr << "WARNING: reconfigure(): resampler construction required in RT mode" << std::endl; std::cerr << "WARNING: reconfigure(): resampler construction required in RT mode" << std::endl;
m_channelData[c]->resampler = Resampler::Parameters params;
new Resampler(Resampler::FastestTolerable, 1, m_sWindowSize, params.quality = Resampler::FastestTolerable;
m_debugLevel); params.maxBufferSize = m_sWindowSize;
params.debugLevel = m_debugLevel;
m_channelData[c]->resampler = new Resampler(params, 1);
size_t rbs = size_t rbs =
lrintf(ceil((m_increment * m_timeRatio * 2) / m_pitchScale)); lrintf(ceil((m_increment * m_timeRatio * 2) / m_pitchScale));

View File

@@ -217,8 +217,9 @@ RubberBandStretcher::Impl::consumeChannel(size_t c,
input = inputs[c] + offset; input = inputs[c] + offset;
} }
toWrite = cd.resampler->resample(&input, toWrite = cd.resampler->resample(&cd.resamplebuf,
&cd.resamplebuf, cd.resamplebufSize,
&input,
samples, samples,
1.0 / m_pitchScale, 1.0 / m_pitchScale,
final); final);
@@ -1090,8 +1091,9 @@ RubberBandStretcher::Impl::writeChunk(size_t channel, size_t shiftIncrement, boo
#endif #endif
#endif #endif
size_t outframes = cd.resampler->resample(&cd.accumulator, size_t outframes = cd.resampler->resample(&cd.resamplebuf,
&cd.resamplebuf, cd.resamplebufSize,
&cd.accumulator,
si, si,
1.0 / m_pitchScale, 1.0 / m_pitchScale,
last); last);

File diff suppressed because it is too large Load Diff

View File

@@ -21,60 +21,118 @@
you must obtain a valid commercial licence before doing so. you must obtain a valid commercial licence before doing so.
*/ */
#ifndef _RUBBERBAND_RESAMPLER_H_ #ifndef RUBBERBAND_RESAMPLER_H
#define _RUBBERBAND_RESAMPLER_H_ #define RUBBERBAND_RESAMPLER_H
#include "system/sysutils.h" #include "system/sysutils.h"
namespace RubberBand { namespace RubberBand {
class ResamplerImpl;
class Resampler class Resampler
{ {
public: public:
enum Quality { Best, FastestTolerable, Fastest }; enum Quality { Best, FastestTolerable, Fastest };
enum Exception { ImplementationError }; enum Exception { ImplementationError };
struct Parameters {
/**
* Resampler filter quality level.
*/
Quality quality;
/**
* Rate of expected input prior to resampling: may be used to
* determine the filter bandwidth for the quality setting. If
* you don't know what this will be, you can provide an
* arbitrary rate (such as the default) and the resampler will
* work fine, but quality may not be as designed.
*/
double initialSampleRate;
/**
* Bound on the maximum incount size that may be passed to the
* resample function before the resampler needs to reallocate
* its internal buffers. Default is zero, so that buffer
* allocation will happen on the first call and any subsequent
* call with a greater incount.
*/
int maxBufferSize;
/**
* Debug output level, from 0 to 3. Controls the amount of
* debug information printed to stderr.
*/
int debugLevel;
Parameters() :
quality(FastestTolerable),
initialSampleRate(44100),
maxBufferSize(0),
debugLevel(0) { }
};
/** /**
* Construct a resampler with the given quality level and channel * Construct a resampler to process the given number of channels,
* count. maxBufferSize gives a bound on the maximum incount size * with the given quality level, initial sample rate, and other
* that may be passed to the resample function before the * parameters.
* resampler needs to reallocate its internal buffers.
*/ */
Resampler(Quality quality, int channels, int maxBufferSize = 0, Resampler(Parameters parameters, int channels);
int debugLevel = 0);
~Resampler(); ~Resampler();
/** /**
* Resample the given multi-channel buffers, where incount is the * Resample the given multi-channel buffers, where incount is the
* number of frames in the input buffers. Returns the number of * number of frames in the input buffers and outspace is the space
* frames written to the output buffers. * available in the output buffers. Generally you want outspace to
* be at least ceil(incount * ratio).
*
* Returns the number of frames written to the output
* buffers. This may be smaller than outspace even where the ratio
* suggests otherwise, particularly at the start of processing
* where there may be a filter tail to allow for.
*/ */
int resample(const float *const R__ *const R__ in, #ifdef __GNUC__
float *const R__ *const R__ out, __attribute__((warn_unused_result))
#endif
int resample(float *const R__ *const R__ out,
int outspace,
const float *const R__ *const R__ in,
int incount, int incount,
float ratio, double ratio,
bool final = false); bool final = false);
/** /**
* Resample the given interleaved buffer, where incount is the * Resample the given interleaved buffer, where incount is the
* number of frames in the input buffer (i.e. it has incount * * number of frames in the input buffer (i.e. it has incount *
* getChannelCount() samples). Returns the number of frames * getChannelCount() samples) and outspace is the space available
* written to the output buffer. * in frames in the output buffer (i.e. it has space for at least
* outspace * getChannelCount() samples). Generally you want
* outspace to be at least ceil(incount * ratio).
*
* Returns the number of frames written to the output buffer. This
* may be smaller than outspace even where the ratio suggests
* otherwise, particularly at the start of processing where there
* may be a filter tail to allow for.
*/ */
int resampleInterleaved(const float *const R__ in, #ifdef __GNUC__
float *const R__ out, __attribute__((warn_unused_result))
#endif
int resampleInterleaved(float *const R__ out,
int outspace,
const float *const R__ in,
int incount, int incount,
float ratio, double ratio,
bool final = false); bool final = false);
int getChannelCount() const; int getChannelCount() const;
void reset(); void reset();
class Impl;
protected: protected:
ResamplerImpl *d; Impl *d;
int m_method; int m_method;
}; };

View File

@@ -21,8 +21,8 @@
you must obtain a valid commercial licence before doing so. you must obtain a valid commercial licence before doing so.
*/ */
#ifndef _RUBBERBAND_ALLOCATORS_H_ #ifndef RUBBERBAND_ALLOCATORS_H
#define _RUBBERBAND_ALLOCATORS_H_ #define RUBBERBAND_ALLOCATORS_H
#include "VectorOps.h" #include "VectorOps.h"