1 module pxtone.pulse.oscillator; 2 3 import pxtone.pxtn; 4 5 import std.math; 6 7 struct pxtnPulse_Oscillator { 8 private: 9 pxtnPOINT[] _p_point = null; 10 int _point_num = 0; 11 int _point_reso = 0; 12 int _volume = 0; 13 int _sample_num = 0; 14 15 public: 16 void ReadyGetSample(pxtnPOINT[] p_point, int point_num, int volume, int sample_num, int point_reso) nothrow @safe { 17 _volume = volume; 18 _p_point = p_point; 19 _sample_num = sample_num; 20 _point_num = point_num; 21 _point_reso = point_reso; 22 } 23 24 double GetOneSample_Overtone(int index) nothrow @safe { 25 int o; 26 double work_double; 27 double pi = 3.1415926535897932; 28 double sss; 29 30 work_double = 0; 31 for (o = 0; o < _point_num; o++) { 32 sss = 2 * pi * (_p_point[o].x) * index / _sample_num; 33 work_double += (sin(sss) * cast(double) _p_point[o].y / (_p_point[o].x) / 128); 34 } 35 work_double = work_double * _volume / 128; 36 37 return work_double; 38 } 39 40 double GetOneSample_Coodinate(int index) nothrow @safe { 41 int i; 42 int c; 43 int x1, y1, x2, y2; 44 int w, h; 45 double work; 46 47 i = _point_reso * index / _sample_num; 48 49 // find target 2 ponits 50 c = 0; 51 while (c < _point_num) { 52 if (_p_point[c].x > i) { 53 break; 54 } 55 c++; 56 } 57 58 //末端 59 if (c == _point_num) { 60 x1 = _p_point[c - 1].x; 61 y1 = _p_point[c - 1].y; 62 x2 = _point_reso; 63 y2 = _p_point[0].y; 64 } else { 65 if (c) { 66 x1 = _p_point[c - 1].x; 67 y1 = _p_point[c - 1].y; 68 x2 = _p_point[c].x; 69 y2 = _p_point[c].y; 70 } else { 71 x1 = _p_point[0].x; 72 y1 = _p_point[0].y; 73 x2 = _p_point[0].x; 74 y2 = _p_point[0].y; 75 } 76 } 77 78 w = x2 - x1; 79 i = i - x1; 80 h = y2 - y1; 81 82 if (i) { 83 work = cast(double) y1 + cast(double) h * cast(double) i / cast(double) w; 84 } else { 85 work = y1; 86 } 87 88 return work * _volume / 128 / 128; 89 90 } 91 }