I’ve a code that process buffers of samples/audio data. Here’s the code:

`#include `
#include
#include
#include
#define PI 3.141592653589793238
#define TWOPI 6.283185307179586476
const int blockSize = 256;
const double mSampleRate = 44100.0;
const double mHostPitch = 2.0;
const double mRadiansPerSample = TWOPI / mSampleRate;
double mGainNormalizedValues[blockSize];
double mPitchNormalizedValues[blockSize];
double mOffsetNormalizedValues[blockSize];
class Oscillator
{
public:
double mPhase = 0.0;
double minPitch = -48.0;
double maxPitch = 48.0;
double rangePitch = maxPitch - minPitch;
double pitchPd = log(2.0) / 12.0;
double minOffset = -900.0;
double maxOffset = 900.0;
double rangeOffset = maxOffset - minOffset;
Oscillator() { }
void ProcessBuffer(double voiceFrequency, int blockSize, double *left, double *right) {
// precomputed data
double bp0 = voiceFrequency * mHostPitch;
// process block
for (int sampleIndex = 0; sampleIndex < blockSize; sampleIndex++) {
double output = (sin(mPhase)) * mGainNormalizedValues[sampleIndex];
*left++ += output;
*right++ += output;
// next phase
mPhase += std::clamp(mRadiansPerSample * (bp0 * WarpPitch(mPitchNormalizedValues[sampleIndex])) + WarpOffset(mOffsetNormalizedValues[sampleIndex]), 0.0, PI);
while (mPhase >= TWOPI) { mPhase -= TWOPI; }
}
}
inline double WarpPitch(double normalizedValue) { return exp((minPitch + normalizedValue * rangePitch) * pitchPd); }
inline double WarpOffset(double normalizedValue) { return minOffset + normalizedValue * rangeOffset; }
};
int main(int argc, const char *argv[]) {
int numBuffer = 1024;
int counterBuffer = 0;
Oscillator oscillator;
// I fill the buffer often
while (counterBuffer < numBuffer) {
// init buffer
double bufferLeft[blockSize];
double bufferRight[blockSize];
memset(&bufferLeft, 0, blockSize * sizeof(double));
memset(&bufferRight, 0, blockSize * sizeof(double));
// emulate params values for this buffer
for(int i = 0; i < blockSize; i++) {
mGainNormalizedValues[i] = i / (double)blockSize;
mPitchNormalizedValues[i] = i / (double)blockSize;
mOffsetNormalizedValues[i] = i / (double)blockSize;
}
// process osc buffer
oscillator.ProcessBuffer(130.81278, blockSize, &bufferLeft[0], &bufferRight[0]);
// do somethings with buffer
counterBuffer++;
}
}

Basically:

- init a Oscillator object
- for each buffer, fill some param arrays with values (gain, pitch, offset); gain remain normalized
`[0.0, 1.0]`

, while pitch and offset range in`-48/48`

and`-900/900`

- then I iterate the buffer, calculating the Oscillator's sine due to pitch and offset, and I apply a gain; later, I move the phase, incrementing it

The whole domain of operations are normalized `[0.0, 1.0]`

. But when I need to manage pitch and offset, I need to switch domain and use different values (i.e. the Warp functions).

This required lots of computations and process. I'd like to avoid it, so I can improve the code and performances.

How would you do it? Can I keep into `[0.0, 1.0]`

? Could I improve the performance?