21#define stackAllocate(T, count) static_cast<T*>(alloca(count * sizeof(T)))
27 const unsigned char *channelFlags,
const float *volumes,
30 const auto pSrc = &src;
31 for (
unsigned int c = 0; c < numChannels; c++) {
35 for (
int j = 0; j < len; ++j)
36 dest[j] += pSrc[j] * volumes[c];
46 : mDownmixSources(
std::move(downmixSources))
53 , mFloatBuffers { 3, bufferSize, 1, 1 }
54 , mNumChannels(numChannels)
55 , mApplyVolume(applyGain)
83 for (
auto c = 0;c < data.
Channels(); ++c)
88 auto oResult = downmixSource->GetDownstream().Acquire(
mFloatBuffers, maxToProcess);
94 const auto result = *oResult;
95 maxOut = std::max(maxOut, result);
99 const auto limit = std::min<size_t>(downmixSource->NChannels(), maxChannels);
100 for (
size_t j = 0; j < limit; ++j)
108 volumes[c] = downmixSource->GetChannelGain(c);
110 volumes[c] = downmixSource->GetChannelGain(j);
114 downmixSource->CanMakeMono())
116 volumes[0] /=
static_cast<float>(limit);
120 downmixSource->FindChannelFlags(channelFlags,
mNumChannels, j);
124 downmixSource->GetDownstream().Release();
132 assert(maxOut <= maxToProcess);
137 return std::accumulate(
140 return std::max(sum, source->GetDownstream().Remaining());
#define stackAllocate(T, count)
Accumulates (non-interleaved) data during effect processing.
float & GetWritePosition(unsigned iChannel)
Get writable position for one channel.
void Advance(size_t count)
Move the positions.
size_t BufferSize() const
size_t Rotate()
Shift all data at and after the old position to position 0.
unsigned Channels() const
void ClearBuffer(unsigned iChannel, size_t n)
constSamplePtr GetReadPosition(unsigned iChannel) const
Get accumulated data for one channel.
sampleCount Remaining() const override
Result includes any amount Acquired and not yet Released.
AudioGraph::Buffers mFloatBuffers
std::vector< std::unique_ptr< DownmixSource > > mDownmixSources
std::optional< size_t > Acquire(Buffers &data, size_t maxToProcess) override
Occupy vacant space in Buffers with some data.
bool AcceptsBuffers(const Buffers &buffers) const override
DownmixStage(std::vector< std::unique_ptr< DownmixSource > > downmixSources, size_t numChannels, size_t bufferSize, ApplyVolume applyGain)
bool Release() override
Caller is done examining last Acquire()d positions.
bool AcceptsBlockSize(size_t blockSize) const override
Positions or offsets within audio files need a wide type.
void MixBuffers(unsigned numChannels, const unsigned char *channelFlags, const float *volumes, const float &src, AudioGraph::Buffers &dests, int len)