|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * Support for Linux/USS sound
5: *
6: * Copyright 1997 Bernd Schmidt
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 <sys/ioctl.h>
22:
23: #ifdef HAVE_SYS_SOUNDCARD_H
24: #include <sys/soundcard.h>
25: #elif defined HAVE_MACHINE_SOUNDCARD_H
26: #include <machine/soundcard.h>
27: #else
28: #error "Something went wrong during configuration."
29: #endif
30:
31: int sound_fd;
32: static int have_sound;
33: static unsigned long formats;
34:
35: uae_u16 sndbuffer[44100];
36: uae_u16 *sndbufpt;
37: int sndbufsize;
38:
39: static int exact_log2(int v)
40: {
41: int l = 0;
42: while ((v >>= 1) != 0)
43: l++;
44: return l;
45: }
46:
47: void close_sound(void)
48: {
49: if (have_sound)
50: close(sound_fd);
51: }
52:
53: int setup_sound(void)
54: {
55: sound_fd = open ("/dev/dsp", O_WRONLY);
56: have_sound = !(sound_fd < 0);
57: if (!have_sound)
58: return 0;
59:
60: if (ioctl (sound_fd, SNDCTL_DSP_GETFMTS, &formats) == -1) {
61: fprintf(stderr, "ioctl failed - can't use sound.\n");
62: close(sound_fd);
63: have_sound = 0;
64: return 0;
65: }
66:
67: sound_available = 1;
68: return 1;
69: }
70:
71: int init_sound (void)
72: {
73: int tmp;
74: int rate;
75: int dspbits;
76:
77: if (currprefs.sound_maxbsiz < 128 || currprefs.sound_maxbsiz > 16384) {
78: fprintf(stderr, "Sound buffer size %d out of range.\n", currprefs.sound_maxbsiz);
79: currprefs.sound_maxbsiz = 8192;
80: }
81:
82: tmp = 0x00040000 + exact_log2(currprefs.sound_maxbsiz);
83: ioctl (sound_fd, SNDCTL_DSP_SETFRAGMENT, &tmp);
84: ioctl (sound_fd, SNDCTL_DSP_GETBLKSIZE, &sndbufsize);
85:
86: dspbits = currprefs.sound_bits;
87: ioctl (sound_fd, SNDCTL_DSP_SAMPLESIZE, &dspbits);
88: ioctl (sound_fd, SOUND_PCM_READ_BITS, &dspbits);
89: if (dspbits != currprefs.sound_bits) {
90: fprintf(stderr, "Can't use sound with %d bits\n", currprefs.sound_bits);
91: return 0;
92: }
93:
94: tmp = currprefs.stereo;
95: ioctl (sound_fd, SNDCTL_DSP_STEREO, &tmp);
96:
97: rate = currprefs.sound_freq;
98: ioctl (sound_fd, SNDCTL_DSP_SPEED, &rate);
99: ioctl (sound_fd, SOUND_PCM_READ_RATE, &rate);
100: /* Some soundcards have a bit of tolerance here. */
101: if (rate < currprefs.sound_freq * 90 / 100 || rate > currprefs.sound_freq * 110 / 100) {
102: fprintf(stderr, "Can't use sound with desired frequency %d\n", currprefs.sound_freq);
103: return 0;
104: }
105:
106: sample_evtime = (long)maxhpos * maxvpos * 50 / rate;
107:
108: if (dspbits == 16) {
109: /* Will this break horribly on bigendian machines? Possible... */
110: if (!(formats & AFMT_S16_LE))
111: return 0;
112: init_sound_table16 ();
113: eventtab[ev_sample].handler = currprefs.stereo ? sample16s_handler : sample16_handler;
114: } else {
115: if (!(formats & AFMT_U8))
116: return 0;
117: init_sound_table8 ();
118: eventtab[ev_sample].handler = currprefs.stereo ? sample8s_handler : sample8_handler;
119: }
120: sound_available = 1;
121: printf ("Sound driver found and configured for %d bits at %d Hz, buffer is %d bytes\n",
122: dspbits, rate, sndbufsize);
123: sndbufpt = sndbuffer;
124:
125: #ifdef FRAME_RATE_HACK
126: vsynctime = vsynctime * 9 / 10;
127: #endif
128:
129: return 1;
130: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.