I've implemented an harmonizer, using Stefan Bernsee's code, which works great. I figured out the logic of finding the root note, and the right harmony in the scale.
The only problem is that, my upper voices sound like someone who has taken too much helium !
After some research, I found that, that was because I didn't preserve formants. The problem is I don't know how to do that ! I've heard that I must use a Cepstrum, but that's pretty much it.
Stephan's code, modified by me is :
/* ***************** PROCESSING ******************* */
/* this does the actual pitch shifting */
memset(mSynMagn, 0, mParent.mFftFrameSize * sizeof(float));
memset(mSynFreq, 0, mParent.mFftFrameSize * sizeof(float));
for (k = 0; k <= mParent.mFftFrameSize2; k++)
{
index = k * pitchShift;
if (index <= mParent.mFftFrameSize2)
{
mSynMagn[index] = mParent.mAnaMagn[k];
mSynFreq[index] = mParent.mAnaFreq[k] * pitchShift;
}
}
I think I must mess with the SynMagn array but I don't know how. I think calculating the Cepstrum, is just going through mAnaMag and taking the log ? (which base ?) Then when I have that Cepstrum, what should I do with it ? What should those line become ?
mSynMagn[index] = mParent.mAnaMagn[k];
mSynFreq[index] = mParent.mAnaFreq[k] * pitchShift;