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 }