iOS音调生成

时间:2012-03-06 02:24:41

标签: ios audio sampling sine

我正在看这个example about sound generation on iOS,因为我需要做类似的事情,但有些部分我不明白,我希望有人可以帮助我。

在这部分代码中:

    double theta_increment = 2.0 * M_PI * viewController->frequency / viewController->sampleRate;
    // Generate the samples
    for (UInt32 frame = 0; frame < inNumberFrames; frame++) 
    {
        buffer[frame] = sin(theta) * amplitude;

        theta += theta_increment;
        if (theta > 2.0 * M_PI)
        {
            theta -= 2.0 * M_PI;
        }
    }

我真的不明白theta += theta_increment;部分的用途。对我来说,在for循环中做这样的事情更有意义:

buffer[frame] = sin(theta_increment * frame);

知道为什么那不起作用?另外,我不知道代码的这一部分是什么:if (theta > 2.0 * M_PI)所以对此的任何解释都是非常受欢迎的。

2 个答案:

答案 0 :(得分:0)

我想它会以你的方式工作(但不要忘记乘以振幅):

buffer[frame] = sin(theta_increment * frame) * amplitude;

表达相同数学的两种不同方式。看起来编写原始代码的人想要保持0&lt; = theta&lt; 2pi,但这可能没有必要(除非sin()调用以我不知道的方式很奇怪)。此外,他们可能想要保持&#34;数学&#34;部分独立于框架变量,以防相同的片段出现在其他地方的其他循环中,但这只是推测。

答案 1 :(得分:0)

您的方法可用于创建相同的结果,表达方式不同。但是,theta += theta_increment;将比您建议的更简单(计算)。

阶段的域被包装到sin'的逻辑参数域。对于短样品,此步骤实际上不是必需的。由于浮点存储的限制,您的频率最终可能会发生变化,并且如果未包装该值,最终永远不会增加,具体取决于您生成的样本数量以及是否使用floatdouble。可以这样想一想:如果你有一个巨大的正浮点数(相位累加器的值)并且你试图向它添加0.000004,会发生什么?浮点误差将使其圆整以适合浮点数或双精度,并且误差将导致相位并最终导致音高不稳定。对于短样品(例如一些循环),在这种情况下不需要包裹,但是对于许多循环,它用于稳定节距和相位累加器随着时间的推移。

最后,theta将用于存储相位斜坡的最后一个值,以便在后续渲染调用中从中断处继续生成。如果没有这个,输出将在渲染调用边界处重新开始,产生非常令人不快的噪音和错误的频率。

考虑所有因素:可能是因为它是一个简单的演示,并且是在该环境中生成正弦的快速方法。你的方法有一些“昂贵的”转换,但它是无分支的 - 它可能比原始的更快,特别是对于更高的频率。