【问题标题】:iOS tone generationiOS 音调生成
【发布时间】:2012-03-06 02:24:40
【问题描述】:

我正在查看此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 &gt; 2.0 * M_PI) 所以任何对此的解释也非常受欢迎。

【问题讨论】:

    标签: ios audio sampling trigonometry


    【解决方案1】:

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

    阶段的域被包装到sin's 逻辑参数域。对于短样本,这一步实际上是不必要的。由于浮点存储的限制,如果值未包装,您的频率最终可能会发生变化并且最终永远不会增加,这取决于您生成的样本数量以及您使用的是float 还是double。可以这样想:如果您有一个 巨大 正浮点数(相位累加器的值)并且您尝试将 0.000004 添加到它会发生什么?浮点误差会将其舍入以适应浮点数或双精度数,并且该误差将导致相位并最终导致音高不稳定。对于短样本(例如某些周期),在这种情况下不需要回绕,但对于许多周期,它可以随着时间的推移稳定音高和相位累加器。

    最后,theta 将用于存储相位渐变的最后一个值,以便在随后的渲染调用中从中断处恢复生成。否则,输出将在渲染调用边界处从 0 处重新开始,产生非常令人不快的噪音和错误的频率。

    考虑所有因素:这可能是因为它是一个简单的演示,并且是在该上下文中生成正弦的快速方法。你的方法有一些“昂贵”的转换,但它是无分支的——它可能比原来的更快,尤其是对于更高的频率。

    【讨论】:

      【解决方案2】:

      我想它会按照你的方式工作得很好(但不要忘记乘以幅度):

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

      只是表达相同数学的两种不同方式。看起来编写原始代码的人想要保留 0

      【讨论】:

        猜你喜欢
        • 2011-09-23
        • 1970-01-01
        • 2015-02-20
        • 1970-01-01
        • 1970-01-01
        • 2013-05-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多