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 =
mpLeader->GetRate();
75 const double initialWarp =
mRate / mSpeed / sequenceRate;
76 const double tstep = 1.0 / sequenceRate;
80 double endTime =
mpLeader->GetEndTime();
81 double startTime =
mpLeader->GetStartTime();
82 const double tEnd = backwards
83 ? std::max(startTime, mT1)
85 return mpLeader->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);
132 iChannel, nChannels, dst.data(), pos, getLen, backwards,
135 memset(dst[
i], 0,
sizeof(
float) * getLen);
137 mEnvValues.data(), getLen, (pos).as_double() / sequenceRate,
141 for (
decltype(getLen)
i = 0;
i < getLen;
i++)
156 thisProcessLen = queueLen;
159 double factor = initialWarp;
169 t - (
double)thisProcessLen / sequenceRate + tstep, t + tstep);
172 t, t + (
double)thisProcessLen / sequenceRate);
175 std::pair<size_t, size_t> results;
179 const auto pFloat = floatBuffers[
iChannel];
183 results = pResample->Process(factor,
198 const auto input_used = results.first;
199 queueStart += input_used;
200 queueLen -= input_used;
201 out += results.second;
202 t += (input_used / sequenceRate) * (backwards ? -1 : 1);
209 assert(out <= maxOut);
218 float *floatBuffers[])
221 const bool backwards = (mT1 < mT0);
222 const auto sequenceRate =
mpLeader->GetRate();
224 const double sequenceEndTime =
mpLeader->GetEndTime();
225 const double sequenceStartTime =
mpLeader->GetStartTime();
227 ? std::max(sequenceStartTime, mT1)
236 const double t = (pos).as_double() / sequenceRate;
239 if ((backwards ? t <= tEnd : t >= tEnd))
247 sampleCount{ (backwards ? t - tEnd : tEnd - t) * sequenceRate + 0.5 }
252 iChannel, nChannels, floatBuffers, pos, slen, backwards,
256 memset(floatBuffers[
iChannel], 0,
sizeof(
float) * slen);
261 const auto pFloat = floatBuffers[
iChannel];
262 for (
size_t i = 0;
i < slen;
i++)
271 assert(slen <= maxOut);
277 size_t produced,
size_t max,
float &floatBuffer)
279 assert(produced <= max);
280 const auto pFloat = &floatBuffer;
281 std::fill(pFloat + produced, pFloat + max, 0);
285 const std::shared_ptr<const WideSampleSequence> &leader,
size_t bufferSize,
287 bool mayThrow, std::shared_ptr<TimesAndSpeed> pTimesAndSpeed,
289) : mpLeader{ leader }
290 , mnChannels{ mpLeader->NChannels() }
292 , mEnvelope{ options.envelope }
293 , mMayThrow{ mayThrow }
294 , mTimesAndSpeed{ move(pTimesAndSpeed) }
295 , mSampleQueue{
initVector<float>(mnChannels, sQueueMaxLen) }
298 , mResampleParameters{ highQuality, mpLeader->
GetRate(), rate, options }
299 , mResample( mnChannels )
300 , mEnvValues(
std::max(sQueueMaxLen, bufferSize) )
331#define stackAllocate(T, count) static_cast<T*>(alloca(count * sizeof(T)))
341 const bool backwards = (mT1 < mT0);
344 const auto limit = std::min<size_t>(
mnChannels, maxChannels);
348 for (
size_t j = 0; j < limit; ++j)
354 maxTrack = std::max(maxTrack, result);
359 mTime = std::max(mTime, newT);
360 for (
size_t j = 0; j < limit; ++j) {
364 for (
size_t j = 0; j < limit; ++j) {
366 const auto result = mixed[j];
367 ZeroFill(result, maxTrack, *pFloat);
371 assert(maxTrack <= bound);
375 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.
sampleCount Remaining() const override
Result includes any amount Acquired and not yet Released.
const std::shared_ptr< const WideSampleSequence > mpLeader
size_t MixSameRate(unsigned nChannels, size_t maxOut, float *floatBuffers[])
static constexpr size_t sQueueMaxLen
bool AcceptsBlockSize(size_t blockSize) const override
MixerSource(const std::shared_ptr< const WideSampleSequence > &leader, size_t bufferSize, double rate, const MixerOptions::Warp &options, bool highQuality, bool mayThrow, std::shared_ptr< TimesAndSpeed > pTimesAndSpeed, const ArrayOf< bool > *pMap)
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
const ArrayOf< bool > *const mpMap
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)
const bool * MixerSpec(unsigned iChannel) const
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.