I want to experiment with additive synthesis. So I quickly wrote some code that simply adds up a bunch of sine waves. Nothing else. The problem is even this is way to slow. I implemented the sine oscillators by simply multiplying complex numbers in the obvious way.
Is this the right direction? Should I just spend time to implement this with SSE and hope it gets fast enough or is there a bettwer way?
Code: Select all (#)
template<typename S>
class SinOscStack
{
std::vector<S> stateSin;
std::vector<S> stateCos;
std::vector<S> stepSin;
std::vector<S> stepCos;
S state1, state2;
S step1, step2;
unsigned harmonics;
public:
SinOscStack(S freq, unsigned harmonics, S samplerate)
: stateSin(harmonics)
, stateCos(harmonics)
, stepSin(harmonics)
, stepCos(harmonics)
, harmonics(harmonics)
{
static const double pi = 3.1415926535897932384626433832795;
for(unsigned i=0; i<harmonics; ++i)
{
stateSin[i] = 0;
stateCos[i] = 1;
stepCos[i] = std::cos((i+1) + pi*freq/samplerate);
stepSin[i] = std::sin((i+1) + pi*freq/samplerate);
}
}
void update(S * buffer1, S * buffer2, std::size_t length)
{
for (std::size_t i=0; i<length; ++i)
{
S sumCos = 0;
S sumSin = 0;
for (unsigned h=0; h<harmonics; ++h)
{
const S oldCos = stateCos[h];
const S oldSin = stateSin[h];
stateCos[h] = oldCos * stepCos[h] - oldSin * stepSin[h];
stateSin[h] = oldSin * stepCos[h] + oldCos * stepSin[h];
sumCos += stateCos[h];
sumSin += stateSin[h];
}
buffer1[i] = sumCos;
buffer2[i] = sumSin;
}
}
};