Created
January 12, 2018 22:22
-
-
Save lynn/616f73663879fefc514d9a5da1800b8c to your computer and use it in GitHub Desktop.
very simple FM synthesis!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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