I am sampling a sine wave at 48 kHz, the frequency range of my sine wave can vary from 0 to 20000 Hz with a step of about 100 Hz. I am using a lookup table approach. So I genera
You're on the right track - first we need to generate a sine wave LUT:
const int Fs = 48000; // sample rate (Hz)
const int LUT_SIZE = 1024; // lookup table size
int16_t LUT[LUT_SIZE]; // our sine wave LUT
for (int i = 0; i < LUT_SIZE; ++i)
{
LUT[i] = (int16_t)roundf(SHRT_MAX * sinf(2.0f * M_PI * (float)i / LUT_SIZE));
} // fill LUT with 16 bit sine wave sample values
Note that we only need to generate this LUT once, e.g. during initialisation.
Now that we have a sine wave LUT we can use it to generate any frequency we wish to using a phase accumulator:
const int BUFF_SIZE = 4096; // size of output buffer (samples)
int16_t buff[BUFF_SIZE]; // output buffer
const int f = 1000; // frequency we want to generate (Hz)
const float delta_phi = (float) f / Fs * LUT_SIZE;
// phase increment
float phase = 0.0f; // phase accumulator
// generate buffer of output
for (int i = 0; i < BUFF_SIZE; ++i)
{
int phase_i = (int)phase; // get integer part of our phase
buff[i] = LUT[phase_i]; // get sample value from LUT
phase += delta_phi; // increment phase
if (phase >= (float)LUT_SIZE) // handle wraparound
phase -= (float)LUT_SIZE;
}
Note: for higher quality output you can use linear interpolation between the LUT values at phase_i
and phase_i + 1
, but the above approach is good enough for most audio applications.