mirror of
https://github.com/RPCS3/soundtouch.git
synced 2024-11-08 20:12:27 +01:00
Added functions to get initial processing latency, and clarified reporting input/output batch sizes
This commit is contained in:
parent
62d63e7881
commit
ac03757ec8
@ -116,30 +116,61 @@ namespace soundtouch
|
||||
#define SETTING_OVERLAP_MS 5
|
||||
|
||||
|
||||
/// Call "getSetting" with this ID to query nominal average processing sequence
|
||||
/// size in samples. This value tells approcimate value how many input samples
|
||||
/// SoundTouch needs to gather before it does DSP processing run for the sample batch.
|
||||
/// Call "getSetting" with this ID to query processing sequence size in samples.
|
||||
/// This value gives approximate value of how many input samples you'll need to
|
||||
/// feed into SoundTouch after initial buffering to get out a new batch of
|
||||
/// output samples.
|
||||
///
|
||||
/// This value does not include initial buffering at beginning of a new processing
|
||||
/// stream, use SETTING_INITIAL_LATENCY to get the initial buffering size.
|
||||
///
|
||||
/// Notices:
|
||||
/// - This is read-only parameter, i.e. setSetting ignores this parameter
|
||||
/// - Returned value is approximate average value, exact processing batch
|
||||
/// size may wary from time to time
|
||||
/// - This parameter value is not constant but may change depending on
|
||||
/// - This parameter value is not constant but change depending on
|
||||
/// tempo/pitch/rate/samplerate settings.
|
||||
#define SETTING_NOMINAL_INPUT_SEQUENCE 6
|
||||
#define SETTING_NOMINAL_INPUT_SEQUENCE 6
|
||||
|
||||
|
||||
/// Call "getSetting" with this ID to query nominal average processing output
|
||||
/// size in samples. This value tells approcimate value how many output samples
|
||||
/// SoundTouch outputs once it does DSP processing run for a batch of input samples.
|
||||
///
|
||||
///
|
||||
/// Notices:
|
||||
/// - This is read-only parameter, i.e. setSetting ignores this parameter
|
||||
/// - Returned value is approximate average value, exact processing batch
|
||||
/// size may wary from time to time
|
||||
/// - This parameter value is not constant but may change depending on
|
||||
/// - This parameter value is not constant but change depending on
|
||||
/// tempo/pitch/rate/samplerate settings.
|
||||
#define SETTING_NOMINAL_OUTPUT_SEQUENCE 7
|
||||
#define SETTING_NOMINAL_OUTPUT_SEQUENCE 7
|
||||
|
||||
|
||||
/// Call "getSetting" with this ID to query initial processing latency, i.e.
|
||||
/// approx. how many samples you'll need to enter to SoundTouch pipeline before
|
||||
/// you can expect to get first batch of ready output samples out.
|
||||
///
|
||||
/// After the first output batch, you can then expect to get approx.
|
||||
/// SETTING_NOMINAL_OUTPUT_SEQUENCE ready samples out for every
|
||||
/// SETTING_NOMINAL_INPUT_SEQUENCE samples that you enter into SoundTouch.
|
||||
///
|
||||
/// Example:
|
||||
/// processing with parameter -tempo=5
|
||||
/// => initial latency = 5509 samples
|
||||
/// input sequence = 4167 samples
|
||||
/// output sequence = 3969 samples
|
||||
///
|
||||
/// Accordingly, you can expect to feed in approx. 5509 samples at beginning of
|
||||
/// the stream, and then you'll get out the first 3969 samples. After that, for
|
||||
/// every approx. 4167 samples that you'll put in, you'll receive again approx.
|
||||
/// 3969 samples out.
|
||||
///
|
||||
/// This also means that average latency during stream processing is
|
||||
/// INITIAL_LATENCY-OUTPUT_SEQUENCE/2, in the above example case 5509-3969/2
|
||||
/// = 3524 samples
|
||||
///
|
||||
/// Notices:
|
||||
/// - This is read-only parameter, i.e. setSetting ignores this parameter
|
||||
/// - This parameter value is not constant but change depending on
|
||||
/// tempo/pitch/rate/samplerate settings.
|
||||
#define SETTING_INITIAL_LATENCY 8
|
||||
|
||||
|
||||
class SoundTouch : public FIFOProcessor
|
||||
{
|
||||
|
@ -208,6 +208,13 @@ int RateTransposer::isEmpty() const
|
||||
}
|
||||
|
||||
|
||||
/// Return approximate initial input-output latency
|
||||
int RateTransposer::getLatency() const
|
||||
{
|
||||
return (bUseAAFilter) ? pAAFilter->getLength() : 0;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TransposerBase - Base class for interpolation
|
||||
|
@ -447,7 +447,7 @@ int SoundTouch::getSetting(int settingId) const
|
||||
return pRateTransposer->getAAFilter()->getLength();
|
||||
|
||||
case SETTING_USE_QUICKSEEK :
|
||||
return (uint) pTDStretch->isQuickSeekEnabled();
|
||||
return (uint)pTDStretch->isQuickSeekEnabled();
|
||||
|
||||
case SETTING_SEQUENCE_MS:
|
||||
pTDStretch->getParameters(NULL, &temp, NULL, NULL);
|
||||
@ -462,10 +462,51 @@ int SoundTouch::getSetting(int settingId) const
|
||||
return temp;
|
||||
|
||||
case SETTING_NOMINAL_INPUT_SEQUENCE :
|
||||
return pTDStretch->getInputSampleReq();
|
||||
{
|
||||
int size = pTDStretch->getInputSampleReq();
|
||||
|
||||
#ifndef SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER
|
||||
if (rate <= 1.0)
|
||||
{
|
||||
// transposing done before timestretch, which impacts latency
|
||||
return (int)(size * rate + 0.5);
|
||||
}
|
||||
#endif
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
case SETTING_NOMINAL_OUTPUT_SEQUENCE :
|
||||
return pTDStretch->getOutputBatchSize();
|
||||
{
|
||||
int size = pTDStretch->getOutputBatchSize();
|
||||
|
||||
if (rate > 1.0)
|
||||
{
|
||||
// transposing done after timestretch, which impacts latency
|
||||
return (int)(size / rate + 0.5);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
case SETTING_INITIAL_LATENCY:
|
||||
{
|
||||
double latency = pTDStretch->getLatency();
|
||||
int latency_tr = pRateTransposer->getLatency();
|
||||
|
||||
#ifndef SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER
|
||||
if (rate <= 1.0)
|
||||
{
|
||||
// transposing done before timestretch, which impacts latency
|
||||
latency = (latency + latency_tr) * rate;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
latency += (double)latency_tr / rate;
|
||||
}
|
||||
|
||||
return (int)(latency + 0.5);
|
||||
}
|
||||
|
||||
default :
|
||||
return 0;
|
||||
|
@ -656,7 +656,7 @@ void TDStretch::processSamples()
|
||||
// to form a processing frame.
|
||||
while ((int)inputBuffer.numSamples() >= sampleReq)
|
||||
{
|
||||
// If tempo differs from the normal ('SCALE'), scan for the best overlapping
|
||||
// If tempo differs from the normal ('SCALE'), scan for the best overlapping
|
||||
// position
|
||||
offset = seekBestOverlapPosition(inputBuffer.ptrBegin());
|
||||
|
||||
@ -673,7 +673,7 @@ void TDStretch::processSamples()
|
||||
temp = (seekWindowLength - 2 * overlapLength);
|
||||
|
||||
// crosscheck that we don't have buffer overflow...
|
||||
if ((int)inputBuffer.numSamples() < (offset + temp + overlapLength * 2))
|
||||
if ((int)inputBuffer.numSamples() < (offset + seekWindowLength))
|
||||
{
|
||||
continue; // just in case, shouldn't really happen
|
||||
}
|
||||
|
@ -247,6 +247,13 @@ public:
|
||||
{
|
||||
return seekWindowLength - overlapLength;
|
||||
}
|
||||
|
||||
|
||||
/// return approximate initial input-output latency
|
||||
int getLatency() const
|
||||
{
|
||||
return sampleReq;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user