Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
716 | lvd | 1 | #include "std.h" |
2 | |||
3 | #include "emul.h" |
||
4 | #include "vars.h" |
||
5 | #include "gs.h" |
||
6 | #include "tape.h" |
||
7 | #include "config.h" |
||
8 | |||
9 | #include "sndrender/sndcounter.h" |
||
10 | |||
11 | extern SNDRENDER sound; |
||
12 | extern SNDCHIP ay[2]; |
||
13 | extern SNDCOUNTER sndcounter; |
||
14 | |||
15 | int spkr_dig = 0, mic_dig = 0, covFB_vol = 0, covDD_vol = 0, sd_l = 0, sd_r = 0; |
||
16 | |||
17 | void flush_dig_snd() |
||
18 | { |
||
19 | // __debugbreak(); |
||
20 | if (temp.sndblock) |
||
21 | return; |
||
22 | unsigned mono = (spkr_dig+mic_dig+covFB_vol+covDD_vol); |
||
23 | // printf("mono=%u\n", mono); |
||
24 | //[vv] |
||
25 | sound.update(cpu.t - temp.cpu_t_at_frame_start, mono + sd_l, mono + sd_r); |
||
26 | } |
||
27 | |||
28 | void init_snd_frame() |
||
29 | { |
||
30 | temp.cpu_t_at_frame_start = cpu.t; |
||
31 | //[vv] |
||
32 | sound.start_frame(); |
||
33 | // comp.tape.sound.start_frame(); //Alone Coder |
||
34 | comp.tape_sound.start_frame(); //Alone Coder |
||
35 | |||
36 | if (conf.sound.ay_scheme) |
||
37 | { |
||
38 | ay[0].start_frame(); |
||
39 | if (conf.sound.ay_scheme > AY_SCHEME_SINGLE) |
||
40 | ay[1].start_frame(); |
||
41 | } |
||
42 | |||
43 | Saa1099.start_frame(); |
||
44 | |||
45 | #ifdef MOD_GS |
||
46 | init_gs_frame(); |
||
47 | #endif |
||
48 | } |
||
49 | |||
50 | float y_1[2] = { 0.0 }; |
||
51 | i16 x_1[2] = { 0 }; |
||
52 | |||
53 | void flush_snd_frame() |
||
54 | { |
||
55 | tape_bit(); |
||
56 | #ifdef MOD_GS |
||
57 | flush_gs_frame(); |
||
58 | #endif |
||
59 | |||
60 | if (temp.sndblock) |
||
61 | return; |
||
62 | |||
63 | unsigned endframe = cpu.t - temp.cpu_t_at_frame_start; |
||
64 | |||
65 | if (conf.sound.ay_scheme) |
||
66 | { // sound chip present |
||
67 | |||
68 | ay[0].end_frame(endframe); |
||
69 | // if (conf.sound.ay_samples) mix_dig(ay[0]); |
||
70 | |||
71 | if (conf.sound.ay_scheme > AY_SCHEME_SINGLE) |
||
72 | { |
||
73 | |||
74 | ay[1].end_frame(endframe); |
||
75 | // if (conf.sound.ay_samples) mix_dig(ay[1]); |
||
76 | |||
77 | if (conf.sound.ay_scheme == AY_SCHEME_PSEUDO) |
||
78 | { |
||
79 | unsigned char last = ay[0].get_r13_reloaded()? 13 : 12; |
||
80 | for (unsigned char r = 0; r <= last; r++) |
||
81 | ay[1].select(r), ay[1].write(0, ay[0].get_reg(r)); |
||
82 | } |
||
83 | } |
||
84 | |||
85 | if (savesndtype == 2) |
||
86 | { |
||
87 | if (!vtxbuf) |
||
88 | { |
||
89 | vtxbuf = (unsigned char*)malloc(32768); |
||
90 | vtxbufsize = 32768; |
||
91 | vtxbuffilled = 0; |
||
92 | } |
||
93 | |||
94 | if (vtxbuffilled + 14 >= vtxbufsize) |
||
95 | { |
||
96 | vtxbufsize += 32768; |
||
97 | vtxbuf = (unsigned char*)realloc(vtxbuf, vtxbufsize); |
||
98 | } |
||
99 | |||
100 | for (unsigned char r = 0; r < 14; r++) |
||
101 | vtxbuf[vtxbuffilled+r] = ay[0].get_reg(r); |
||
102 | |||
103 | if (!ay[0].get_r13_reloaded()) |
||
104 | vtxbuf[vtxbuffilled+13] = 0xFF; |
||
105 | |||
106 | vtxbuffilled += 14; |
||
107 | } |
||
108 | } |
||
109 | Saa1099.end_frame(endframe); |
||
110 | |||
111 | sound.end_frame(endframe); |
||
112 | // if (comp.tape.play_pointer) // play tape pulses |
||
113 | // comp.tape.sound.end_frame(endframe); //Alone Coder |
||
114 | comp.tape_sound.end_frame(endframe); //Alone Coder |
||
115 | // else comp.tape.sound.end_empty_frame(endframe); |
||
116 | |||
117 | unsigned bufplay, n_samples; |
||
118 | sndcounter.begin(); |
||
119 | |||
120 | sndcounter.count(sound); |
||
121 | // sndcounter.count(comp.tape.sound); //Alone Coder |
||
122 | sndcounter.count(comp.tape_sound); //Alone Coder |
||
123 | if (conf.sound.ay_scheme) |
||
124 | { |
||
125 | sndcounter.count(ay[0]); |
||
126 | if (conf.sound.ay_scheme > AY_SCHEME_SINGLE) |
||
127 | sndcounter.count(ay[1]); |
||
128 | } |
||
129 | |||
130 | sndcounter.count(Saa1099); |
||
131 | |||
132 | #ifdef MOD_GS |
||
133 | #ifdef MOD_GSZ80 |
||
134 | if (conf.gs_type==1) |
||
135 | sndcounter.count(z80gs::sound); |
||
136 | #endif |
||
137 | |||
138 | #ifdef MOD_GSBASS |
||
139 | // if (conf.gs_type==2) { gs.mix_fx(); return; } |
||
140 | #endif |
||
141 | #endif // MOD_GS |
||
142 | sndcounter.end(bufplay, n_samples); |
||
143 | |||
144 | for (unsigned k = 0; k < n_samples; k++, bufplay++) |
||
145 | { |
||
146 | u32 v = sndbuf[bufplay & (SNDBUFSIZE-1)]; |
||
147 | u32 Y; |
||
148 | if(conf.RejectDC) // DC rejection filter |
||
149 | { |
||
150 | i16 x[2]; |
||
151 | float y[2]; |
||
152 | x[0] = i16(v & 0xFFFF); |
||
153 | x[1] = i16(v >> 16U); |
||
154 | y[0] = 0.995f * (x[0] - x_1[0]) + 0.99f * y_1[0]; |
||
155 | y[1] = 0.995f * (x[1] - x_1[1]) + 0.99f * y_1[1]; |
||
156 | x_1[0] = x[0]; |
||
157 | x_1[1] = x[1]; |
||
158 | y_1[0] = y[0]; |
||
159 | y_1[1] = y[1]; |
||
160 | Y = ((i16(y[1]) & 0xFFFF)<<16) | (i16(y[0]) & 0xFFFF); |
||
161 | } |
||
162 | else |
||
163 | { |
||
164 | Y = v; |
||
165 | } |
||
166 | |||
167 | sndplaybuf[k] = Y; |
||
168 | sndbuf[bufplay & (SNDBUFSIZE-1)] = 0; |
||
169 | } |
||
170 | |||
171 | #if 0 |
||
172 | // printf("n_samples=%u\n", n_samples); |
||
173 | for (unsigned k = 0; k < n_samples; k++, bufplay++) |
||
174 | { |
||
175 | sndplaybuf[k] = sndbuf[bufplay & (SNDBUFSIZE-1)]; |
||
176 | /* |
||
177 | if(sndplaybuf[k] == 0x20002000) |
||
178 | __debugbreak(); |
||
179 | */ |
||
180 | sndbuf[bufplay & (SNDBUFSIZE-1)] = 0; |
||
181 | } |
||
182 | #endif |
||
183 | spbsize = n_samples*4; |
||
184 | // assert(spbsize != 0); |
||
185 | |||
186 | return; |
||
187 | |||
188 | /* |
||
189 | |||
190 | // count available samples and copy to sound buffer |
||
191 | unsigned save_ticks = temp.snd_frame_ticks; // sound output limit = 1 frame |
||
192 | save_ticks = min(save_ticks, sound.ready_samples()); |
||
193 | save_ticks = min(save_ticks, comp.ay->sound.ready_samples()); |
||
194 | save_ticks = min(save_ticks, comp.tape.sound.ready_samples()); |
||
195 | #ifdef MOD_GSZ80 |
||
196 | if (conf.gs_type == 1) |
||
197 | save_ticks = min(save_ticks, z80gs::sound.ready_samples()); |
||
198 | #endif |
||
199 | |||
200 | // fx player always gives enough samples |
||
201 | #ifdef MOD_GSBASS |
||
202 | if (conf.gs_type == 2) |
||
203 | for (int i = 0; i < 4; i++) |
||
204 | save_ticks = min(save_ticks, gs.chan[i].sound_state.ready_samples()); |
||
205 | #endif |
||
206 | */ |
||
207 | |||
208 | } |
||
209 | |||
210 | void restart_sound() |
||
211 | { |
||
212 | // printf("%s\n", __FUNCTION__); |
||
213 | |||
214 | unsigned cpufq = conf.intfq * conf.frame; |
||
215 | sound.set_timings(cpufq, conf.sound.fq); |
||
216 | // comp.tape.sound.set_timings(cpufq, conf.sound.fq); //Alone Coder |
||
217 | comp.tape_sound.set_timings(cpufq, conf.sound.fq); //Alone Coder |
||
218 | if (conf.sound.ay_scheme) |
||
219 | { |
||
220 | ay[0].set_timings(cpufq, conf.sound.ayfq, conf.sound.fq); |
||
221 | if (conf.sound.ay_scheme > AY_SCHEME_SINGLE) ay[1].set_timings(cpufq, conf.sound.ayfq, conf.sound.fq); |
||
222 | } |
||
223 | |||
224 | Saa1099.set_timings(cpufq, conf.sound.saa1099fq, conf.sound.fq); |
||
225 | |||
226 | // comp.tape.sound.clear(); |
||
227 | #ifdef MOD_GS |
||
228 | reset_gs_sound(); |
||
229 | #endif |
||
230 | |||
231 | sndcounter.reset(); |
||
232 | |||
233 | memset(sndbuf, 0, sizeof sndbuf); |
||
234 | } |
||
235 | |||
236 | void apply_sound() |
||
237 | { |
||
238 | if (conf.sound.ay_scheme < AY_SCHEME_QUADRO) comp.active_ay = 0; |
||
239 | |||
240 | load_ay_stereo(); |
||
241 | load_ay_vols(); |
||
242 | |||
243 | ay[0].set_chip((SNDCHIP::CHIP_TYPE)conf.sound.ay_chip); |
||
244 | ay[1].set_chip((SNDCHIP::CHIP_TYPE)conf.sound.ay_chip); |
||
245 | |||
246 | const SNDCHIP_VOLTAB *voltab = (SNDCHIP_VOLTAB*)&conf.sound.ay_voltab; |
||
247 | const SNDCHIP_PANTAB *stereo = (SNDCHIP_PANTAB*)&conf.sound.ay_stereo_tab; |
||
248 | ay[0].set_volumes(conf.sound.ay_vol, voltab, stereo); |
||
249 | |||
250 | SNDCHIP_PANTAB reversed; |
||
251 | if (conf.sound.ay_scheme == AY_SCHEME_PSEUDO) { |
||
252 | for (int i = 0; i < 6; i++) |
||
253 | reversed.raw[i] = stereo->raw[i^1]; // swap left/right |
||
254 | stereo = &reversed; |
||
255 | } |
||
256 | ay[1].set_volumes(conf.sound.ay_vol, voltab, stereo); |
||
257 | |||
258 | |||
259 | #ifdef MOD_GS |
||
260 | apply_gs(); |
||
261 | #endif |
||
262 | |||
263 | restart_sound(); |
||
264 | } |
||
265 | |||
266 | /* |
||
267 | #define SAMPLE_SIZE (1024*3) |
||
268 | #define SAMPLE_T 256 |
||
269 | int waveA[SAMPLE_SIZE], waveB[SAMPLE_SIZE], waveC[SAMPLE_SIZE]; |
||
270 | |||
271 | void mix_dig(SNDCHIP &chip) |
||
272 | { |
||
273 | unsigned base = sb_start_frame >> TICK_FF; |
||
274 | for (unsigned i = 0; i < temp.snd_frame_samples; i++) { |
||
275 | |||
276 | ta += fa; while (ta >= SAMPLE_SIZE*0x100) ta -= SAMPLE_SIZE*0x100; |
||
277 | tb += fb; while (tb >= SAMPLE_SIZE*0x100) tb -= SAMPLE_SIZE*0x100; |
||
278 | tc += fc; while (tc >= SAMPLE_SIZE*0x100) tc -= SAMPLE_SIZE*0x100; |
||
279 | tn += fn; |
||
280 | while (tn >= 0x10000) { |
||
281 | ns = (ns*2+1) ^ (((ns>>16)^(ns>>13)) & 1); |
||
282 | bitN = 0 - ((ns >> 16) & 1); |
||
283 | tn -= 0x10000; |
||
284 | } |
||
285 | te += fe; |
||
286 | while (te >= 0x10000) { |
||
287 | env += denv; |
||
288 | if (env & ~31) { |
||
289 | unsigned mask = 1 << r_env; |
||
290 | if (mask & ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<9)|(1<<15))) |
||
291 | env = denv = 0; |
||
292 | else if (mask & ((1<<8)|(1<<12))) |
||
293 | env &= 31; |
||
294 | else if (mask & ((1<<10)|(1<<14))) |
||
295 | denv = -(int)denv, env = env + denv; |
||
296 | else env = 31, denv = 0; //11,13 |
||
297 | } |
||
298 | te -= 0x10000; |
||
299 | } |
||
300 | |||
301 | unsigned left = 0, right = 0, en, vol; |
||
302 | |||
303 | en = (r_vA & 0x10) ? env : (r_vA & 0x0F)*2+1; |
||
304 | vol = (bitN | bit3) & (waveA[ta/0x100] | bit0) & 0xFFFF; |
||
305 | left += vol*vols[0][en], right += vol*vols[1][en]; |
||
306 | |||
307 | en = (r_vB & 0x10) ? env : (r_vB & 0x0F)*2+1; |
||
308 | vol = (bitN | bit4) & (waveB[tb/0x100] | bit1) & 0xFFFF; |
||
309 | left += vol*vols[2][en], right += vol*vols[3][en]; |
||
310 | |||
311 | en = (r_vC & 0x10) ? env : (r_vC & 0x0F)*2+1; |
||
312 | vol = (bitN | bit5) & (waveC[tc/0x100] | bit2) & 0xFFFF; |
||
313 | left += vol*vols[4][en], right += vol*vols[5][en]; |
||
314 | |||
315 | *(unsigned*)&sndbuf[(i+base) & (SNDBUFSIZE-1)] += (left >> 16) + (right & 0xFFFF0000); |
||
316 | } |
||
317 | sound.flush_empty(); |
||
318 | } |
||
319 | |||
320 | #define PI 3.14159265359 |
||
321 | |||
322 | double sin1(int i) { |
||
323 | while (i > SAMPLE_SIZE) i -= SAMPLE_SIZE; |
||
324 | if (i < SAMPLE_SIZE/2) return (double)i*2/SAMPLE_SIZE; |
||
325 | return 2-(double)i*2/SAMPLE_SIZE; |
||
326 | } |
||
327 | double cos1(int i) { |
||
328 | return 1-sin1(i); |
||
329 | } |
||
330 | |||
331 | int *wavs[3] = { waveA, waveB, waveC }; |
||
332 | void make_samples() |
||
333 | { |
||
334 | #define cl (0.35) |
||
335 | #define cl2 (0.25) |
||
336 | #define clip(x) (((x>cl) ? cl : (x < cl) ? -cl : x)/cl) |
||
337 | #define clip2(x) ((x < -cl2) ? 0 : (x+cl2)) |
||
338 | for (int i = 0; i < SAMPLE_SIZE; i++) { |
||
339 | double p1 = 0.8+0.2*sin1(i*4); |
||
340 | double p2 = 0.7+0.3*cos1(i*2); |
||
341 | double p3 = 0.9+0.1*sin1(i); |
||
342 | double t = (double)(i % SAMPLE_T)*2*PI/SAMPLE_T; |
||
343 | // #define fabs(x) (x) |
||
344 | waveA[i] = (unsigned)(fabs(p1*clip(1+sin(3*t/2))*0.7+p3*clip(sin(t))+p1*sin(4*t)*0.25+p2*clip2(cos(1+6*t)))*0x3FFF); |
||
345 | waveB[i] = (unsigned)(fabs(p1*clip(2+sin(3*t/2))*0.7+p3*clip(sin(t))+p1*sin(1+7*t/2)*0.4+p2*clip2(cos(2+5*t)))*0x3FFF); |
||
346 | waveC[i] = (unsigned)(fabs(p1*clip(0.5+sin(3*t/2))*0.7+p3*clip(sin(t))+p1*sin(0.2+9*t/2)*0.6+p2*clip2(cos(3+5*t)))*0x3FFF); |
||
347 | // #undef fabs |
||
348 | } |
||
349 | #undef clip |
||
350 | #undef cl |
||
351 | #undef cl2 |
||
352 | #undef clip2 |
||
353 | for (int ind = 0; ind < 3; ind++) { |
||
354 | int *arr = wavs[ind], max = -0x7FFFFFFF, min = 0x7FFFFFFF; |
||
355 | for (int i1 = 0; i1 < SAMPLE_SIZE; i1++) { |
||
356 | if (arr[i1] > max) max = arr[i1]; |
||
357 | if (arr[i1] < min) min = arr[i1]; |
||
358 | } |
||
359 | for (i1 = 0; i1 < SAMPLE_SIZE; i1++) |
||
360 | arr[i1] = (int)(((double)arr[i1] - min)*0x10000/(max-min)); |
||
361 | } |
||
362 | } |
||
363 | */ |