23template<
typename T,
typename F> std::vector<T>
26 std::vector<T> result( dim1 );
27 for (
auto &row : result)
32template<
typename T> std::vector<std::vector<T>>
35 return initVector<std::vector<T>>(dim1,
36 [dim2](
auto &row){ row.resize(dim2); });
43 mResample[j] = std::make_unique<Resample>(
69 unsigned nChannels,
const size_t maxOut,
float *floatBuffers[])
72 const bool backwards = (mT1 < mT0);
74 const double sequenceRate =
mpSeq->GetRate();
75 const double initialWarp =
mRate / mSpeed / sequenceRate;
76 const double tstep = 1.0 / sequenceRate;
79 const auto endPos = [
mpSeq =
mpSeq, mT1 = mT1, backwards]{
80 double endTime =
mpSeq->GetEndTime();
81 double startTime =
mpSeq->GetStartTime();
82 const double tEnd = backwards
83 ? std::max(startTime, mT1)
85 return mpSeq->TimeToLongSamples(tEnd);
106 double t = ((pos).as_long_long() +
107 (backwards ? queueLen : - queueLen)) / sequenceRate;
109 while (out < maxOut) {
114 memmove(queue, &queue[queueStart], (queueLen) * sampleSize);
122 backwards ? pos - endPos : endPos - pos
127 std::vector<float*> dst;
129 dst.push_back(queue.data() + queueLen);
131 if (!
mpSeq->GetFloats(
132 iChannel, nChannels, dst.data(), pos, getLen, backwards,
138 mpSeq->GetEnvelopeValues(
139 mEnvValues.data(), getLen, (pos).as_double() / sequenceRate,
143 for (
decltype(getLen)
i = 0;
i < getLen;
i++)
158 thisProcessLen = queueLen;
161 double factor = initialWarp;
171 t - (
double)thisProcessLen / sequenceRate + tstep, t + tstep);
174 t, t + (
double)thisProcessLen / sequenceRate);
177 std::pair<size_t, size_t> results;
181 const auto pFloat = floatBuffers[
iChannel];
185 results = pResample->Process(factor,
200 const auto input_used = results.first;
201 queueStart += input_used;
202 queueLen -= input_used;
203 out += results.second;
204 t += (input_used / sequenceRate) * (backwards ? -1 : 1);
211 assert(out <= maxOut);
220 float *floatBuffers[])
223 const bool backwards = (mT1 < mT0);
224 const auto sequenceRate =
mpSeq->GetRate();
225 const double tEnd = [
mpSeq =
mpSeq, mT1 = mT1, backwards]{
226 const double sequenceEndTime =
mpSeq->GetEndTime();
227 const double sequenceStartTime =
mpSeq->GetStartTime();
229 ? std::max(sequenceStartTime, mT1)
238 const double t = (pos).as_double() / sequenceRate;
241 if ((backwards ? t <= tEnd : t >= tEnd))
249 sampleCount{ (backwards ? t - tEnd : tEnd - t) * sequenceRate + 0.5 }
253 if (!
mpSeq->GetFloats(
254 iChannel, nChannels, floatBuffers, pos, slen, backwards,
266 const auto pFloat = floatBuffers[
iChannel];
267 for (
size_t i = 0;
i < slen;
i++)
276 assert(slen <= maxOut);
282 size_t produced,
size_t max,
float &floatBuffer)
284 assert(produced <= max);
285 const auto pFloat = &floatBuffer;
286 std::fill(pFloat + produced, pFloat + max, 0);
290 const std::shared_ptr<const WideSampleSequence> &seq,
size_t bufferSize,
292 bool mayThrow, std::shared_ptr<TimesAndSpeed> pTimesAndSpeed
294 , mnChannels{ mpSeq->NChannels() }
296 , mEnvelope{ options.envelope }
297 , mMayThrow{ mayThrow }
298 , mTimesAndSpeed{ move(pTimesAndSpeed) }
299 , mSampleQueue{
initVector<float>(mnChannels, sQueueMaxLen) }
302 , mResampleParameters{ highQuality, mpSeq->
GetRate(), rate, options }
303 , mResample( mnChannels )
304 , mEnvValues(
std::max(sQueueMaxLen, bufferSize) )
329#define stackAllocate(T, count) static_cast<T*>(alloca(count * sizeof(T)))
339 const bool backwards = (mT1 < mT0);
342 const auto limit = std::min<size_t>(
mnChannels, maxChannels);
346 for (
size_t j = 0; j < limit; ++j)
352 maxTrack = std::max(maxTrack, result);
357 mTime = std::max(mTime, newT);
358 for (
size_t j = 0; j < limit; ++j) {
362 for (
size_t j = 0; j < limit; ++j) {
364 const auto result = mixed[j];
365 ZeroFill(result, maxTrack, *pFloat);
369 assert(maxTrack <= bound);
373 assert(bound == 0 ||
Remaining() == 0 || maxTrack > 0);
#define stackAllocate(T, count)
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Accumulates (non-interleaved) data during effect processing.
float & GetWritePosition(unsigned iChannel)
Get writable position for one channel.
size_t BufferSize() const
unsigned Channels() const
Piecewise linear or piecewise exponential function from double to double.
double AverageOfInverse(double t0, double t1) const
std::vector< double > mEnvValues
Gain envelopes are applied to input before other transformations.
int mQueueStart
Position of the start of the next block to resample.
int mQueueLen
The number of available samples after the queue start.
const ResampleParameters mResampleParameters
const BoundedEnvelope *const mEnvelope
Resampling, as needed, after gain envelope.
const std::shared_ptr< TimesAndSpeed > mTimesAndSpeed
std::vector< std::vector< float > > mSampleQueue
First intermediate buffer when resampling is needed.
MixerSource(const std::shared_ptr< const WideSampleSequence > &seq, size_t bufferSize, double rate, const MixerOptions::Warp &options, bool highQuality, bool mayThrow, std::shared_ptr< TimesAndSpeed > pTimesAndSpeed)
const std::shared_ptr< const WideSampleSequence > mpSeq
sampleCount Remaining() const override
Result includes any amount Acquired and not yet Released.
size_t MixSameRate(unsigned nChannels, size_t maxOut, float *floatBuffers[])
static constexpr size_t sQueueMaxLen
bool AcceptsBlockSize(size_t blockSize) const override
bool AcceptsBuffers(const Buffers &buffers) const override
size_t MixVariableRates(unsigned nChannels, size_t maxOut, float *floatBuffers[])
static constexpr size_t sProcessLen
bool Terminates() const override
bool Release() override
Caller is done examining last Acquire()d positions.
std::vector< std::unique_ptr< Resample > > mResample
void Reposition(double time, bool skipping)
unsigned mMaxChannels
Remember how many channels were passed to Acquire()
void ZeroFill(size_t produced, size_t max, float &floatBuffer)
std::optional< size_t > Acquire(Buffers &data, size_t bound) override
Occupy vacant space in Buffers with some data.
sampleCount mSamplePos
Fetch position for source.
const WideSampleSequence & GetSequence() const
sampleCount TimeToLongSamples(double t0) const
virtual double GetRate() const =0
Positions or offsets within audio files need a wide type.
std::vector< std::vector< T > > initVector(size_t dim1, size_t dim2)
double ComputeWarpFactor(const Envelope &env, double t0, double t1)
Compute the integral warp factor between two non-warped time points.
double GetRate(const Track &track)
Immutable structure is an argument to Mixer's constructor.