1 #include "cydosc.h"
2 #include "cyddefs.h"
3 #include "cyd.h"
4 
cyd_pulse(Uint32 acc,Uint32 pw)5 static inline Uint32 cyd_pulse(Uint32 acc, Uint32 pw)
6 {
7 	return (((acc >> ((ACC_BITS - 17))) >= (pw << 4) ? (WAVE_AMP - 1) : 0));
8 }
9 
10 
cyd_saw(Uint32 acc)11 static inline Uint32 cyd_saw(Uint32 acc)
12 {
13 	return (acc >> (ACC_BITS - OUTPUT_BITS - 1)) & (WAVE_AMP - 1);
14 }
15 
16 
cyd_triangle(Uint32 acc)17 static inline Uint32 cyd_triangle(Uint32 acc)
18 {
19 	return ((((acc & (ACC_LENGTH / 2)) ? ~acc : acc) >> (ACC_BITS - OUTPUT_BITS - 2)) & (WAVE_AMP * 2 - 1));
20 }
21 
22 
cyd_noise(Uint32 acc)23 static inline Uint32 cyd_noise(Uint32 acc)
24 {
25 	return acc & (WAVE_AMP - 1);
26 }
27 
28 #ifndef CYD_DISABLE_LFSR
cyd_lfsr(Uint32 bits)29 Uint32 cyd_lfsr(Uint32 bits)
30 {
31 	return bits;
32 }
33 #endif
34 
cyd_osc(Uint32 flags,Uint32 accumulator,Uint32 pw,Uint32 random,Uint32 lfsr_acc)35 Sint32 cyd_osc(Uint32 flags, Uint32 accumulator, Uint32 pw, Uint32 random, Uint32 lfsr_acc)
36 {
37 	switch (flags & WAVEFORMS & ~CYD_CHN_ENABLE_WAVE)
38 	{
39 		case CYD_CHN_ENABLE_PULSE:
40 		return cyd_pulse(accumulator, pw);
41 		break;
42 
43 		case CYD_CHN_ENABLE_SAW:
44 		return cyd_saw(accumulator);
45 		break;
46 
47 		case CYD_CHN_ENABLE_TRIANGLE:
48 		return cyd_triangle(accumulator);
49 		break;
50 
51 		case CYD_CHN_ENABLE_NOISE:
52 		return cyd_noise(random);
53 		break;
54 
55 		case CYD_CHN_ENABLE_TRIANGLE|CYD_CHN_ENABLE_PULSE:
56 		return cyd_pulse(accumulator, pw) & cyd_triangle(accumulator);
57 		break;
58 
59 		case CYD_CHN_ENABLE_SAW|CYD_CHN_ENABLE_PULSE:
60 		return cyd_saw(accumulator) & cyd_pulse(accumulator, pw);
61 		break;
62 
63 		case CYD_CHN_ENABLE_NOISE|CYD_CHN_ENABLE_PULSE:
64 		return cyd_noise(random) & cyd_pulse(accumulator, pw);
65 		break;
66 
67 		case CYD_CHN_ENABLE_TRIANGLE|CYD_CHN_ENABLE_SAW:
68 		return cyd_triangle(accumulator) & cyd_saw(accumulator);
69 		break;
70 
71 		case CYD_CHN_ENABLE_NOISE|CYD_CHN_ENABLE_SAW:
72 		return cyd_noise(random) & cyd_saw(accumulator);
73 		break;
74 
75 		case CYD_CHN_ENABLE_NOISE|CYD_CHN_ENABLE_TRIANGLE:
76 		return cyd_noise(random) & cyd_triangle(accumulator);
77 		break;
78 
79 		case CYD_CHN_ENABLE_TRIANGLE|CYD_CHN_ENABLE_PULSE|CYD_CHN_ENABLE_SAW:
80 		return cyd_pulse(accumulator, pw) & cyd_triangle(accumulator) & cyd_saw(accumulator);
81 		break;
82 
83 		case CYD_CHN_ENABLE_TRIANGLE|CYD_CHN_ENABLE_PULSE|CYD_CHN_ENABLE_NOISE:
84 		return cyd_pulse(accumulator, pw) & cyd_triangle(accumulator) & cyd_noise(random);
85 		break;
86 
87 		case CYD_CHN_ENABLE_TRIANGLE|CYD_CHN_ENABLE_NOISE|CYD_CHN_ENABLE_SAW:
88 		return cyd_saw(accumulator) & cyd_triangle(accumulator) & cyd_noise(random);
89 		break;
90 
91 		case CYD_CHN_ENABLE_PULSE|CYD_CHN_ENABLE_NOISE|CYD_CHN_ENABLE_SAW:
92 		return cyd_pulse(accumulator, pw) & cyd_saw(accumulator) & cyd_noise(random);
93 		break;
94 
95 		case CYD_CHN_ENABLE_NOISE|CYD_CHN_ENABLE_SAW|CYD_CHN_ENABLE_PULSE|CYD_CHN_ENABLE_TRIANGLE:
96 		return cyd_saw(accumulator) & cyd_pulse(accumulator, pw) & cyd_triangle(accumulator) & cyd_noise(random);
97 		break;
98 
99 #ifndef CYD_DISABLE_LFSR
100 		case CYD_CHN_ENABLE_LFSR:
101 		return cyd_lfsr(lfsr_acc);
102 		break;
103 
104 		case CYD_CHN_ENABLE_PULSE|CYD_CHN_ENABLE_LFSR:
105 		return cyd_pulse(accumulator, pw) & cyd_lfsr(lfsr_acc);
106 		break;
107 
108 		case CYD_CHN_ENABLE_SAW|CYD_CHN_ENABLE_LFSR:
109 		return cyd_saw(accumulator) & cyd_lfsr(lfsr_acc);
110 		break;
111 
112 		case CYD_CHN_ENABLE_TRIANGLE|CYD_CHN_ENABLE_LFSR:
113 		return cyd_triangle(accumulator) & cyd_lfsr(lfsr_acc);
114 		break;
115 
116 		case CYD_CHN_ENABLE_NOISE|CYD_CHN_ENABLE_LFSR:
117 		return cyd_noise(random) & cyd_lfsr(lfsr_acc);
118 		break;
119 
120 		case CYD_CHN_ENABLE_TRIANGLE|CYD_CHN_ENABLE_PULSE|CYD_CHN_ENABLE_LFSR:
121 		return cyd_pulse(accumulator, pw) & cyd_triangle(accumulator) & cyd_lfsr(lfsr_acc);
122 		break;
123 
124 		case CYD_CHN_ENABLE_SAW|CYD_CHN_ENABLE_PULSE|CYD_CHN_ENABLE_LFSR:
125 		return cyd_saw(accumulator) & cyd_pulse(accumulator, pw) & cyd_lfsr(lfsr_acc);
126 		break;
127 
128 		case CYD_CHN_ENABLE_NOISE|CYD_CHN_ENABLE_PULSE|CYD_CHN_ENABLE_LFSR:
129 		return cyd_noise(random) & cyd_pulse(accumulator, pw) & cyd_lfsr(lfsr_acc);
130 		break;
131 
132 		case CYD_CHN_ENABLE_TRIANGLE|CYD_CHN_ENABLE_SAW|CYD_CHN_ENABLE_LFSR:
133 		return cyd_triangle(accumulator) & cyd_saw(accumulator) & cyd_lfsr(lfsr_acc);
134 		break;
135 
136 		case CYD_CHN_ENABLE_NOISE|CYD_CHN_ENABLE_SAW|CYD_CHN_ENABLE_LFSR:
137 		return cyd_noise(random) & cyd_saw(accumulator) & cyd_lfsr(lfsr_acc);
138 		break;
139 
140 		case CYD_CHN_ENABLE_NOISE|CYD_CHN_ENABLE_TRIANGLE|CYD_CHN_ENABLE_LFSR:
141 		return cyd_noise(random) & cyd_triangle(accumulator) & cyd_lfsr(lfsr_acc);
142 		break;
143 
144 		case CYD_CHN_ENABLE_TRIANGLE|CYD_CHN_ENABLE_PULSE|CYD_CHN_ENABLE_SAW|CYD_CHN_ENABLE_LFSR:
145 		return cyd_pulse(accumulator, pw) & cyd_triangle(accumulator) & cyd_saw(accumulator) & cyd_lfsr(lfsr_acc);
146 		break;
147 
148 		case CYD_CHN_ENABLE_TRIANGLE|CYD_CHN_ENABLE_PULSE|CYD_CHN_ENABLE_NOISE|CYD_CHN_ENABLE_LFSR:
149 		return cyd_pulse(accumulator, pw) & cyd_triangle(accumulator) & cyd_noise(random) & cyd_lfsr(lfsr_acc);
150 		break;
151 
152 		case CYD_CHN_ENABLE_TRIANGLE|CYD_CHN_ENABLE_NOISE|CYD_CHN_ENABLE_SAW|CYD_CHN_ENABLE_LFSR:
153 		return cyd_saw(accumulator) & cyd_triangle(accumulator) & cyd_noise(random) & cyd_lfsr(lfsr_acc);
154 		break;
155 
156 		case CYD_CHN_ENABLE_PULSE|CYD_CHN_ENABLE_NOISE|CYD_CHN_ENABLE_SAW|CYD_CHN_ENABLE_LFSR:
157 		return cyd_pulse(accumulator, pw) & cyd_saw(accumulator) & cyd_noise(random) & cyd_lfsr(lfsr_acc);
158 		break;
159 
160 		case CYD_CHN_ENABLE_NOISE|CYD_CHN_ENABLE_SAW|CYD_CHN_ENABLE_PULSE|CYD_CHN_ENABLE_TRIANGLE|CYD_CHN_ENABLE_LFSR:
161 		return cyd_saw(accumulator) & cyd_pulse(accumulator, pw) & cyd_triangle(accumulator) & cyd_noise(random) & cyd_lfsr(lfsr_acc);
162 		break;
163 #endif
164 		default:
165 		return WAVE_AMP / 2;
166 		break;
167 	}
168 }
169