Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 避免音频合成器中的sin()调用_Algorithm_Audio_Trigonometry - Fatal编程技术网

Algorithm 避免音频合成器中的sin()调用

Algorithm 避免音频合成器中的sin()调用,algorithm,audio,trigonometry,Algorithm,Audio,Trigonometry,简单正弦波生成器获取一组n值,并对每个值调用sin函数: for i = 0; i < 2*pi ; i = i+step { output = append(output, sin(i) ) } 表示i=0;i

简单正弦波生成器获取一组n值,并对每个值调用sin函数:

for i = 0; i < 2*pi ; i = i+step {
    output = append(output, sin(i) )
}
表示i=0;i<2*pi;i=i+步进{
输出=附加(输出,sin(i))
}
但是,这会大量调用可能代价高昂的sin函数,并且无法利用以下事实:所有样本都是连续的,之前已经计算过,并且将四舍五入为整数(PCM)。那么,还有什么选择呢


我在想象一个高分辨率的样本,然后通过每n个条目来缩小规模,但是如果这个问题有一个“工业实力”的解决方案,我很乐意听到它。

你可以计算向量z,当你加上(1,0)时,它会给你(cosθ,sinθ),其中θ=2*pi/步。然后将这个向量加到(1,0)中,得到下一个sin值作为和的y坐标。然后将z旋转角度θ(通过角度θ乘以旋转矩阵),并将其添加到上一个向量(cosθ,sinθ),以获得下一个sin值作为结果和向量的y坐标。等等这需要只计算一次cosθ和sinθ,然后通过2x2矩阵与二维向量的矩阵相乘,然后进行简单的加法,这比使用幂级数展开计算sin()要快。

您在问题中似乎提到sin()是值将四舍五入到最接近的整数。这是真的吗?啊,应该澄清一下。这是一个wav编码器,所以它是PCM。因此,任何浮点值都将以有符号16位int结束。您需要多高的频率分辨率?比如44khz采样率和10 Hz的较低阈值,这对应于最小步长4.4 mrad(我认为)。可以在中找到非常令人印象深刻的sin近似值。但我不知道准确度是否足够适合音频应用。技术不错。以双精度进行此操作可能是明智的,以避免累积舍入误差。在精度问题上达成一致意见,我考虑了这一点,无法想出一个巧妙的解决舍入问题的方法,因此舍入误差目前是不可避免的,虽然如果步长不是太小,并且使用了双精度,则可以忽略不计。很抱歉,如果我的评论听起来像是吹毛求疵,我只是向普通读者指出,这是一个应该避免使用单精度作为“优化”的示例。基准测试naive与golang中的上述内容相比(使用math.Sin函数作为参考)。速度提高了约4倍,在10000次迭代中,平均误差约为5e-11,这是一个相当可忽略的误差,但该误差在不进行处理的情况下会复合。这是一个好东西。