18 #define DIFFERENTIATOR 2
24 : mTapData(NULL), mNumTaps(numTaps), mNumBands(numBands), mFrequencies(NULL), mResponses(NULL), mWeights(NULL) {
29 if (freqs != NULL && resps != NULL && weights != NULL)
45 if (frequencies != NULL)
52 if (responses != NULL)
71 logMsg(
"Use convolution for long FIRs.");
76 void remez(
double h[],
int numtaps,
int numband,
double bands[],
double des[],
double weight[],
int type);
79 bool shouldNormalize =
false;
83 shouldNormalize =
true;
101 if (tapDelays == NULL) {
102 for (
unsigned i = 0; i < numTaps; i++)
138 if (tapDelays != NULL)
148 configData = fopen(fileName,
"r");
149 fscanf(configData,
"%d\n", &numTaps);
151 float * theTapData =
new float[numTaps];
152 for (i = 0; i < numTaps; i++)
153 fscanf(configData,
"%f\n", &theTapData[i]);
159 for (i = 0; i < numTaps; i++)
160 logMsg(
"\t%g\n ", theTapData[i]);
168 logMsg(
"Taps (%d): ", nt);
169 for (
unsigned i = 0; i < nt; i++)
177 sample * outPtr = outputBuffer.buffer(outBufNum);
178 unsigned numFrames = outputBuffer.mNumFrames;
179 unsigned numTaps = mFilterSpec->mNumTaps;
180 double *tapDataPtr = mFilterSpec->mTapData;
185 sample *inputPtr = mInputPtr;
187 for (
unsigned i = 0; i < numFrames; i++) {
189 mDLine[mOffset] = inputPtr[i];
191 for (
unsigned j = 0; j < numTaps; j++) {
192 sum += mDLine[tap] * tapDataPtr[j];
194 if (tap < 0) tap = numTaps - 1;
229 #define Pi 3.1415926535897932
230 #define Pi2 6.2831853071795865
231 #define GRIDDENSITY 16
232 #define MAXITERATIONS 40
261 double des[],
double weight[],
int *gridsize,
262 double Grid[],
double D[],
double W[],
266 double delf, lowf, highf;
275 if ((symmetry ==
NEGATIVE) && (delf > bands[0]))
279 for (band=0; band < numband; band++)
281 Grid[j] = bands[2*band];
282 lowf = bands[2*band];
283 highf = bands[2*band + 1];
284 k = (int)((highf - lowf)/delf + 0.5);
301 (Grid[*gridsize-1] > (0.5 - delf)) &&
304 Grid[*gridsize-1] = 0.5-delf;
330 Ext[i] = i * (gridsize-1) / r;
354 void CalcParms(
int r,
int Ext[],
double Grid[],
double D[],
double W[],
355 double ad[],
double x[],
double y[])
358 double sign, xi, delta, denom, numer;
364 x[i] = cos(
Pi2 * Grid[Ext[i]]);
376 for (k=j; k<=r; k+=ld)
378 denom *= 2.0*(xi - x[k]);
380 if (fabs(denom)<0.00001)
392 numer += ad[i] * D[Ext[i]];
393 denom += sign * ad[i]/W[Ext[i]];
404 y[i] = D[Ext[i]] - sign * delta/W[Ext[i]];
431 double ComputeA(
double freq,
int r,
double ad[],
double x[],
double y[])
434 double xc, c, denom, numer;
437 xc = cos(
Pi2 * freq);
441 if (fabs(c) < 1.0e-7)
479 void CalcError(
int r,
double ad[],
double x[],
double y[],
480 int gridsize,
double Grid[],
481 double D[],
double W[],
double E[])
486 for (i=0; i<gridsize; i++)
489 E[i] = W[i] * (D[i] - A);
519 int gridsize,
double E[])
521 int i, j, k, l, extra;
528 foundExt = (
int *)malloc((2*r) *
sizeof(int));
534 if (((E[0]>0.0) && (E[0]>E[1])) ||
535 ((E[0]<0.0) && (E[0]<E[1])))
541 for (i=1; i<gridsize-1; i++)
543 if (((E[i]>=E[i-1]) && (E[i]>E[i+1]) && (E[i]>0.0)) ||
544 ((E[i]<=E[i-1]) && (E[i]<E[i+1]) && (E[i]<0.0)))
552 if (((E[j]>0.0) && (E[j]>E[j-1])) ||
553 ((E[j]<0.0) && (E[j]<E[j-1])))
564 if (E[foundExt[0]] > 0.0)
573 if (fabs(E[foundExt[j]]) < fabs(E[foundExt[l]]))
575 if ((up) && (E[foundExt[j]] < 0.0))
577 else if (( ! up) && (E[foundExt[j]] > 0.0))
590 if ((alt) && (extra == 1))
592 if (fabs(E[foundExt[k-1]]) < fabs(E[foundExt[0]]))
600 foundExt[j] = foundExt[j+1];
608 Ext[i] = foundExt[i];
647 val += 2.0 * A[k] * cos(x*k);
657 for (k=1; k<=(N/2-1); k++)
658 val += 2.0 * A[k] * cos(x*k);
672 val += 2.0 * A[k] * sin(x*k);
680 val = A[N/2] * sin(
Pi * (n - M));
682 for (k=1; k<=(N/2-1); k++)
683 val += 2.0 * A[k] * sin(x*k);
708 short isDone(
int r,
int Ext[],
double E[])
713 min = max = fabs(E[Ext[0]]);
717 current = fabs(E[off]);
723 if (((max-min)/max) < 0.0001)
751 int numband,
double bands[],
double des[],
double weight[],
754 double *Grid, *W, *D, *E;
755 int i, iter, gridsize, r, *Ext;
766 if ((numtaps%2) && (symmetry ==
POSITIVE))
774 for (i=0; i<numband; i++)
776 gridsize += (int)(2*r*
GRIDDENSITY*(bands[2*i+1] - bands[2*i]) + .5);
786 Grid = (
double *)malloc(gridsize *
sizeof(
double));
787 D = (
double *)malloc(gridsize *
sizeof(
double));
788 W = (
double *)malloc(gridsize *
sizeof(
double));
789 E = (
double *)malloc(gridsize *
sizeof(
double));
790 Ext = (
int *)malloc((r+1) *
sizeof(int));
791 taps = (
double *)malloc((r+1) *
sizeof(double));
792 x = (
double *)malloc((r+1) *
sizeof(double));
793 y = (
double *)malloc((r+1) *
sizeof(double));
794 ad = (
double *)malloc((r+1) *
sizeof(double));
800 &gridsize, Grid, D, W, symmetry);
808 for (i=0; i<gridsize; i++)
822 if (numtaps % 2 == 0)
824 for (i=0; i<gridsize; i++)
826 c = cos(
Pi * Grid[i]);
836 for (i=0; i<gridsize; i++)
838 c = sin(
Pi2 * Grid[i]);
845 for (i=0; i<gridsize; i++)
847 c = sin(
Pi * Grid[i]);
860 CalcError(r, ad, x, y, gridsize, Grid, D, W, E);
861 Search(r, Ext, gridsize, E);
865 if (iter == MAXITERATIONS)
867 printf(
"Reached maximum iteration count.\nResults may be bad.\n");
877 for (i=0; i<=numtaps/2; i++)
884 c = cos(
Pi * (
double)i/numtaps);
889 c = sin(
Pi2 * (
double)i/numtaps);
891 c = sin(
Pi * (
double)i/numtaps);
893 taps[i] =
ComputeA((
double)i/numtaps, r, ad, x, y)*c;
void setNumTaps(unsigned numTaps)
void logMsg(const char *format,...)
These are the public logging messages.
void pullInput(Buffer &outputBuffer)
void resetDLine()
zero-out mDline and reallocate memory if necessary;
AdditiveInstrument.h – Sum-of-sines synthesis instrument class.
Effect – mix-in for classes that have unit generators as inputs (like filters).
sample * mDLine
mNumTaps length delay line
void FreqSample(int N, double A[], double h[], int symm)
void remez(double h[], int numtaps, int numband, double bands[], double des[], double weight[], int type)
void nextBuffer(Buffer &outputBuffer, unsigned outBufNum)
The work method...
void setFrequencies(double *frequencies)
Accessors.
void CreateDenseGrid(int r, int numtaps, int numband, double bands[], double des[], double weight[], int *gridsize, double Grid[], double D[], double W[], int symmetry)
static float frameRateF()
default frame rate as a float
short isDone(int r, int Ext[], double E[])
unsigned mNumTaps
number of taps desired
double * mTapData
the FIR tap weights (created by the planFilter method)
float sample
(could be changed to int, or double)
void Search(int r, int Ext[], int gridsize, double E[])
void InitialGuess(int r, int Ext[], int gridsize)
void planFilter()
method to plan the filter (execute the search/iterate algorithm)
void CalcError(int r, double ad[], double x[], double y[], int gridsize, double Grid[], double D[], double W[], double E[])
FilterSpecification(unsigned numTaps=0, unsigned numBands=0, double *freqs=NULL, double *resps=NULL, double *weights=NULL)
Constructors.
double * mWeights
band error weights (mNumBands)
unsigned mOffset
offset "pointer" for loop counting Here are the sample buffers (dynamically allocated) ...
double ComputeA(double freq, int r, double ad[], double x[], double y[])
void CalcParms(int r, int Ext[], double Grid[], double D[], double W[], double ad[], double x[], double y[])
unsigned mNumBands
length of specification
Buffer – the multi-channel sample buffer class (passed around between generators and IO guys)...
double * mResponses
band responses (mNumBands)
void logMsgNN(const char *format,...)
no-newline versions
FIR(UnitGenerator &in, unsigned numTaps=2, float *tapDelay=NULL)
Various constructors Takes a UGen, and optionally the number of taps and the tap IR array...
void setResponses(double *responses)
void setWeights(double *weights)
double * mFrequencies
band edge frequencies (2 * mNumBands)
void readTaps(char *fileName)
void setTaps(unsigned numTaps, float *tapDelays)
Base class of CSL exceptions (written upper-case). Has a string message.
FilterSpecification * mFilterSpec