This is an interesting thread. Let's keep it going.  I wonder what the best solution is.  How about if the existing core layout was not a limiting factor? How would we do it with a blank canvas?

Paul

On Apr 7, 2010 1:53 PM, "Stefan Fendt" <stefan@sfendt.de> wrote:

Maybe this is of use for someone...

// Oversampled "naive" Oscillator to suppress audible aliasing. This concept
// will work also with a wavetable-based oscillator. It does _not_
deliver alias
// *free*-output, but the alias is sufficiently suppressed to be
unaudible at
// 32-times oversampling and above.
//
// Usually one would use a FIR-Filter for this, but an IIR-Filter works also
// and gives the output some "analogue" touch-up... ;-) Despite that the
IIR is
// faster and we are not interested in having something with
zero-phase-shift
// anyways...
//
// This is proof of concept-code, so do not expect any beauty...
//
// (C)2010 S.Fendt, released into the public domain in the hope it will
be usefull
// for someone...

#include <iostream>
#include <fstream>
#include <cmath>
#include <cstdlib>

class lowpassfilter
{
   double a0,a1,a2,b1,b2;
   double x0,x1,x2,y1,y2,y0;

   public:

   lowpassfilter( float rel_frequency )
   {
       double fx = cos( M_PIl*rel_frequency );
       double fy = sin( M_PIl*rel_frequency );

       double sD = sqrt( pow( (-1.0) - fx, 2.0 ) + pow( -fy, 2.0 ) )/
                   sqrt( pow( (+1.0) - fx, 2.0 ) + pow( -fy, 2.0 ) );
       double sR = sD/fabs( pow(sD, 2.0) - 1.0 )*2.0;

       if( sR > 10000 ) sR=10000;

       double alpha = asin( fy / sR );

       double px = 0;
       double py = 0;

       if( fx >= 0 )
       {
         double sX = fx + sR*cos( asin( fy / sR ) );
         px = cos(M_PI-alpha*0.45)*sR+sX;
         py = sin(M_PI-alpha*0.45)*sR;
       }
       else
       {
         double sX = fx - sR*cos( asin( fy / sR ) );
         px = cos(alpha*0.45)*sR+sX;
         py = sin(alpha*0.45)*sR;
       }

       a0 = ( px*px + py*py - 2.0 * px + 1 )/4.0;

       a1 = +2.0 * a0;
       a2 = +1.0 * a0;

       b1 = +2.0 * px;
       b2 = -( px*px + py*py );

       x0 = x1 = x2 = y0 = y1 = y2 = 0.0;
   }

   inline double run( double in )
   {
       x2 = x1; x1 = x0; x0 = in;
       y2 = y1; y1 = y0;

       y0 = x0*a0 + x1*a1 + x2*a2 + y1*b1 + y2*b2;

       return( y0 );
   }
};

class oscillator
{
   float phase;
   float frequency;
   float samplerate;
   int oversampling;
   int pos;

   float out;

   lowpassfilter* lp0;
   lowpassfilter* lp1;
   lowpassfilter* lp2;
   lowpassfilter* lp3;

   public:

   oscillator(float samplerate)
   {
       this->samplerate = samplerate;
       this->phase = 0;
       this->frequency = 8000;
       this->oversampling = 256; // 64times oversampling runs >10times
faster
                                 // than realtime on my system
(E5400@2.7GHz)
                                 // and is free of audible aliasing...
       out = 0;

       lp0 = new lowpassfilter( 0.66/(float)oversampling );
       lp1 = new lowpassfilter( 0.66/(float)oversampling );
       lp2 = new lowpassfilter( 0.66/(float)oversampling );
       lp3 = new lowpassfilter( 0.66/(float)oversampling );
   }

   ~oscillator()
   {
   }

   float run()
   {
       const float alpha = 0.125f/(float)oversampling;

       for(int n=0; n<oversampling; n++)
       {
           phase += frequency/(samplerate*(float)oversampling);
           phase  = phase>1.0f? phase-1.0f:phase;

           if(1)
           {
             if(phase<0.125)
               out = lp3->run(lp2->run(lp1->run(lp0->run( +0.5 ))));
             else
               out = lp3->run(lp2->run(lp1->run(lp0->run( -0.5 ))));
           }
           else
           {
               out = lp3->run(lp2->run(lp1->run(lp0->run(
(phase-0.5)*2.0 ))));
           }
       }
       return( out );
   }

   void set_frequency( float frequency )
   {
       this->frequency = frequency;
   }
};

int main()
{
   std::fstream fileout( "outfile.dat", std::ios::out|std::ios::binary );

   float samplerate = 44100;
   union
   {
       float f;
       char  c[4];
   } sample;

   oscillator m_oscillator( samplerate );

   float f0 = 100;
   float f1 = 8000;

   for(int n=0; n<(int)(samplerate*10); n++ )
   {
       m_oscillator.set_frequency( f0*((float)n/(samplerate*10)) + f1 *
(1.0-(float)n/(samplerate*10)) );
       sample.f = m_oscillator.run();
       fileout.write( &sample.c[0], 4 );
   }
   fileout.close();

}

------------------------------------------------------------------------------
Download Intel&#17...