* Consume output when running stretcher in RT mode from Vamp plugin;
start some documentation
This commit is contained in:
@@ -26,6 +26,125 @@ class RubberBandStretcher : public TimeStretcher
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processing options for the timestretcher. The preferred
|
||||||
|
* options should normally be set in the constructor, as a bitwise
|
||||||
|
* OR of the option flags. The default value (DefaultOptions) is
|
||||||
|
* intended to give good results in most situations.
|
||||||
|
*
|
||||||
|
* 1. Flags prefixed OptionProcess determine how the timestretcher
|
||||||
|
* will be invoked. These options may not be changed after
|
||||||
|
* construction.
|
||||||
|
*
|
||||||
|
* OptionProcessOffline - Run the stretcher in offline mode. In
|
||||||
|
* this mode the input data needs to be provided twice, once to
|
||||||
|
* study(), which calculates a stretch profile for the audio,
|
||||||
|
* and once to process(), which stretches it.
|
||||||
|
*
|
||||||
|
* OptionProcessRealTime - Run the stretcher in real-time mode.
|
||||||
|
* In this mode only process() should be called, and the
|
||||||
|
* stretcher adjusts dynamically in response to the input audio.
|
||||||
|
*
|
||||||
|
* The Process setting is likely to depend on your architecture:
|
||||||
|
* non-real-time operation on seekable files: Offline; real-time
|
||||||
|
* or streaming operation: RealTime.
|
||||||
|
*
|
||||||
|
* 2. Flags prefixed OptionStretch control the profile used for
|
||||||
|
* variable timestretching. Rubber Band always adjusts the
|
||||||
|
* stretch profile to minimise stretching of busy broadband
|
||||||
|
* transient sounds, but the degree to which it does so is
|
||||||
|
* adjustable. These options may not be changed after
|
||||||
|
* construction.
|
||||||
|
*
|
||||||
|
* OptionStretchElastic - Only meaningful in offline mode, and
|
||||||
|
* the default in that mode. The audio will be stretched at a
|
||||||
|
* variable rate, aimed at preserving the quality of transient
|
||||||
|
* sounds as much as possible. The timings of low activity
|
||||||
|
* regions between transients may be less exact than when the
|
||||||
|
* precise flag is set.
|
||||||
|
*
|
||||||
|
* OptionStretchPrecise - Although still using a variable
|
||||||
|
* stretch rate, the audio will be stretched so as to maintain
|
||||||
|
* as close as possible to a linear stretch ratio throughout.
|
||||||
|
* Timing may be better than when using OptionStretchElastic, at
|
||||||
|
* slight cost to the sound quality of transients. This setting
|
||||||
|
* is always used when running in real-time mode.
|
||||||
|
*
|
||||||
|
* 3. Flags prefixed OptionTransients control the component
|
||||||
|
* frequency phase-reset mechanism that may be used at transient
|
||||||
|
* points to provide clarity and realism to percussion and other
|
||||||
|
* significant transient sounds. These options may be changed
|
||||||
|
* after construction when running in real-time mode, but not when
|
||||||
|
* running in offline mode.
|
||||||
|
*
|
||||||
|
* OptionTransientsCrisp - Reset component phases at the peak of
|
||||||
|
* each transient (the start of a significant note or percussive
|
||||||
|
* event). This, the default setting, usually results in a
|
||||||
|
* clear-sounding output; but it is not always consistent, and
|
||||||
|
* may cause interruptions in stable sounds present at the same
|
||||||
|
* time as transient events.
|
||||||
|
*
|
||||||
|
* OptionTransientsMixed - Reset component phases at the peak of
|
||||||
|
* each transient, outside a frequency range typical of musical
|
||||||
|
* fundamental frequencies. The results may be more regular for
|
||||||
|
* mixed stable and percussive notes than OptionTransientsCrisp,
|
||||||
|
* but with a "phasier" sound. The balance may sound very good
|
||||||
|
* for certain types of music and fairly bad for others.
|
||||||
|
*
|
||||||
|
* OptionTransientsSmooth - Do not reset component phases at any
|
||||||
|
* point. The results will be smoother and more regular but may
|
||||||
|
* be less clear than with either of the other transients flags.
|
||||||
|
*
|
||||||
|
* 4. Flags prefixed OptionPhase control the adjustment of
|
||||||
|
* component frequency phases from one analysis window to the next
|
||||||
|
* during non-transient segments. These options may be changed at
|
||||||
|
* any time.
|
||||||
|
*
|
||||||
|
* OptionPhaseAdaptive - Lock the adjustments of phase for
|
||||||
|
* frequencies close to peak frequencies to those of the peak,
|
||||||
|
* but reduce the degree of locking as the stretch ratio gets
|
||||||
|
* longer. This, the default setting, should give a good
|
||||||
|
* balance between clarity and smoothness in most situations.
|
||||||
|
*
|
||||||
|
* OptionPhasePeakLocked - Lock the adjustments of phase for
|
||||||
|
* frequencies close to peak frequencies to those of the peak.
|
||||||
|
* This should give a clear result in situations with relatively
|
||||||
|
* low stretch ratios, but a relatively metallic sound at longer
|
||||||
|
* stretches.
|
||||||
|
*
|
||||||
|
* OptionPhaseIndependent - Do not lock phase adjustments to
|
||||||
|
* peak frequencies. This usually results in a softer, phasier
|
||||||
|
* sound.
|
||||||
|
*
|
||||||
|
* 5. Options prefixed OptionThreading control the threading model
|
||||||
|
* of the stretcher. These options may not be changed after
|
||||||
|
* construction.
|
||||||
|
*
|
||||||
|
* OptionThreadingAuto - Permit the stretcher to determine its
|
||||||
|
* own threading model. Usually this means using one processing
|
||||||
|
* thread per audio channel in offline mode, and one thread only
|
||||||
|
* in realtime mode.
|
||||||
|
*
|
||||||
|
* OptionThreadingNone - Never use more than one thread.
|
||||||
|
*
|
||||||
|
* 6. Options prefixed OptionWindow control the window size for
|
||||||
|
* FFT processing. The window size actually used will depend on
|
||||||
|
* many factors, but it can be influenced. These options may not
|
||||||
|
* be changed after construction.
|
||||||
|
*
|
||||||
|
* OptionWindowStandard - Use the default window size. The
|
||||||
|
* actual size will vary depending on other parameters. This
|
||||||
|
* option is expected to produce better results than the other
|
||||||
|
* window options in most situations.
|
||||||
|
*
|
||||||
|
* OptionWindowShort - Use a shorter window. This may result in
|
||||||
|
* crisper sound for audio that depends strongly on its timing
|
||||||
|
* qualities.
|
||||||
|
*
|
||||||
|
* OptionWindowLong - Use a longer window. This is likely to
|
||||||
|
* result in a smoother sound at the expense of clarity and
|
||||||
|
* timing.
|
||||||
|
*/
|
||||||
typedef int Options;
|
typedef int Options;
|
||||||
|
|
||||||
static const int OptionProcessOffline = 0x00000000;
|
static const int OptionProcessOffline = 0x00000000;
|
||||||
@@ -53,6 +172,14 @@ public:
|
|||||||
static const int PercussiveOptions = OptionWindowShort | \
|
static const int PercussiveOptions = OptionWindowShort | \
|
||||||
OptionPhaseIndependent;
|
OptionPhaseIndependent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a time-and-pitch-scaling object to run at the given
|
||||||
|
* sample rate, with the given number of channels. Processing
|
||||||
|
* options and the time and pitch scaling ratios may be provided.
|
||||||
|
* The time and pitch ratios may be changed after construction,
|
||||||
|
* but most of the options may not. See the option documentation
|
||||||
|
* above for more details.
|
||||||
|
*/
|
||||||
RubberBandStretcher(size_t sampleRate,
|
RubberBandStretcher(size_t sampleRate,
|
||||||
size_t channels,
|
size_t channels,
|
||||||
Options options = DefaultOptions,
|
Options options = DefaultOptions,
|
||||||
@@ -62,7 +189,7 @@ public:
|
|||||||
|
|
||||||
virtual void reset();
|
virtual void reset();
|
||||||
virtual void setTimeRatio(double ratio);
|
virtual void setTimeRatio(double ratio);
|
||||||
virtual void setPitchScale(double scale); //!!!??? pitch ratio?
|
virtual void setPitchScale(double scale);
|
||||||
|
|
||||||
virtual double getTimeRatio() const;
|
virtual double getTimeRatio() const;
|
||||||
virtual double getPitchScale() const;
|
virtual double getPitchScale() const;
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ public:
|
|||||||
size_t m_counter;
|
size_t m_counter;
|
||||||
size_t m_accumulatedIncrement;
|
size_t m_accumulatedIncrement;
|
||||||
|
|
||||||
|
float **m_outputDump;
|
||||||
|
|
||||||
FeatureSet processOffline(const float *const *inputBuffers,
|
FeatureSet processOffline(const float *const *inputBuffers,
|
||||||
Vamp::RealTime timestamp);
|
Vamp::RealTime timestamp);
|
||||||
|
|
||||||
@@ -92,6 +94,12 @@ RubberBandVampPlugin::RubberBandVampPlugin(float inputSampleRate) :
|
|||||||
|
|
||||||
RubberBandVampPlugin::~RubberBandVampPlugin()
|
RubberBandVampPlugin::~RubberBandVampPlugin()
|
||||||
{
|
{
|
||||||
|
if (m_d->m_outputDump) {
|
||||||
|
for (size_t i = 0; i < m_d->m_stretcher->getChannelCount(); ++i) {
|
||||||
|
delete[] m_d->m_outputDump[i];
|
||||||
|
}
|
||||||
|
delete[] m_d->m_outputDump;
|
||||||
|
}
|
||||||
delete m_d->m_stretcher;
|
delete m_d->m_stretcher;
|
||||||
delete m_d;
|
delete m_d;
|
||||||
}
|
}
|
||||||
@@ -403,13 +411,15 @@ RubberBandVampPlugin::initialise(size_t channels, size_t stepSize, size_t blockS
|
|||||||
delete m_d->m_stretcher;
|
delete m_d->m_stretcher;
|
||||||
m_d->m_stretcher = new RubberBand::RubberBandStretcher
|
m_d->m_stretcher = new RubberBand::RubberBandStretcher
|
||||||
(m_d->m_sampleRate, channels, options);
|
(m_d->m_sampleRate, channels, options);
|
||||||
m_d->m_stretcher->setDebugLevel(2);
|
m_d->m_stretcher->setDebugLevel(1);
|
||||||
m_d->m_stretcher->setTimeRatio(m_d->m_timeRatio);
|
m_d->m_stretcher->setTimeRatio(m_d->m_timeRatio);
|
||||||
m_d->m_stretcher->setPitchScale(m_d->m_pitchRatio);
|
m_d->m_stretcher->setPitchScale(m_d->m_pitchRatio);
|
||||||
|
|
||||||
m_d->m_counter = 0;
|
m_d->m_counter = 0;
|
||||||
m_d->m_accumulatedIncrement = 0;
|
m_d->m_accumulatedIncrement = 0;
|
||||||
|
|
||||||
|
m_d->m_outputDump = 0;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -510,6 +520,18 @@ RubberBandVampPlugin::Impl::processRealTime(const float *const *inputBuffers,
|
|||||||
m_counter, false);
|
m_counter, false);
|
||||||
m_counter += outputIncrements.size();
|
m_counter += outputIncrements.size();
|
||||||
|
|
||||||
|
int available = 0;
|
||||||
|
while ((available = m_stretcher->available()) > 0) {
|
||||||
|
if (!m_outputDump) {
|
||||||
|
m_outputDump = new float *[m_stretcher->getChannelCount()];
|
||||||
|
for (size_t i = 0; i < m_stretcher->getChannelCount(); ++i) {
|
||||||
|
m_outputDump[i] = new float[m_blockSize];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_stretcher->retrieve(m_outputDump,
|
||||||
|
std::min(int(m_blockSize), available));
|
||||||
|
}
|
||||||
|
|
||||||
return features;
|
return features;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user