|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * OS specific functions
5: *
6: * Copyright 1995, 1996, 1997 Bernd Schmidt
7: * Copyright 1996 Marcus Sundberg
8: * Copyright 1996 Manfred Thole
9: */
10:
11: #include "sysconfig.h"
12: #include "sysdeps.h"
13:
14: #include "config.h"
15: #include "options.h"
16: #include "memory.h"
17: #include "custom.h"
1.1.1.7 root 18: #include "newcpu.h"
19: #include "autoconf.h"
1.1 root 20: #include "gensound.h"
21: #include "sounddep/sound.h"
22: #include "events.h"
23: #include "audio.h"
1.1.1.8 root 24: #include "savestate.h"
1.1 root 25:
1.1.1.13 root 26: struct audio_channel_data audio_channel[4];
1.1.1.2 root 27: int sound_available = 0;
1.1 root 28: int sound_table[64][256];
1.1.1.2 root 29: void (*sample_handler) (void);
1.1.1.7 root 30:
31: unsigned long sample_evtime, scaled_sample_evtime;
32: int scaled_sample_evtime_ok;
33:
1.1.1.2 root 34: static unsigned long last_cycles, next_sample_evtime;
1.1 root 35:
1.1.1.2 root 36: void init_sound_table16 (void)
1.1 root 37: {
38: int i,j;
39:
40: for (i = 0; i < 256; i++)
41: for (j = 0; j < 64; j++)
1.1.1.13 root 42: sound_table[j][i] = j * (uae_s8)i * (currprefs.sound_stereo ? 2 : 1);
1.1 root 43: }
44:
45: void init_sound_table8 (void)
46: {
47: int i,j;
48:
49: for (i = 0; i < 256; i++)
50: for (j = 0; j < 64; j++)
1.1.1.13 root 51: sound_table[j][i] = (j * (uae_s8)i * (currprefs.sound_stereo ? 2 : 1)) / 256;
1.1 root 52: }
53:
54: #define MULTIPLICATION_PROFITABLE
55:
56: #ifdef MULTIPLICATION_PROFITABLE
57: typedef uae_s8 sample8_t;
58: #define DO_CHANNEL_1(v, c) do { (v) *= audio_channel[c].vol; } while (0)
59: #define SBASEVAL8(logn) ((logn) == 1 ? SOUND8_BASE_VAL << 7 : SOUND8_BASE_VAL << 8)
60: #define SBASEVAL16(logn) ((logn) == 1 ? SOUND16_BASE_VAL >> 1 : SOUND16_BASE_VAL)
1.1.1.7 root 61: #define FINISH_DATA(data,b,logn) do { if (14 - (b) + (logn) > 0) (data) >>= 14 - (b) + (logn); else (data) <<= (b) - 14 - (logn); } while (0);
1.1 root 62: #else
63: typedef uae_u8 sample8_t;
64: #define DO_CHANNEL_1(v, c) do { (v) = audio_channel[c].voltbl[(v)]; } while (0)
65: #define SBASEVAL8(logn) SOUND8_BASE_VAL
66: #define SBASEVAL16(logn) SOUND16_BASE_VAL
67: #define FINISH_DATA(b,logn)
68: #endif
69:
1.1.1.7 root 70: /* Always put the right word before the left word. */
71: #define DELAY_BUFFER 32
72: static uae_u32 right_word_saved[DELAY_BUFFER];
73: static uae_u32 left_word_saved[DELAY_BUFFER];
74: static int saved_ptr;
1.1 root 75:
1.1.1.7 root 76: STATIC_INLINE void put_sound_word_right (uae_u32 w)
1.1 root 77: {
1.1.1.7 root 78: if (currprefs.mixed_stereo) {
79: right_word_saved[saved_ptr] = w;
80: return;
1.1 root 81: }
82:
1.1.1.7 root 83: PUT_SOUND_WORD_RIGHT (w);
1.1 root 84: }
85:
1.1.1.7 root 86: STATIC_INLINE void put_sound_word_left (uae_u32 w)
1.1.1.5 root 87: {
1.1.1.7 root 88: if (currprefs.mixed_stereo) {
89: uae_u32 rold, lold, rnew, lnew, tmp;
1.1.1.5 root 90:
1.1.1.7 root 91: left_word_saved[saved_ptr] = w;
92: lnew = w - SOUND16_BASE_VAL;
93: rnew = right_word_saved[saved_ptr] - SOUND16_BASE_VAL;
1.1.1.5 root 94:
1.1.1.7 root 95: saved_ptr = (saved_ptr + 1) & (DELAY_BUFFER - 1);
96: lold = left_word_saved[saved_ptr] - SOUND16_BASE_VAL;
97: tmp = (rnew * 5 + lold * 3) >> 3;
98: tmp += SOUND16_BASE_VAL;
99: PUT_SOUND_WORD_RIGHT (tmp);
1.1.1.5 root 100:
1.1.1.7 root 101: rold = right_word_saved[saved_ptr] - SOUND16_BASE_VAL;
102: w = (lnew * 5 + rold * 3) >> 3;
103: }
104: PUT_SOUND_WORD_LEFT (w);
105: }
1.1.1.5 root 106:
1.1.1.7 root 107: #define DO_CHANNEL(v, c) do { (v) &= audio_channel[c].adk_mask; data += v; } while (0);
1.1.1.5 root 108:
1.1.1.7 root 109: void sample16_handler (void)
110: {
1.1.1.13 root 111: uae_u32 data0 = audio_channel[0].current_sample;
112: uae_u32 data1 = audio_channel[1].current_sample;
113: uae_u32 data2 = audio_channel[2].current_sample;
114: uae_u32 data3 = audio_channel[3].current_sample;
115: DO_CHANNEL_1 (data0, 0);
116: DO_CHANNEL_1 (data1, 1);
117: DO_CHANNEL_1 (data2, 2);
118: DO_CHANNEL_1 (data3, 3);
119: data0 &= audio_channel[0].adk_mask;
120: data1 &= audio_channel[1].adk_mask;
121: data2 &= audio_channel[2].adk_mask;
122: data3 &= audio_channel[3].adk_mask;
123: data0 += data1;
124: data0 += data2;
125: data0 += data3;
126: {
127: uae_u32 data = SBASEVAL16(2) + data0;
128: FINISH_DATA (data, 16, 2);
129: PUT_SOUND_WORD (data);
1.1.1.5 root 130: }
131: check_sound_buffers ();
132: }
133:
1.1.1.7 root 134: void sample16i_rh_handler (void)
1.1.1.6 root 135: {
1.1.1.13 root 136: unsigned long delta, ratio;
137:
138: uae_u32 data0 = audio_channel[0].current_sample;
139: uae_u32 data1 = audio_channel[1].current_sample;
140: uae_u32 data2 = audio_channel[2].current_sample;
141: uae_u32 data3 = audio_channel[3].current_sample;
142: uae_u32 data0p = audio_channel[0].last_sample;
143: uae_u32 data1p = audio_channel[1].last_sample;
144: uae_u32 data2p = audio_channel[2].last_sample;
145: uae_u32 data3p = audio_channel[3].last_sample;
146: DO_CHANNEL_1 (data0, 0);
147: DO_CHANNEL_1 (data1, 1);
148: DO_CHANNEL_1 (data2, 2);
149: DO_CHANNEL_1 (data3, 3);
150: DO_CHANNEL_1 (data0p, 0);
151: DO_CHANNEL_1 (data1p, 1);
152: DO_CHANNEL_1 (data2p, 2);
153: DO_CHANNEL_1 (data3p, 3);
1.1.1.6 root 154:
1.1.1.13 root 155: data0 &= audio_channel[0].adk_mask;
156: data0p &= audio_channel[0].adk_mask;
157: data1 &= audio_channel[1].adk_mask;
158: data1p &= audio_channel[1].adk_mask;
159: data2 &= audio_channel[2].adk_mask;
160: data2p &= audio_channel[2].adk_mask;
161: data3 &= audio_channel[3].adk_mask;
162: data3p &= audio_channel[3].adk_mask;
1.1.1.6 root 163:
1.1.1.13 root 164: /* linear interpolation and summing up... */
165: delta = audio_channel[0].per;
166: ratio = ((audio_channel[0].evtime % delta) << 8) / delta;
167: data0 = (data0 * (256 - ratio) + data0p * ratio) >> 8;
168: delta = audio_channel[1].per;
169: ratio = ((audio_channel[1].evtime % delta) << 8) / delta;
170: data0 += (data1 * (256 - ratio) + data1p * ratio) >> 8;
171: delta = audio_channel[2].per;
172: ratio = ((audio_channel[2].evtime % delta) << 8) / delta;
173: data0 += (data2 * (256 - ratio) + data2p * ratio) >> 8;
174: delta = audio_channel[3].per;
175: ratio = ((audio_channel[3].evtime % delta) << 8) / delta;
176: data0 += (data3 * (256 - ratio) + data3p * ratio) >> 8;
1.1.1.6 root 177:
1.1.1.13 root 178: {
179: uae_u32 data = SBASEVAL16(2) + data0;
180: FINISH_DATA (data, 16, 2);
181: PUT_SOUND_WORD (data);
1.1.1.6 root 182: }
1.1.1.13 root 183:
184: check_sound_buffers ();
1.1.1.7 root 185: }
1.1.1.6 root 186:
1.1.1.7 root 187: void sample16i_crux_handler (void)
188: {
1.1.1.13 root 189: uae_u32 data0 = audio_channel[0].current_sample;
190: uae_u32 data1 = audio_channel[1].current_sample;
191: uae_u32 data2 = audio_channel[2].current_sample;
192: uae_u32 data3 = audio_channel[3].current_sample;
193: uae_u32 data0p = audio_channel[0].last_sample;
194: uae_u32 data1p = audio_channel[1].last_sample;
195: uae_u32 data2p = audio_channel[2].last_sample;
196: uae_u32 data3p = audio_channel[3].last_sample;
197: DO_CHANNEL_1 (data0, 0);
198: DO_CHANNEL_1 (data1, 1);
199: DO_CHANNEL_1 (data2, 2);
200: DO_CHANNEL_1 (data3, 3);
201: DO_CHANNEL_1 (data0p, 0);
202: DO_CHANNEL_1 (data1p, 1);
203: DO_CHANNEL_1 (data2p, 2);
204: DO_CHANNEL_1 (data3p, 3);
205:
206: data0 &= audio_channel[0].adk_mask;
207: data0p &= audio_channel[0].adk_mask;
208: data1 &= audio_channel[1].adk_mask;
209: data1p &= audio_channel[1].adk_mask;
210: data2 &= audio_channel[2].adk_mask;
211: data2p &= audio_channel[2].adk_mask;
212: data3 &= audio_channel[3].adk_mask;
213: data3p &= audio_channel[3].adk_mask;
214:
1.1.1.15! root 215: {
1.1.1.13 root 216: struct audio_channel_data *cdp;
217: unsigned long ratio, ratio1;
1.1.1.7 root 218: #define INTERVAL (scaled_sample_evtime * 3)
1.1.1.13 root 219: cdp = audio_channel + 0;
220: ratio1 = cdp->per - cdp->evtime;
221: ratio = (ratio1 << 12) / INTERVAL;
222: if (cdp->evtime < scaled_sample_evtime || ratio1 >= INTERVAL)
223: ratio = 4096;
224: data0 = (data0 * ratio + data0p * (4096 - ratio)) >> 12;
225:
226: cdp = audio_channel + 1;
227: ratio1 = cdp->per - cdp->evtime;
228: ratio = (ratio1 << 12) / INTERVAL;
229: if (cdp->evtime < scaled_sample_evtime || ratio1 >= INTERVAL)
230: ratio = 4096;
231: data1 = (data1 * ratio + data1p * (4096 - ratio)) >> 12;
232:
233: cdp = audio_channel + 2;
234: ratio1 = cdp->per - cdp->evtime;
235: ratio = (ratio1 << 12) / INTERVAL;
236: if (cdp->evtime < scaled_sample_evtime || ratio1 >= INTERVAL)
237: ratio = 4096;
238: data2 = (data2 * ratio + data2p * (4096 - ratio)) >> 12;
239:
240: cdp = audio_channel + 3;
241: ratio1 = cdp->per - cdp->evtime;
242: ratio = (ratio1 << 12) / INTERVAL;
243: if (cdp->evtime < scaled_sample_evtime || ratio1 >= INTERVAL)
244: ratio = 4096;
245: data3 = (data3 * ratio + data3p * (4096 - ratio)) >> 12;
246: }
247: data1 += data2;
248: data0 += data3;
249: data0 += data1;
250: {
251: uae_u32 data = SBASEVAL16(2) + data0;
252: FINISH_DATA (data, 16, 2);
253: PUT_SOUND_WORD (data);
1.1.1.7 root 254: }
1.1.1.6 root 255: check_sound_buffers ();
256: }
257:
1.1.1.2 root 258: void sample8_handler (void)
1.1 root 259: {
260: uae_u32 data0 = audio_channel[0].current_sample;
261: uae_u32 data1 = audio_channel[1].current_sample;
262: uae_u32 data2 = audio_channel[2].current_sample;
263: uae_u32 data3 = audio_channel[3].current_sample;
264: DO_CHANNEL_1 (data0, 0);
265: DO_CHANNEL_1 (data1, 1);
266: DO_CHANNEL_1 (data2, 2);
267: DO_CHANNEL_1 (data3, 3);
268: data0 &= audio_channel[0].adk_mask;
269: data1 &= audio_channel[1].adk_mask;
270: data2 &= audio_channel[2].adk_mask;
271: data3 &= audio_channel[3].adk_mask;
272: data0 += data1;
273: data0 += data2;
274: data0 += data3;
275: {
276: uae_u32 data = SBASEVAL8(2) + data0;
1.1.1.7 root 277: FINISH_DATA (data, 8, 2);
1.1 root 278: PUT_SOUND_BYTE (data);
279: }
280:
281: check_sound_buffers ();
282: }
283:
284: #ifdef HAVE_STEREO_SUPPORT
1.1.1.2 root 285: void sample16s_handler (void)
1.1 root 286: {
1.1.1.13 root 287: uae_u32 data0 = audio_channel[0].current_sample;
288: uae_u32 data1 = audio_channel[1].current_sample;
289: uae_u32 data2 = audio_channel[2].current_sample;
290: uae_u32 data3 = audio_channel[3].current_sample;
291: DO_CHANNEL_1 (data0, 0);
292: DO_CHANNEL_1 (data1, 1);
293: DO_CHANNEL_1 (data2, 2);
294: DO_CHANNEL_1 (data3, 3);
295:
296: data0 &= audio_channel[0].adk_mask;
297: data1 &= audio_channel[1].adk_mask;
298: data2 &= audio_channel[2].adk_mask;
299: data3 &= audio_channel[3].adk_mask;
1.1.1.15! root 300:
1.1.1.13 root 301: data0 += data3;
302: {
303: uae_u32 data = SBASEVAL16(1) + data0;
304: FINISH_DATA (data, 16, 1);
305: put_sound_word_right (data);
306: }
1.1 root 307:
1.1.1.13 root 308: data1 += data2;
309: {
1.1.1.15! root 310: uae_u32 data = SBASEVAL16(1) + data1;
1.1.1.13 root 311: FINISH_DATA (data, 16, 1);
312: put_sound_word_left (data);
1.1 root 313: }
1.1.1.7 root 314:
1.1 root 315: check_sound_buffers ();
316: }
317:
1.1.1.6 root 318: void sample16si_crux_handler (void)
1.1.1.5 root 319: {
1.1.1.13 root 320: uae_u32 data0 = audio_channel[0].current_sample;
321: uae_u32 data1 = audio_channel[1].current_sample;
322: uae_u32 data2 = audio_channel[2].current_sample;
323: uae_u32 data3 = audio_channel[3].current_sample;
324: uae_u32 data0p = audio_channel[0].last_sample;
325: uae_u32 data1p = audio_channel[1].last_sample;
326: uae_u32 data2p = audio_channel[2].last_sample;
327: uae_u32 data3p = audio_channel[3].last_sample;
328:
329: DO_CHANNEL_1 (data0, 0);
330: DO_CHANNEL_1 (data1, 1);
331: DO_CHANNEL_1 (data2, 2);
332: DO_CHANNEL_1 (data3, 3);
333: DO_CHANNEL_1 (data0p, 0);
334: DO_CHANNEL_1 (data1p, 1);
335: DO_CHANNEL_1 (data2p, 2);
336: DO_CHANNEL_1 (data3p, 3);
337:
338: data0 &= audio_channel[0].adk_mask;
339: data0p &= audio_channel[0].adk_mask;
340: data1 &= audio_channel[1].adk_mask;
341: data1p &= audio_channel[1].adk_mask;
342: data2 &= audio_channel[2].adk_mask;
343: data2p &= audio_channel[2].adk_mask;
344: data3 &= audio_channel[3].adk_mask;
345: data3p &= audio_channel[3].adk_mask;
346:
1.1.1.15! root 347: {
1.1.1.13 root 348: struct audio_channel_data *cdp;
349: unsigned long ratio, ratio1;
1.1.1.7 root 350: #define INTERVAL (scaled_sample_evtime * 3)
1.1.1.13 root 351: cdp = audio_channel + 0;
352: ratio1 = cdp->per - cdp->evtime;
353: ratio = (ratio1 << 12) / INTERVAL;
354: if (cdp->evtime < scaled_sample_evtime || ratio1 >= INTERVAL)
355: ratio = 4096;
356: data0 = (data0 * ratio + data0p * (4096 - ratio)) >> 12;
357:
358: cdp = audio_channel + 1;
359: ratio1 = cdp->per - cdp->evtime;
360: ratio = (ratio1 << 12) / INTERVAL;
361: if (cdp->evtime < scaled_sample_evtime || ratio1 >= INTERVAL)
362: ratio = 4096;
363: data1 = (data1 * ratio + data1p * (4096 - ratio)) >> 12;
364:
365: cdp = audio_channel + 2;
366: ratio1 = cdp->per - cdp->evtime;
367: ratio = (ratio1 << 12) / INTERVAL;
368: if (cdp->evtime < scaled_sample_evtime || ratio1 >= INTERVAL)
369: ratio = 4096;
370: data2 = (data2 * ratio + data2p * (4096 - ratio)) >> 12;
371:
372: cdp = audio_channel + 3;
373: ratio1 = cdp->per - cdp->evtime;
374: ratio = (ratio1 << 12) / INTERVAL;
375: if (cdp->evtime < scaled_sample_evtime || ratio1 >= INTERVAL)
376: ratio = 4096;
377: data3 = (data3 * ratio + data3p * (4096 - ratio)) >> 12;
378: }
379: data1 += data2;
380: data0 += data3;
381: {
382: uae_u32 data = SBASEVAL16 (1) + data0;
383: FINISH_DATA (data, 16, 1);
384: put_sound_word_right (data);
385: }
1.1.1.6 root 386:
1.1.1.13 root 387: {
388: uae_u32 data = SBASEVAL16 (1) + data1;
389: FINISH_DATA (data, 16, 1);
390: put_sound_word_left (data);
391: }
1.1.1.6 root 392: check_sound_buffers ();
393: }
394:
395: void sample16si_rh_handler (void)
396: {
1.1.1.13 root 397: unsigned long delta, ratio;
1.1.1.6 root 398:
1.1.1.13 root 399: uae_u32 data0 = audio_channel[0].current_sample;
400: uae_u32 data1 = audio_channel[1].current_sample;
401: uae_u32 data2 = audio_channel[2].current_sample;
402: uae_u32 data3 = audio_channel[3].current_sample;
403: uae_u32 data0p = audio_channel[0].last_sample;
404: uae_u32 data1p = audio_channel[1].last_sample;
405: uae_u32 data2p = audio_channel[2].last_sample;
406: uae_u32 data3p = audio_channel[3].last_sample;
1.1.1.5 root 407:
1.1.1.13 root 408: DO_CHANNEL_1 (data0, 0);
409: DO_CHANNEL_1 (data1, 1);
410: DO_CHANNEL_1 (data2, 2);
411: DO_CHANNEL_1 (data3, 3);
412: DO_CHANNEL_1 (data0p, 0);
413: DO_CHANNEL_1 (data1p, 1);
414: DO_CHANNEL_1 (data2p, 2);
415: DO_CHANNEL_1 (data3p, 3);
416:
417: data0 &= audio_channel[0].adk_mask;
418: data0p &= audio_channel[0].adk_mask;
419: data1 &= audio_channel[1].adk_mask;
420: data1p &= audio_channel[1].adk_mask;
421: data2 &= audio_channel[2].adk_mask;
422: data2p &= audio_channel[2].adk_mask;
423: data3 &= audio_channel[3].adk_mask;
424: data3p &= audio_channel[3].adk_mask;
425:
426: /* linear interpolation and summing up... */
427: delta = audio_channel[0].per;
428: ratio = ((audio_channel[0].evtime % delta) << 8) / delta;
429: data0 = (data0 * (256 - ratio) + data0p * ratio) >> 8;
430: delta = audio_channel[1].per;
431: ratio = ((audio_channel[1].evtime % delta) << 8) / delta;
432: data1 = (data1 * (256 - ratio) + data1p * ratio) >> 8;
433: delta = audio_channel[2].per;
434: ratio = ((audio_channel[2].evtime % delta) << 8) / delta;
435: data1 += (data2 * (256 - ratio) + data2p * ratio) >> 8;
436: delta = audio_channel[3].per;
437: ratio = ((audio_channel[3].evtime % delta) << 8) / delta;
438: data0 += (data3 * (256 - ratio) + data3p * ratio) >> 8;
439: {
440: uae_u32 data = SBASEVAL16 (1) + data0;
441: FINISH_DATA (data, 16, 1);
442: put_sound_word_right (data);
443: }
444:
445: {
446: uae_u32 data = SBASEVAL16 (1) + data1;
447: FINISH_DATA (data, 16, 1);
448: put_sound_word_left (data);
449: }
1.1.1.5 root 450: check_sound_buffers ();
451: }
452:
1.1.1.2 root 453: void sample8s_handler (void)
1.1 root 454: {
455: uae_u32 data0 = audio_channel[0].current_sample;
456: uae_u32 data1 = audio_channel[1].current_sample;
457: uae_u32 data2 = audio_channel[2].current_sample;
458: uae_u32 data3 = audio_channel[3].current_sample;
459: DO_CHANNEL_1 (data0, 0);
460: DO_CHANNEL_1 (data1, 1);
461: DO_CHANNEL_1 (data2, 2);
462: DO_CHANNEL_1 (data3, 3);
463:
464: data0 &= audio_channel[0].adk_mask;
465: data1 &= audio_channel[1].adk_mask;
466: data2 &= audio_channel[2].adk_mask;
467: data3 &= audio_channel[3].adk_mask;
468:
469: data0 += data3;
470: {
471: uae_u32 data = SBASEVAL8(1) + data0;
1.1.1.7 root 472: FINISH_DATA (data, 8, 1);
1.1 root 473: PUT_SOUND_BYTE_RIGHT (data);
474: }
475: data1 += data2;
476: {
477: uae_u32 data = SBASEVAL8(1) + data1;
1.1.1.7 root 478: FINISH_DATA (data, 8, 1);
1.1 root 479: PUT_SOUND_BYTE_LEFT (data);
480: }
481:
482: check_sound_buffers ();
483: }
484: #else
1.1.1.2 root 485: void sample8s_handler (void)
1.1 root 486: {
487: sample8_handler();
488: }
1.1.1.2 root 489: void sample16s_handler (void)
1.1 root 490: {
491: sample16_handler();
492: }
1.1.1.6 root 493: void sample16si_crux_handler (void)
494: {
495: sample16i_crux_handler();
496: }
497: void sample16si_rh_handler (void)
498: {
499: sample16i_rh_handler();
500: }
1.1 root 501: #endif
502:
1.1.1.2 root 503: static uae_u8 int2ulaw (int ch)
1.1 root 504: {
505: int mask;
506:
507: if (ch < 0) {
508: ch = -ch;
509: mask = 0x7f;
510: }
511: else {
512: mask = 0xff;
513: }
514:
515: if (ch < 32) {
516: ch = 0xF0 | ( 15 - (ch/2) );
517: } else if (ch < 96) {
518: ch = 0xE0 | ( 15 - (ch-32)/4 );
519: } else if (ch < 224) {
520: ch = 0xD0 | ( 15 - (ch-96)/8 );
521: } else if (ch < 480) {
522: ch = 0xC0 | ( 15 - (ch-224)/16 );
523: } else if (ch < 992 ) {
524: ch = 0xB0 | ( 15 - (ch-480)/32 );
525: } else if (ch < 2016) {
526: ch = 0xA0 | ( 15 - (ch-992)/64 );
527: } else if (ch < 4064) {
528: ch = 0x90 | ( 15 - (ch-2016)/128 );
529: } else if (ch < 8160) {
530: ch = 0x80 | ( 15 - (ch-4064)/256 );
531: } else {
532: ch = 0x80;
533: }
534: return (uae_u8)(mask & ch);
535: }
536:
537: void sample_ulaw_handler (void)
538: {
539: int nr;
540: uae_u32 data = 0;
541:
542: for (nr = 0; nr < 4; nr++) {
543: if (!(adkcon & (0x11 << nr))) {
544: uae_u32 d = audio_channel[nr].current_sample;
545: DO_CHANNEL_1 (d, nr);
546: data += d;
547: }
548: }
549: PUT_SOUND_BYTE (int2ulaw (data));
550: check_sound_buffers ();
551: }
552:
1.1.1.7 root 553: void schedule_audio (void)
554: {
555: unsigned long best = ~0ul;
556: int i;
557:
558: eventtab[ev_audio].active = 0;
559: eventtab[ev_audio].oldcycles = get_cycles ();
560: for (i = 0; i < 6; i++) {
561: struct audio_channel_data *cdp = audio_channel + i;
562:
563: if (cdp->state != 0) {
564: if (best > cdp->evtime) {
565: best = cdp->evtime;
566: eventtab[ev_audio].active = 1;
567: }
1.1.1.15! root 568: }
1.1.1.7 root 569: }
570: eventtab[ev_audio].evtime = get_cycles () + best;
571: }
572:
1.1 root 573: static void audio_handler (int nr)
574: {
575: struct audio_channel_data *cdp = audio_channel + nr;
576:
577: switch (cdp->state) {
578: case 0:
1.1.1.11 root 579: write_log ("Bug in sound code\n");
1.1 root 580: break;
581:
582: case 1:
583: /* We come here at the first hsync after DMA was turned on. */
1.1.1.7 root 584: cdp->evtime = maxhpos * CYCLE_UNIT;
1.1 root 585:
586: cdp->state = 5;
587: INTREQ(0x8000 | (0x80 << nr));
588: if (cdp->wlen != 1)
1.1.1.9 root 589: cdp->wlen = (cdp->wlen - 1) & 0xFFFF;
1.1.1.10 root 590: cdp->nextdat = chipmem_wget (cdp->pt);
1.1 root 591:
592: cdp->pt += 2;
593: break;
594:
595: case 5:
596: /* We come here at the second hsync after DMA was turned on. */
597: if (currprefs.produce_sound == 0)
1.1.1.7 root 598: cdp->per = PERIOD_MAX;
1.1 root 599:
1.1.1.2 root 600: cdp->evtime = cdp->per;
1.1 root 601: cdp->dat = cdp->nextdat;
1.1.1.5 root 602: cdp->last_sample = cdp->current_sample;
1.1 root 603: cdp->current_sample = (sample8_t)(cdp->dat >> 8);
604:
605: cdp->state = 2;
606: {
607: int audav = adkcon & (1 << nr);
608: int audap = adkcon & (16 << nr);
609: int napnav = (!audav && !audap) || audav;
610: if (napnav)
611: cdp->data_written = 2;
612: }
613: break;
614:
615: case 2:
616: /* We come here when a 2->3 transition occurs */
617: if (currprefs.produce_sound == 0)
1.1.1.7 root 618: cdp->per = PERIOD_MAX;
1.1 root 619:
1.1.1.5 root 620: cdp->last_sample = cdp->current_sample;
1.1 root 621: cdp->current_sample = (sample8_t)(cdp->dat & 0xFF);
1.1.1.2 root 622: cdp->evtime = cdp->per;
1.1 root 623:
624: cdp->state = 3;
625:
626: /* Period attachment? */
627: if (adkcon & (0x10 << nr)) {
628: if (cdp->intreq2 && cdp->dmaen)
1.1.1.9 root 629: INTREQ (0x8000 | (0x80 << nr));
1.1 root 630: cdp->intreq2 = 0;
631:
632: cdp->dat = cdp->nextdat;
633: if (cdp->dmaen)
634: cdp->data_written = 2;
635: if (nr < 3) {
636: if (cdp->dat == 0)
1.1.1.7 root 637: (cdp+1)->per = PERIOD_MAX;
638: else if (cdp->dat < maxhpos * CYCLE_UNIT / 2 && currprefs.produce_sound < 3)
639: (cdp+1)->per = maxhpos * CYCLE_UNIT / 2;
1.1 root 640: else
1.1.1.7 root 641: (cdp+1)->per = cdp->dat * CYCLE_UNIT;
1.1 root 642: }
643: }
644: break;
645:
646: case 3:
647: /* We come here when a 3->2 transition occurs */
648: if (currprefs.produce_sound == 0)
1.1.1.7 root 649: cdp->per = PERIOD_MAX;
1.1 root 650:
1.1.1.2 root 651: cdp->evtime = cdp->per;
1.1 root 652:
653: if ((INTREQR() & (0x80 << nr)) && !cdp->dmaen) {
654: cdp->state = 0;
1.1.1.5 root 655: cdp->last_sample = 0;
1.1 root 656: cdp->current_sample = 0;
657: break;
658: } else {
659: int audav = adkcon & (1 << nr);
660: int audap = adkcon & (16 << nr);
661: int napnav = (!audav && !audap) || audav;
662: cdp->state = 2;
663:
664: if ((cdp->intreq2 && cdp->dmaen && napnav)
665: || (napnav && !cdp->dmaen))
666: INTREQ(0x8000 | (0x80 << nr));
667: cdp->intreq2 = 0;
668:
669: cdp->dat = cdp->nextdat;
1.1.1.5 root 670: cdp->last_sample = cdp->current_sample;
1.1 root 671: cdp->current_sample = (sample8_t)(cdp->dat >> 8);
672:
673: if (cdp->dmaen && napnav)
674: cdp->data_written = 2;
675:
676: /* Volume attachment? */
677: if (audav) {
678: if (nr < 3) {
679: (cdp+1)->vol = cdp->dat;
680: #ifndef MULTIPLICATION_PROFITABLE
681: (cdp+1)->voltbl = sound_table[cdp->dat];
682: #endif
683: }
684: }
685: }
686: break;
687:
688: default:
689: cdp->state = 0;
690: break;
691: }
692: }
693:
694: void aud0_handler (void)
695: {
696: audio_handler (0);
697: }
698: void aud1_handler (void)
699: {
700: audio_handler (1);
701: }
702: void aud2_handler (void)
703: {
704: audio_handler (2);
705: }
706: void aud3_handler (void)
707: {
708: audio_handler (3);
709: }
710:
1.1.1.10 root 711: void audio_channel_enable_dma (struct audio_channel_data *cdp)
712: {
713: if (cdp->state == 0) {
714: cdp->state = 1;
715: cdp->pt = cdp->lc;
716: cdp->wper = cdp->per;
717: cdp->wlen = cdp->len;
718: cdp->data_written = 2;
719: cdp->evtime = eventtab[ev_hsync].evtime - get_cycles ();
720: }
721: }
722:
723: void audio_channel_disable_dma (struct audio_channel_data *cdp)
724: {
725: if (cdp->state == 1 || cdp->state == 5) {
726: cdp->state = 0;
727: cdp->last_sample = 0;
728: cdp->current_sample = 0;
729: }
730: }
731:
1.1 root 732: void audio_reset (void)
733: {
1.1.1.8 root 734: int i;
735: if (savestate_state != STATE_RESTORE) {
736: memset (audio_channel, 0, 4 * sizeof *audio_channel);
737: audio_channel[0].per = PERIOD_MAX;
738: audio_channel[1].per = PERIOD_MAX;
739: audio_channel[2].per = PERIOD_MAX;
740: audio_channel[3].per = PERIOD_MAX;
741: audio_channel[0].voltbl = sound_table[0];
742: audio_channel[1].voltbl = sound_table[0];
743: audio_channel[2].voltbl = sound_table[0];
744: audio_channel[3].voltbl = sound_table[0];
745: } else
746: for (i = 0; i < 4; i++)
747: audio_channel[i].dmaen = (dmacon & 0x200) && (dmacon & (1 << i));
748:
749: #ifndef MULTIPLICATION_PROFITABLE
1.1.1.13 root 750: for (i = 0; i < 4; i++)
1.1.1.8 root 751: audio_channel[nr].voltbl = sound_table[audio_channel[nr].vol];
752: #endif
1.1.1.2 root 753:
754: last_cycles = 0;
1.1.1.7 root 755: next_sample_evtime = scaled_sample_evtime;
1.1.1.8 root 756:
757: schedule_audio ();
1.1.1.2 root 758: }
759:
1.1.1.6 root 760: STATIC_INLINE int sound_prefs_changed (void)
1.1.1.2 root 761: {
762: return (changed_prefs.produce_sound != currprefs.produce_sound
1.1.1.13 root 763: || changed_prefs.sound_stereo != currprefs.sound_stereo
1.1.1.7 root 764: || changed_prefs.mixed_stereo != currprefs.mixed_stereo
1.1.1.9 root 765: || changed_prefs.sound_maxbsiz != currprefs.sound_maxbsiz
1.1.1.4 root 766: || changed_prefs.sound_freq != currprefs.sound_freq
1.1.1.2 root 767: || changed_prefs.sound_bits != currprefs.sound_bits);
768: }
769:
770: void check_prefs_changed_audio (void)
771: {
1.1.1.6 root 772: if (sound_available && sound_prefs_changed ()) {
773: close_sound ();
1.1.1.2 root 774:
1.1.1.6 root 775: currprefs.produce_sound = changed_prefs.produce_sound;
1.1.1.13 root 776: currprefs.sound_stereo = changed_prefs.sound_stereo;
1.1.1.7 root 777: currprefs.mixed_stereo = changed_prefs.mixed_stereo;
1.1.1.6 root 778: currprefs.sound_bits = changed_prefs.sound_bits;
779: currprefs.sound_freq = changed_prefs.sound_freq;
1.1.1.9 root 780: currprefs.sound_maxbsiz = changed_prefs.sound_maxbsiz;
1.1.1.6 root 781: if (currprefs.produce_sound >= 2) {
1.1.1.7 root 782: if (init_audio ()) {
783: last_cycles = get_cycles () - 1;
784: next_sample_evtime = scaled_sample_evtime;
1.1.1.6 root 785: } else
786: if (! sound_available) {
1.1.1.11 root 787: write_log ("Sound is not supported.\n");
1.1.1.6 root 788: } else {
1.1.1.11 root 789: write_log ("Sorry, can't initialize sound.\n");
1.1.1.6 root 790: currprefs.produce_sound = 0;
791: /* So we don't do this every frame */
792: changed_prefs.produce_sound = 0;
793: }
794: }
1.1.1.12 root 795: compute_vsynctime ();
1.1.1.2 root 796: }
1.1.1.6 root 797: /* Select the right interpolation method. */
798: if (sample_handler == sample16_handler
799: || sample_handler == sample16i_crux_handler
800: || sample_handler == sample16i_rh_handler)
801: sample_handler = (currprefs.sound_interpol == 0 ? sample16_handler
802: : currprefs.sound_interpol == 1 ? sample16i_rh_handler
803: : sample16i_crux_handler);
804: else if (sample_handler == sample16s_handler
805: || sample_handler == sample16si_crux_handler
806: || sample_handler == sample16si_rh_handler)
807: sample_handler = (currprefs.sound_interpol == 0 ? sample16s_handler
808: : currprefs.sound_interpol == 1 ? sample16si_rh_handler
809: : sample16si_crux_handler);
1.1.1.7 root 810: if (currprefs.produce_sound == 0) {
811: eventtab[ev_audio].active = 0;
812: events_schedule ();
813: }
1.1.1.2 root 814: }
815:
816: void update_audio (void)
817: {
818: unsigned long int n_cycles;
819:
1.1.1.8 root 820: if (currprefs.produce_sound == 0 || savestate_state == STATE_RESTORE)
1.1.1.2 root 821: return;
822:
1.1.1.7 root 823: n_cycles = get_cycles () - last_cycles;
1.1.1.2 root 824: for (;;) {
825: unsigned long int best_evtime = n_cycles + 1;
826: if (audio_channel[0].state != 0 && best_evtime > audio_channel[0].evtime)
1.1.1.10 root 827: best_evtime = audio_channel[0].evtime;
1.1.1.2 root 828: if (audio_channel[1].state != 0 && best_evtime > audio_channel[1].evtime)
1.1.1.10 root 829: best_evtime = audio_channel[1].evtime;
1.1.1.2 root 830: if (audio_channel[2].state != 0 && best_evtime > audio_channel[2].evtime)
1.1.1.10 root 831: best_evtime = audio_channel[2].evtime;
1.1.1.2 root 832: if (audio_channel[3].state != 0 && best_evtime > audio_channel[3].evtime)
1.1.1.10 root 833: best_evtime = audio_channel[3].evtime;
1.1.1.7 root 834: if (currprefs.produce_sound > 1 && best_evtime > next_sample_evtime)
1.1.1.2 root 835: best_evtime = next_sample_evtime;
836:
837: if (best_evtime > n_cycles)
838: break;
839:
840: next_sample_evtime -= best_evtime;
841: audio_channel[0].evtime -= best_evtime;
842: audio_channel[1].evtime -= best_evtime;
843: audio_channel[2].evtime -= best_evtime;
844: audio_channel[3].evtime -= best_evtime;
845: n_cycles -= best_evtime;
1.1.1.3 root 846: if (next_sample_evtime == 0 && currprefs.produce_sound > 1) {
1.1.1.7 root 847: next_sample_evtime = scaled_sample_evtime;
1.1.1.2 root 848: (*sample_handler) ();
849: }
850: if (audio_channel[0].evtime == 0 && audio_channel[0].state != 0)
851: audio_handler (0);
852: if (audio_channel[1].evtime == 0 && audio_channel[1].state != 0)
853: audio_handler (1);
854: if (audio_channel[2].evtime == 0 && audio_channel[2].state != 0)
855: audio_handler (2);
856: if (audio_channel[3].evtime == 0 && audio_channel[3].state != 0)
857: audio_handler (3);
858: }
1.1.1.7 root 859: last_cycles = get_cycles () - n_cycles;
860: }
861:
862: void audio_evhandler (void)
863: {
864: if (currprefs.produce_sound == 0)
865: abort ();
866:
867: update_audio ();
868: schedule_audio ();
1.1.1.2 root 869: }
870:
1.1.1.15! root 871: void audio_hsync (int dmaaction)
! 872: {
! 873: int nr;
! 874:
! 875: update_audio ();
! 876:
! 877: /* Sound data is fetched at the beginning of each line */
! 878: for (nr = 0; nr < 4; nr++) {
! 879: struct audio_channel_data *cdp = audio_channel + nr;
! 880:
! 881: if (cdp->data_written == 2) {
! 882: cdp->data_written = 0;
! 883: cdp->nextdat = chipmem_wget (cdp->pt);
! 884: cdp->pt += 2;
! 885: if (cdp->state == 2 || cdp->state == 3) {
! 886: if (cdp->wlen == 1) {
! 887: cdp->pt = cdp->lc;
! 888: cdp->wlen = cdp->len;
! 889: cdp->intreq2 = 1;
! 890: } else
! 891: cdp->wlen = (cdp->wlen - 1) & 0xFFFF;
! 892: }
! 893: }
! 894: }
! 895: }
! 896:
1.1.1.2 root 897: void AUDxDAT (int nr, uae_u16 v)
898: {
899: struct audio_channel_data *cdp = audio_channel + nr;
900:
1.1.1.7 root 901: if (currprefs.produce_sound == 0)
902: return;
903:
1.1.1.2 root 904: update_audio ();
905:
906: cdp->dat = v;
907: if (cdp->state == 0 && !(INTREQR() & (0x80 << nr))) {
908: cdp->state = 2;
909: INTREQ(0x8000 | (0x80 << nr));
910: /* data_written = 2 ???? */
911: cdp->evtime = cdp->per;
1.1.1.7 root 912: schedule_audio ();
913: events_schedule ();
1.1.1.2 root 914: }
915: }
916:
917: void AUDxLCH (int nr, uae_u16 v)
918: {
919: update_audio ();
920:
921: audio_channel[nr].lc = (audio_channel[nr].lc & 0xffff) | ((uae_u32)v << 16);
922: }
923:
924: void AUDxLCL (int nr, uae_u16 v)
925: {
926: update_audio ();
927:
928: audio_channel[nr].lc = (audio_channel[nr].lc & ~0xffff) | (v & 0xFFFE);
929: }
930:
931: void AUDxPER (int nr, uae_u16 v)
932: {
1.1.1.7 root 933: unsigned long per = v * CYCLE_UNIT;
1.1.1.2 root 934: update_audio ();
935:
1.1.1.7 root 936: if (per == 0)
937: per = PERIOD_MAX;
1.1.1.2 root 938:
1.1.1.7 root 939: if (per < maxhpos * CYCLE_UNIT / 2 && currprefs.produce_sound < 3)
940: per = maxhpos * CYCLE_UNIT / 2;
1.1.1.2 root 941:
1.1.1.8 root 942: if (audio_channel[nr].per == PERIOD_MAX
943: && per != PERIOD_MAX)
944: {
945: audio_channel[nr].evtime = CYCLE_UNIT;
1.1.1.9 root 946: if (currprefs.produce_sound > 0) {
947: schedule_audio ();
948: events_schedule ();
949: }
1.1.1.8 root 950: }
1.1.1.7 root 951: audio_channel[nr].per = per;
1.1.1.2 root 952: }
953:
954: void AUDxLEN (int nr, uae_u16 v)
955: {
956: update_audio ();
957: audio_channel[nr].len = v;
958: }
959:
960: void AUDxVOL (int nr, uae_u16 v)
961: {
962: int v2 = v & 64 ? 63 : v & 63;
963:
964: update_audio ();
965:
966: audio_channel[nr].vol = v2;
967: #ifndef MULTIPLICATION_PROFITABLE
968: audio_channel[nr].voltbl = sound_table[v2];
969: #endif
1.1 root 970: }
971:
1.1.1.15! root 972: void update_adkmasks (void)
! 973: {
! 974: unsigned long t;
! 975:
! 976: t = adkcon | (adkcon >> 4);
! 977: audio_channel[0].adk_mask = (((t >> 0) & 1) - 1);
! 978: audio_channel[1].adk_mask = (((t >> 1) & 1) - 1);
! 979: audio_channel[2].adk_mask = (((t >> 2) & 1) - 1);
! 980: audio_channel[3].adk_mask = (((t >> 3) & 1) - 1);
! 981: }
! 982:
1.1.1.7 root 983: int init_audio (void)
1.1 root 984: {
1.1.1.7 root 985: int retval;
986: /* Some backward compatibility hacks until every port initializes
987: scaled_sample_evtime... */
988: scaled_sample_evtime_ok = 0;
989: retval = init_sound ();
990: if (! scaled_sample_evtime_ok)
991: scaled_sample_evtime = sample_evtime * CYCLE_UNIT;
992: return retval;
993: }
994:
1.1.1.8 root 995: /* audio save/restore code FIXME: not working correctly */
996: /* help needed */
997:
1.1.1.15! root 998: uae_u8 *restore_audio (int i, uae_u8 *src)
1.1.1.8 root 999: {
1000: struct audio_channel_data *acd;
1001: uae_u16 p;
1002:
1003: acd = audio_channel + i;
1004: acd->state = restore_u8 ();
1005: acd->vol = restore_u8 ();
1006: acd->intreq2 = restore_u8 ();
1007: acd->data_written = restore_u8 ();
1008: acd->len = restore_u16 ();
1009: acd->wlen = restore_u16 ();
1010: p = restore_u16 ();
1011: acd->per = p ? p * CYCLE_UNIT : PERIOD_MAX;
1012: p = restore_u16 ();
1013: acd->wper = p ? p * CYCLE_UNIT : PERIOD_MAX;
1014: acd->lc = restore_u32 ();
1015: acd->pt = restore_u32 ();
1016: acd->evtime = restore_u32 ();
1017:
1018: return src;
1019: }
1020:
1.1.1.15! root 1021: uae_u8 *save_audio (int i, int *len)
1.1.1.8 root 1022: {
1023: struct audio_channel_data *acd;
1024: uae_u8 *dst = malloc (100);
1025: uae_u8 *dstbak = dst;
1026: uae_u16 p;
1027:
1028: acd = audio_channel + i;
1029: save_u8 ((uae_u8)acd->state);
1030: save_u8 (acd->vol);
1031: save_u8 (acd->intreq2);
1032: save_u8 (acd->data_written);
1033: save_u16 (acd->len);
1034: save_u16 (acd->wlen);
1035: p = acd->per == PERIOD_MAX ? 0 : acd->per / CYCLE_UNIT;
1036: save_u16 (p);
1037: p = acd->per == PERIOD_MAX ? 0 : acd->wper / CYCLE_UNIT;
1038: save_u16 (p);
1039: save_u32 (acd->lc);
1040: save_u32 (acd->pt);
1041: save_u32 (acd->evtime);
1042: *len = dst - dstbak;
1043: return dstbak;
1044: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.