|
|
1.1.1.2 root 1: /*
1.1 root 2: * UAE - The Un*x Amiga Emulator
1.1.1.2 root 3: *
1.1 root 4: * Support for Linux/ALSA sound
1.1.1.2 root 5: *
1.1 root 6: * Copyright 1997 Bernd Schmidt
7: * Copyright 2004 Heikki Orsila
8: *
9: * BUGS: certainly
10: * TODO:
11: * - if setup_sound() fails, there may still be hope to get the
12: * sound device, but we totally give up.. see sd-uss.
13: */
14:
15: #include "sysconfig.h"
16: #include "sysdeps.h"
17:
18: #include "options.h"
19: #include "memory.h"
20: #include "events.h"
21: #include "custom.h"
22: #include "gensound.h"
23: #include "sounddep/sound.h"
24:
25: #include <alsa/asoundlib.h>
26:
27: int sound_fd;
28: static int have_sound = 0;
29: static unsigned long formats;
30:
31: uae_u16 sndbuffer[44100];
32: uae_u16 *sndbufpt;
33: int sndbufsize;
34:
35: snd_pcm_t *alsa_playback_handle = 0;
36: int alsa_to_frames_divisor = 4;
37:
38: void close_sound (void)
39: {
40: if (alsa_playback_handle) {
41: snd_pcm_close (alsa_playback_handle);
42: alsa_playback_handle = 0;
43: }
44: }
45:
46: static int open_sound(void)
47: {
48: return snd_pcm_open (&alsa_playback_handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
49: }
50:
51: /* Try to determine whether sound is available. This is only for GUI purposes. */
52: int setup_sound (void)
53: {
54: int err;
55: sound_available = 0;
56: if ((err = open_sound()) < 0) {
57: /* TODO: if the pcm was busy, we should the same as sd-uss does.
58: tell the caller that sound is available. in any other
59: condition we should just return 0. */
60: fprintf (stderr, "cannot open audio device (%s)\n", snd_strerror (err));
61: return 0;
62: }
63: snd_pcm_close (alsa_playback_handle);
64: alsa_playback_handle = 0;
65: sound_available = 1;
66: return 1;
67: }
68:
69: int init_sound (void)
70: {
71: int tmp;
72: int rate;
73: int dspbits;
74: int alsamode;
75: int channels;
76: int err;
77: snd_pcm_hw_params_t *hw_params;
78: snd_pcm_uframes_t buffer_frames;
79:
1.1.1.3 ! root 80: dspbits = 16;
1.1 root 81: channels = currprefs.sound_stereo ? 2 : 1;
82: rate = currprefs.sound_freq;
83:
84: have_sound = 0;
85: alsa_playback_handle = 0;
86: if ((err = open_sound()) < 0) {
87: fprintf (stderr, "cannot open audio device (%s)\n", snd_strerror (err));
88: goto nosound;
89: }
90:
91: if (currprefs.sound_maxbsiz < 128 || currprefs.sound_maxbsiz > 16384) {
92: fprintf (stderr, "Sound buffer size %d out of range.\n", currprefs.sound_maxbsiz);
93: currprefs.sound_maxbsiz = 8192;
94: }
95: sndbufsize = currprefs.sound_maxbsiz;
96:
97: if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
98: fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
99: snd_strerror (err));
100: goto nosound;
101: }
102:
103: if ((err = snd_pcm_hw_params_any (alsa_playback_handle, hw_params)) < 0) {
104: fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
105: snd_strerror (err));
106: goto nosound;
107: }
108:
109: if ((err = snd_pcm_hw_params_set_access (alsa_playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
110: fprintf (stderr, "cannot set access type (%s)\n",
111: snd_strerror (err));
112: goto nosound;
113: }
114:
1.1.1.3 ! root 115: alsamode = SND_PCM_FORMAT_S16;
1.1 root 116:
117: if ((err = snd_pcm_hw_params_set_format (alsa_playback_handle, hw_params, alsamode)) < 0) {
118: fprintf (stderr, "cannot set sample format (%s)\n",
119: snd_strerror (err));
120: goto nosound;
121: }
122:
123: if ((err = snd_pcm_hw_params_set_channels (alsa_playback_handle, hw_params, channels)) < 0) {
124: fprintf (stderr, "cannot set channel count (%s)\n",
125: snd_strerror (err));
126: goto nosound;
127: }
128:
129: if ((err = snd_pcm_hw_params_set_rate_near (alsa_playback_handle, hw_params, &rate, 0)) < 0) {
130: fprintf (stderr, "cannot set sample rate (%s)\n",
131: snd_strerror (err));
132: goto nosound;
133: }
1.1.1.2 root 134:
1.1.1.3 ! root 135: alsa_to_frames_divisor = channels * 2;
1.1 root 136: buffer_frames = sndbufsize / alsa_to_frames_divisor;
137: if ((err = snd_pcm_hw_params_set_period_size_near(alsa_playback_handle, hw_params, &buffer_frames, 0)) < 0) {
138: fprintf (stderr, "cannot set period size near (%s)\n", snd_strerror (err));
139: goto nosound;
140: }
141:
142: if ((err = snd_pcm_hw_params (alsa_playback_handle, hw_params)) < 0) {
143: fprintf (stderr, "cannot set parameters (%s)\n",
144: snd_strerror (err));
145: goto nosound;
146: }
1.1.1.2 root 147:
1.1 root 148: snd_pcm_hw_params_free (hw_params);
1.1.1.2 root 149:
1.1 root 150: if ((err = snd_pcm_prepare (alsa_playback_handle)) < 0) {
151: fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
152: snd_strerror (err));
153: goto nosound;
154: }
155:
1.1.1.3 ! root 156: obtainedfreq = rate;
! 157:
! 158: init_sound_table16 ();
! 159: sample_handler = currprefs.sound_stereo ? sample16s_handler : sample16_handler;
1.1.1.2 root 160:
1.1 root 161: have_sound = 1;
162: sound_available = 1;
1.1.1.3 ! root 163: printf ("Sound driver found and configured at %d Hz, buffer is %d bytes\n", rate, sndbufsize);
1.1 root 164:
165: sndbufpt = sndbuffer;
166: return 1;
167:
168: nosound:
169: have_sound = 0;
170: close_sound();
171: return 0;
172: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.