* documentation
This commit is contained in:
3
TODO
3
TODO
@@ -1,12 +1,13 @@
|
||||
|
||||
* Fix "!!!" points
|
||||
* Add and test Win32 threading primitives in Thread.cpp
|
||||
* LADSPA plugin has too much "artificial latency"
|
||||
* LADSPA plugin probably doesn't want to go any higher than about +2 octaves
|
||||
* Return value check in FFT and resampler!
|
||||
* implement+test, or remove, reset()
|
||||
* sweeps & tones
|
||||
* ensure default options don't produce garbage at any extreme
|
||||
|
||||
DONE * Add and test Win32 threading primitives in Thread.cpp
|
||||
DONE * Threading lock structure is very slow if it becomes starved of CPUs
|
||||
DONE * Rationalise naming further (e.g. use of "lock" for both peak phases
|
||||
and resynchronisation at transients; use of block vs chunk vs frame
|
||||
|
||||
@@ -179,7 +179,7 @@ public:
|
||||
OptionPhaseIndependent;
|
||||
|
||||
/**
|
||||
* Construct a time-and-pitch-scaling object to run at the given
|
||||
* Construct a time and pitch stretcher 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,
|
||||
@@ -193,34 +193,198 @@ public:
|
||||
double initialPitchScale = 1.0);
|
||||
virtual ~RubberBandStretcher();
|
||||
|
||||
/**
|
||||
* Reset the stretcher's internal buffers. The stretcher should
|
||||
* subsequently behave as if it had just been constructed
|
||||
* (although retaining the current time and pitch ratio).
|
||||
*/
|
||||
virtual void reset();
|
||||
|
||||
/**
|
||||
* Set the time ratio for the stretcher. This is the ratio of
|
||||
* stretched to unstretched duration -- not tempo. For example, a
|
||||
* ratio of 2.0 would make the audio twice as long (i.e. halve the
|
||||
* tempo); 0.5 would make it half as long (i.e. double the tempo);
|
||||
* 1.0 would leave the duration unaffected.
|
||||
*
|
||||
* If the stretcher was constructed in Offline mode, the time
|
||||
* ratio is fixed throughout operation; this function may be
|
||||
* called any number of times between construction (or a call to
|
||||
* reset()) and the first call to study() or process(), but may
|
||||
* not be called after study() or process() has been called.
|
||||
*
|
||||
* If the stretcher was constructed in RealTime mode, the time
|
||||
* ratio may be varied during operation; this function may be
|
||||
* called at any time, so long as it is not called concurrently
|
||||
* with process(). You should either call this function from the
|
||||
* same thread as process(), or provide your own mutex or similar
|
||||
* mechanism to ensure that setTimeRatio and process() cannot be
|
||||
* run at once (there is no internal mutex for this purpose).
|
||||
*/
|
||||
virtual void setTimeRatio(double ratio);
|
||||
|
||||
/**
|
||||
* Set the pitch scaling ratio for the stretcher. This is the
|
||||
* ratio of target frequency to source frequency. For example, a
|
||||
* ratio of 2.0 would shift up by one octave; 0.5 down by one
|
||||
* octave; or 1.0 leave the pitch unaffected.
|
||||
*
|
||||
* To put this in musical terms, a pitch scaling ratio
|
||||
* corresponding to a shift of S equal-tempered semitones (where S
|
||||
* is positive for an upwards shift and negative for downwards) is
|
||||
* pow(2.0, S / 12.0).
|
||||
*
|
||||
* If the stretcher was constructed in Offline mode, the pitch
|
||||
* scaling ratio is fixed throughout operation; this function may
|
||||
* be called any number of times between construction (or a call
|
||||
* to reset()) and the first call to study() or process(), but may
|
||||
* not be called after study() or process() has been called.
|
||||
*
|
||||
* If the stretcher was constructed in RealTime mode, the pitch
|
||||
* scaling ratio may be varied during operation; this function may
|
||||
* be called at any time, so long as it is not called concurrently
|
||||
* with process(). You should either call this function from the
|
||||
* same thread as process(), or provide your own mutex or similar
|
||||
* mechanism to ensure that setPitchScale and process() cannot be
|
||||
* run at once (there is no internal mutex for this purpose).
|
||||
*/
|
||||
virtual void setPitchScale(double scale);
|
||||
|
||||
/**
|
||||
* Return the last time ratio value that was set (either on
|
||||
* construction or with setTimeRatio()).
|
||||
*/
|
||||
virtual double getTimeRatio() const;
|
||||
|
||||
/**
|
||||
* Return the last pitch scaling ratio value that was set (either
|
||||
* on construction or with setPitchScale()).
|
||||
*/
|
||||
virtual double getPitchScale() const;
|
||||
|
||||
/**
|
||||
* Return the processing latency of the stretcher. This is the
|
||||
* number of audio samples that one would have to discard at the
|
||||
* start of the output in order to ensure that the resulting audio
|
||||
* aligned with the input audio at the start. In Offline mode,
|
||||
* latency is automatically adjusted for and the result is zero.
|
||||
* In RealTime mode, the latency may depend on the time and pitch
|
||||
* ratio and other options.
|
||||
*/
|
||||
virtual size_t getLatency() const;
|
||||
|
||||
/**
|
||||
* Change an OptionTransients configuration setting. This may be
|
||||
* called at any time in RealTime mode. It may not be called in
|
||||
* Offline mode (for which the transients option is fixed on
|
||||
* construction).
|
||||
*/
|
||||
virtual void setTransientsOption(Options options);
|
||||
|
||||
/**
|
||||
* Change an OptionPhase configuration setting. This may be
|
||||
* called at any time in any mode.
|
||||
*
|
||||
* Note that if running multi-threaded in Offline mode, the change
|
||||
* may not take effect immediately if processing is already under
|
||||
* way when this function is called.
|
||||
*/
|
||||
virtual void setPhaseOption(Options options);
|
||||
|
||||
/**
|
||||
* Tell the stretcher exactly how many input samples it will
|
||||
* receive. This is only useful in Offline mode, when it allows
|
||||
* the stretcher to ensure that the number of output samples is
|
||||
* exactly correct. In RealTime mode no such guarantee is
|
||||
* possible and this value is ignored.
|
||||
*/
|
||||
virtual void setExpectedInputDuration(size_t samples);
|
||||
virtual void setMaxProcessSize(size_t samples);
|
||||
|
||||
/**
|
||||
* Ask the stretcher how many audio sample frames should be
|
||||
* provided as input in order to ensure that some more output
|
||||
* becomes available. Normal usage consists of querying this
|
||||
* function, providing that number of samples to process(),
|
||||
* reading the output using available() and retrieve(), and then
|
||||
* repeating.
|
||||
*
|
||||
* Note that this value is only relevant to process(), not to
|
||||
* study() (to which you may pass any number of samples at a time,
|
||||
* and from which there is no output).
|
||||
*/
|
||||
virtual size_t getSamplesRequired() const;
|
||||
|
||||
// if samples == 0, input may be null
|
||||
/**
|
||||
* Tell the stretcher the maximum number of sample frames that you
|
||||
* will ever be passing in to a single process() call. If you
|
||||
* don't call this function, the stretcher will assume that you
|
||||
* never pass in more samples than getSamplesRequired() suggested
|
||||
* you should. You should not pass in more samples than that
|
||||
* unless you have called setMaxProcessSize first.
|
||||
*
|
||||
* This function may not be called after the first call to study()
|
||||
* or process().
|
||||
*
|
||||
* Note that this value is only relevant to process(), not to
|
||||
* study() (to which you may pass any number of samples at a time,
|
||||
* and from which there is no output).
|
||||
*/
|
||||
virtual void setMaxProcessSize(size_t samples);
|
||||
|
||||
/**
|
||||
* Provide a block of "samples" sample frames for the stretcher to
|
||||
* study and calculate a stretch profile from.
|
||||
*
|
||||
* This is only meaningful in Offline mode, and is required if
|
||||
* running in that mode. You should pass the entire input through
|
||||
* study() before any process() calls are made, as a sequence of
|
||||
* blocks in individual study() calls, or as a single large block.
|
||||
*
|
||||
* "input" should point to de-interleaved audio data with one
|
||||
* float array per channel. "samples" supplies the number of
|
||||
* audio sample frames available in "input". If "samples" is
|
||||
* zero, "input" may be NULL.
|
||||
*
|
||||
* Set "final" to true if this is the last block of data that will
|
||||
* be provided to study() before the first process() call.
|
||||
*/
|
||||
virtual void study(const float *const *input, size_t samples, bool final);
|
||||
|
||||
/**
|
||||
* Provide a block of "samples" sample frames for processing.
|
||||
* See also getSamplesRequired() and setMaxProcessSize().
|
||||
*
|
||||
* Set "final" to true if this is the last block of input data.
|
||||
*/
|
||||
virtual void process(const float *const *input, size_t samples, bool final);
|
||||
|
||||
virtual int available() const; // returns -1 if all data processed and nothing further will be available
|
||||
/**
|
||||
* Ask the stretcher how many audio sample frames of output data
|
||||
* are available for reading (via retrieve()).
|
||||
*
|
||||
* This function returns 0 if no frames are available: this
|
||||
* usually means more input data needs to be provided, but if the
|
||||
* stretcher is running in threaded mode it may just mean that not
|
||||
* enough data has yet been processed. Call getSamplesRequired()
|
||||
* to discover whether more input is needed.
|
||||
*
|
||||
* This function returns -1 if all data has been fully processed
|
||||
* and all output read, and the stretch process is now finished.
|
||||
*/
|
||||
virtual int available() const;
|
||||
|
||||
/**
|
||||
* Obtain some processed output data from the stretcher. Up to
|
||||
* "samples" samples will be stored in the output arrays (one per
|
||||
* channel for de-interleaved audio data) pointed to by "output".
|
||||
* The return value is the actual number of sample frames
|
||||
* retrieved.
|
||||
*/
|
||||
virtual size_t retrieve(float *const *output, size_t samples) const;
|
||||
|
||||
virtual float getFrequencyCutoff(int n) const;
|
||||
virtual void setFrequencyCutoff(int n, float f);
|
||||
|
||||
//!!! ideally, this stuff wouldn't be here...
|
||||
|
||||
virtual size_t getInputIncrement() const;
|
||||
virtual std::vector<int> getOutputIncrements() const; //!!! document particular meaning in RT mode
|
||||
virtual std::vector<float> getPhaseResetCurve() const; //!!! document particular meaning in RT mode
|
||||
|
||||
@@ -338,7 +338,7 @@ RubberBandPitchShifter::runImpl(unsigned long insamples)
|
||||
|
||||
float *ptrs[2];
|
||||
|
||||
//!!! We have to break up the input into chunks like this because
|
||||
// We have to break up the input into chunks like this because
|
||||
// insamples could be arbitrarily large
|
||||
|
||||
while (processed < samples) {
|
||||
|
||||
Reference in New Issue
Block a user