I'm working on a project in which I'm additively re-synthesizing a pipe Organ in C. I took samples of the original, approximated them into lists of frequency and amplitude (the necessary variables to recreate any harmonic spectra)
I have a functioning model running in the command line, but the current Issue I'm running up against is that I am adding sine functions together in real time, creating a very computationally expensive synthesis engine (I have to run at 2048 sample buffer with only 4 voices to avoid timeout errors.
each stop variable looks like the one below, for 12 stops in total, coming out to somewhere just over 100 sine functions, all processing in real time.
clarFour = (0.5 *
(sin(voice * M_PI * 2.0f * 1.0f * 4.0f ) * 0.0901f)+
(sin(voice * M_PI * 2.0f * 2.0f * 4.0f ) * 0.108f)+
(sin(voice * M_PI * 2.0f * 3.0f * 4.0f ) * 0.0609f)+
(sin(voice * M_PI * 2.0f * 4.0f * 4.0f ) * 0.0319f)+
(sin(voice * M_PI * 2.0f * 5.0f * 4.0f ) * 0.0184f)+
(sin(voice * M_PI * 2.0f * 6.0f * 4.0f ) * 0.0393f)+
(sin(voice * M_PI * 2.0f * 7.0f * 4.0f ) * 0.0350f)+
(sin(voice * M_PI * 2.0f * 8.0f * 4.0f ) * 0.0555f)+
(sin(voice * M_PI * 2.0f * 9.0f * 4.0f ) * 0.0331f)+
(sin(voice * M_PI * 2.0f * 10.0f * 4.0f ) * 0.0412f)+
(sin(voice * M_PI * 2.0f * 11.0f * 4.0f ) * 0.0263f)+
(sin(voice * M_PI * 2.0f * 12.0f * 4.0f ) * 0.0151f)+
(sin(voice * M_PI * 2.0f * 13.0f * 4.0f ) * 0.0123f)+
(sin(voice * M_PI * 2.0f * 15.0f * 4.0f ) * 0.00237f)+
(sin(voice * M_PI * 2.0f * 16.0f * 4.0f ) * 0.00139f));
and then adding each stop variable in a theta variable that in turn does the actual synthesis sample-by-sample.
theta = bourEight +
bourFour +
clarFour +
fifTwo +
melEight +
mixOne +
octFour +
prinEight +
truEight +
truSixt +
tweTwo +
vioEight;
sine = theta;
for(int c = 0; c < kNumChannels; c++){
buffer[n + c] += pow(sineWave->amplitude[q], 0.25) * sine;
}
sineWave->phase[q] += sineWave->frequency[q];
if(sineWave->phase[q] >= 1.0f){
sineWave->phase[q] -= 1.0f;
}
is there a good way to package this up into something that doesn't eat CPU like cheerios? each stop is a set waveform anyways, so is there a better way computationally to approximate an arbitrary waveform without adding so many sine functions together?
ideally I'd like to do this without completely having to rebuild my synthesis engine, but I recognize that may be having my cake and eating it too.
the full project can be viewed at https://github.com/Natameme/NatalieHogue_EP_353_Classwork/blob/main/Final/Source/StMaximilliansOrganMK1.c
it only requires the external libraries for PortAudio and PortMidi to run