我试图只使用整数而不使用表格来近似 sin 函数。
每个步骤都会调用该函数。我已经在matlab中成功地近似了它,但是我的C代码有问题。由于某种原因,我得到错误的频率读数,并且该功能不适用于所有频率。
typedef volatile struct tone_s{
int32_t impulse;
int32_t acceleration;
int32_t rollover;
int32_t velocity;
int32_t phase;
int32_t counter;
int32_t position_acc;
int32_t velocity_acc;
}tone_t;
static void Osc_Init(tone_t *osc, uint32_t frequency, uint32_t sample_rate){
int32_t max_int = (1UL << 16);
frequency *= 4UL;
osc->impulse = (max_int * frequency);
osc->acceleration = max_int/sample_rate * frequency * frequency;
osc->rollover = (sample_rate * 2UL / frequency);
osc->velocity = osc->impulse - (osc->acceleration / 2UL);
osc->velocity_acc = osc->velocity;
osc->phase = -1UL;
osc->counter = 0;
osc->position_acc = 0;
}
#include <stdio.h>
static int16_t Osc_GenSample(tone_t *osc){
if(osc->counter == osc->rollover){
osc->velocity_acc = osc->velocity;
osc->position_acc = 0;
osc->phase = -osc->phase;
osc->counter = 0;
}
int32_t sample = (osc->position_acc / 4194304UL) * osc->phase;
osc->position_acc += osc->velocity_acc;
osc->velocity_acc -= osc->acceleration;
osc->counter++;
//fprintf(stdout, "%d - %d %d %d %d %d %d %d\n", sample, osc->impulse, osc->acceleration, osc->velocity, osc->rollover, osc->position_acc, osc->velocity_acc, osc->counter);
return sample;
}
也许我把它复杂化了。