gpt4 book ai didi

signal-processing - 在IOS中高效生成正弦波

转载 作者:行者123 更新时间:2023-12-04 07:46:23 25 4
gpt4 key购买 nike

为运行 IOS 的设备生成正弦波的最有效方法是什么。出于练习的目的,假设频率为 440Hz,采样率为 44100Hz,采样率为 1024。

一个普通的 C 实现看起来像。

#define SAMPLES 1024
#define TWO_PI (3.14159 * 2)
#define FREQUENCY 440
#define SAMPLING_RATE 44100

int main(int argc, const char * argv[]) {
float samples[SAMPLES];

float phaseIncrement = TWO_PI * FREQUENCY / SAMPLING_RATE;
float currentPhase = 0.0;
for (int i = 0; i < SAMPLES; i ++){
samples[i] = sin(currentPhase);
currentPhase += phaseIncrement;
}

return 0;
}

为了利用 Accelerate Framework 和 vecLib vvsinf 函数,可以将循环更改为仅执行加法操作。
#define SAMPLES 1024
#define TWO_PI (3.14159 * 2)
#define FREQUENCY 440
#define SAMPLING_RATE 44100

int main(int argc, const char * argv[]) {
float samples[SAMPLES] __attribute__ ((aligned));
float results[SAMPLES] __attribute__ ((aligned));

float phaseIncrement = TWO_PI * FREQUENCY / SAMPLING_RATE;
float currentPhase = 0.0;
for (int i = 0; i < SAMPLES; i ++){
samples[i] = currentPhase;
currentPhase += phaseIncrement;
}
vvsinf(results, samples, SAMPLES);

return 0;
}

但是就效率而言,只是应用 vvsinf 函数就我应该做的吗?

我不太了解 Accelerate 框架,不知道我是否也可以替换循环。我可以使用 vecLib 或 vDSP 函数吗?

就此而言,是否可以使用完全不同的算法来用正弦波填充缓冲区?

最佳答案

鉴于您正在计算以固定增量增加的相位参数的正弦,通常使用 this "How to Create Oscillators in Software" postthis "DSP Trick: Sinusoidal Tone Generator" post 中描述的递归方程实现信号生成通常要快得多,两者都在 dspguru 上:

y[n] = 2*cos(w)*y[n-1] - y[n-2]

请注意,此递推方程可能会受到数值舍入误差累积的影响,您应该避免一次计算太多样本(您选择 SAMPLES == 1024 应该没问题)。在获得前两个值 y[0]y[1](初始条件)后,可以使用此递推方程。由于您生成的初始相位为 0,因此它们很简单:
samples[0] = 0;
samples[1] = sin(phaseIncrement);

或更一般地,具有任意初始阶段(对于经常重新初始化递推方程以避免我之前提到的数值舍入误差累积特别有用):
samples[0] = sin(initialPhase);
samples[1] = sin(initialPhase+phaseIncrement);

然后可以直接实现递推方程:
float scale = 2*cos(phaseIncrement);
// initialize first 2 samples for the 0 initial phase case
samples[0] = 0;
samples[1] = sin(phaseIncrement);
for (int i = 2; i < SAMPLES; i ++){
samples[i] = scale * samples[i-1] - samples[i-2];
}

请注意,可以通过计算具有适当相对相移的多个音调(每个音调具有相同的频率,但样本之间的相位增量更大),然后将结果交错以获得原始音调(例如计算 sin(4*w*n)sin(4*w*n+w)sin(4*w*n+2*w)sin(4*w*n+3*w))。然而,这会使实现更加模糊,以获得相对较小的 yield 。

或者,可以通过使用 vDsp_deq22 来实现该等式:
// setup dummy array which will hold zeros as input
float nullInput[SAMPLES];
memset(nullInput, 0, SAMPLES * sizeof(float));

// setup filter coefficients
float coefficients[5];
coefficients[0] = 0;
coefficients[1] = 0;
coefficients[2] = 0;
coefficients[3] = -2*cos(phaseIncrement);
coefficients[4] = 1.0;

// initialize first 2 samples for the 0 initial phase case
samples[0] = 0;
samples[1] = sin(phaseIncrement);
vDsp_deq22(nullInput, 1, coefficients, samples, 1, SAMPLES-2);

关于signal-processing - 在IOS中高效生成正弦波,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34971557/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com