inline STKfloat BlitSaw::tick( voID ) { Stkfloat tmp,denominator = sin( phase_ ); if ( fabs(denominator) <= std::numeric_limits<Stkfloat>::epsilon() ) tmp = a_; else { tmp = sin( m_ * phase_ ); tmp /= p_ * denominator; } tmp += state_ - C2_; state_ = tmp * 0.995; phase_ += rate_; if ( phase_ >= PI ) phase_ -= PI; lastFrame_[0] = tmp; return lastFrame_[0];}
方波振荡器大致相似.在顶部,有这样的评论:
// A fully optimized version of this code would replace the two sin // calls with a pair of fast sin oscillators,for which stable fast // two-multiply algorithms are well kNown.
我不知道从哪里开始寻找这些“快速双倍算法”,我很欣赏一些指针.我可以使用查找表,但我很想知道这些’快速振荡器’是什么.我也可以使用缩写的泰勒系列,但这可能超过两倍.搜索没有发现任何太多,虽然我确实发现了这个近似值:
#define AD_SIN(n) (n*(2.f- fabs(n)))
绘制出来表明它不是-1到1范围之外的近似值,所以当phase_在-pi到pi的范围内时,我认为我不能使用它:
这里,正弦是蓝线,紫线是近似值.
分析我的代码表明,对sin()的调用是最耗时的调用,所以我真的想优化这一部分.
谢谢
编辑感谢您详细而多样的答案.我将在周末探索这些并接受一个.
编辑2请匿名关闭选民请在评论中解释他们的投票吗?谢谢.
解决方法 本质上,正弦振荡器是一个(或多个)变量,随着每个DSP步骤而变化,而不是从头开始重新计算.最简单的是基于以下三角形身份:(其中d是常数,因此cos(d)和sin(d)也是如此)
sin(x+d) = sin(x) cos(d) + cos(x) sin(d)cos(x+d) = cos(x) cos(d) - sin(x) sin(d)
然而,这需要两个变量(一个用于sin,一个用于cos)和4个乘法来更新.然而,这仍然比在每一步计算完整正弦要快得多.
Oli Charlesworth的解决方案基于这个通用方程的解决方案
A_{n+1} = a A_{n} + A_{n-1}
在寻找形式A_n = k e ^(iθ)的解的情况下给出θ的等式.
e^(i theta (n+1) ) = a e^(i theta n ) + b e^(i theta (n-1) )
这简化为
e^(i theta) - e^(-i theta ) = a2 cos(theta) = a
给予
A_{n+1} = 2 cos(theta) A_{n} + A_{n-1}
无论您使用哪种方法,您都需要为每个频率使用一个或两个这些振荡器,或者使用另一个触发标识来获得更高或更低的频率.
总结以上是内存溢出为你收集整理的c – 快速等效于STK中引用的DSP的sin()全部内容,希望文章能够帮你解决c – 快速等效于STK中引用的DSP的sin()所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)