Skip to content

Instantly share code, notes, and snippets.

@lynn
Created January 12, 2018 22:22
Show Gist options
  • Save lynn/616f73663879fefc514d9a5da1800b8c to your computer and use it in GitHub Desktop.
Save lynn/616f73663879fefc514d9a5da1800b8c to your computer and use it in GitHub Desktop.
very simple FM synthesis!
// clang++ -std=c++14 fm.cc && ./a.out | aplay -r44 -f S16_LE
#include <cstdint>
#include <cmath>
#include <cstdio>
using s16 = std::int16_t; // signed 16-bit samples
const auto rate = 1.0 / 44000.0; // 44 kHz
const auto τ = 3.14159265 * 2;
s16 to_sample(double x) { return s16((x<-1?-1:x>1?1:x) * 0x7fff); }
double wave(double t) { // t in seconds
const auto ωc = 110.0; // carrier freq
const auto ωm = ωc * 4; // mod freq
const auto ω3 = ωc * 23; // op3 freq
const auto A = 0.5 * exp(-3 * t); // carrier amplitude
const auto β = 1.8 * exp(-2 * t); // mod amplitude
const auto γ = 0.3 * exp(-1 * t); // op3 amplitude
const auto φ = 1.5; // feedback
static double op3, opM, opC; // ┌───┐
op3 = sin(ω3*τ*t + φ*op3); // φ│ ┌───┐γ┌───┐β┌───┐A
opM = sin(ωm*τ*t + γ*op3); // └→│ 3 │→│ M │→│ C │→
opC = sin(ωc*τ*t + β*opM); // └───┘ └───┘ └───┘
return A*opC;
}
int main() {
for (int s = 0; rate * s < 2.0; s++) {
s16 sample = to_sample(wave(rate * s));
putchar(sample & 0xFF);
putchar(sample >> 8);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment