Main Archive Specials Wiki | FAQ Links Submit Forum


C# Oscilator class

Type : Sine, Saw, Variable Pulse, Triangle, C64 Noise
References : Posted by neotec

Notes :
Parameters:

Pitch: The Osc's pitch in Cents [0 - 14399] startig at A -> 6.875Hz
Pulsewidth: [0 - 65535] -> 0% to 99.99%
Value: The last Output value, a set to this property 'syncs' the Oscilator


Code :
public class SynthOscilator
{
public enum OscWaveformType
{
SAW, PULSE, TRI, NOISE, SINE
}

public int Pitch
{
get
{
return this._Pitch;
}
set
{
this._Pitch = this.MinMax(0, value, 14399);
this.OscStep = WaveSteps[this._Pitch];
}
}

public int PulseWidth
{
get
{
return this._PulseWidth;
}
set
{
this._PulseWidth = this.MinMax(0, value, 65535);
}
}

public OscWaveformType Waveform
{
get
{
return this._WaveForm;
}
set
{
this._WaveForm = value;
}
}

public int Value
{
get
{
return this._Value;
}
set
{
this._Value = 0;
this.OscNow = 0;
}
}

private int _Pitch;
private int _PulseWidth;
private int _Value;
private OscWaveformType _WaveForm;

private int OscNow;
private int OscStep;
private int ShiftRegister;

public const double BaseFrequence = 6.875;
public const int SampleRate = 44100;
public static int[] WaveSteps = new int[0];
public static int[] SineTable = new int[0];

public SynthOscilator()
{
if (WaveSteps.Length == 0)
this.CalcSteps();

if (SineTable.Length == 0)
this.CalcSine();

this._Pitch = 7200;
this._PulseWidth = 32768;
this._WaveForm = OscWaveformType.SAW;

this.ShiftRegister = 0x7ffff8;

this.OscNow = 0;
this.OscStep = WaveSteps[this._Pitch];
this._Value = 0;
}

private void CalcSteps()
{
WaveSteps = new int[14400];

for (int i = 0; i < 14400; i++)
{
double t0, t1, t2;

t0 = Math.Pow(2.0, (double)i / 1200.0);
t1 = BaseFrequence * t0;
t2 = (t1 * 65536.0) / (double)this.SampleRate;

WaveSteps[i] = (int)Math.Round(t2 * 4096.0);
}
}

private void CalcSine()
{
SineTable = new int[65536];

double s = Math.PI / 32768.0;

for (int i = 0; i < 65536; i++)
{
double v = Math.Sin((double)i * s) * 32768.0;

int t = (int)Math.Round(v) + 32768;

if (t < 0)
t = 0;
else if (t > 65535)
t = 65535;

SineTable[i] = t;
}
}

public override int Run()
{
int ret = 32768;
int osc = this.OscNow >> 12;

switch (this._WaveForm)
{
case OscWaveformType.SAW:
ret = osc;
break;
case OscWaveformType.PULSE:
if (osc < this.PulseWidth)
ret = 65535;
else
ret = 0;
break;
case OscWaveformType.TRI:
if (osc < 32768)
ret = osc << 1;
else
ret = 131071 - (osc << 1);
break;
case OscWaveformType.NOISE:
ret = ((this.ShiftRegister & 0x400000) >> 11) |
((this.ShiftRegister & 0x100000) >> 10) |
((this.ShiftRegister & 0x010000) >> 7) |
((this.ShiftRegister & 0x002000) >> 5) |
((this.ShiftRegister & 0x000800) >> 4) |
((this.ShiftRegister & 0x000080) >> 1) |
((this.ShiftRegister & 0x000010) << 1) |
((this.ShiftRegister & 0x000004) << 2);
ret <<= 4;
break;
case OscWaveformType.SINE:
ret = SynthTools.SineTable[osc];
break;
default:
break;
}

this.OscNow += this.OscStep;

if (this.OscNow > 0xfffffff)
{
int bit0 = ((this.ShiftRegister >> 22) ^ (this.ShiftRegister >> 17)) & 0x1;
this.ShiftRegister <<= 1;
this.ShiftRegister &= 0x7fffff;
this.ShiftRegister |= bit0;
}

this.OscNow &= 0xfffffff;

this._Value = ret - 32768;

return this._Value;
}

public int MinMax(int a, int b, int c)
{
if (b < a)
return a;
else if (b > c)
return c;
else
return b;
}
}



Comments

There are no comments on this item

Add your own comment
Comments are displayed in fixed width, no HTML code allowed!
Email:

Comment:

Are you human?



Site created and maintained by Bram
Graphic design by line.out | Server sponsered by fxpansion