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