I've isolated it, testing some performance in my DAW:
Code: Select all
// buffer
int remainingSamples = nFrames;
while (remainingSamples > 0) {
int blockSize = remainingSamples;
if (blockSize > PLUG_MAX_PROCESS_BLOCK) {
blockSize = PLUG_MAX_PROCESS_BLOCK;
}
// voices (buffer is 32; 16 simultaneous + 16 free slot for cutoof previous one)
for (int voiceIndex = 0; voiceIndex < PLUG_VOICES_BUFFER_SIZE; voiceIndex++) {
Voice &voice = pVoiceManager->mVoices[voiceIndex];
if (!voice.mIsPlaying) { continue; }
// samples
int remainingVoiceSamples = blockSize;
while (remainingVoiceSamples > 0) {
for (int envelopeIndex = 0; envelopeIndex < mNumEnvelopes; envelopeIndex++) {
Envelope &envelope = *pEnvelope[envelopeIndex];
EnvelopeVoiceData &envelopeVoiceData = envelope.mEnvelopeVoicesData[voiceIndex];
// skip disabled envelopes
if (!envelope.mIsEnabled) { continue; }
// process block
if (envelopeVoiceData.mBlockStep >= gBlockSize) {
// calculate new envelope values for this block. its processed every 100 samples, not so heavy as operation, so it seems I can ignore the core of my code here
}
// update output value
double value = envelopeVoiceData.mBlockStartAmp + (envelopeVoiceData.mBlockStep * envelopeVoiceData.mBlockDeltaAmp);
envelope.mValue[voiceIndex] = ((1 + envelope.mIsBipolar) / 2.0 * value + (1 - envelope.mIsBipolar) / 2.0) * envelope.mAmount;
// next phase
envelopeVoiceData.mBlockStep += envelope.mRate;
envelopeVoiceData.mStep += envelope.mRate;
}
voice.mSampleIndex++;
remainingVoiceSamples--;
}
}
remainingSamples -= blockSize;
}
For what I see, it is not doing very huge and intensive calculations (some sum and division); also, first I iterate voices, than samples buffers for each voice (as learned in these years, its better for cache swapping).
There are some parts I can optimize it out?
Branch predictions could be a problem here?
Or allocate References to envelope and theirs voice data is it so expencive?
Any tips or suggestions?
Thanks masters!!!