BogaudioModules

BogaudioModules for VCV Rack
Log | Files | Refs | README | LICENSE

scatter.cpp (2519B)


      1 #include <stdlib.h>
      2 #include <stdio.h>
      3 #include <stdint.h>
      4 #include <string.h>
      5 #include <math.h>
      6 #include <cmath>
      7 #include <algorithm>
      8 
      9 struct Scatter {
     10 	virtual ~Scatter() {}
     11 	virtual bool next(float& x, float &y) = 0;
     12 };
     13 
     14 struct TestScatter : Scatter {
     15 	int i = 0;
     16 
     17 	bool next(float& x, float &y) override {
     18 		x = i;
     19 		y = i;
     20 		++i;
     21 		return i < 5;
     22 	}
     23 };
     24 
     25 struct ButterworthPoles : Scatter {
     26 	int k = 1;
     27 	int n;
     28 	bool conjugate = false;
     29 
     30 	ButterworthPoles(int n) : n(n) {}
     31 
     32 	bool next(float& x, float &y) override {
     33 		float a = ((float)(2 * k + n - 1)) * M_PI / (float)(2 * n);
     34 
     35 		x = std::cos(a);
     36 		y = std::sin(a);
     37 		if (conjugate) {
     38 			y = -y;
     39 		}
     40 		conjugate = !conjugate;
     41 		k += !conjugate;
     42 		return k <= n / 2;
     43 	}
     44 };
     45 
     46 struct ChebyshevPoles : Scatter {
     47 	int k = 1;
     48 	int n;
     49 	double ripple;
     50 	double e;
     51 	double ef;
     52 	bool conjugate = false;
     53 
     54 	ChebyshevPoles(int n, double ripple) : n(n), ripple(ripple) {
     55 		e = ripple / 10.0;
     56 		e = std::pow(10.0, e);
     57 		e -= 1.0f;
     58 		e = std::sqrt(e);
     59 
     60 		ef = std::asinh(1.0 / e) / (float)n;
     61 	}
     62 
     63 	bool next(float& x, float &y) override {
     64 		double a = ((double)(2 * k + n - 1)) * M_PI / (double)(2 * n);
     65 
     66 		x = -std::sinh(ef) * std::sin(a);
     67 		y = std::cosh(ef) * std::cos(a);
     68 		if (conjugate) {
     69 			y = -y;
     70 		}
     71 		conjugate = !conjugate;
     72 		k += !conjugate;
     73 		return k <= n / 2;
     74 	}
     75 };
     76 
     77 struct ChebyshevPoles2 : Scatter {
     78 	int k = 1;
     79 	int n;
     80 	double ripple;
     81 	double e;
     82 	double ef;
     83 
     84 	ChebyshevPoles2(int n, double ripple) : n(n), ripple(ripple) {
     85 		e = ripple / 10.0;
     86 		e = std::pow(10.0, e);
     87 		e -= 1.0f;
     88 		e = std::sqrt(e);
     89 
     90 		ef = std::asinh(1.0 / e) / (float)n;
     91 	}
     92 
     93 	bool next(float& x, float &y) override {
     94 		double a = (double)(2 * k - 1) * M_PI / (double)(2 * n);
     95 		x = -std::sinh(ef) * std::sin(a);
     96 		y = std::cosh(ef) * std::cos(a);
     97 		++k;
     98 		return k <= n;
     99 	}
    100 };
    101 
    102 struct ButterworthPoles2 : Scatter {
    103 	int k = 1;
    104 	int n;
    105 
    106 	ButterworthPoles2(int n) : n(n) {}
    107 
    108 	bool next(float& x, float &y) override {
    109 		float a = ((float)(2 * k + n - 1)) * M_PI / (float)(2 * n);
    110 
    111 		x = std::cos(a);
    112 		y = std::sin(a);
    113 		++k;
    114 		return k <= n;
    115 	}
    116 };
    117 
    118 int main() {
    119 	// std::unique_ptr<Scatter> s(new TestScatter());
    120 	// std::unique_ptr<Scatter> s(new ButterworthPoles(16));
    121 	// std::unique_ptr<Scatter> s(new ButterworthPoles2(7));
    122 	// std::unique_ptr<Scatter> s(new ChebyshevPoles(16, 0.01));
    123 	std::unique_ptr<Scatter> s(new ChebyshevPoles2(4, 3.0));
    124 
    125 	float x = 0.0f;
    126 	float y = 0.0f;
    127 	while (true) {
    128 		bool c = s->next(x, y);
    129 		printf("%f, %f\n", x, y);
    130 		if (!c) {
    131 			break;
    132 		}
    133 	}
    134 
    135 	return 0;
    136 }