Я делаю простой грубый синтез с ограниченным диапазоном, суммируя гармоники. Я скопировал формулы из Википедии, но не было никакой информации, как получить максимальное число гармоник. Может кто-нибудь дать мне формулу?
Вот что я придумала для интуиции:
Пульсовая волна:
numharmonics = samplerate / 2.0 / frequency;
float sample = dutycycle;
// Precomputing 2 * Pi * (phase - duty / 2).
// It is used inside cos() a lot.
float precompute1 = (phase - dutycycle / 2.0) * 2.0 * M_PI;
for (std::size_t i = 1; i <= numharmonics; ++i)
{
float harmonic = 2.0 / (i * M_PI) *
std::sin(M_PI * i * dutycycle) *
std::cos(i * precompute1);
sample += harmonic;
}
sample = sample * 2.0 - 1.0;
phase += phasedelta;
return sample;
Волна треугольника:
numharmonics = (samplerate / 2.0 / frequency - 1.0) / 2.0;
float sample = 0.0;
// Precomputing 2 * Pi * phase. It is used inside sin() a lot.
float precompute1 = 2.0 * M_PI * phase;
for (std::size_t i = 0; i <= numharmonics; ++i)
{
float harmonic = std::sin((2 * i + 1) * precompute1) /
std::pow((2 * i + 1), 2);
if ((i % 2) == 0)
{
sample += harmonic;
}
else
{
sample -= harmonic;
}
}
sample = sample * 8.0 / std::pow(M_PI, 2);
phase += phasedelta;
return sample;
Пилообразная волна:
numharmonics = samplerate / 2.0 / frequency;
float sample = 0.0;
// Precomputing 2 * Pi * phase. It is used inside sin() a lot.
float precompute1 = 2.0 * M_PI * phase;
for (std::size_t i = 1; i <= numharmonics; ++i)
{
float harmonic = std::sin(precompute1 * i) / i;
if ((i % 2) == 1)
{
sample += harmonic;
}
else
{
sample -= harmonic;
}
}
sample = -1.0 / M_PI * sample;
phase += phasedelta;
return sample;
Задача ещё не решена.
Других решений пока нет …