Eu tenho um sistema de processamento de sinal digital de ponto flutuante que opera a uma taxa de amostragem fixa de amostras por segundo implementada usando um processador x86-64. Supondo que o sistema DSP esteja sincronizado com o que quer que seja importante, qual é a melhor maneira de implementar um oscilador digital em alguma frequência ?
Especificamente, quero gerar o sinal: que para o número da amostra .
Uma idéia é acompanhar um vetor que giramos em um ângulo em cada ciclo do relógio.
Como uma implementação de pseudocódigo do Matlab (a implementação real está em C):
%% Initialization code
f_s = 32768; % sample rate [Hz]
f = 19.875; % some constant frequency [Hz]
v = [1 0]; % initial condition
d_phi = 2*pi * f / f_s; % change in angle per clock cycle
% initialize the rotation matrix (only once):
R = [cos(d_phi), -sin(d_phi) ; ...
sin(d_phi), cos(d_phi)]
Em seguida, em cada ciclo do relógio, rotacionamos o vetor um pouco:
%% in-loop code
while (forever),
v = R*v; % rotate the vector by d_phi
y = v(1); % this is the sine wave we're generating
output(y);
end
Isso permite que o oscilador seja calculado com apenas 4 multiplicações por ciclo. No entanto, eu me preocuparia com erros de fase e estabilidade de amplitude. (Em testes simples, fiquei surpreso que a amplitude não tenha morrido ou explodido imediatamente - talvez a sincos
instrução garanta ?).
Qual é a maneira certa de fazer isso?
sincos
compara a um punhado de multiplicações? Existem possíveis armadilhas a serem observadas com amod
operação?