Takie rzeczy robi się ogólnie w ten sposób:
Masz tablicę tfun np. o długości N gdzie najlepiej jak jest potęgą 2 (upraszcza adresowanie). Tablica ta zawiera próbki jednego okresu generowanego przebiegu, np. sinus dla argumentu od <0 do 2*Π).
Wartości kolejne tablicy liczysz z wzoru:
$$tfun[i]:=sin(\frac{2*Pi*i}{N})$$
dla i=0...N-1
potem realizujesz w przerwaniach odczyt tej tablicy:
init:
wsk:=0; { pseudofaza }
dwsk:=1; { przyrost fazy }
interrupt (np. 48 000 na sekundę - częstotliwość standardowa DAT-ów)
out:=AMP*tfun[wsk];
wsk:=wsk+dwsk;
wsk:=wsk and (N-1) ; { gdy N jest potęga liczby 2}
lub
if wsk>N then wsk:=wsk-N; {dla innego N}
endinterrupt
======================
częstotliwość wyjściowa:
$$fwy=dwsk*\frac{fp}{N}$$
gdzie
fp - częstotliwość próbkowania
N - długość tablicy
dwsk - przyrost fazy = 1..N/2
powyższe ogranicza mozliwości do uzyskania fwy będącej całkowitą wielokrotnością fp/N ale daje bardzo czysty sygnał (dla sinusa).
Można zastosować ułamkowy przyrost fazy np. dwsk=1.5 i tu są trzy metody odczytu tablicy (ze względu, że nie ma adresu 1.5).
Można obcinać część ułamkową fazy (po dodawaniu a przed adresowaniem tablicy) i liczyć:
Ciąg kolejnych wartości wskaźnika:
0, 1.5, 3, 4.5, 6, 7.5, 9 ...
Obcinanie:
0, 1, 3, 4, 6, 7 ...
Zaokrąglanie
0, 2, 3, 5, 6, 8, 9 ...
Interpolacja daje najlepsze wyniki.
i:=Int(wsk); { część całkowita fazy}
p:=Frac(wsk); {część ułamkowa fazy}
out:=tfun[i]+(tfun[(i+1) mod N]-tfun[i])*p
======================================
Dla sinusoidy maksymalna teoretyczna częstotliwość to fp/2 ale przyjmuje się np. 0.45 fp ze względu na nieidealność filtru wyjściowego i potrzebę uniknięcia aliasingu.
Przy generacji przebiegów złożonych (typu prostokąt, piła trójkąt) przez przetwornik C/A nalezy pamiętać aby żadna składowa przebiegu generowananego nie była większa niż fp/2 dla uniknięcia zjawiska aliasingu.
Np. dla prostokąta, fp=48000 kHz i założenia obecności piątej harmonicznej w sygnale wychodzi, że fwy<4800 Hz (fp/2/5).