Sajnos nem olvastam utána eléggé a DDS témának így írtam róla pár faszságot. Ami engem legjobban zavart a dologban, az a jitter volt, illetve az, hogy magasabb frekvenciákon nem megy végig a generálandó jel összes mintáján... Aztán futtattam néhány szimulációt és kiderült hogy nem olyan rossz a helyzet mint eredetileg sejtettem, ráadásul az is, hogy a DDS hátrányaival együtt tud élni néhány digitális függvénygenerátor, amiket 250 ezer forint körül vesztegetnek, hmmm...
Néhány sor kódot bedobok ide, amivel mindenki kipróbálhatja és akár jobban meg is értheti, hogyan működik egy DDS (vagy NCO), csak kedvenc fejlesztőeszközünkbe kell másoljuk (ez most C#, de nagyon hasonló Java vagy C is)double[] LUT = new double[1 << 10];
double[] LUT2 = new double[1 << 10];
for (int i = 0; i < LUT.Length; i++)
{
LUT[i] = Math.Sin(((Math.PI * 2) / LUT.Length) * i);
LUT2[i] = (double)((double)(2.0/LUT2.Length) * i) - 1.0;
}
int xscale = pbOut.Size.Width;
int yscale = pbOut.Size.Height;
Random r = new Random();
Bitmap bitmap = new Bitmap(xscale, yscale);
Graphics graphics = Graphics.FromImage(bitmap);
graphics.FillRectangle(Brushes.White, 0, 0, xscale, yscale);
Int32 freqreg = Int32.Parse(tbFreqReg.Text);
Int32 phaseacc = 0;
float prevx = 0;
float prevy = yscale/2;
float prevx2 = 0;
float prevy2 = yscale / 2;
for (int i = 0; i < xscale; i++)
{
phaseacc += freqreg;
// dither
int dither = r.Next();
dither &= (1 << 20) -1;
dither -= (1 << 19);
UInt16 crop = (UInt16)((((UInt32)(phaseacc + dither)) >> 20) & (UInt16)((1 << 10)-1)) ;
graphics.DrawLine(Pens.Black, prevx, prevy, i * 4, (float)(LUT[crop] * (yscale / 2)) + yscale / 2);
prevx = i * 4;
prevy = (float)(LUT[crop] * (yscale / 2)) + yscale / 2;
graphics.DrawLine(Pens.Red, prevx2, prevy2, i * 4, (float)(LUT2[crop] * (yscale / 2)) + yscale / 2);
prevx2 = i * 4;
prevy2 = (float)(LUT2[crop] * (yscale / 2)) + yscale / 2;
}