1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-02 17:09:26 +02:00

ToneGen: refactor code for linear/log cases since it is substantially more complicated and duplicated after bug 635 fix.

This commit is contained in:
mchinen 2013-05-19 10:00:20 +00:00
parent 8fd058e8ee
commit e9353e32e0

View File

@ -145,75 +145,37 @@ bool EffectToneGen::MakeTone(float *buffer, sampleCount len)
double a,b; double a,b;
int k; int k;
double frequencyQuantum;
double BlendedFrequency; double BlendedFrequency;
double BlendedAmplitude; double BlendedAmplitude;
double BlendedLogFrequency;
// calculate delta, and reposition from where we left // calculate delta, and reposition from where we left
double amplitudeQuantum = (amplitude[1]-amplitude[0]) / numSamples; double amplitudeQuantum = (amplitude[1]-amplitude[0]) / numSamples;
double frequencyQuantum = (frequency[1]-frequency[0]) / numSamples;
BlendedAmplitude = amplitude[0] + amplitudeQuantum * mSample; BlendedAmplitude = amplitude[0] + amplitudeQuantum * mSample;
// precalculations: // precalculations:
double pre2PI = 2 * M_PI; double pre2PI = 2 * M_PI;
double pre4divPI = 4. / M_PI; double pre4divPI = 4. / M_PI;
/* // initial setup should calculate deltas
Duplicate the code for the two cases, log interpolation and linear interpolation
I hope this is more readable, a bit faster (only one branching in mbLogInterpolation)
Local variables are declared inside respective branch, globals are declared up.
*/
bool bLogInterpolation = mbLogInterpolation;
if( abs( frequency[1]-frequency[0] ) < 0.000000001 )
bLogInterpolation = true;
// this for log interpolation
if( mbLogInterpolation ) if( mbLogInterpolation )
{ {
// this for log interpolation
logFrequency[0] = log10( frequency[0] ); logFrequency[0] = log10( frequency[0] );
logFrequency[1] = log10( frequency[1] ); logFrequency[1] = log10( frequency[1] );
// calculate delta, and reposition from where we left // calculate delta, and reposition from where we left
double logfrequencyQuantum = (logFrequency[1]-logFrequency[0]) / numSamples; frequencyQuantum = (logFrequency[1]-logFrequency[0]) / numSamples;
double BlendedLogFrequency = logFrequency[0] + logfrequencyQuantum * mSample; BlendedLogFrequency = logFrequency[0] + frequencyQuantum * mSample;
for (i = 0; i < len; i++)
{
BlendedFrequency = pow( 10.0, (double)BlendedLogFrequency ); BlendedFrequency = pow( 10.0, (double)BlendedLogFrequency );
switch (waveform) {
case 0: //sine
f = (float) sin(pre2PI * mPositionInCycles/mCurRate);
break;
case 1: //square
f = (modf(mPositionInCycles/mCurRate, &throwaway) < 0.5) ? 1.0f :-1.0f;
break;
case 2: //sawtooth
f = (2 * modf(mPositionInCycles/mCurRate+0.5f, &throwaway)) -1.0f;
break;
case 3: //square, no alias. Good down to 110Hz @ 44100Hz sampling.
//do fundamental (k=1) outside loop
b = (1. + cos((pre2PI * BlendedFrequency)/mCurRate))/pre4divPI; //scaling
f = (float) pre4divPI * sin(pre2PI * mPositionInCycles/mCurRate);
for(k=3; (k<200) && (k * BlendedFrequency < mCurRate/2.); k+=2)
{
//Hanning Window in freq domain
a = 1. + cos((pre2PI * k * BlendedFrequency)/mCurRate);
//calc harmonic, apply window, scale to amplitude of fundamental
f += (float) a * sin(pre2PI * mPositionInCycles/mCurRate * k)/(b*k);
}
}
// insert value in buffer
buffer[i] = BlendedAmplitude * f;
// update freq,amplitude
mPositionInCycles += BlendedFrequency;
BlendedAmplitude += amplitudeQuantum;
BlendedLogFrequency += logfrequencyQuantum;
}
} else { } else {
// this for regular case, linear interpolation // this for regular case, linear interpolation
frequencyQuantum = (frequency[1]-frequency[0]) / numSamples;
BlendedFrequency = frequency[0] + frequencyQuantum * mSample; BlendedFrequency = frequency[0] + frequencyQuantum * mSample;
for (i = 0; i < len; i++) }
{
// synth loop
for (i = 0; i < len; i++) {
switch (waveform) { switch (waveform) {
case 0: //sine case 0: //sine
f = (float) sin(pre2PI * mPositionInCycles/mCurRate); f = (float) sin(pre2PI * mPositionInCycles/mCurRate);
@ -240,10 +202,15 @@ bool EffectToneGen::MakeTone(float *buffer, sampleCount len)
buffer[i] = BlendedAmplitude * f; buffer[i] = BlendedAmplitude * f;
// update freq,amplitude // update freq,amplitude
mPositionInCycles += BlendedFrequency; mPositionInCycles += BlendedFrequency;
BlendedFrequency += frequencyQuantum;
BlendedAmplitude += amplitudeQuantum; BlendedAmplitude += amplitudeQuantum;
if (mbLogInterpolation) {
BlendedLogFrequency += frequencyQuantum;
BlendedFrequency = pow( 10.0, (double)BlendedLogFrequency);
} else {
BlendedFrequency += frequencyQuantum;
} }
} }
// update external placeholder // update external placeholder
mSample += len; mSample += len;
return true; return true;