From e9353e32e0caf417a8d6061541c7edd443d37e14 Mon Sep 17 00:00:00 2001 From: mchinen Date: Sun, 19 May 2013 10:00:20 +0000 Subject: [PATCH] ToneGen: refactor code for linear/log cases since it is substantially more complicated and duplicated after bug 635 fix. --- src/effects/ToneGen.cpp | 121 +++++++++++++++------------------------- 1 file changed, 44 insertions(+), 77 deletions(-) diff --git a/src/effects/ToneGen.cpp b/src/effects/ToneGen.cpp index c0060c349..c02e1742c 100644 --- a/src/effects/ToneGen.cpp +++ b/src/effects/ToneGen.cpp @@ -145,105 +145,72 @@ bool EffectToneGen::MakeTone(float *buffer, sampleCount len) double a,b; int k; + double frequencyQuantum; double BlendedFrequency; double BlendedAmplitude; + double BlendedLogFrequency; // calculate delta, and reposition from where we left double amplitudeQuantum = (amplitude[1]-amplitude[0]) / numSamples; - double frequencyQuantum = (frequency[1]-frequency[0]) / numSamples; BlendedAmplitude = amplitude[0] + amplitudeQuantum * mSample; // precalculations: double pre2PI = 2 * M_PI; double pre4divPI = 4. / M_PI; - /* - 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 + // initial setup should calculate deltas if( mbLogInterpolation ) { + // this for log interpolation logFrequency[0] = log10( frequency[0] ); logFrequency[1] = log10( frequency[1] ); // calculate delta, and reposition from where we left - double logfrequencyQuantum = (logFrequency[1]-logFrequency[0]) / numSamples; - double BlendedLogFrequency = logFrequency[0] + logfrequencyQuantum * mSample; - - for (i = 0; i < len; i++) - { - 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; - } - + frequencyQuantum = (logFrequency[1]-logFrequency[0]) / numSamples; + BlendedLogFrequency = logFrequency[0] + frequencyQuantum * mSample; + BlendedFrequency = pow( 10.0, (double)BlendedLogFrequency ); } else { // this for regular case, linear interpolation + frequencyQuantum = (frequency[1]-frequency[0]) / numSamples; BlendedFrequency = frequency[0] + frequencyQuantum * mSample; - for (i = 0; i < len; i++) - { - 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; + } + + // synth loop + for (i = 0; i < len; i++) { + 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; + if (mbLogInterpolation) { + BlendedLogFrequency += frequencyQuantum; + BlendedFrequency = pow( 10.0, (double)BlendedLogFrequency); + } else { BlendedFrequency += frequencyQuantum; - BlendedAmplitude += amplitudeQuantum; } } + // update external placeholder mSample += len; return true;