mirror of
https://codeberg.org/armin/monostep.git
synced 2026-09-01 04:10:46 +02:00
101 lines
2 KiB
C++
101 lines
2 KiB
C++
#pragma once
|
|
|
|
#include <cmath>
|
|
#include <algorithm>
|
|
#include <random>
|
|
|
|
namespace monostep
|
|
{
|
|
|
|
enum class Waveform : int
|
|
{
|
|
sine = 0,
|
|
triangle = 1,
|
|
saw = 2,
|
|
square = 3,
|
|
pulse = 4,
|
|
noise = 5,
|
|
sub = 6,
|
|
pluck = 7
|
|
};
|
|
|
|
inline float frac (float x)
|
|
{
|
|
return x - std::floor (x);
|
|
}
|
|
|
|
inline float polyBlep (float t, float dt)
|
|
{
|
|
if (t < dt)
|
|
{
|
|
t /= dt;
|
|
return t + t - t * t - 1.0f;
|
|
}
|
|
|
|
if (t > 1.0f - dt)
|
|
{
|
|
t = (t - 1.0f) / dt;
|
|
return t * t + t + t + 1.0f;
|
|
}
|
|
|
|
return 0.0f;
|
|
}
|
|
|
|
inline float renderWave (Waveform w, float phase, float inc)
|
|
{
|
|
switch (w)
|
|
{
|
|
case Waveform::sine:
|
|
return std::sin (phase * 6.283185307179586f);
|
|
|
|
case Waveform::triangle:
|
|
{
|
|
const float f = frac (phase);
|
|
return 4.0f * std::min (f, 1.0f - f) - 1.0f;
|
|
}
|
|
|
|
case Waveform::saw:
|
|
{
|
|
const float f = frac (phase);
|
|
return (2.0f * f - 1.0f) - polyBlep (f, inc);
|
|
}
|
|
|
|
case Waveform::square:
|
|
{
|
|
const float f = frac (phase);
|
|
float v = (f < 0.5f) ? 1.0f : -1.0f;
|
|
v += polyBlep (f, inc);
|
|
v -= polyBlep (frac (f + 0.5f), inc);
|
|
return v;
|
|
}
|
|
|
|
case Waveform::pulse:
|
|
{
|
|
const float f = frac (phase);
|
|
return (f < 0.3f) ? 1.0f : -1.0f;
|
|
}
|
|
|
|
case Waveform::sub:
|
|
{
|
|
const float f = frac (phase * 0.25f);
|
|
return 4.0f * std::min (f, 1.0f - f) - 1.0f;
|
|
}
|
|
|
|
case Waveform::noise:
|
|
{
|
|
thread_local static std::mt19937 rng { std::random_device {}() };
|
|
thread_local static std::uniform_real_distribution<float> dist (-1.0f, 1.0f);
|
|
return dist (rng);
|
|
}
|
|
|
|
case Waveform::pluck:
|
|
{
|
|
const float f = frac (phase);
|
|
return 2.0f * std::sin (f * 6.283185307179586f * 2.0f) * std::exp (-10.0f * f);
|
|
}
|
|
}
|
|
|
|
return 0.0f;
|
|
}
|
|
|
|
} // namespace monostep
|