|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * Support for DOS
5: *
1.1.1.2 ! root 6: * Copyright 1997, 1998 Gustavo Goedert
1.1 root 7: */
8:
9: #include "sysconfig.h"
10: #include "sysdeps.h"
11:
12: #include "config.h"
13: #include "options.h"
14: #include "memory.h"
15: #include "custom.h"
16: #include "audio.h"
17: #include "gensound.h"
18: #include "sounddep/sound.h"
19: #include "events.h"
20:
21: #include <go32.h>
22: #include <sys/farptr.h>
23: #include <time.h>
24:
25: #include "sound/sb.h"
1.1.1.2 ! root 26:
! 27: typedef uae_s8 sample8_t;
! 28: #define DO_CHANNEL_1(v, c) do { (v) *= audio_channel[c].vol; } while (0)
! 29: #define SBASEVAL8(logn) ((logn) == 1 ? SOUND8_BASE_VAL << 7 : SOUND8_BASE_VAL << 8)
! 30: #define SBASEVAL16(logn) ((logn) == 1 ? SOUND16_BASE_VAL >> 1 : SOUND16_BASE_VAL)
! 31: #define FINISH_DATA(b,logn) do { if (14 - (b) + (logn) > 0) data >>= 14 - (b) + (logn); else data <<= (b) - 14 - (logn); } while (0);
1.1 root 32:
33: uae_u16 sndbuffer[44100];
34: uae_u16 *sndbufpt;
35: int sndbufsize;
36: extern int sound_table[256][64];
37: int dspbits;
38:
39: int sound_curfreq;
40:
1.1.1.2 ! root 41: void (*SND_DirectWrite)(unsigned int size, int freq); // Pointer to function that plays data on card
! 42: #define SND_DirectWrite SB_DirectWrite
1.1 root 43: volatile int IsPlaying = 0;
44: int CurrentBuffer = 0;
45: unsigned int direct_buffers[2], direct_sndbufpt;
46:
47: void direct_mono_sample16_handler(void);
48: void direct_mono_sample8_handler(void);
49: void direct_stereo_sample16_handler(void);
50: void direct_stereo_sample8_handler(void);
51: void interpol_freq(int new_freq);
52: void direct_check_sound_buffers(void);
53:
54: #define INTERPOL_SIZE 8
55: int freq_buf[INTERPOL_SIZE];
56: int buf_tot, buf_pos=0;
57:
58: inline void interpol_freq(int new_freq) {
59: buf_tot = buf_tot - freq_buf[buf_pos] + new_freq;
60: freq_buf[buf_pos] = new_freq;
61: buf_pos++;
62: if (buf_pos == INTERPOL_SIZE) buf_pos = 0;
63: sound_curfreq = buf_tot/INTERPOL_SIZE;
64: if (sound_curfreq<currprefs.sound_freq) {
65: sound_curfreq |= 0xff;
66: if (sound_curfreq<5512)
67: sound_curfreq = 5512;
68: }
69: if (sound_curfreq>currprefs.sound_freq)
70: sound_curfreq = currprefs.sound_freq;
71: }
72:
73: unsigned int sound_bytes = 0, last_clock = 0;
74:
75: inline void direct_check_sound_buffers(void) {
76: int played_size = direct_sndbufpt - direct_buffers[CurrentBuffer];
77:
78: sound_bytes++;
79: if ((!IsPlaying) && played_size >= currprefs.sound_minbsiz) {
80: SND_DirectWrite(played_size, sound_curfreq);
81: if (currprefs.sound_adjust) {
82: unsigned int cur_clock, new_freq;
83:
84: if (last_clock == 0)
85: last_clock = uclock();
86: else {
87: cur_clock = uclock();
88: new_freq = (unsigned long long) sound_bytes * UCLOCKS_PER_SEC / (cur_clock-last_clock);
89: interpol_freq(new_freq);
90: last_clock = cur_clock;
91: }
92: sound_bytes = 0;
93: }
94: CurrentBuffer = !CurrentBuffer;
95: direct_sndbufpt = direct_buffers[CurrentBuffer];
96: } else if (played_size >= currprefs.sound_maxbsiz) {
97: if (currprefs.sound_adjust)
98: interpol_freq(currprefs.sound_freq);
99: while(IsPlaying);
100: SND_DirectWrite(currprefs.sound_maxbsiz, sound_curfreq);
101: CurrentBuffer = !CurrentBuffer;
102: direct_sndbufpt = direct_buffers[CurrentBuffer];
103: last_clock=0;
104: }
105: }
106:
107: void direct_mono_sample16_handler(void)
108: {
1.1.1.2 ! root 109: uae_u32 data0 = audio_channel[0].current_sample;
! 110: uae_u32 data1 = audio_channel[1].current_sample;
! 111: uae_u32 data2 = audio_channel[2].current_sample;
! 112: uae_u32 data3 = audio_channel[3].current_sample;
! 113: DO_CHANNEL_1 (data0, 0);
! 114: DO_CHANNEL_1 (data1, 1);
! 115: DO_CHANNEL_1 (data2, 2);
! 116: DO_CHANNEL_1 (data3, 3);
! 117: data0 &= audio_channel[0].adk_mask;
! 118: data1 &= audio_channel[1].adk_mask;
! 119: data2 &= audio_channel[2].adk_mask;
! 120: data3 &= audio_channel[3].adk_mask;
! 121: data0 += data1;
! 122: data0 += data2;
! 123: data0 += data3;
! 124: {
! 125: uae_u32 data = SBASEVAL16(2) + data0;
! 126: FINISH_DATA(16, 2);
! 127: _farnspokew(direct_sndbufpt, data);
! 128: direct_sndbufpt += 2;
! 129: }
! 130:
! 131: direct_check_sound_buffers();
1.1 root 132:
133: eventtab[ev_sample].evtime = cycles + sample_evtime;
134: eventtab[ev_sample].oldcycles = cycles;
135: }
136:
137: void direct_mono_sample8_handler(void)
138: {
1.1.1.2 ! root 139: uae_u32 data0 = audio_channel[0].current_sample;
! 140: uae_u32 data1 = audio_channel[1].current_sample;
! 141: uae_u32 data2 = audio_channel[2].current_sample;
! 142: uae_u32 data3 = audio_channel[3].current_sample;
! 143: DO_CHANNEL_1 (data0, 0);
! 144: DO_CHANNEL_1 (data1, 1);
! 145: DO_CHANNEL_1 (data2, 2);
! 146: DO_CHANNEL_1 (data3, 3);
! 147: data0 &= audio_channel[0].adk_mask;
! 148: data1 &= audio_channel[1].adk_mask;
! 149: data2 &= audio_channel[2].adk_mask;
! 150: data3 &= audio_channel[3].adk_mask;
! 151: data0 += data1;
! 152: data0 += data2;
! 153: data0 += data3;
! 154: {
! 155: uae_u32 data = SBASEVAL8(2) + data0;
! 156: FINISH_DATA(8, 2);
! 157: _farnspokeb(direct_sndbufpt++, data);
! 158: }
1.1 root 159:
160: direct_check_sound_buffers();
161:
162: eventtab[ev_sample].evtime = cycles + sample_evtime;
163: eventtab[ev_sample].oldcycles = cycles;
164: }
165:
1.1.1.2 ! root 166: void direct_stereo_sample16_handler(void)
1.1 root 167: {
1.1.1.2 ! root 168: uae_u32 data0 = audio_channel[0].current_sample;
! 169: uae_u32 data1 = audio_channel[1].current_sample;
! 170: uae_u32 data2 = audio_channel[2].current_sample;
! 171: uae_u32 data3 = audio_channel[3].current_sample;
! 172: DO_CHANNEL_1 (data0, 0);
! 173: DO_CHANNEL_1 (data1, 1);
! 174: DO_CHANNEL_1 (data2, 2);
! 175: DO_CHANNEL_1 (data3, 3);
! 176:
! 177: data0 &= audio_channel[0].adk_mask;
! 178: data1 &= audio_channel[1].adk_mask;
! 179: data2 &= audio_channel[2].adk_mask;
! 180: data3 &= audio_channel[3].adk_mask;
! 181:
! 182: data0 += data3;
! 183: {
! 184: uae_u32 data = SBASEVAL16(1) + data0;
! 185: FINISH_DATA (16, 1);
! 186: _farnspokew(direct_sndbufpt, data);
! 187: direct_sndbufpt += 2;
! 188: }
1.1 root 189:
1.1.1.2 ! root 190: data1 += data2;
! 191: {
! 192: uae_u32 data = SBASEVAL16(1) + data1;
! 193: FINISH_DATA (16, 1);
! 194: _farnspokew(direct_sndbufpt, data);
! 195: direct_sndbufpt += 2;
! 196: }
1.1 root 197:
198: direct_check_sound_buffers();
199:
200: eventtab[ev_sample].evtime = cycles + sample_evtime;
201: eventtab[ev_sample].oldcycles = cycles;
202: }
203:
1.1.1.2 ! root 204: void direct_stereo_sample8_handler(void)
1.1 root 205: {
1.1.1.2 ! root 206: uae_u32 data0 = audio_channel[0].current_sample;
! 207: uae_u32 data1 = audio_channel[1].current_sample;
! 208: uae_u32 data2 = audio_channel[2].current_sample;
! 209: uae_u32 data3 = audio_channel[3].current_sample;
! 210: DO_CHANNEL_1 (data0, 0);
! 211: DO_CHANNEL_1 (data1, 1);
! 212: DO_CHANNEL_1 (data2, 2);
! 213: DO_CHANNEL_1 (data3, 3);
! 214:
! 215: data0 &= audio_channel[0].adk_mask;
! 216: data1 &= audio_channel[1].adk_mask;
! 217: data2 &= audio_channel[2].adk_mask;
! 218: data3 &= audio_channel[3].adk_mask;
! 219:
! 220: data0 += data3;
! 221: {
! 222: uae_u32 data = SBASEVAL8(1) + data0;
! 223: FINISH_DATA (8, 1);
! 224: _farnspokeb(direct_sndbufpt++, data);
! 225: }
! 226: data1 += data2;
! 227: {
! 228: uae_u32 data = SBASEVAL8(1) + data1;
! 229: FINISH_DATA (8, 1);
! 230: _farnspokeb(direct_sndbufpt++, data);
! 231: }
! 232:
! 233: direct_check_sound_buffers();
1.1 root 234:
235: eventtab[ev_sample].evtime = cycles + sample_evtime;
236: eventtab[ev_sample].oldcycles = cycles;
237: }
238:
239: int init_sound (void)
240: {
241: int tmp;
242: int rate;
243: int i;
244:
245: if (currprefs.sound_minbsiz > currprefs.sound_maxbsiz) {
246: fprintf(stderr, "Minimum sound buffer size bigger then maximum, exchanging.\n");
247: tmp = currprefs.sound_minbsiz;
248: currprefs.sound_minbsiz = currprefs.sound_maxbsiz;
249: currprefs.sound_maxbsiz = tmp;
250: }
251:
252: dspbits = currprefs.sound_bits;
253: rate = currprefs.sound_freq;
254: sndbufsize = currprefs.sound_maxbsiz;
255:
1.1.1.2 ! root 256: if (SB_DetectInitSound(&dspbits, &rate, &sndbufsize, direct_buffers, &currprefs.stereo));
1.1 root 257: else if (0/*OTHER_CARD_DETECT_ROUTINE*/);
258: else
259: return 0;
260:
261: currprefs.sound_freq = rate;
262: currprefs.sound_minbsiz = (currprefs.sound_minbsiz>>2)<<2;
263: currprefs.sound_maxbsiz = sndbufsize;
264:
265: sample_evtime = (long)maxhpos * maxvpos * 50 / rate;
266:
267: if (dspbits == 16) {
268: init_sound_table16 ();
1.1.1.2 ! root 269: if (currprefs.stereo)
! 270: eventtab[ev_sample].handler = direct_stereo_sample16_handler;
! 271: else
! 272: eventtab[ev_sample].handler = direct_mono_sample16_handler;
1.1 root 273: } else {
274: init_sound_table8 ();
1.1.1.2 ! root 275: if (currprefs.stereo)
! 276: eventtab[ev_sample].handler = direct_stereo_sample8_handler;
! 277: else
! 278: eventtab[ev_sample].handler = direct_mono_sample8_handler;
1.1 root 279: }
280: printf ("Sound driver found and configured for %d bits at %d Hz, buffer is %d:%d bytes\n",
281: dspbits, rate, currprefs.sound_minbsiz, currprefs.sound_maxbsiz);
282: sndbufpt = sndbuffer;
283: direct_sndbufpt = direct_buffers[0];
284:
285: sound_curfreq = currprefs.sound_freq;
286: for (i=0; i<INTERPOL_SIZE; i++)
287: freq_buf[i] = sound_curfreq;
288: buf_tot = sound_curfreq * INTERPOL_SIZE;
289:
1.1.1.2 ! root 290: #ifdef FRAME_RATE_HACK
! 291: vsynctime = vsynctime * 9 / 10;
! 292: #endif
! 293:
1.1 root 294: return 1;
295: }
1.1.1.2 ! root 296:
! 297: int setup_sound (void)
! 298: {
! 299: sound_available = 1;
! 300: return 1;
! 301: }
! 302:
! 303: void close_sound(void)
! 304: {
! 305: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.