|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * Support for DOS
5: *
6: * Copyright 1997 Gustavo Goedert
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"
26: #include "sound/gus.h"
27:
28: uae_u16 sndbuffer[44100];
29: uae_u16 *sndbufpt;
30: int sndbufsize;
31: extern int sound_table[256][64];
32: int dspbits;
33:
34: int sound_curfreq;
35:
36: void (*SND_Write)(void *buf, unsigned long size); // Pointer to function that plays data on card
37: void (*SND_DirectWrite)(unsigned int size, int freq); // New function that plays data directly
38: volatile int IsPlaying = 0;
39: int CurrentBuffer = 0;
40: unsigned int direct_buffers[2], direct_sndbufpt;
41:
42: void direct_mono_sample16_handler(void);
43: void direct_mono_sample8_handler(void);
44: void direct_stereo_sample16_handler(void);
45: void direct_stereo_sample8_handler(void);
46: void normal_sample16_handler(void);
47: void normal_sample8_handler(void);
48: void interpol_freq(int new_freq);
49: void direct_check_sound_buffers(void);
50: void normal_check_sound_buffers(void);
51:
52: #define INTERPOL_SIZE 8
53: int freq_buf[INTERPOL_SIZE];
54: int buf_tot, buf_pos=0;
55:
56: inline void interpol_freq(int new_freq) {
57: buf_tot = buf_tot - freq_buf[buf_pos] + new_freq;
58: freq_buf[buf_pos] = new_freq;
59: buf_pos++;
60: if (buf_pos == INTERPOL_SIZE) buf_pos = 0;
61: sound_curfreq = buf_tot/INTERPOL_SIZE;
62: if (sound_curfreq<currprefs.sound_freq) {
63: sound_curfreq |= 0xff;
64: if (sound_curfreq<5512)
65: sound_curfreq = 5512;
66: }
67: if (sound_curfreq>currprefs.sound_freq)
68: sound_curfreq = currprefs.sound_freq;
69: }
70:
71: unsigned int sound_bytes = 0, last_clock = 0;
72:
73: inline void direct_check_sound_buffers(void) {
74: int played_size = direct_sndbufpt - direct_buffers[CurrentBuffer];
75:
76: sound_bytes++;
77: if ((!IsPlaying) && played_size >= currprefs.sound_minbsiz) {
78: SND_DirectWrite(played_size, sound_curfreq);
79: if (currprefs.sound_adjust) {
80: unsigned int cur_clock, new_freq;
81:
82: if (last_clock == 0)
83: last_clock = uclock();
84: else {
85: cur_clock = uclock();
86: new_freq = (unsigned long long) sound_bytes * UCLOCKS_PER_SEC / (cur_clock-last_clock);
87: interpol_freq(new_freq);
88: last_clock = cur_clock;
89: }
90: sound_bytes = 0;
91: }
92: CurrentBuffer = !CurrentBuffer;
93: direct_sndbufpt = direct_buffers[CurrentBuffer];
94: } else if (played_size >= currprefs.sound_maxbsiz) {
95: if (currprefs.sound_adjust)
96: interpol_freq(currprefs.sound_freq);
97: while(IsPlaying);
98: SND_DirectWrite(currprefs.sound_maxbsiz, sound_curfreq);
99: CurrentBuffer = !CurrentBuffer;
100: direct_sndbufpt = direct_buffers[CurrentBuffer];
101: last_clock=0;
102: }
103: }
104:
105: inline void normal_check_sound_buffers(void) {
106: if ((char *)sndbufpt - (char *)sndbuffer >= sndbufsize) {
107: SND_Write(sndbuffer, sndbufsize);
108: sndbufpt = sndbuffer;
109: }
110: }
111:
112: /* Gustavo et al.: *please* don't duplicate code like this, but use the functions
113: * in audio.c */
114: void direct_mono_sample16_handler(void)
115: {
116: int nr, adk;
117: uae_u32 data = SOUND16_BASE_VAL;
118:
119: eventtab[ev_sample].evtime = cycles + sample_evtime;
120: eventtab[ev_sample].oldcycles = cycles;
121:
122: adk = adkcon;
123:
124: if (!(adk & 0x11))
125: data += sound_table[audio_channel[0].current_sample][audio_channel[0].vol];
126: if (!(adk & 0x22))
127: data += sound_table[audio_channel[1].current_sample][audio_channel[1].vol];
128: if (!(adk & 0x44))
129: data += sound_table[audio_channel[2].current_sample][audio_channel[2].vol];
130: if (!(adk & 0x88))
131: data += sound_table[audio_channel[3].current_sample][audio_channel[3].vol];
132:
133: _farnspokew(direct_sndbufpt, data);
134: direct_sndbufpt += 2;
135: direct_check_sound_buffers();
136: }
137:
138: void direct_mono_sample8_handler(void)
139: {
140: int nr, adk, played_size;
141: uae_u32 data = SOUND8_BASE_VAL;
142:
143: eventtab[ev_sample].evtime = cycles + sample_evtime;
144: eventtab[ev_sample].oldcycles = cycles;
145:
146: adk = adkcon;
147:
148: if (!(adk & 0x11))
149: data += sound_table[audio_channel[0].current_sample][audio_channel[0].vol];
150: if (!(adk & 0x22))
151: data += sound_table[audio_channel[1].current_sample][audio_channel[1].vol];
152: if (!(adk & 0x44))
153: data += sound_table[audio_channel[2].current_sample][audio_channel[2].vol];
154: if (!(adk & 0x88))
155: data += sound_table[audio_channel[3].current_sample][audio_channel[3].vol];
156:
157: _farnspokeb(direct_sndbufpt++, data);
158: direct_check_sound_buffers();
159: }
160:
161: void direct_stereo_sample16_handler(void)
162: {
163: int nr, adk;
164: uae_u32 ldata = SOUND16_BASE_VAL, rdata = SOUND16_BASE_VAL;
165:
166: eventtab[ev_sample].evtime = cycles + sample_evtime;
167: eventtab[ev_sample].oldcycles = cycles;
168:
169: adk = adkcon;
170:
171: if (!(adk & 0x11))
172: ldata += sound_table[audio_channel[0].current_sample][audio_channel[0].vol];
173: if (!(adk & 0x22))
174: rdata += sound_table[audio_channel[1].current_sample][audio_channel[1].vol];
175: if (!(adk & 0x44))
176: rdata += sound_table[audio_channel[2].current_sample][audio_channel[2].vol];
177: if (!(adk & 0x88))
178: ldata += sound_table[audio_channel[3].current_sample][audio_channel[3].vol];
179:
180: _farnspokew(direct_sndbufpt, ldata);
181: direct_sndbufpt += 2;
182: _farnspokew(direct_sndbufpt, rdata);
183: direct_sndbufpt += 2;
184: direct_check_sound_buffers();
185: }
186:
187: void direct_stereo_sample8_handler(void)
188: {
189: int nr, adk, played_size;
190: uae_u32 ldata = SOUND8_BASE_VAL, rdata = SOUND8_BASE_VAL;
191:
192: eventtab[ev_sample].evtime = cycles + sample_evtime;
193: eventtab[ev_sample].oldcycles = cycles;
194:
195: adk = adkcon;
196:
197: if (!(adk & 0x11))
198: ldata += sound_table[audio_channel[0].current_sample][audio_channel[0].vol];
199: if (!(adk & 0x22))
200: rdata += sound_table[audio_channel[1].current_sample][audio_channel[1].vol];
201: if (!(adk & 0x44))
202: rdata += sound_table[audio_channel[2].current_sample][audio_channel[2].vol];
203: if (!(adk & 0x88))
204: ldata += sound_table[audio_channel[3].current_sample][audio_channel[3].vol];
205:
206: _farnspokeb(direct_sndbufpt++, ldata);
207: _farnspokeb(direct_sndbufpt++, rdata);
208: direct_check_sound_buffers();
209: }
210:
211:
212: void normal_sample16_handler(void)
213: {
214: int nr, adk;
215: uae_u32 data = SOUND16_BASE_VAL;
216:
217: eventtab[ev_sample].evtime = cycles + sample_evtime;
218: eventtab[ev_sample].oldcycles = cycles;
219:
220: adk = adkcon;
221:
222: if (!(adk & 0x11))
223: data += sound_table[audio_channel[0].current_sample][audio_channel[0].vol];
224: if (!(adk & 0x22))
225: data += sound_table[audio_channel[1].current_sample][audio_channel[1].vol];
226: if (!(adk & 0x44))
227: data += sound_table[audio_channel[2].current_sample][audio_channel[2].vol];
228: if (!(adk & 0x88))
229: data += sound_table[audio_channel[3].current_sample][audio_channel[3].vol];
230:
231: *(uae_u16 *)sndbufpt = data;
232: sndbufpt = (uae_u16 *)(((uae_u8 *)sndbufpt) + 2);
233: normal_check_sound_buffers();
234: }
235:
236: void normal_sample8_handler(void)
237: {
238: int nr, adk;
239: uae_u32 data = SOUND8_BASE_VAL;
240:
241: eventtab[ev_sample].evtime = cycles + sample_evtime;
242: eventtab[ev_sample].oldcycles = cycles;
243:
244: adk = adkcon;
245:
246: if (!(adk & 0x11))
247: data += sound_table[audio_channel[0].current_sample][audio_channel[0].vol];
248: if (!(adk & 0x22))
249: data += sound_table[audio_channel[1].current_sample][audio_channel[1].vol];
250: if (!(adk & 0x44))
251: data += sound_table[audio_channel[2].current_sample][audio_channel[2].vol];
252: if (!(adk & 0x88))
253: data += sound_table[audio_channel[3].current_sample][audio_channel[3].vol];
254:
255: *(uae_u8 *)sndbufpt = data;
256: sndbufpt = (uae_u16 *)(((uae_u8 *)sndbufpt) + 1);
257: normal_check_sound_buffers();
258: }
259:
260: void close_sound(void) {
261: }
262:
263: int setup_sound(void) {
264: sound_available = 1;
265: return 1;
266: }
267:
268: int init_sound (void)
269: {
270: int tmp;
271: int rate;
272: int i;
273:
274: if (currprefs.sound_minbsiz > currprefs.sound_maxbsiz) {
275: fprintf(stderr, "Minimum sound buffer size bigger then maximum, exchanging.\n");
276: tmp = currprefs.sound_minbsiz;
277: currprefs.sound_minbsiz = currprefs.sound_maxbsiz;
278: currprefs.sound_maxbsiz = tmp;
279: }
280:
281: dspbits = currprefs.sound_bits;
282: rate = currprefs.sound_freq;
283: sndbufsize = currprefs.sound_maxbsiz;
284:
285: if (GUS_Init(&dspbits, &rate, &sndbufsize, direct_buffers, &currprefs.stereo));
286: else if (SB_DetectInitSound(&dspbits, &rate, &sndbufsize, direct_buffers, &currprefs.stereo));
287: else if (0/*OTHER_CARD_DETECT_ROUTINE*/);
288: else
289: return 0;
290:
291: currprefs.sound_freq = rate;
292: currprefs.sound_minbsiz = (currprefs.sound_minbsiz>>2)<<2;
293: currprefs.sound_maxbsiz = sndbufsize;
294:
295: if (direct_buffers[0] == 0)
296: currprefs.sound_minbsiz = currprefs.sound_maxbsiz;
297:
298: sample_evtime = (long)maxhpos * maxvpos * 50 / rate;
299:
300: if (dspbits == 16) {
301: init_sound_table16 ();
302: if (direct_buffers[0] != 0) {
303: if (currprefs.stereo)
304: eventtab[ev_sample].handler = direct_stereo_sample16_handler;
305: else
306: eventtab[ev_sample].handler = direct_mono_sample16_handler;
307: } else
308: eventtab[ev_sample].handler = normal_sample16_handler;
309: } else {
310: init_sound_table8 ();
311: if (direct_buffers[0] != 0) {
312: if (currprefs.stereo)
313: eventtab[ev_sample].handler = direct_stereo_sample8_handler;
314: else
315: eventtab[ev_sample].handler = direct_mono_sample8_handler;
316: } else
317: eventtab[ev_sample].handler = normal_sample8_handler;
318: }
319: sound_available = 1;
320: printf ("Sound driver found and configured for %d bits at %d Hz, buffer is %d:%d bytes\n",
321: dspbits, rate, currprefs.sound_minbsiz, currprefs.sound_maxbsiz);
322: sndbufpt = sndbuffer;
323: direct_sndbufpt = direct_buffers[0];
324:
325: sound_curfreq = currprefs.sound_freq;
326: for (i=0; i<INTERPOL_SIZE; i++)
327: freq_buf[i] = sound_curfreq;
328: buf_tot = sound_curfreq * INTERPOL_SIZE;
329:
330: return 1;
331: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.