|
|
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.