diff --git a/lib/soundtouch-master/source/SoundTouch/TDStretch.cpp b/lib/soundtouch-master/source/SoundTouch/TDStretch.cpp index 80c421ca..adfb67c2 100644 --- a/lib/soundtouch-master/source/SoundTouch/TDStretch.cpp +++ b/lib/soundtouch-master/source/SoundTouch/TDStretch.cpp @@ -210,6 +210,35 @@ void TDStretch::clear() { outputBuffer.clear(); 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') overlap(outputBuffer.ptrEnd((uint)overlapLength), inputBuffer.ptrBegin(), (uint)offset); outputBuffer.putSamples((uint)overlapLength); + emitSource(SourceKind::Mix, sourceMid, sourceInput + offset, (unsigned)overlapLength); offset += overlapLength; } else @@ -683,6 +713,7 @@ void TDStretch::processSamples() // length of sequence temp = (seekWindowLength - 2 * overlapLength); 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 // 'midBuffer' for being mixed with the beginning of the next @@ -690,6 +721,7 @@ void TDStretch::processSamples() assert((offset + temp + overlapLength) <= (int)inputBuffer.numSamples()); memcpy(pMidBuffer, inputBuffer.ptrBegin() + channels * (offset + temp), channels * sizeof(SAMPLETYPE) * overlapLength); + sourceMid = sourceInput + offset + temp; // Remove the processed samples from the input buffer. Update // the difference between integer & nominal skip step to 'skipFract' @@ -697,7 +729,7 @@ void TDStretch::processSamples() skipFract += nominalSkip; // real skip size ovlSkip = (int)skipFract; // rounded to integer skip skipFract -= ovlSkip; // maintain the fraction part, i.e. real vs. integer skip - inputBuffer.receiveSamples((uint)ovlSkip); + sourceInput += inputBuffer.receiveSamples((uint)ovlSkip); } } diff --git a/lib/soundtouch-master/source/SoundTouch/TDStretch.h b/lib/soundtouch-master/source/SoundTouch/TDStretch.h index 483dd536..b5efe6bd 100644 --- a/lib/soundtouch-master/source/SoundTouch/TDStretch.h +++ b/lib/soundtouch-master/source/SoundTouch/TDStretch.h @@ -41,6 +41,7 @@ #include "STTypes.h" #include "RateTransposer.h" #include "FIFOSamplePipe.h" +#include "SourceSpan.h" namespace soundtouch { @@ -135,6 +136,13 @@ protected: FIFOSampleBuffer outputBuffer; 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); virtual void clearCrossCorrState(); @@ -167,6 +175,10 @@ public: TDStretch(); 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 /// depending on if we've a MMX/SSE/etc-capable CPU available or not. static void *operator new(size_t s);