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
([email protected])
                                  // 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&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
LMMS-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/lmms-devel

Reply via email to