1 | #include "Header/main.h"
|
2 |
|
3 | //The look-up-table for the sine values / phase accumulator
|
4 | static double lut[LUT_SIZE];
|
5 |
|
6 | //Phaseaccumulator
|
7 | static double phase;
|
8 |
|
9 | void DDS_init()
|
10 | {
|
11 | //Fill LUT
|
12 | Uint8 aa = 0;
|
13 | for(aa = 0; aa < LUT_SIZE; aa++)
|
14 | {
|
15 | //Calculate sine samples, Int16 -32.768 to 32.767 => amplify by 32767 (2^15-1)
|
16 | lut[aa] = (double) sin(PI * aa / LUT_SIZE);
|
17 | }
|
18 |
|
19 | //Preset variable for the phaseaccumulator
|
20 | phase = 0;
|
21 | }
|
22 |
|
23 | /// <summary>
|
24 | /// Direct Digital Synthesis (DDS) using Lanczos-Splines for interpolation.
|
25 | /// It is desinged for a frequency range from 100Hz-10kHz
|
26 | /// This method accumulates phase jumps non-quantized and returns corresponding
|
27 | /// sine values from a look-up-table, in which only half a wave is stored.
|
28 | /// Values between two LUT-indexes are interpolated by a Lanczos-Spline. The spline starts one index before
|
29 | /// the arbitrary value, and ends two indexes after.
|
30 | /// </summary>
|
31 | /// <param name="A">Amplitude</param>
|
32 | /// <param name="f">Frequency</param>
|
33 | /// <returns>Array with calculated sine values</returns>
|
34 | void DDS(Int16 *target, double A, Int16 f)
|
35 | {
|
36 | //Binary tuning word (Normally multiplied by 2 but since we are using 2 Buffers ping/pong
|
37 | //we have to output only 25 times the ping, and 25 times the pong buffer
|
38 | double jumpSize = (double)f * LUT_SIZE / F_CLK;
|
39 |
|
40 | //Current position in the LUT
|
41 | Int16 index = 0;
|
42 |
|
43 | //Current iteration step of the accumulation
|
44 | Int32 iterator = 0;
|
45 |
|
46 | //Count variable to loop through the output buffer
|
47 | Uint16 aa = 0;
|
48 | for(aa = 0; aa < OUT_SIZE; aa++)
|
49 | {
|
50 | // Lanczos a=3 (x0' = floor(x0))
|
51 | // Î(x0) = L(x0-x0'-1)*lut(x0'-1) + L(x0-x0')*lut(x0') + L(x0-x0'+1)*lut(x0'+1) + L(x0-x0'+2)*lut(x0'+2)
|
52 |
|
53 | //Result
|
54 | double result = 0;
|
55 | Uint8 bb = 0;
|
56 |
|
57 | //Loop through the sum (Sigma)
|
58 | for(bb = 0; bb < 4; bb++)
|
59 | {
|
60 | //Set iterator
|
61 | iterator = (Int32)phase + bb - 1;
|
62 |
|
63 | //Set index for the LUT
|
64 | index = iterator % (2 * LUT_SIZE);
|
65 |
|
66 | //Get the sine value from the LUT, corresponding to the index.
|
67 | //Actually the LUT is a ringbuffer, if the index is negativ =>
|
68 | //Get the value from the end. Since we have only stored half
|
69 | //a sine wave, we also have to invert the value
|
70 | //Also calculate a step of the accumulation: L(x0-x0'-bb-1) * lut(x0'-bb-1)
|
71 | if(index < 0)
|
72 | {
|
73 | //If index is below the size of the lut, set to end and invert
|
74 | result += Lanczos(phase - iterator) * -lut[LUT_SIZE + index];
|
75 | }
|
76 | else if(index < LUT_SIZE)
|
77 | {
|
78 | //First half
|
79 | result += Lanczos(phase - iterator) * lut[index];
|
80 | }
|
81 | else
|
82 | {
|
83 | //If index is beyond the size of the lut => second half, set to start but invert value
|
84 | result += Lanczos(phase - iterator) * -lut[index - LUT_SIZE];
|
85 | }
|
86 | }
|
87 |
|
88 | //Amplify the result by amplitude A
|
89 | *(target + aa) = A * result * 32767;
|
90 |
|
91 | //Increment phase
|
92 | phase += jumpSize;
|
93 | }
|
94 |
|
95 | //Decrement phase;
|
96 | phase = (Int32)phase % OUT_SIZE;
|
97 | }
|