我正在使用向量化(仅SSE2 max作为SIMD)将一束谐波加在一起,每个谐波具有不同的相位/幅度。
这是我的实际尝试:
float output = 0.0f;
simd::float_4 freqFundamentalNormalized = freq * (1.0f / sampleRate);
simd::float_4 harmonicIndex{1.0f, 2.0f, 3.0f, 4.0f};
simd::float_4 harmonicIncrement{4.0f, 4.0f, 4.0f, 4.0f};
// harmonics
const int numHarmonicsV4 = numHarmonics / 4;
const int numHarmonicsRemainder = numHarmonics - (numHarmonicsV4 * 4);
// v4
for (int i = 0; i < numHarmonicsV4; i++) {
// signal
simd::float_4 sineOutput4 = simd::sin(mPhases4[i] * g2PIf) * mMagnitudes4[i];
for (int v = 0; v < 4; v++) {
output += sineOutput4[v];
}
// increments
mPhases4[i] += harmonicIndex * freqFundamentalNormalized;
mPhases4[i] -= simd::floor(mPhases4[i]);
harmonicIndex += harmonicIncrement;
}
// remainder
if (numHarmonicsRemainder > 0) {
// signal
simd::float_4 sineOutput4 = simd::sin(mPhases4[numHarmonicsV4] * g2PIf) * mMagnitudes4[numHarmonicsV4];
for (int v = 0; v < numHarmonicsRemainder; v++) {
output += sineOutput4[v];
}
// increments
mPhases4[numHarmonicsV4] += harmonicIndex * freqFundamentalNormalized;
mPhases4[numHarmonicsV4] -= simd::floor(mPhases4[numHarmonicsV4]);
}
但:
V4
,一次重复remainder
(如果谐波的数量不是%4):有没有办法在最后的V4放置某种“遮罩”(例如)幅度在0?(因此,它在同一块中执行相同的操作,但不会求和为最终输出)。问题的第二部分是最简单的。幅度为0的任何谐波都不会影响正弦输出,因此只需将其填充mMagnitude
为4的倍数即可。
正如Damien指出的那样,sin(x)
价格昂贵。但由Euler exp(x)=cos(x) + i sin(x)
,和exp(x+dx)==exp(x)*exp(dx)
。每个步骤只是一个复杂的乘法。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句