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" <[email protected]> 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
([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...
------------------------------------------------------------------------------
Download Intel® 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