|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * Support for Amiga audio.device sound ! 5: * ! 6: * Copyright 1996, 1997 Samuel Devulder ! 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 <hardware/custom.h> ! 22: #include <hardware/cia.h> ! 23: ! 24: #define CIAAPRA 0xBFE001 ! 25: #define CUSTOM 0xDFF000 ! 26: ! 27: static struct Custom *custom= (struct Custom*) CUSTOM; ! 28: static struct CIA *cia = (struct CIA *) CIAAPRA; ! 29: ! 30: /* ! 31: * Compared to Linux, AF_SOUND, and mac above, the AMIGA sound processing ! 32: * with OS routines is awfull. (sam). But with AHI DOSDriver it is far more ! 33: * easier. ! 34: */ ! 35: ! 36: char whichchannel[]={1,2,4,8}; ! 37: struct IOAudio *AudioIO; ! 38: struct MsgPort *AudioMP; ! 39: struct Message *AudioMSG; ! 40: ! 41: unsigned char *buffers[2]; ! 42: uae_u16 *sndbuffer; ! 43: uae_u16 *sndbufpt; ! 44: int sndbufsize; ! 45: int bufidx, devopen; ! 46: ! 47: int have_sound, clockval, oldledstate, period; ! 48: ! 49: ULONG AUDIO_FILE; ! 50: ! 51: static ULONG TST_AUDIO_FILE(char *buff, char *name, int rate, int bsize) ! 52: { ! 53: struct Process *pr = (void*)FindTask(NULL); ! 54: ULONG wd, fd; ! 55: ! 56: if(!name) return 0; ! 57: wd = (ULONG)pr->pr_WindowPtr; ! 58: pr->pr_WindowPtr = (APTR)-1; ! 59: sprintf(buff,name,rate,bsize); ! 60: fd = Open(buff, MODE_NEWFILE); ! 61: pr->pr_WindowPtr = (APTR)wd; ! 62: return fd; ! 63: } ! 64: ! 65: int setup_sound(void) ! 66: { ! 67: sound_available = 1; ! 68: return 1; ! 69: } ! 70: ! 71: int init_sound (void) ! 72: { /* too complex ? No it is only the allocation of a single channel ! */ ! 73: /* it would have been far less painfull if AmigaOS provided a */ ! 74: /* SOUND: device handler */ ! 75: int rate; ! 76: char buff[256],*devname = NULL; ! 77: ! 78: atexit(close_sound); /* if only amiga os had resource tracking */ ! 79: ! 80: /* determine the clock */ ! 81: { ! 82: struct GfxBase *GB; ! 83: GB = (void*)OpenLibrary("graphics.library",0L); ! 84: if(!GB) goto fail; ! 85: if (GB->DisplayFlags & PAL) ! 86: clockval = 3546895; /* PAL clock */ ! 87: else ! 88: clockval = 3579545; /* NTSC clock */ ! 89: CloseLibrary((void*)GB); ! 90: } ! 91: ! 92: /* check buffsize */ ! 93: if (currprefs.sound_maxbsiz < 2 || currprefs.sound_maxbsiz > (256*1024)) { ! 94: fprintf(stderr, "Sound buffer size %d out of range.\n", currprefs.sound_maxbsiz); ! 95: currprefs.sound_maxbsiz = 8192; ! 96: } ! 97: sndbufsize = (currprefs.sound_maxbsiz + 1)&~1; ! 98: ! 99: /* check freq */ ! 100: if (!currprefs.sound_freq) currprefs.sound_freq = 1; ! 101: if (clockval/currprefs.sound_freq < 124 || clockval/currprefs.sound_freq > 65535) { ! 102: fprintf(stderr, "Can't use sound with desired frequency %d Hz\n", currprefs.sound_freq); ! 103: currprefs.sound_freq = 22000; ! 104: } ! 105: rate = currprefs.sound_freq; ! 106: period = (uae_u16)(clockval/rate); ! 107: ! 108: /* check for $AUDIONAME or AUD: or AUDIO: device */ ! 109: devname = buff; ! 110: AUDIO_FILE = TST_AUDIO_FILE(buff, getenv("AUDIONAME"), ! 111: rate, sndbufsize); ! 112: if(!AUDIO_FILE) /* AHI */ ! 113: AUDIO_FILE = TST_AUDIO_FILE(buff, "AUDIO:FREQUENCY=%d/BUFFER=%d", ! 114: rate, sndbufsize); ! 115: if(!AUDIO_FILE) /* AUD: */ ! 116: AUDIO_FILE = TST_AUDIO_FILE(buff, "AUDIO:FREQUENCY%d/BUFFER%d", ! 117: rate, sndbufsize); ! 118: if(!AUDIO_FILE) ! 119: AUDIO_FILE = TST_AUDIO_FILE(buff, "AUD:FREQUENCY%d/BUFFER%d", ! 120: rate, sndbufsize); ! 121: ! 122: /* else use audio.device */ ! 123: if(!AUDIO_FILE) { ! 124: /* setup the stuff */ ! 125: AudioMP = CreatePort(0,0); ! 126: if(!AudioMP) goto fail; ! 127: AudioIO = (struct IOAudio *)CreateExtIO(AudioMP, ! 128: sizeof(struct IOAudio)); ! 129: if(!AudioIO) goto fail; ! 130: ! 131: AudioIO->ioa_Request.io_Message.mn_Node.ln_Pri /*pfew!!*/ = 85; ! 132: AudioIO->ioa_Data = whichchannel; ! 133: AudioIO->ioa_Length = sizeof(whichchannel); ! 134: AudioIO->ioa_AllocKey = 0; ! 135: if(OpenDevice(devname = AUDIONAME, 0, (void*)AudioIO, 0)) goto fail; ! 136: devopen = 1; ! 137: } ! 138: ! 139: /* get the buffers */ ! 140: if(AUDIO_FILE) { ! 141: buffers[0] = (void*)AllocMem(sndbufsize,MEMF_ANY|MEMF_CLEAR); ! 142: buffers[1] = NULL; ! 143: if(!buffers[0]) goto fail; ! 144: } else { ! 145: buffers[0] = (void*)AllocMem(sndbufsize,MEMF_CHIP|MEMF_CLEAR); ! 146: buffers[1] = (void*)AllocMem(sndbufsize,MEMF_CHIP|MEMF_CLEAR); ! 147: if(!buffers[0] || !buffers[1]) goto fail; ! 148: } ! 149: bufidx = 0; ! 150: sndbuffer = sndbufpt = (uae_u16*)buffers[bufidx]; ! 151: ! 152: oldledstate = cia->ciapra & (1<<CIAB_LED); ! 153: cia->ciapra |= (1<<CIAB_LED); ! 154: ! 155: sample_evtime = (long)maxhpos * maxvpos * 50 / rate; ! 156: init_sound_table8 (); ! 157: eventtab[ev_sample].handler = sample8_handler; ! 158: ! 159: fprintf(stderr, "Sound driver found and configured for %d bits " ! 160: "at %d Hz, buffer is %d bytes (%s)\n", ! 161: 8, rate, sndbufsize,devname); ! 162: ! 163: sound_available = 1; ! 164: return 1; ! 165: fail: ! 166: sound_available = 0; ! 167: return 0; ! 168: } ! 169: ! 170: void close_sound(void) ! 171: { ! 172: if(AUDIO_FILE) Close(AUDIO_FILE); ! 173: if(devopen) {CloseDevice((void*)AudioIO);devopen = 0;} ! 174: if(AudioIO) {DeleteExtIO((void*)AudioIO);AudioIO = NULL;} ! 175: if(AudioMP) {DeletePort((void*)AudioMP);AudioMP = NULL;} ! 176: if(buffers[0]) {FreeMem((APTR)buffers[0],sndbufsize);buffers[0] = 0;} ! 177: if(buffers[1]) {FreeMem((APTR)buffers[1],sndbufsize);buffers[1] = 0;} ! 178: if(sound_available) { ! 179: cia->ciapra = (cia->ciapra & ~(1<<CIAB_LED)) | oldledstate; ! 180: sound_available = 0; ! 181: } ! 182: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.