logo
Main Page | Namespaces | Classes | Compounds | Files | Compound Members | Related

sndutils.cpp

00001 //
00002 //  SYNTOPIA. See http://Syntopia.sourceforge.net for details and documentation.        
00003 //
00004 //      Author of this file: Mikael Hvidtfeldt Christensen (mikaelc@users.sourceforge.net)
00005 //
00006 
00007 #include <iostream>
00008 #include "sndutils.h"
00009 #include <math.h>
00010 #include <complex>
00011 #include "Utils.h"
00012 #include "fft.h"
00013 
00014 namespace SynthCore {
00015 
00016 #define IS_DENORMAL(f) (((*(unsigned int *)&(f))&0x7f800000) == 0)
00017 
00018 DelayLine::DelayLine(int Length) {      
00019         bufferLength = Length;
00020 
00021         bufferStart = new float[bufferLength];
00022         bufferEnd = bufferStart + bufferLength;
00023         for(int i=0; i<bufferLength; i++) { bufferStart[i] = 0.0f; }
00024         readPtr = bufferStart;
00025 }
00026 
00027 DelayLine::~DelayLine() {
00028         delete[] bufferStart;
00029 }
00030 
00031 float DelayLine::read(float input) {
00032 
00033         // catch denormal numbers.
00034         if (IS_DENORMAL(input)) {input = 0;}
00035 
00036         output1 = *readPtr;  
00037         *readPtr = input;
00038         
00039         if (((*readPtr) < 0.0001) && ((*readPtr) > -0.0001)) {*readPtr = 0.0f;}
00040         
00041         if(++readPtr >= bufferEnd) readPtr = bufferStart;
00042         
00043         return output1;         
00044 }
00045 
00046 float DelayLine::readNBack(int N) {
00047         
00048         temp = readPtr;  
00049         temp -= N; // step back N steps;
00050                                 
00051         if(temp < bufferStart) temp += bufferLength;
00052         
00053         return *temp;   
00054 }
00055 
00056 
00057 float DelayLine::readNForward(int N) {
00058         
00059         temp = readPtr;  
00060         temp += N; // step forward N steps;
00061                                 
00062         if(temp >= bufferEnd) temp -= bufferLength;
00063         
00064         return *temp;   
00065 }
00066 
00067 
00068 // The BiFilter class coefficient formulas are based on the following reference:
00069 //
00070 // -------------------------------------------------------------------------------------------------------------
00071 //           Cookbook formulae for audio EQ biquad filter coefficients
00072 //            by Robert Bristow-Johnson  <robert@wavemechanics.com>
00073 // -------------------------------------------------------------------------------------------------------------
00074 // http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
00075 //
00076 // 
00077 
00078 BiFilter::BiFilter() {
00079         // init vars
00080         a1 = 0.0f; a2 = 0.0f; a0 = 1.0f;
00081         b1 = 0.0f; b2 = 0.0f; b0 = 0.0f;
00082         x1 = 0.0f; x2 = 0.0f; x0 = 0.0f;
00083         y1 = 0.0f; y2 = 0.0f; y0 = 0.0f;
00084         lowpassFreqAndQ(1222.0f, 0.15f);
00085 }
00086 
00087  
00088 
00089 
00090 float BiFilter::read(float input) { 
00091         x2 = x1; x1 = x0; 
00092         
00093 
00094         y2 = y1; y1 = y0;       
00095         
00096     x0 = input;
00097         y0 = (b0)*x0 + (b1)*x1 + (b2)*x2 - (a1)*y1 - (a2)*y2;  
00098         if (IS_DENORMAL(y0)) {y0=0.0f;}  
00099         return y0;      
00100 }
00101 
00102 void BiFilter::getPolesAndZeroes(float &p1r,float &p1i,float &p2r,float &p2i,float &z1r,float &z1i,float &z2r,float &z2i)
00103 {
00104         // 2. degrees pol. -b+-sqrt(D) / 2a
00105         // D=b*b-4a*c
00106 
00107         float a,b,c,D;
00108         
00109         // First find roots of pole polynomium.
00110         //
00111         
00112         a = 1.0f; // we have normalized, so that a0 is 1.0
00113         b = a1;
00114         c = a2;
00115 
00116         D=b*b-4*a*c;
00117         if (D < 0) {
00118                 p1r=-b/(2*a);
00119                 p1i=sqrt(-D)/(2*a);
00120                 p2r=p1r;
00121                 p2i=-p1i;
00122         } else {
00123                 p1r=(-b+sqrt(D))/(2*a);
00124                 p2r=(-b-sqrt(D))/(2*a);
00125                 p1i=0;
00126                 p2i=0;
00127         }
00128 
00129         a = b0; // we have normalized, so that a0 is 1.0
00130         b = b1;
00131         c = b2;
00132 
00133         if (a==0) { a= 1.0f; }
00134 
00135         // find roots of zeroes polynomium
00136 
00137         D=b*b-4*a*c;
00138         if (D < 0) {
00139                 z1r=-b/(2*a);
00140                 z1i=sqrt(-D)/(2*a);
00141                 z2r=z1r;
00142                 z2i=-z1i;
00143         } else {
00144                 z1r=(-b+sqrt(D))/(2*a);
00145                 z2r=(-b-sqrt(D))/(2*a);
00146                 z1i=0;
00147                 z2i=0;
00148         }
00149 
00150 }
00151 
00152 float BiFilter::getFreqResponse(float wT) {
00153         // should be changed to FFT method.
00154         std::complex<float> temp;
00155         std::complex<float> temp2;
00156 
00157         
00158         temp = b0 * std::complex<float>(1.0,0);
00159         temp += b1 * std::complex<float>(cos(-wT),sin(-wT));
00160         temp += b2 * std::complex<float>(cos(-2*wT),sin(-2*wT));
00161         
00162         temp2 = std::complex<float>(1.0,0)+(a1) * std::complex<float>(cos(-wT),sin(-wT));
00163         temp2 += a2 * std::complex<float>(cos(-2*wT),sin(-2*wT));
00164         
00165         temp2 = temp/temp2;
00166 
00167         return std::abs(temp2);
00168 }
00169 
00170 float BiFilter::getPhaseResponse(float wT) {
00171         // should be changed to FFT method.
00172         std::complex<float> temp;
00173         std::complex<float> temp2;
00174 
00175         
00176         temp = b0 * std::complex<float>(1.0,0);
00177         temp += b1 * std::complex<float>(cos(-wT),sin(-wT));
00178         temp += b2 * std::complex<float>(cos(-2*wT),sin(-2*wT));
00179         
00180         temp2 = std::complex<float>(1.0,0)+(a1) * std::complex<float>(cos(-wT),sin(-wT));
00181         temp2 += a2 * std::complex<float>(cos(-2*wT),sin(-2*wT));
00182         
00183         temp2 = temp/temp2;
00184 
00185         return std::arg(temp2);
00186 }
00187 
00188 float BiFilter::getFreqResponse2(float wT) {
00189         // should be changed to FFT method.
00190         float c=0.0f;
00191         float temp;
00192         float max;
00193         for (int t = 0; t<120; t++) 
00194         {
00195                 c++;
00196                 read(cos(wT*c));
00197         }
00198         temp = 0; max = 0;
00199         for (int y = 0; y<2020; y++) 
00200         {
00201                 c++;
00202                 temp =  read(cos(wT*c));
00203                 if (temp>max) {max=temp;}
00204                 if (-temp>max) {max=-temp;}
00205         }
00206         return max;
00207 }
00208 
00209 Sample * BiFilter::getFreqResponseSample(int resolution)
00210 {
00211         Sample * mySample = new Sample(resolution);
00212         float f;
00213         for (int i = 0; i< resolution; i++)
00214         {
00215                 f = (getFreqResponse(3.1415927*(float)i/(float) resolution));
00216                 if (f<0.0f) {f = 0.0000001f;}
00217                 mySample->samples[i] = 20.0f*log(f);
00218         }
00219         return mySample;
00220 }
00221 
00222 Sample * BiFilter::getPhaseResponseSample(int resolution)
00223 {
00224         Sample * mySample = new Sample(resolution);
00225         for (int i = 0; i< resolution; i++)
00226         {
00227                 mySample->samples[i] = (getPhaseResponse(3.1415927*(float)i/(float) resolution));
00228         }
00229         return mySample;
00230 }
00231 
00232 
00233 void BiFilter::lowpassFreqAndQ(float freq, float Q)
00234 {
00235         /*
00236         // -------------------------------------------------------------------------------------
00237     A     = sqrt[ 10^(dBgain/20) ]
00238           = 10^(dBgain/40)                    (for peaking and shelving EQ filters only)
00239 
00240     omega = 2*pi*frequency/sampleRate
00241 
00242     sin   = sin(omega)
00243     cos   = cos(omega)
00244 
00245 
00246     alpha = sin/(2*Q)                                      (if Q is specified)
00247           = sin*sinh[ ln(2)/2 * bandwidth * omega/sin ]    (if bandwidth is specified)
00248 
00249         The relationship between bandwidth and Q is
00250                 1/Q = 2*sinh[ln(2)/2*bandwidth*omega/sin]  (digital filter using BLT)
00251         or      1/Q = 2*sinh[ln(2)/2*bandwidth])           (analog filter prototype)
00252 
00253 
00254     beta  = sqrt(A)/Q                                      (for shelving EQ filters only)
00255           = sqrt(A)*sqrt[ (A + 1/A)*(1/S - 1) + 2 ]        (if shelf slope is specified)
00256           = sqrt[ (A^2 + 1)/S - (A-1)^2 ]
00257 
00258         The relationship between shelf slope and Q is
00259                 1/Q = sqrt[(A + 1/A)*(1/S - 1) + 2]
00260    // -----------------------------------------------------------------------------------
00261    */
00262 
00263         
00264         omega = (float) 2.0f*3.1415f*freq/48000.0f;
00265         cs = (float) cos(omega);
00266     alpha = (float) (sin(omega)/(2*(Q*5.0f)));
00267         
00268         a0 =  (1.0f + alpha);
00269     
00270         b0 =  (1.0f - cs)/(2.0f*a0);
00271     b1 =  (1.0f - cs)/a0;
00272         b2= b0;
00273     
00274         a1 =  (-2.0f*cs)/a0;
00275     a2 =  (1.0f - alpha)/a0;
00276 }
00277 
00278 
00279 void BiFilter::bypassFreqAndQ(float freq, float Q)
00280 {
00281         // Bypass filter.
00282         b0 =  1.0f;    
00283         a0 =  b1 =  b2 =  a1 =  a2 =  0.0f;
00284 }
00285 
00286         
00287 void BiFilter::allpassFreqAndQ(float freq, float Q)
00288 {
00289         /*
00290         APF:    H(s) = (s^2 - s/Q + 1) / (s^2 + s/Q + 1)
00291 
00292             b0 =   1 - alpha
00293             b1 =  -2*cos
00294             b2 =   1 + alpha
00295             a0 =   1 + alpha
00296             a1 =  -2*cos
00297             a2 =   1 - alpha
00298         */
00299         
00300         omega = (float) 2.0f*3.1415f*freq/48000.0f;
00301         cs = (float) cos(omega);
00302     alpha = (float) (sin(omega)/(2*(Q*5.0f)));
00303         
00304         a0 =  (1.0f + alpha);
00305         a0INV = 1.0f/a0;
00306     
00307         b0 =  (1.0f - alpha)*a0INV;
00308     b1 =  (- 2.0f*cs)*a0INV;
00309         b2=   1;
00310         a1 =  b1;
00311     a2 =  b0;
00312 }
00313  
00314 void BiFilter::clone(BiFilter * from)
00315 {
00316         a0 = from->a0;
00317         a1 = from->a1;
00318         a2 = from->a2;
00319         b0 = from->b0;
00320         b1 = from->b1;
00321         b2 = from->b2;
00322 }
00323 
00324 
00325 
00326 void BiFilter::highpassFreqAndQ(float freq, float Q)
00327 {
00328         /*
00329         HPF:        H(s) = s^2 / (s^2 + s/Q + 1)
00330 
00331             b0 =  (1 + cos)/2
00332             b1 = -(1 + cos)
00333             b2 =  (1 + cos)/2
00334             a0 =   1 + alpha
00335             a1 =  -2*cos
00336             a2 =   1 - alpha
00337         */
00338 
00339         
00340         omega = (float) 2.0f*3.1415f*freq/48000.0f;
00341         cs = (float) cos(omega);
00342     alpha = (float) (sin(omega)/(2*(Q*5.0f)));
00343         
00344         a0 =  (1.0f + alpha);
00345         a0INV = 1.0f/a0;
00346     
00347         b0 =  (1.0f + cs)*a0INV*0.5f;
00348     b1 =  -b0*2.0f;
00349         b2=   b0;
00350         a1 =  (-2.0f*cs)*a0INV;
00351     a2 =  (1.0f-alpha)*a0INV;
00352 }
00353 
00354 void BiFilter::bandpass1FreqAndQ(float freq, float Q)
00355 { /*
00356 BPF:        H(s) = s / (s^2 + s/Q + 1)          (constant skirt gain, peak gain = Q)
00357 
00358             b0 =   sin/2  =   Q*alpha
00359             b1 =   0
00360             b2 =  -sin/2  =  -Q*alpha
00361             a0 =   1 + alpha
00362             a1 =  -2*cos
00363             a2 =   1 - alpha
00364 */
00365         
00366         omega = (float) 2.0f*3.1415f*freq/48000.0f;
00367         cs = (float) cos(omega);
00368         sn = (float) sin(omega);
00369     alpha = (float) (sin(omega)/(2*(Q*5.0f)));
00370         
00371         a0 =  (1.0f + alpha);
00372         a0INV = 1.0f/a0;
00373     
00374         b0 =  sn*a0INV*0.5f;
00375     b1 =  0.0f;
00376         b2=   -b0;
00377         a1 =  (-2.0f*cs)*a0INV;
00378     a2 =  (1.0f-alpha)*a0INV;
00379 }
00380 
00381 void BiFilter::bandpass2FreqAndQ(float freq, float Q)
00382 { /*
00383 BPF2:        H(s) = (s/Q) / (s^2 + s/Q + 1)      (constant 0 dB peak gain)
00384 
00385             b0 =   alpha
00386             b1 =   0
00387             b2 =  -alpha
00388             a0 =   1 + alpha
00389             a1 =  -2*cos
00390             a2 =   1 - alpha
00391 */
00392         
00393         omega = (float) 2.0f*3.1415f*freq/48000.0f;
00394         cs = (float) cos(omega);
00395         sn = (float) sin(omega);
00396     alpha = (float) (sin(omega)/(2*(Q*5.0f)));
00397         
00398         a0 =  (1.0f + alpha);
00399         a0INV = 1.0f/a0;
00400     
00401         b0 =  alpha*a0INV;
00402     b1 =  0.0f;
00403         b2=   -b0;
00404         a1 =  (-2.0f*cs)*a0INV;
00405     a2 =  (1.0f-alpha)*a0INV;
00406 }
00407 
00408 void BiFilter::notchFreqAndQ(float freq, float Q)
00409 { /*
00410  H(s) = (s^2 + 1) / (s^2 + s/Q + 1)
00411 
00412             b0 =   1
00413             b1 =  -2*cos
00414             b2 =   1
00415             a0 =   1 + alpha
00416             a1 =  -2*cos
00417             a2 =   1 - alpha
00418 
00419 */
00420         
00421         omega = (float) 2.0f*3.1415f*freq/48000.0f;
00422         cs = (float) cos(omega);
00423         sn = (float) sin(omega);
00424     alpha = (float) (sin(omega)/(2*(Q*5.0f)));
00425         
00426         a0 =  (1.0f + alpha);
00427         a0INV = 1.0f/a0;
00428     
00429         b0 =  1.0f*a0INV;
00430     b1 =  (-2.0f*cs)*a0INV;
00431         b2=   b0;
00432         a1 =  (-2.0f*cs)*a0INV;
00433     a2 =  (1.0f-alpha)*a0INV;
00434 }
00435 
00436 
00437 void BiFilter::peakingEQFreqAndQAndA(float freq, float Q, float A)
00438 { 
00439 /*
00440 peakingEQ:  H(s) = (s^2 + s*(A/Q) + 1) / (s^2 + s/(A*Q) + 1)
00441 
00442             b0 =   1 + alpha*A
00443             b1 =  -2*cos
00444             b2 =   1 - alpha*A
00445             a0 =   1 + alpha/A
00446             a1 =  -2*cos
00447             a2 =   1 - alpha/A*/
00448         
00449         omega = (float) 2.0f*3.1415f*freq/48000.0f;
00450         cs = (float) cos(omega);
00451         sn = (float) sin(omega);
00452     alpha = (float) (sin(omega)/(2*(Q*5.0f)));
00453         beta  = sqrt(A)/Q  ;
00454         
00455         a0 =  (1.0f + alpha/A);
00456         a0INV = 1.0f/a0;
00457     
00458         b0 =  (1.0f+alpha*A)*a0INV;
00459     b1 =  (-2.0f*cs)*a0INV;
00460         b2=   (1.0f-alpha*A)*a0INV;
00461         a1 =  (-2.0f*cs)*a0INV;
00462     a2 =  (1.0f - alpha/A)*a0INV;
00463 }
00464 
00465 
00466 void BiFilter::lowShelfFreqAndQAndA(float freq, float Q, float A)
00467 { 
00468 /*
00469 lowShelf:   H(s) = A * (s^2 + (sqrt(A)/Q)*s + A) / (A*s^2 + (sqrt(A)/Q)*s + 1)
00470 
00471             b0 =    A*[ (A+1) - (A-1)*cos + beta*sin ]
00472             b1 =  2*A*[ (A-1) - (A+1)*cos            ]
00473             b2 =    A*[ (A+1) - (A-1)*cos - beta*sin ]
00474             a0 =        (A+1) + (A-1)*cos + beta*sin
00475             a1 =   -2*[ (A-1) + (A+1)*cos            ]
00476             a2 =        (A+1) + (A-1)*cos - beta*sin
00477         */
00478         
00479         omega = (float) 2.0f*3.1415f*freq/48000.0f;
00480         cs = (float) cos(omega);
00481         sn = (float) sin(omega);
00482     alpha = (float) (sin(omega)/(2*(Q*5.0f)));
00483         beta  = sqrt(A)/Q  ;
00484         
00485 
00486         a0 =  (A+1) + (A-1)*cs + beta*sn;
00487         a0INV = 1.0f/a0;
00488     
00489         b0 =  A*( (A+1) - (A-1)*cs + beta* sn)*a0INV;
00490     b1 =  2.0f*A*( (A-1) - (A+1)*cs)*a0INV;
00491         b2=   A*( (A+1) - (A-1)*cs - beta* sn)*a0INV;
00492         a1 =  -2*( (A-1) + (A+1)*cs )*a0INV;
00493     a2 = ((A+1) + (A-1)*cs - beta*sn)*a0INV;
00494 }
00495 
00496 void BiFilter::highShelfFreqAndQAndA(float freq, float Q, float A)
00497 { 
00498 /*
00499   b0 =    A*[ (A+1) + (A-1)*cos + beta*sin ]
00500             b1 = -2*A*[ (A-1) + (A+1)*cos            ]
00501             b2 =    A*[ (A+1) + (A-1)*cos - beta*sin ]
00502             a0 =        (A+1) - (A-1)*cos + beta*sin
00503             a1 =    2*[ (A-1) - (A+1)*cos            ]
00504             a2 =        (A+1) - (A-1)*cos - beta*sin
00505         */
00506         
00507         omega = (float) 2.0f*3.1415f*freq/48000.0f;
00508         cs = (float) cos(omega);
00509         sn = (float) sin(omega);
00510     alpha = (float) (sin(omega)/(2*(Q*5.0f)));
00511         beta  = sqrt(A)/Q  ;
00512         
00513 
00514         a0 =  (A+1) - (A-1)*cs + beta*sn;
00515         a0INV = 1.0f/a0;
00516     
00517         b0 =  A*( (A+1) + (A-1)*cs + beta* sn)*a0INV;
00518     b1 =  -2.0f*A*( (A-1) + (A+1)*cs)*a0INV;
00519         b2=   A*( (A+1) + (A-1)*cs - beta* sn)*a0INV;
00520         a1 =  2*( (A-1) - (A+1)*cs )*a0INV;
00521     a2 = ((A+1) + (A-1)*cs - beta*sn)*a0INV;
00522 }
00523 
00524 
00525 
00526 
00527 void Fourier::transform(float data[], unsigned long nn, int isign) {
00528         float * fr = new float[nn];
00529         float * fi = new float[nn];
00530 
00531 
00532 
00533         for (int i = 0; i< nn; i++)
00534         {
00535                 fr[i] = data[i*2];
00536                 fi[i] = data[i*2+1];
00537         }
00538         
00539         int ldn = (int) Utils::Log2(nn);
00540 
00541         fft_f(fr,fi,ldn, isign);
00542         
00543 
00544         {
00545         for (int i = 0; i< nn; i++)
00546         {
00547                 data[i*2] = fr[i];
00548                 data[i*2+1] = fi[i];
00549         }}
00550 
00551         delete[] fr;
00552         delete[] fi;
00553 
00554 }
00555 
00556 
00557 
00558 Sample * Fourier::sawtooth(int sampleLength, int partials, int wrapAround)
00559 {
00560                 float * array= new float[sampleLength*2];
00561                 
00562                 if (partials > (sampleLength / 4)) {partials = sampleLength / 4; }
00563 
00564                 // reset array
00565                 for (int j=0; j<sampleLength * 2; j++) {
00566                         array[j] = 0.0; 
00567                 }
00568 
00569                 // setup Fourier components.            
00570                 for (int n=1; n<partials; n++) {
00571                         // Set imaginary part of Fourier spectrum.
00572                         array[(n*2)+1]=1.0/(float)(n);
00573                         array[sampleLength*2-(n*2)+1]=-1.0/(float)(n);
00574                 }
00575 
00576                 // do transformation
00577                 Fourier::transform(array, sampleLength, -1);
00578 
00579                 // create a new sample
00580                 Sample * mySample= new Sample(sampleLength,wrapAround);
00581 
00582                 for (int i=0; i<sampleLength; i++) {
00583                         // Copy real part of Fourier transform to mySample.
00584                         mySample->samples[i] = array[i*2];      
00585                 }
00586 
00587                 mySample->makeWrap();
00588                 mySample->wavenormalize();
00589                 delete [] array;
00590                 return mySample;
00591 }
00592 
00593 Sample * Fourier::square(int sampleLength, int partials, int wrapAround)
00594 {
00595                 float * array= new float[sampleLength*2];
00596                 
00597                 if (partials > (sampleLength / 4)) {partials = sampleLength / 4; }
00598 
00599                 // reset array
00600                 for (int j=0; j<sampleLength * 2; j++) {
00601                         array[j] = 0.0; 
00602                 }
00603 
00604                 // setup Fourier components.            
00605                 for (int n=1; n<partials; n=n+2) {
00606                                 // Set imaginary part of Fourier spectrum.
00607                                 array[(n*2)+1]=1.0/(float)(n);
00608                                 array[sampleLength*2-(n*2)+1]=-1.0/(float)(n);
00609                 }       
00610 
00611                 // do transformation
00612                 Fourier::transform(array, sampleLength, -1);
00613 
00614                 // create a new sample
00615                 Sample * mySample= new Sample(sampleLength,wrapAround);
00616 
00617                 for (int i=0; i<sampleLength; i++) {
00618                         // Copy real part of Fourier transform to mySample.
00619                         mySample->samples[i] = array[i*2];      
00620                 }
00621 
00622                 mySample->makeWrap();
00623                 mySample->wavenormalize();              
00624                 delete [] array;
00625                 return mySample;
00626 }               
00627 
00628 Sample * Fourier::triangle(int sampleLength, int partials, int wrapAround)
00629 {
00630                 float * array= new float[sampleLength*2];
00631                 
00632                 if (partials > (sampleLength / 2)) {partials = sampleLength / 2; }
00633 
00634                 // reset array
00635                 for (int j=0; j<sampleLength * 2; j++) {
00636                         array[j] = 0.0; 
00637                 }
00638 
00639                 // setup Fourier components.            
00640                 for (int n=1; n<partials; n++) {
00641                         if ((n % 2)==1)
00642                         {       // Set real part of Fourier spectrum.
00643                                 array[(n*2)]=1.0/(float)(n*n);
00644                                 array[sampleLength*2-(n*2)]=1.0/(float)(n*n);
00645                         }               
00646                 }
00647 
00648                 // do transformation
00649                 Fourier::transform(array, sampleLength, -1);
00650 
00651                 // create a new sample
00652                 Sample * mySample= new Sample(sampleLength,wrapAround);
00653 
00654                 for (int i=0; i<sampleLength; i++) {
00655                         // Copy real part of Fourier transform to mySample.
00656                         mySample->samples[i] = array[i*2];      
00657                 }
00658 
00659                 mySample->makeWrap();
00660                 mySample->wavenormalize();
00661                 delete [] array;
00662                 return mySample;
00663 }
00664 
00665 
00666 Sample * Fourier::sine(int sampleLength, int partials, int wrapAround)
00667 {
00668                 float * array= new float[sampleLength*2];
00669                 
00670                 if (partials > (sampleLength / 2)) {partials = sampleLength / 2; }
00671 
00672                 // reset array
00673                 for (int j=0; j<sampleLength * 2; j++) {
00674                         array[j] = 0.0; 
00675                 }
00676 
00677         
00678                         {       // Set real part of Fourier spectrum.
00679                                 array[2]=1.0f;
00680                                 array[sampleLength*2-2]=1.0f;
00681                         }               
00682         
00683                 // do transformation
00684                 Fourier::transform(array, sampleLength, -1);
00685 
00686                 // create a new sample
00687                 Sample * mySample= new Sample(sampleLength,wrapAround);
00688 
00689                 for (int i=0; i<sampleLength; i++) {
00690                         // Copy real part of Fourier transform to mySample.
00691                         mySample->samples[i] = array[i*2];      
00692                 }
00693 
00694                 mySample->makeWrap();
00695                 mySample->wavenormalize();
00696                 delete [] array;
00697                 return mySample;
00698 }
00699 
00700 Sample * Fourier::wave1(int sampleLength, int partials, int wrapAround)
00701 {
00702                 float * array= new float[sampleLength*2];
00703                 
00704                 if (partials > (sampleLength / 2)) {partials = sampleLength / 2; }
00705 
00706                 // reset array
00707                 for (int j=0; j<sampleLength * 2; j++) {
00708                         array[j] = 0.0; 
00709                 }
00710 
00711         
00712                         {       // Set real part of Fourier spectrum.
00713                                 
00714                                 array[2]=1.0f;
00715                                 array[sampleLength*2-2]=1.0f;
00716 
00717                                 array[8]=1.0f;
00718                                 array[sampleLength*2-8]=0.25f;
00719 
00720                                 array[4]=1.0f;
00721                                 array[sampleLength*2-4]=0.5f;
00722 
00723                                 array[16]=1.0f;
00724                                 array[sampleLength*2-16]=0.125f;
00725                         }               
00726         
00727                 // do transformation
00728                 Fourier::transform(array, sampleLength, -1);
00729 
00730                 // create a new sample
00731                 Sample * mySample= new Sample(sampleLength,wrapAround);
00732 
00733                 for (int i=0; i<sampleLength; i++) {
00734                         // Copy real part of Fourier transform to mySample.
00735                         mySample->samples[i] = array[i*2];      
00736                 }
00737 
00738                 mySample->makeWrap();
00739                 mySample->wavenormalize();
00740                 delete [] array;
00741                 return mySample;
00742 }
00743 
00744 Sample * Fourier::wave2(int sampleLength, int partials, int wrapAround)
00745 {
00746                 float * array= new float[sampleLength*2];
00747                 
00748                 if (partials > (sampleLength / 2)) {partials = sampleLength / 2; }
00749 
00750                 // reset array
00751                 for (int j=0; j<sampleLength * 2; j++) {
00752                         array[j] = 0.0; 
00753                 }
00754 
00755         
00756                 for (int n=1; n<partials; n++) {
00757                         if ((n % 3)==1)
00758                         {       // Set real part of Fourier spectrum.
00759                                 array[(n*2)]=1.0/(float)(n);
00760                                 array[sampleLength*2-(n*2)]=1.0/(float)(n);
00761                         }               
00762                 }       
00763         
00764                 // do transformation
00765                 Fourier::transform(array, sampleLength, -1);
00766 
00767                 // create a new sample
00768                 Sample * mySample= new Sample(sampleLength,wrapAround);
00769 
00770                 for (int i=0; i<sampleLength; i++) {
00771                         // Copy real part of Fourier transform to mySample.
00772                         mySample->samples[i] = array[i*2];      
00773                 }
00774 
00775                 mySample->makeWrap();
00776                 mySample->wavenormalize();
00777                 delete [] array;
00778                 return mySample;
00779 }
00780 
00781 
00782 Sample * Fourier::wave3(int sampleLength, int partials, int wrapAround)
00783 {
00784                 float * array= new float[sampleLength*2];
00785                 
00786                 if (partials > (sampleLength / 2)) {partials = sampleLength / 2; }
00787 
00788                 // reset array
00789                 for (int j=0; j<sampleLength * 2; j++) {
00790                         array[j] = 0.0; 
00791                 }
00792 
00793         
00794                 for (int n=1; n<partials; n++) {
00795                         if ((n % 2)==1)
00796                         {       // Set real part of Fourier spectrum.
00797                                 array[(n*2)]=1.0/(float)(sqrt(n));
00798                                 array[sampleLength*2-(n*2)]=1.0/(float)(sqrt(n));
00799                         }               
00800                 }                       
00801         
00802                 // do transformation
00803                 Fourier::transform(array, sampleLength, -1);
00804 
00805                 // create a new sample
00806                 Sample * mySample= new Sample(sampleLength,wrapAround);
00807 
00808                 for (int i=0; i<sampleLength; i++) {
00809                         // Copy real part of Fourier transform to mySample.
00810                         mySample->samples[i] = array[i*2];      
00811                 }
00812 
00813                 mySample->makeWrap();
00814                 mySample->wavenormalize();
00815                 delete [] array;
00816                 return mySample;
00817 }
00818 
00819 
00820 Sample * Fourier::wave4(int sampleLength, int partials, int wrapAround)
00821 {
00822                 float * array= new float[sampleLength*2];
00823                 
00824                 if (partials > (sampleLength / 2)) {partials = sampleLength / 2; }
00825 
00826                 // reset array
00827                 for (int j=0; j<sampleLength * 2; j++) {
00828                         array[j] = 0.0; 
00829                 }
00830 
00831         
00832                 for (int n=1; n<partials; n++) {
00833                         if ((n % 2)==1)
00834                         {       // Set real part of Fourier spectrum.
00835                                 array[(n*2)]=1.0;
00836                                 array[sampleLength*2-(n*2)]=1.0;
00837                         }               
00838                 }               
00839         
00840                 // do transformation
00841                 Fourier::transform(array, sampleLength, -1);
00842 
00843                 // create a new sample
00844                 Sample * mySample= new Sample(sampleLength,wrapAround);
00845 
00846                 for (int i=0; i<sampleLength; i++) {
00847                         // Copy real part of Fourier transform to mySample.
00848                         mySample->samples[i] = array[i*2];      
00849                 }
00850 
00851                 mySample->makeWrap();
00852                 mySample->wavenormalize();
00853                 delete [] array;
00854                 return mySample;
00855 }
00856 
00857 }; // end of namespace: SynthCore
00858 
00859 

Syntopia Project. Visit the web page, or the SourceForge page.
Docs made by Doxygen. Email: Mikael Christensen