如何从固定大小的查找表中查找不同频率的正弦? [英] How to look up sine of different frequencies from a fixed sized lookup table?
问题描述
// Pseudocode
uint16_t audio_sample [4096] = {...}
NSTEP = freq; //?步长如何与这里的频率有关
for(int i = 0; i< 4096; i = i + NSTEP)
{
sine_f(i)= audio_sample [i];
}
提前感谢
你在正确的轨道上 - 首先我们需要生成一个正弦波LUT:
const int Fs = 48000; // sample rate(Hz)
const int LUT_SIZE = 1024; //查找表大小
int16_t LUT [LUT_SIZE]; //我们的正弦波LUT
(int i = 0; i< LUT_SIZE; ++ i)
{
LUT [i] =(int16_t)roundf(SHRT_MAX * sinf(2.0f * M_PI *(float)i / LUT_SIZE));
} //使用16位正弦波样本值填充LUT
请注意,我们只需要生成该LUT一次,例如在初始化期间。
现在我们有一个正弦波LUT,我们可以使用它来生成我们希望使用相位累加器的任何频率:
const int BUFF_SIZE = 4096; //输出缓冲区大小(样本)
int16_t buff [BUFF_SIZE]; //输出缓冲区
const int f = 1000; //我们要生成的频率(Hz)
const float delta_phi =(float)f / Fs * LUT_SIZE;
//相位增量
float phase = 0.0f; //阶段累加器
//生成
的缓冲区(int i = 0; i< BUFF_SIZE; ++ i)
{
int phase_i = (INT)相; //获取我们阶段的整数部分
buff [i] = LUT [phase_i]; //从LUT获取样本值
phase + = delta_phi; //增量阶段
if(phase> =(float)LUT_SIZE)// handle wraparound
phase - =(float)LUT_SIZE;
}
注意:对于更高质量的输出,您可以使用LUT值之间的线性插值 phase_i
和 phase_i + 1
,但上述方法对于大多数音频应用来说都是足够好的。
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 generate 4096 samples for a sine wave for 4096 different phases. I think the general idea behind this to increment the step size and use different step sizes for different frequncy. So I do the following (pseudo code). But I am not sure how the step size is going to be related to the frequency I want to generate the samples of the sine wave of? For example if my frequency is 15000 Hz what would be the step size that I have to traverse? Is my sample size (4096) too low for this?
// Pseudocode
uint16_t audio_sample[4096] = {...};
NSTEP = freq; //???How is the step size going to be related to the freq here
for(int i = 0; i < 4096; i = i+NSTEP)
{
sine_f(i) = audio_sample[i];
}
Thanks in advance.
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.
这篇关于如何从固定大小的查找表中查找不同频率的正弦?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!