Report copied and overlapping source ranges from TDStretch
This commit is contained in:
1 parent
ceb06bafcf
commit
edcd34d942
2 files changed
+45
-1
No files matched your search
@@ -210,6 +210,35 @@ void TDStretch::clear()
|
|||||||
{
|
{
|
||||||
outputBuffer.clear();
|
outputBuffer.clear();
|
||||||
clearInput();
|
clearInput();
|
||||||
|
sourceInput = sourceOutput = sourceMid = 0;
|
||||||
|
sourceValid = sourceCallback != nullptr;
|
||||||
|
if (sourceCallback) sourceCallback(sourceContext, {SourceKind::Reset});
|
||||||
|
}
|
||||||
|
|
||||||
|
// uTun: метаданные принадлежат потребителю, SoundTouch не выделяет память для карты.
|
||||||
|
void TDStretch::setSourceCallback(SourceCallback callback, void* context, unsigned offset)
|
||||||
|
{
|
||||||
|
sourceCallback = callback;
|
||||||
|
sourceContext = context;
|
||||||
|
sourceOffset = offset;
|
||||||
|
sourceInput = sourceOutput = sourceMid = 0;
|
||||||
|
sourceValid = callback != nullptr;
|
||||||
|
if (callback) callback(context, {SourceKind::Reset});
|
||||||
|
}
|
||||||
|
|
||||||
|
void TDStretch::invalidateSource(SourceError reason)
|
||||||
|
{
|
||||||
|
if (!sourceValid) return;
|
||||||
|
sourceValid = false;
|
||||||
|
sourceCallback(sourceContext, {SourceKind::Invalid, reason});
|
||||||
|
}
|
||||||
|
|
||||||
|
void TDStretch::emitSource(SourceKind kind, uint64_t first, uint64_t second, unsigned count)
|
||||||
|
{
|
||||||
|
if (!sourceValid || !count) return;
|
||||||
|
sourceCallback(sourceContext, {kind, SourceError::None, sourceOutput,
|
||||||
|
first + sourceOffset, second + sourceOffset, count});
|
||||||
|
sourceOutput += count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -645,6 +674,7 @@ void TDStretch::processSamples()
|
|||||||
// (that's in 'midBuffer')
|
// (that's in 'midBuffer')
|
||||||
overlap(outputBuffer.ptrEnd((uint)overlapLength), inputBuffer.ptrBegin(), (uint)offset);
|
overlap(outputBuffer.ptrEnd((uint)overlapLength), inputBuffer.ptrBegin(), (uint)offset);
|
||||||
outputBuffer.putSamples((uint)overlapLength);
|
outputBuffer.putSamples((uint)overlapLength);
|
||||||
|
emitSource(SourceKind::Mix, sourceMid, sourceInput + offset, (unsigned)overlapLength);
|
||||||
offset += overlapLength;
|
offset += overlapLength;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -683,6 +713,7 @@ void TDStretch::processSamples()
|
|||||||
// length of sequence
|
// length of sequence
|
||||||
temp = (seekWindowLength - 2 * overlapLength);
|
temp = (seekWindowLength - 2 * overlapLength);
|
||||||
outputBuffer.putSamples(inputBuffer.ptrBegin() + channels * offset, (uint)temp);
|
outputBuffer.putSamples(inputBuffer.ptrBegin() + channels * offset, (uint)temp);
|
||||||
|
emitSource(SourceKind::Copy, sourceInput + offset, 0, (unsigned)temp);
|
||||||
|
|
||||||
// Copies the end of the current sequence from 'inputBuffer' to
|
// Copies the end of the current sequence from 'inputBuffer' to
|
||||||
// 'midBuffer' for being mixed with the beginning of the next
|
// 'midBuffer' for being mixed with the beginning of the next
|
||||||
@@ -690,6 +721,7 @@ void TDStretch::processSamples()
|
|||||||
assert((offset + temp + overlapLength) <= (int)inputBuffer.numSamples());
|
assert((offset + temp + overlapLength) <= (int)inputBuffer.numSamples());
|
||||||
memcpy(pMidBuffer, inputBuffer.ptrBegin() + channels * (offset + temp),
|
memcpy(pMidBuffer, inputBuffer.ptrBegin() + channels * (offset + temp),
|
||||||
channels * sizeof(SAMPLETYPE) * overlapLength);
|
channels * sizeof(SAMPLETYPE) * overlapLength);
|
||||||
|
sourceMid = sourceInput + offset + temp;
|
||||||
|
|
||||||
// Remove the processed samples from the input buffer. Update
|
// Remove the processed samples from the input buffer. Update
|
||||||
// the difference between integer & nominal skip step to 'skipFract'
|
// the difference between integer & nominal skip step to 'skipFract'
|
||||||
@@ -697,7 +729,7 @@ void TDStretch::processSamples()
|
|||||||
skipFract += nominalSkip; // real skip size
|
skipFract += nominalSkip; // real skip size
|
||||||
ovlSkip = (int)skipFract; // rounded to integer skip
|
ovlSkip = (int)skipFract; // rounded to integer skip
|
||||||
skipFract -= ovlSkip; // maintain the fraction part, i.e. real vs. integer skip
|
skipFract -= ovlSkip; // maintain the fraction part, i.e. real vs. integer skip
|
||||||
inputBuffer.receiveSamples((uint)ovlSkip);
|
sourceInput += inputBuffer.receiveSamples((uint)ovlSkip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
#include "STTypes.h"
|
#include "STTypes.h"
|
||||||
#include "RateTransposer.h"
|
#include "RateTransposer.h"
|
||||||
#include "FIFOSamplePipe.h"
|
#include "FIFOSamplePipe.h"
|
||||||
|
#include "SourceSpan.h"
|
||||||
|
|
||||||
namespace soundtouch
|
namespace soundtouch
|
||||||
{
|
{
|
||||||
@@ -135,6 +136,13 @@ protected:
|
|||||||
FIFOSampleBuffer outputBuffer;
|
FIFOSampleBuffer outputBuffer;
|
||||||
FIFOSampleBuffer inputBuffer;
|
FIFOSampleBuffer inputBuffer;
|
||||||
|
|
||||||
|
SourceCallback sourceCallback = nullptr;
|
||||||
|
void* sourceContext = nullptr;
|
||||||
|
bool sourceValid = false;
|
||||||
|
uint64_t sourceInput = 0, sourceOutput = 0, sourceMid = 0;
|
||||||
|
unsigned sourceOffset = 0;
|
||||||
|
void emitSource(SourceKind kind, uint64_t first, uint64_t second, unsigned count);
|
||||||
|
|
||||||
void acceptNewOverlapLength(int newOverlapLength);
|
void acceptNewOverlapLength(int newOverlapLength);
|
||||||
|
|
||||||
virtual void clearCrossCorrState();
|
virtual void clearCrossCorrState();
|
||||||
@@ -167,6 +175,10 @@ public:
|
|||||||
TDStretch();
|
TDStretch();
|
||||||
virtual ~TDStretch() override;
|
virtual ~TDStretch() override;
|
||||||
|
|
||||||
|
// Только SoundTouch: регистрация на пустом тракте, затем события из processSamples().
|
||||||
|
void setSourceCallback(SourceCallback callback, void* context, unsigned offset);
|
||||||
|
void invalidateSource(SourceError reason);
|
||||||
|
|
||||||
/// Operator 'new' is overloaded so that it automatically creates a suitable instance
|
/// Operator 'new' is overloaded so that it automatically creates a suitable instance
|
||||||
/// depending on if we've a MMX/SSE/etc-capable CPU available or not.
|
/// depending on if we've a MMX/SSE/etc-capable CPU available or not.
|
||||||
static void *operator new(size_t s);
|
static void *operator new(size_t s);
|
||||||
|
|||||||
Reference in new issue
Block a user